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

Aktuelle Zeit: Fr Jul 18, 2025 17:03

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



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Texturmatrix im Fragmentshader
BeitragVerfasst: Mo Apr 02, 2007 15:42 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hallo erstmal,

ich hab mich in den letzten wochen mal etwas intensiver mit Shadern auseinander gesetzt und bin jetzt promt ein Problem gestoßen:

Erstmal mein Ziel: ich habe eine Szene, dich ich zuerst spiegele und dann in eine Textur render. (Also eine Textur als Spiegel...). Soweit ist die Welt ja noch in Ordnung, meine Szene wird korrekt gerendert und ausgegeben. Nun will ich die Spiegelfläche mit einem Shader modifizieren (erstmal ein einfacher Texturewrapper, der eine spiegelnde Wasseroberfläche erstellen soll). Und jetzt beginnt mein Problem:

Da ich für die korrekte Darstellung der Reflektionstextur die Texturmatrix ändere, funktioniert mein Shader nicht mehr so ganz. Ich habe bereits viel im Shader ausprobiert (gl_TexCoord mit der TexturMatrix mulitpliziert usw.) aber nichts hat wirklich funkioniert.



Ich poste mal die wichtigsten Teile meines Quelltextes, um die Sache etwas verständlicher zu machen:

Die gespiegelte Szene wird hier in die Textur kopiert:
Code:
  1.  
  2.   glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, ForItem.ReflectionTexWidth, ForItem.ReflectionTexHeight);
  3.  


Bevor ich die Textur rendere, verändere ich noch die Texturmatrix. Sonst wird die Textur nicht korrekt auf das Quad gezeichnet:
Code:
  1.  
  2. glMatrixMode(GL_TEXTURE);      
  3.   glLoadIdentity;
  4.   glTranslatef(0.5, 0.5, 0);
  5.   glScalef(0.5, 0.5, 0);
  6.   gluPerspective(45, Engine_RenderOptions.iViewPortWidth/Engine_RenderOptions.iViewPortHeight, 0.001, 128);
  7.  
  8.   glMultMatrixf(@Engine_RenderOptions.mCameraMatrix);
  9. glMatrixMode(GL_MODELVIEW);                                
  10. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  11. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  12. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  13. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  14. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  15.  

Jetzt das Rendern des Quads (GL_TEXTURE0_ARB ist die "Normal-Textur", die die Wasseroberfläche simuliert, GL_TEXTURE1_ARB ist die Reflektionstextur) (Nicht wundern, dass die Texturkoordinaten gleich mit den Vertex-Koordinaten sind. Ich hab mir den Quelltext von einer Demo von Delphi3d.net abgekupfert - meine selbstgeschriebene Reflektionsfunktion usw. hat hinten und vorne nicht funkioniert)

Code:
  1.  
  2. glBegin(GL_QUADS);
  3.   glMultiTexCoord2fvARB(GL_TEXTURE0_ARB, TexturePos1);
  4.   glMultiTexCoord3fvARB(GL_TEXTURE1_ARB, VertexPos1);
  5.   glVertex3f(VertexPos1);
  6.  
  7.  
  8.   glMultiTexCoord2fvARB(GL_TEXTURE0_ARB, TexturePos2);
  9.   glMultiTexCoord3fvARB(GL_TEXTURE1_ARB, VertexPos2);
  10.   glVertex3f(VertexPos2);
  11.  
  12.  
  13.   glMultiTexCoord2fvARB(GL_TEXTURE0_ARB, TexturePos3);
  14.   glMultiTexCoord3fvARB(GL_TEXTURE1_ARB, VertexPos3);
  15.   glVertex3f(VertexPos3);
  16.  
  17.  
  18.   glMultiTexCoord2fvARB(GL_TEXTURE0_ARB, TexturePos4);
  19.   glMultiTexCoord3fvARB(GL_TEXTURE1_ARB, VertexPos4);
  20.   glVertex3f(VertexPos4);
  21. glEnd();
  22.  


