Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Mai 14, 2024 07:17

Foren-Übersicht » Programmierung » Shader
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 23 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: So Feb 13, 2011 14:36 
Offline
DGL Member

Registriert: Do Mai 20, 2010 10:54
Beiträge: 10
Programmiersprache: C/C++
Hi, Du brauchst eigentlich nur für die Position eine RGBA32F-Textur, für alle weiteren Texturen würde ich das GL_RGBA8 Format verwenden.
Entsprechend der OpenGL 3(.3) Spezifikation kannst Du durchaus auch Texturen mit verschiedenen Formaten an einen Framebuffer binden.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: Sa Mär 05, 2011 16:26 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
So nach langer Zeit bin ich wieder zurück ;). Also ich machs doch jetzt mit einer Depth - Texture anstatt mit einer Vertex. Leider find ich im Internet fast gar nix darüber, wie man mittels Depth - Texture die 3D - Position eines bestimmten Pixels ermittelt. Also der Deferred - Shader sieht momentan wie folgt aus:

Fragment:
Code:
uniform sampler2D Texture0;   // Color - Texture
uniform sampler2D Texture1;   // Normal - Texture
uniform sampler2D Texture2;   // Depth - Texture

varying mat4 matProjectionInverse;
varying mat4 matModelView;

const float f = 10000.0;
const float n = 0.1;

void main() {
   vec2 texcoord = vec2(gl_TexCoord[0]);

   vec4 vColor = texture2D(Texture0, texcoord);
   float fDepth = texture2D(Texture2, texcoord).x;

   // Infinity = no light
   if(fDepth >= 1.0) {
      gl_FragColor = vec4(vColor.rgb, 1.0);
      discard;
   }

   vec4 vNormal = texture2D(Texture1, texcoord);
   vNormal.xyz = vNormal.xyz * 2.0 - 1.0;


   // === Hier liegt das Problem ===

   float fZ = (2.0 * n) / (f + n - fDepth * (f - n));

   vec4 vVertex = vec4(texcoord.xy, fDepth, 1.0) * matProjectionInverse;
   vVertex.xyz /= vVertex.w;

   // ==============================


   vec3 ISpecular = vec3(0.0, 0.0, 0.0);
   vec3 IDiffuse = vec3(0.0, 0.0, 0.0);
   vec3 vEye = normalize(-vVertex.xyz);
   float lightFactor;

   for(int i = 0; i < 8; i++) {
      if(gl_LightSource[i].constantAttenuation > 0.0) {
         if(gl_LightSource[i].position.w == 1.0) {
            lightFactor = 1.0 - min(distance(gl_LightSource[i].position.xyz, vVertex.xyz) / gl_LightSource[i].constantAttenuation, 1.0);
         }
         else {
            lightFactor = 1.0;
         }

         if(lightFactor > 0.0) {
            vec3 vLight = normalize(gl_LightSource[i].position.xyz - vVertex.xyz);
            vec3 Reflected = normalize(reflect(-vLight, vNormal.xyz));
            float fDiffuse = lightFactor * (vColor.w * gl_LightSource[i].diffuse.x);
            float fSpecular = lightFactor * (vNormal.w * gl_LightSource[i].specular.x);

            IDiffuse  += fDiffuse * max(dot(vNormal.xyz, vLight), 0.0);
            ISpecular += fSpecular * pow(max(dot(Reflected, vEye), 0.0), 128.0);
         }
      }
   }

   gl_FragColor = vec4((IDiffuse + ISpecular) * vColor.rgb, 1.0);
}



Vertex:
Code:
uniform float fProj[16];

varying mat4 matProjectionInverse;
varying mat4 matModelView;

void main(void) {
   mat4 matProjection;

   matProjection[0][0] = fProj[0];
   matProjection[0][1] = fProj[1];
   matProjection[0][2] = fProj[2];
   matProjection[0][3] = fProj[3];

   matProjection[1][0] = fProj[4];
   matProjection[1][1] = fProj[5];
   matProjection[1][2] = fProj[6];
   matProjection[1][3] = fProj[7];

   matProjection[2][0] = fProj[8];
   matProjection[2][1] = fProj[9];
   matProjection[2][2] = fProj[10];
   matProjection[2][3] = fProj[11];

   matProjection[3][0] = fProj[12];
   matProjection[3][1] = fProj[13];
   matProjection[3][2] = fProj[14];
   matProjection[3][3] = fProj[15];

   matProjectionInverse = gl_ModelViewProjectionMatrixInverse;
   matModelView = gl_ModelViewMatrix;

   gl_TexCoord[0] = gl_MultiTexCoord0;
   gl_Position = matProjection * gl_Vertex;
}


