DGL
https://delphigl.com/forum/

Problem mit Reflektion via glSlang
https://delphigl.com/forum/viewtopic.php?f=20&t=3104
Seite 1 von 2

Autor:  Sascha Willems [ Fr Jul 30, 2004 17:41 ]
Betreff des Beitrags:  Problem mit Reflektion via glSlang

Ich habe in meine Tech-Demo grade planare Reflektionen eingebunden, also im Gegensatz zur glSlang-Demo nutze ich keine Cubemap sondern rendere die Spiegelung in eine einzelne Textur, und lege die so auf die Spiegelfläche :
Code:
  1.  glMatrixMode(GL_TEXTURE);
  2.  glLoadIdentity;
  3.  glTranslatef(0.5, 0.5, 0);
  4.  glScalef(0.5, 0.5, 0);
  5.  gluPerspective(90, Owner.Owner.ClientWidth/Owner.Owner.ClientHeight, 0.01, 100000);
  6.  with Owner do
  7.   begin
  8.   glRotatef(Rotation.x, 1,0,0);
  9.   glRotatef(Rotation.y, 0,1,0);
  10.   glTranslatef(-Position.x, -Position.y, -Position.z);
  11.   end;
  12.  glScalef(1, -1, 1);
  13.  glMatrixMode(GL_MODELVIEW);
  14.  
  15.  if Length(FaceList) > 0 then
  16.   for f := 0 to High(FaceList) do
  17.    begin
  18.    glBegin(GL_TRIANGLES);
  19.     for v := 0 to 2 do
  20.      begin
  21.      glNormal3fv(@NormalArray[FaceList[f][v]]);
  22.      glTexCoord3f(VertexArray[FaceList[f][v]].x, VertexArray[FaceList[f][v]].y, VertexArray[FaceList[f][v]].z);
  23.      glVertex3fv(@VertexArray[FaceList[f][v]]);
  24.      end;
  25.    glEnd;
  26.    end;

Wie man sieht nutze ich die Texturenmatrix um die Koordianten der spiegelnden Fläche so anzupassen dass meine Spiegelung korrekt ist. Das funktioniert auch ohne Probleme.
Dann wollte ich via 3D-Noise (wie in meiner glsl-Water-Demo) die Spiegelfläche um einen Wassereffekt erweitern. Allerdings klappt irgendwie schon das normale Rendern der Spiegelfläche nicht wie ich will. Der Quellcode ist der selbe wie oben, aber zusätzlich werden folgende Shader genutzt :

VS :
Code:
  1. void main(void)
  2. {
  3.  gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
  4.  gl_TexCoord[0] = gl_MultiTexCoord0 * gl_TextureMatrix[0];
  5. }

FS :
Code:
  1. uniform sampler2D mirror;
  2.  
  3.  
  4. void main(void)
  5. {
  6.  gl_FragColor   = texture2D(mirror, gl_TexCoord[0].xy);
  7.  gl_FragColor.a = 1.0;
  8. }
  9.  


Also entweder stehe ich aufm Schlauch, oder es geht so nicht einfach via glSlang. Hat da evtl. jemand mal nen Hinweis wo es bei mir klemmt?

Autor:  LarsMiddendorf [ Fr Jul 30, 2004 18:01 ]
Betreff des Beitrags: 

Man müßte eigentlich projektives Texturing verwenden. Da gibt es die Texture Funktionen mit "proj" am Ende. Die Koordinaten s,t aus der Matrix müssen nochmal durch durch die q Koordinate dividiert werden.

So müßte es auch ohne Texture Matrix und die projektiven Funktionen funktionieren:

Vertex Shader:
fragpos:=gl_ModelViewProjectionMatrix * gl_Vertex;

Fragment Shader:
vec2 coord=(fragpos.xy/fragpos.w*vec2(-0.5,0.5))+0.5;

Autor:  Sascha Willems [ Fr Jul 30, 2004 21:21 ]
Betreff des Beitrags: 

Danke für die Tipps, aber irgendwie steh ich entweder aufm Schlauch, oder irgendwo hakt bei glSlang etwas. Ich hab mich mal durchs Netz gewühlt und diesen Thread auf gamedev.net gefunden, in dem die Technik recht genau beschrieben wird. Den festen Teil hab ich ja bereits so gemacht (und der ging ja auch), und dann hab ich mal die dort von Yann L geposteten cG-Shader nach glSlang "portiert" (war ja recht popelig), aber die Reflektionen funzen trotzdem nicht. Hier mal die neuen Shader :

VS :
Code:
  1. varying vec4 ProjCoords;
  2.  
  3. void main(void)
  4. {
  5.  gl_Position  = gl_ModelViewProjectionMatrix * gl_Vertex;
  6.  ProjCoords = gl_Vertex * gl_TextureMatrix[0];
  7. }