So, das waren die Render-Sachen in Delphi - jetzt zu meinem Shader:
Code:
  1.  
  2. // Vertex Shader
  3. void main(void)
  4. {
  5.   gl_TexCoord[0] = gl_MultiTexCoord0 ;
  6.   gl_TexCoord[1] = gl_MultiTexCoord1 ;
  7.   gl_Position = ftransform();
  8.   gl_FrontColor = gl_Color;
  9. }
  10.  
  11.  
  12. // Fragment Shader
  13. uniform float     syg_Render_Time_TotalTime;     // die aktuelle Zeit in Sekunden
  14. uniform sampler2D syg_Object_Texture_1;          // das ist die Normal-Textur
  15. uniform sampler2D syg_Object_Texture_1_Reflect;  // und das die Reflektionstextur
  16.  
  17. void main(void)
  18. {
  19.   vec3 noiseVec;
  20.   vec2 displacement;
  21.   float scaledTimer;
  22.  
  23.   displacement = gl_TexCoord[0].st;
  24.  
  25.   scaledTimer = syg_Render_Time_TotalTime*0.1;
  26.  
  27.   displacement.x += scaledTimer;
  28.   displacement.y -= scaledTimer;
  29.  
  30.   noiseVec = normalize(texture2D(syg_Object_Texture_1, displacement.xy).xyz);
  31.   noiseVec = (noiseVec * 2.0 - 1.0) * 0.035;
  32.  
  33.   vec4 FragColorA;
  34.   float Alpha;
  35.   Alpha = gl_Color.a;
  36.   FragColorA = texture2D(syg_Object_Texture_1_Reflect, gl_TexCoord[0].st + noiseVec.xy);  
  37.   FragColorA.w = Alpha;
  38.              
  39.   gl_FragColor = FragColorA;
  40. }
  41.  


ich habe mal 3 screenshots gemacht, um das Problem nochmals zu verdeutlichen:

In Bild 1 sieht man ganz deutlich (oder auch nicht so deutlich ... aber bei genauem hinsehen ... in Realtime funkionierts - das könnt ihr mir glauben :-) ), dass der shader schon mal seine dienste ausführt

In Bild 2 sieht man, dass die Reflektionstextur OHNE shader korrekt plaziert wird

In Bild 3 sieht man das eigentliche Problem: die Texturmatrix wird vom Shader nicht übernommen (aber auch hier ist eine leichte Refraction bemerkbar :-) )


Ich danke schon mal für die Hilfe


Dateianhänge:
Dateikommentar: Bild 3
Shader-Geht schief.jpg
Shader-Geht schief.jpg [ 182.49 KiB | 5656-mal betrachtet ]
Dateikommentar: Bild 2
Reflektionstest.jpg
Reflektionstest.jpg [ 218.25 KiB | 5656-mal betrachtet ]
Dateikommentar: Bild 1
Shader-ShaderTest.jpg
Shader-ShaderTest.jpg [ 196.2 KiB | 5656-mal betrachtet ]

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 03, 2007 14:25 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Hm also rein gefühlsmäßig würde ich schon im Vertexshader die Multiplikation mit der Matrux durchführen und das dann weiterleiten. (mit uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];)
Aber mal ne andere Frage:


Code:
  1.   displacement = gl_TexCoord[0].st;

Wieso nimmst du da .st und nicht .xy?

_________________
__________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 03, 2007 15:36 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Hm, die Texturkoordinate bereits im Vertexshader mit der Texturmatrix multiplizieren ... klingt nicht schlecht. Das hab ich noch nicht ausprobiert ... werd es heute abend aber bestimmt probieren.

Pellaeon hat geschrieben:
Code:
  1.   displacement = gl_TexCoord[0].st;

Wieso nimmst du da .st und nicht .xy?


Das ist mir noch garnicht aufgefallen. Hab den Shader mal irgendwie zusammengeschnipselt ... z.t. per Copy&Paste&Forget - ich kann das ja ebenfalls mal ändern, und schauen, ob es einen unterschied macht. (vom gefühl her würde ich sagen - eher nicht)

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 03, 2007 16:03 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Naja mich wunderts einfach vom Syntax her, hab das noch nie gesehen und auch nichts in der Spezifikation dazu gefunden, daher meine Frage.