Also wenn ich die Kameraposition (nur die Position!) verändere, verändert sich auch das Diffuse - Licht. Weiß jemand wie man richtig die Position daraus berechnet? (Den oben gekennzeichneten Code mit der Berechnung der Position hab ich im Internet gefunden.)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: Sa Mär 05, 2011 17:00 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Was spricht gegen die Verwendung von gl_ProjectionMatrix bzw. gl_ProjectionMatrixInverse? Des weiteren kann man auch Uniforms vom Typ mat4 benutzen. Also diese Matrix-Kopieraktion ist definitiv nicht notwendig ;)

Mit gl_ProjectionMatrix bekommst du das was mittels glMatrixMode(GL_PROJECTION) gesetzt wurde. Also wenn du dein Screen-Quad für den Deferred Shader renderst müsstest du dann die alte Projektion setzen. Ist aber kein Problem da man zum rendern eines Screen-Quads ja keine Projektion braucht....bei mir sieht der Vertexshader meist einfach so aus:
Code:
void main() {
   gl_Position = vec4(gl_Vertex.xy, 0, 1);

   gl_TexCoord[0].st = gl_Vertex.st * vec2(0.5,0.5) + vec2(0.5,0.5);
   gl_TexCoord[0].pq = vec2(0,0);
}

Die Vertices (für zwei Dreiecke) sind die folgenden:
Code:
const float vertices[] = {
      -1.0,  1.0,
      1.0,  1.0,
      -1.0, -1.0,
      -1.0, -1.0,
      1.0,  1.0,
      1.0, -1.0
};


========

Also mit Hilfe der Tiefe und der inversen Projektionsmatrix die Vertexposition zu errechnen. Dafür brauchst du den Vertex in den sog. normalisierten Gerätekoordinaten (NDC). Das ist einfach ein Einheitswürfel von -1 bis 1. Für X und Y bekommst du das leicht aus den Texturkoordinaten, ist aber natürlich abhängig wierum deine Texcoord sind...also ggf. musst du noch spiegeln.
Code:
vec4 vertex;
vertex.xy = gl_TexCoord[0].st * 2.0 - 1.0;

Die Z-Koordinate ist natürlich davon abhängig was du da in deiner Textur hast. Der Wert dürfte aber zwischen 0 und 1 liegen denke ich mal. Dann musst du das auf die gleiche weise auf den -1...1 Bereich mappen.
Code:
vertex.z = fDepth * 2.0 - 1.0;

Der Rest ist dann klar:
Code:
vertex.w = 1.0;
vertex = vertex * gl_ProjectionMatrixInverse;
vertex *= 1.0/vertex.w;

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: Sa Mär 05, 2011 17:44 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Danke für die Antwort! Habs übernommen, aber scheinbar siehts leider immer noch so aus wie vorher :( ... Hab das Gefühl als würde die Vertexposition nicht richtig transformiert sein so wie die Lichtposition...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: So Mär 06, 2011 00:17 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
Problem gelöst :D. Nach langem Rumprobieren hab ich herausgefunden, dass es mit gl_ProjectionMatrixInverseTranspose anstatt mit gl_ProjectionMatrixInverse funktioniert. Läuft jetzt alles perfekt. Danke an alle :)! Wens interessiert, hier der Code:

Fragment:
Code:
uniform sampler2D Texture0;   // Color - Texture
uniform sampler2D Texture1;   // Normal - Texture
uniform sampler2D Texture2;   // Depth - Texture

varying mat4 matProjectionInverse;

