DGL
https://delphigl.com/forum/

Shader- & CubeMap-Problem
https://delphigl.com/forum/viewtopic.php?f=20&t=5824
Seite 1 von 1

Autor:  WhiteHunter [ Fr Aug 18, 2006 00:58 ]
Betreff des Beitrags:  Shader- & CubeMap-Problem

Hi,

ich hab da ein kleines Problemchen, an dems grade happert. Ich rendere eine SkyBox mit einer CubeMap. Davor drehe ich die Texturen entsprechend einer Dauerrotation, danach zurück und um 180° (was seltsamerweise nur mit glRotatef(Pi, 0, 1, 0); funktioniert, obwohl alle anderen (Textur-)Rotationen in Grad erfolgen; was aber nichts mit dem Problem zu tun hat) verdreht, damit es auf dem nun gerenderten kleinen Cube vor mir gespiegelt aussieht. Nun will ich da noch einen Shader drauflegen. Allerdings lasse ich derzeit OpenGL mittels glTexGen bzw. über die glBitmap.pas die Texturkoordinaten berechnen. Nun sind diese anscheinend nicht in glSlang verfügbar, da der Cube typisch texturkoordinatenlos-einfarbig blieb. Das brachte mich dann auf diesen Thread, wo es zwar nicht um CubeMaps geht, was aber auch nicht mein Problem löst.

Zusammengefasst:
  • Mit Angaben von 2-dimensionalen Texturkoordinaten erhalte ich ein seltsam verzerrtes Bild mit Strahlen, zwar nicht vom Vertex- sondern vom Bildschirm-Mittelpunkt ausgehend, die texturähnliche Farben haben. Siehe auch Bild imAnhang.
  • Mit Angaben von 3-dimensionalen Texturkoordinaten erhalte ich zwar eine Textur, aber nur eine statische Fassung.
  • Mit der ObjectPlane- oder EyePlane-Lösung aus dem oben genannten Thread
    Code:
    1. vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
    2. gl_TexCoord[0].s = dot( ecPosition, gl_ObjectPlaneS[0] );
    3. gl_TexCoord[0].t = dot( ecPosition, gl_ObjectPlaneT[0] );
    4. gl_TexCoord[0].p = dot( ecPosition, gl_ObjectPlaneR[0] );
    5. gl_TexCoord[0].q = dot( ecPosition, gl_ObjectPlaneQ[0] );
    6.  

    das gleiche Ergebnis wie mit 2-dimensionalen Texturkoordinaten
  • Mit deaktiviertem Shader funktioniert alles wunderbar, der Shader wird auch ohne Meldung kompiliert.

=> Wie kann ich also nun meine CubeMap mit glTexGen wie in glBitmap.pas mit einem Shader benutzen?

Hier nochmal mein derzeitiger kompletter Shadercode, falls doch irgendwo Fehler sein sollten:
Vertex:
Code:
  1. void main(void)
  2. {
  3.         vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
  4.         gl_TexCoord[0].s = dot( ecPosition, gl_ObjectPlaneS[0] );
  5.         gl_TexCoord[0].t = dot( ecPosition, gl_ObjectPlaneT[0] );
  6.         gl_TexCoord[0].p = dot( ecPosition, gl_ObjectPlaneR[0] );
  7.         gl_TexCoord[0].q = dot( ecPosition, gl_ObjectPlaneQ[0] );
  8.         gl_Position = ftransform();
  9. }

Fragment:
Code:
  1. uniform samplerCube texUnit1;
  2.  
  3. void main(void)
  4. {
  5.         gl_FragColor = textureCube(texUnit1, vec3(gl_TexCoord[0]));
  6. }

"Intern":
Code:
  1. tCubeMap := TGLBitmapCubeMap.Create;
  2.   for i := 0 to 5 do
  3.   begin
  4.     tCubeMap.LoadFromFile(ExtractFilePath(Application.ExeName)+'tex\cubemap'+tex[i]+'.bmp');
  5.     tCubeMap.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB+i);
  6.   end;
  7.    tCubeMap.Bind;
  8. ....
  9. glUniform1i(glGetUniformLocationARB(SP.GetObject, PGLCharARB('texUnit1')), 0);
  10.  

(glBitmap.pas Version 1.8.9 und dglOpenGL-Header Version 2.0)
Falls es eine Rolle spielen sollte, Treiber ist 91.31 ForceWare auf einem NV 7900GT-Chip und wie gesagt, ansonsten funktioniert alles prächtig.
Schonmal Danke im Voraus und fürs Durchlesen, ist etwas lang geworden.

MfG

Dateianhänge:
Dateikommentar: beschriebenes Renderverhalten, siehe Posting
screen_error1.jpg [177.1 KiB]
72-mal heruntergeladen

Autor:  Sascha Willems [ Fr Aug 18, 2006 12:23 ]
Betreff des Beitrags: 