FS :
Code:
  1. uniform sampler2D mirror;
  2. varying vec4 ProjCoords;
  3.  
  4. void main(void)
  5. {
  6.  gl_FragColor   = texture2DProj(mirror, ProjCoords);
  7. }


Die sind ja so simple, und die FF-Variante geht ja auch, so dass ich irgendwo schon langsam zur Überzeugung komme dass es da in glSlang selbst ein Problem mit den Texturmatrizen gibt, denn im Endeffekt dürfte obiger Shader ja nix anderes machen als die feste Pipeline auch tun würde, oder?

Autor:  LarsMiddendorf [ Fr Jul 30, 2004 21:43 ]
Betreff des Beitrags: 

Ich bin mir nicht ganz sicher ob's daran liegen könnte aber gl_Vertex * gl_TextureMatrix[0] und gl_TextureMatrix[0]*gl_Vertex ist ja nicht dasselbe.
Eine Alternative wäre direkt die Koordinaten des Fragments zu skalieren und damit auf die Texture zu zugreifen.

Autor:  Sascha Willems [ Fr Jul 30, 2004 21:47 ]
Betreff des Beitrags: 

LarsMiddendorf hat geschrieben:
Ich bin mir nicht ganz sicher ob's daran liegen könnte aber gl_Vertex * gl_TextureMatrix[0] und gl_TextureMatrix[0]*gl_Vertex ist ja nicht dasselbe.


:? *grml*, und seit Stunden bin ich am rumprobieren. Dickes Dankeschön für den Hinweis, nämlich genau DAS war das Problem. gl_TextureMatrix[0] * gl_Vertex; klappt wunderbar und es sieht jetzt mit dem Shader so aus wie es auch mit der FF aussehen sollte.

Autor:  La Boda [ So Aug 01, 2004 17:35 ]
Betreff des Beitrags: 

Hallo,
nur eine kurze Frage:
Warum sind gl_Vertex * gl_TextureMatrix[0] und gl_TextureMatrix[0]*gl_Vertex nicht dasselbe, das geht jetzt über meinen mathematischen Horizont hinaus?

Danke,
La_Boda

Autor:  Sascha Willems [ So Aug 01, 2004 17:44 ]
Betreff des Beitrags: 

Hätt ich selbst mal genauer in die Specs gesehen, dann wäre mir auch Kapitel 5.10 aufgefallen (und Lars hätte mich nicht darauf hinweisen müssen ;) ), in dem genau dass beantwortet wird :

Code:
  1. The exceptions
  2. are matrix multiplied by vector, vector multiplied by matrix, and matrix multiplied by matrix. These do
  3. not operate component-wise, but rather perform the correct linear algebraic multiply. They require the
  4. size of the operands match.
  5.  
  6. vec3 v, u;
  7. mat3 m;
  8. u = v * m;
  9.  
  10. is equivalent to
  11.  
  12. u.x = dot(v, m[0]); // m[0] is the left column of m
  13. u.y = dot(v, m[1]); // dot(a,b) is the inner (dot) product of a and b
  14. u.z = dot(v, m[2]);
  15.  
  16. And
  17.  
  18. u = m * v;
  19.  
  20. is equivalent to
  21.  
  22. u.x = m[0].x * v.x + m[1].x * v.y + m[2].x * v.z;
  23. u.y = m[0].y * v.x + m[1].y * v.y + m[2].y * v.z;
  24. u.z = m[0].z * v.x + m[1].z * v.y + m[2].z * v.z;
  25.  


gl_Vertex * gl_TextureMatrix[0] wäre demnach also gl_Vertex DOT gl_TextureMatrix[0], und gl_TextureMatrix[0]*gl_Vertex eine komponentenweise Addition.

Autor:  LarsMiddendorf [ So Aug 01, 2004 17:46 ]
Betreff des Beitrags: 

Das eine ist zeilenweise und das andere spaltenweise Multiplikation.
Ein Vektor ist ja auch eine Matrix und damit ist eine Multiplikation zwischen Vektor und Matrix ja eigentlich eine Matrizenmultiplikation. Und die Multiplikation zwischen Matrizen ist nicht kommutativ.

Autor:  Sascha Willems [ Mi Aug 04, 2004 19:59 ]
Betreff des Beitrags: 

Bisher schien die Reflektion genauso so laufen wie es sollte, allerdings habe ich die Tage nen weiteren Testraum erstellt, aber dort liegt die reflektierende Wasserfläche nicht auf Null-Höhe, sondern recht weit unten und die Reflektion wie quasi an den Rändern abgeschnitten, wie auf folgendem Shot zu sehen :