void main() {
   vec2 texcoord = vec2(gl_TexCoord[0]);
   vec4 vColor = texture2D(Texture0, texcoord);
   float fDepth = texture2D(Texture2, texcoord).x;

   if(fDepth >= 1.0) {
      gl_FragColor = vec4(vColor.rgb, 1.0);
      discard;
   }

   vec4 vNormal = texture2D(Texture1, texcoord);
   vNormal.xyz = vNormal.xyz * 2.0 - 1.0;

   vec4 vVertex;
   vVertex.xy = gl_TexCoord[0].st * 2.0 - 1.0;
   vVertex.z = fDepth * 2.0 - 1.0;
   vVertex.w = 1.0;
   vVertex *= matProjectionInverse;
   vVertex *= 1.0/vVertex.w;

   float ISpecular = 0.0;
   float IDiffuse = 0.0;
   float lightFactor;

   vec3 vEye = normalize(-vVertex.xyz);

   for(int i = 0; i < 8; i++) {
      if(gl_LightSource[i].constantAttenuation > 0.0) {
         if(gl_LightSource[i].position.w == 1.0) {
            lightFactor = 1.0 - min(distance(gl_LightSource[i].position.xyz, vVertex.xyz) / gl_LightSource[i].constantAttenuation, 1.0);
         }
         else {
            lightFactor = 1.0;
         }

         if(lightFactor > 0.0) {
            vec3 vLight = normalize(gl_LightSource[i].position.xyz - vVertex.xyz);
            vec3 Reflected = normalize(reflect(-vLight, vNormal.xyz));
            float fDiffuse = lightFactor * (vColor.w * gl_LightSource[i].diffuse.x);
            float fSpecular = lightFactor * (vNormal.w * gl_LightSource[i].specular.x);

            IDiffuse  += fDiffuse * max(dot(vNormal.xyz, vLight), 0.0);
            ISpecular += fSpecular * pow(max(dot(Reflected, vEye), 0.0), 128.0);
         }
      }
   }

   gl_FragColor = vec4((IDiffuse + ISpecular) * vColor.rgb, 1.0);
}


Vertex:
Code:
varying mat4 matProjectionInverse;

void main(void) {
   matProjectionInverse = gl_ProjectionMatrixInverseTranspose;

   gl_TexCoord[0].st = gl_Vertex.st * vec2(0.5, 0.5) + vec2(0.5, 0.5);
   gl_TexCoord[0].pq = vec2(0.0, 0.0);

   gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);
}



Normal (Fragment):
Code:
varying vec3 vNormal;

void main(void) {
   vec3 vResult = (vNormal + 1.0) / 2.0;
   gl_FragColor = vec4(vResult, gl_FrontMaterial.specular.x);
}


Color (Fragment):
Code:
uniform sampler2D Texture0;

void main(void) {
   vec2 texcoord = vec2(gl_TexCoord[0]);
   vec3 vColor = texture2D(Texture0, texcoord).rgb;
   gl_FragColor = vec4(vColor, gl_FrontMaterial.diffuse.x);
}



gl_LightSource[i].constantAttenuation = Radius vom Licht
gl_LightSource[i].position.w ( 0 = unendlich strahlendes Licht, 1 = begrenzter Lichtradius)
vColor.w = Diffuse - Anteil
vNormal.w = Specular - Anteil


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: So Mär 06, 2011 11:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Nach langem Rumprobieren hab ich herausgefunden, dass es mit gl_ProjectionMatrixInverseTranspose anstatt mit gl_ProjectionMatrixInverse funktioniert.

Das liegt nur an meiner Dummheit das ich
vertex = vertex * gl_ProjectionMatrixInverse;
statt
vertex = gl_ProjectionMatrixInverse * vertex;
geschrieben habe ;)

Zitat:
varying mat4 matProjectionInverse;

Alle eingebauten Uniforms sind sowohl im Vertex- als auch im Fragmentshader verfügbar. Insofern ist es nicht nötig da ein Varying zu benutzen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: Di Mär 08, 2011 22:59 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
ich häng mich da mal nochmal dran:

renderst du nun via MRT die Szene mit einemmal in den FBO oder einfach nacheinander in verschiedene Texturen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Deferred Shading
BeitragVerfasst: Mi Mär 09, 2011 00:14 
Offline
DGL Member

Registriert: Sa Jun 05, 2010 16:15
Beiträge: 94
@Thmfrnk
Sowohl als auch ;). Habs so gemacht, das sich das an die Hardware anpasst. Also wenn MRT unterstützt wird, wirds auch verwendet. Ansonsten einzeln (2 Renderpasses).

Achja, hier könnt ihr das Ergebnis sehen (hab ein Benchmark - Programm damit gemacht):
http://xyross.de/bench/index.php?id=1


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 23 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.030s | 17 Queries | GZIP : On ]