_________________
__________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 03, 2007 17:54 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Ich glaub das hab ich irgendwann ziemlich spät nachts geschrieben. Wahrscheinlich hab ich da gerade an die Texturparameter r, s und t gedacht. Aber genau weiß ich das nicht mehr. Es hat funktioniert und das war mir in dem Moment am wichtigsten :-)

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 04, 2007 13:04 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
s und t sind korrekt stat dessen konnte man auch r und g schreiben.... Die Texturkoordinaten müssen im Vertexshader mit der entsprechneden Texturmatrix multipliziert werden. In den meisten shadern lässt mn das aus performance gründen weg. Wenn immer die gleiche texturmatrix verwendet wird macht es auch sinn diese direkt im shder einzucoden, da man so konstanten verwenden kann die möglicher weise schneller sind und eventtuel einige unötige operatiuonen wegoptimieren kann.
Performance tip: Benutz ein FBO um direkt in die textur zu rendern. Dann entfällt das kopieren...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 04, 2007 17:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Zitat:
Performance tip: Benutz ein FBO um direkt in die textur zu rendern. Dann entfällt das kopieren.

Also wenn ich jetzt noch nen Framebuffer-Objekt einbaue und der dann vieleicht noch nen Bug hat, dann find ich meinen Fehler wohl nicht mehr so einfach. Falls der Shader funkioniert, wäre diese Methode sehr sinnvoll, doch bis dahin dauerts wahrscheinlich noch nen Meter...


@Topic: Also ich habs jetzt so geschafft, dass die Texturmatrix der Reflektion korrekt benutzt wird.
Code:
  1.  
  2. // vertex shader
  3. // ...
  4.   gl_TexCoord[0] = gl_MutliTexCoord0 * gl_TextureMatrix[0];
  5.   gl_TexCoord[1] = gl_MutliTexCoord1 * gl_TextureMatrix[1];
  6.  


das hat schon mal sehr viel auswirkungen gehabt - vor allem auch noch in die richtige Richtung :-)

Aber nun kommt ein neues Problem:
Code:
  1.  
  2.   gluPerspective(45, Engine_RenderOptions.iViewPortWidth/Engine_RenderOptions.iViewPortHeight, 0.001, 128);
  3.  


Diese Funktion müsste ich noch in den Fragmentshader bekommen. Im endefekt ist ja gluPerspective nur:
Code:
  1.  
  2. procedure OwnPerspective(fovY, aspect, zNear, zFar: double)
  3. var fW, fH : double;
  4. begin
  5.   fH = tan( fovY / 360 * pi ) * zNear;
  6.   fW = fH * aspect;
  7.   glFrustum( -fW, fW, -fH, fH, zNear, zFar );
  8. end;
  9.  


Doch wie bekomm ich glFrustum in Vertex/Fragmentshader hin?????
Diese Funktion ist sehr wichtig, da die Textur dardurch korrekt an die Vertex-ecken gebunden wird.


BTW: ich hab mal mit "texture2DProj" rumgespielt - dadurch bekomm ich schon ein fast perfektes ergebnis - nur dass die Textur noch nicht ganz bis zum Rand gezeichnet wird. Deswegen gleich noch ne Frage: was ist der Unterschied zwischen texture2D(...,...) und texture2DProj(...,...)?

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 04, 2007 17:29 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 15:54
Beiträge: 372
Wohnort: München
Programmiersprache: Delphi, C#, FPC
Oh, mir ist da ein blöder Anfängerfehler unterlaufen!!!

Hätt ich doch die Forum-Suche bereits etwas früher genutzt ... verdammt. Naja, sorry ... falls wer zu faul zum suchen ist: http://www.delphigl.com/forum/viewtopic.php?t=3104&highlight=texture2dproj

_________________
Aktuelles Projekt: Gael - Development Blog
Website: LightBlackSoft.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 09:33 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
glSlang-Spec hat geschrieben:
Use the texture coordinate coord to do a
texture lookup in the 2D texture currently
bound to sampler. For the projective
(“Proj”) versions, the texture coordinate
(coord.s, coord.t) is divided by the last
component of coord. The third component
of coord is ignored for the vec4 coord
variant.


Ich würde das mal so interpretieren: normalerweise sind ja Texturkoordinaten nur x,y. Durch das Nutzen der Texturmatrix kann es aber passieren, dass sich im z was ändert. Damit das dann wieder im PS stimmt, gibts die Proj-Variante.

_________________
__________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.030s | 18 Queries | GZIP : On ]