Bild

Man sieht also nur einen Teil der Reflektion, der schwarze Teil sollte aber natürlich auch die Reflektion beinhalten. Ich habs jetzt ein paar Tage lang probiert hinzubiegen, aber ich hab echt keinen blassen Schimmer mehr was ich da machen soll. "Geholfen" hat eigentlich nur eine Erhöhung des FOVs für den "Spiegel", wodurch sich der abgeschnittene Bereich verkleinet hat. Aber ein FOV von 130° reicht dann trotzdem nicht, und das kann ja auch keine Lösung sein. Also hatt da evtl. jemand ne Idee zur Hand, wie man das korrekt lösen kann? Wäre über jede Hilfe dankbar, denn ich häng da jetzt schon recht viele Stunden dran.

Autor:  Flash [ Do Aug 05, 2004 13:53 ]
Betreff des Beitrags: 

Öhm...Das is doch sowas wie ein Brunnen oder!?
Und du möchtest, dass sich der Brunnenschacht auch spiegelt!?

Hast du denn überhaupt einen Schacht der sich Spiegeln kann?
Wenn da (absichtlich) kein Schacht ist: sind deine Texturen zweiseitig?

Kann natürlich auch sein, du meinst was dodal anderes.

Autor:  Sascha Willems [ Do Aug 05, 2004 13:57 ]
Betreff des Beitrags: 

Ja, ich mein was total anderes. Da gibts keinen Schach, sondern nur eine Fläche die das was darüber ist spiegelt. Und das geht wie gesagt einwandrei solange die Fläche auf Y=0 liegt, ansonsten werden Teile beim Rendern in die Spiegeltextur weggeclippt, was dann nicht sein soll.

Autor:  Sascha Willems [ Do Aug 05, 2004 20:05 ]
Betreff des Beitrags: 

OK, ich geb zu dass obiger Screenshot recht unaussagekräftig ist, weshalb ich mal ne neue Version nachliefere :

Bild

Wie man oben rechts sehen kann, wird die Textur (die die Spiegelung enthält) korrekt erstellt (sieht zumindest so aus), aber (siehe schwarze Fläche) die Texturkoordinaten für die Projektion der Spiegeltextur auf die Spiegelfläche werden nicht mehr korrekt generiert, sobald die Spiegelfläche nicht mehr bei y=0 liegt. Wenn man das genauer betrachtet, dann sieht es so als würden die Koordinaten gegen das Frustum geclippt, denn je nach Betrachtungswinkel sieht man den für ein Frustum typischen kegelförmigen Ausschnitt.

Hab mich jetzt auch stundenlang durchs Netz gearbeitet, und v.a. auf gamedev.net recht viel gefunden, aber in eigentlich jedem Thread wird davon ausgegangen dass sich dei Spiegelfläche bei y=0 befindet, was dann ja in der Beziehung keine Probleme macht. Das ist bei solchen Sachen wie ner Landschaft natürlich akzeptabel, aber ich will meine Wasserfläche gerne überall positionieren können.

Bin also über jede Hilfestellung dankbar!

Autor:  Raphael O. [ Do Aug 05, 2004 20:20 ]
Betreff des Beitrags: 

könntest du das Programm evtl. mal hochladen (da sieht man das dann noch etwas besser, auch wenn ich mir das ejtzt einigermaßen vorstellen kann, würde ich gerne das Verhalten bei Bewegung der Kamera/Szene mal sehen...)

Autor:  Sascha Willems [ Do Aug 05, 2004 20:28 ]
Betreff des Beitrags: 

Nein, das Programm hat mit allem drum-und-dran weit über 30 MByte und braucht ne PS2.0-Karte, ausserdem ists noch alles andere als fertig. Von daher gibts da momentan nichts Hochladbares.

Autor:  Raphael O. [ Do Aug 05, 2004 20:32 ]
Betreff des Beitrags: 

ich dachte du hättest das Problem eh in ein Demotool gekapselt um einen FEhler, der woanders herkommt auszuschließen bspw..

dann ists auch egal..

man schaut doch in einem zylinder quasi nach unten, auf den screenshots, oder?
für mich sieht es irgendwie nicht aus, als ob der Boden das gleiche Niveau hat, auf dem auch der MAntel endet, das ist aber schon so, oder?
(wobei das ja nicht direkt mit dem eigentlichen Problem des "geclippten" zu tun hat...
nur sowas hätte man sich in Bewegung eben genauer anscheuen können und so kann man nur spekulieren ;-)

(bin z.Z. nicht zu Hause und auf der Radeon 9600(?) hier läuft sogar glsl usw. :-) )

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