Zumindest in der 87.xxer Treiberreihe gabs (wenn ich recht entsinne) Probleme mit der Texturkoordinatengenerierung bei Nutzung von glsl, aber evlt. helfen die Shader hier weiter, die ich "damals" für meine 3D-Engine geschrieben habe, die verzichten da nämlich komplett drauf :

Vertexprogramm :
Code:
  1. uniform vec4 light;
  2.  
  3. varying vec4 V_eye;
  4. varying vec4 L_eye;
  5. varying vec4 N_eye;
  6. varying vec3 normal;
  7.  
  8. void main()
  9.  {
  10.  V_eye = gl_ModelViewMatrix * gl_Vertex;
  11.  L_eye = (gl_ModelViewMatrix * light) - V_eye;
  12.  N_eye = vec4(gl_NormalMatrix * gl_Normal, 1.0);
  13.  
  14.  gl_Position = gl_ProjectionMatrix * V_eye;
  15.  V_eye = -V_eye;
  16.  
  17.  normal         = gl_Normal;
  18.  }
  19.  


Fragmentprogramm :
Code:
  1. uniform samplerCube cubemap;
  2.  
  3. varying vec3 normal;
  4. varying vec4 V_eye;
  5. varying vec4 L_eye;
  6. varying vec4 N_eye;
  7.  
  8. const float sharpness = 0.1;
  9.  
  10. void main()
  11.  {
  12.  gl_FragColor = textureCube(cubemap, normal, 0);
  13.  }
  14.  

Autor:  WhiteHunter [ Fr Aug 18, 2006 13:45 ]
Betreff des Beitrags: 

Nach einigem Ausprobieren und Weitersuchen bin ich auf eine Variante, mit zwar nicht identischen, aber für mich erstmal ausreichenden Ergebnissen "gestoßen":

Vertex:
Code:
  1. void main()
  2. {
  3.         gl_Position = ftransform();
  4.         gl_TexCoord[0] = ((gl_TextureMatrix[0] * gl_ModelViewMatrix)
  5.                             * gl_Vertex) * vec4(1.0, 1.0, -1.0, 1.0);
  6. }


Im Fragment die normale Texturkoordinatenübernahme.
Mich hat zunächst die gespiegelte Matrix überrascht, aber da es soweit funktioniert, dürfte es kein totaler Blödsinn sein.

MfG

Autor:  WhiteHunter [ Di Aug 22, 2006 10:37 ]
Betreff des Beitrags: 

Nun hat mich die Sache irgendwie nicht losgelassen, da es bis jetzt nicht sonderlich gut aussieht und ich glaube, ich habe auch eine korrekte Lösung gefunden.
Also hab ich mir mal die Specifications zu OpenGL 2.0 angesehen. Dort fand sich Folgendes zu glTexGen:
Zitat:
If TEXTURE GEN MODE indicates REFLECTION MAP, compute the reflection
vector r as described for the SPHERE MAP mode. Then the value assigned to an
s coordinate is s = rx; the value assigned to a t coordinate is t = ry; and the value
assigned to an r coordinate is r = rz.
[...]
SPHERE MAP texture coordinates are generated
as follows. Denote the unit vector pointing from the origin to the vertex
(in eye coordinates) by u. Denote the current normal, after transformation to eye
coordinates, by nf . Let r = ( rx ry rz )T , the reflection vector, be given by
r = u − 2nfT (nfu) , [...]

Nun klingt "unit vector pointing from the origin to the vertex (in eye coords)" für mich wie
Code:
  1. normalize(gl_Vertex * gl_ModelViewMatrix);
  2.  

und "current normal, after transformation to eye coords" auch wie
Code:
  1. normalize(gl_Normal * gl_NormalMatrix);
  2.  

Nun gibt es in glSlang auch reflect(I, N), was "I – 2 * dot(N, I) * N" berechnet. Da nun REFLECTION_MAP und reflect irgendwie beieinander liegen, müsste die transponierte Matrix weiter oben irgendwie auch für ein Skalarprodukt stehen (zumindest hab ich da irgendwas in Erinnerung).
Daraus hab ich jetzt das gebastelt:
Code:
  1.  
  2. void main()
  3. {
  4.     gl_Position = ftransform();
  5.     vec3 verNormal = normalize(gl_NormalMatrix * gl_Normal);
  6.     vec4 verPosition = normalize(gl_ModelViewMatrix * gl_Vertex);
  7.     gl_TexCoord[0] = vec4(reflect(vec3(verPosition), verNormal), 1.0);
  8. }
  9.  

Für mich sieht es derzeit ziemlich passend aus, obwohl mir aufgefallen ist, dass ich dringend Normalen korrigieren und noch was an der Textur-Drehung feilen muss. Auf jedenfall Danke an Sascha für Codeschnipsel, der mir einiges an Anregung gegeben hat.
Sollte nun doch jemand noch einen meiner berühmten Denkfehler entdecken, immer her damit. ;)

MfG

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/