DGL
https://delphigl.com/forum/

Variable an Shader übergeben
https://delphigl.com/forum/viewtopic.php?f=20&t=11038
Seite 2 von 3

Autor:  mathias [ So Dez 08, 2013 23:08 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Meinst du mit glUniformMatrix4fv, nur dies führte nicht zum Ziel.

Autor:  glAwesome [ So Dez 08, 2013 23:29 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Du schriebst doch schon, dass die Rotationsmatrizen eigentlich funktionieren. Wenn ich dich richtig verstanden habe, hast du also auf der CPU die Matrizen berechnet und mittels glUniformMatrix4fv zur Grafikkarte hochgeladen.

Wenn du jetzt nicht um den Koordinatenursprung drehen möchtest, benötigst du zusätzlich Translationen. Also wenn du um den Punkt P rotieren möchtest, translierst du erst um -P, rotierst dann und anschließend machst du wieder eine Translation um P. Das alles kannst du in eine 4x4-Matrix stecken, indem du die Translationsmatrix mit der Rotationsmatrix multiplizierst und die resultierende Matrix mit der anderen Translationsmatrix multiplizierst. Das was du jetzt raus hast, übergibst du an den Shader.

Das ist auch genau das, was die OpenGL1-Funktionen gemacht haben. Dort lag ganz oben auf dem Matrixstack die aktuelle Modelview-Matrix, die du mit glLoadIdentity() auf die Einheitsmatrix gesetzt hast. Dann hättest du glTranslate aufgerufen, was eine Translationsmatrix erstellt und die Modelview-Matrix damit multipliziert (nicht ersetzt). Analog bei glRotate: Erst wurde eine Rotationsmatrix berechnet und dann wurde die aktuelle Matrix mit dieser Rotationsmatrix multipliziert.

Autor:  mathias [ Mo Dez 09, 2013 17:06 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Habe ich dich richtig verstanden, ich kann die Rotate× Proceduren, welche ich geschrieben habe, in den Shader verschieben ?

Autor:  glAwesome [ Mo Dez 09, 2013 17:27 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Nein. Die Matrizen, egal ob für Rotation, Translation oder Skalierung (oder eine Kombination aus allen) berechnet die CPU. Die fertig berechnete Matrix wird dann an die GPU übergeben, und zwar mit glUniformMatrix4fv. Die Grafikkarte (genauer: der Vertexshader) multipliziert dann die Vertices mit der Matrix.

Autor:  mathias [ Mo Dez 09, 2013 22:46 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Ist sowas möglich ?

VertexShader:
Code:
  1. ...
  2. void Multi(in mat4 m1, in mat4 m2, out mat4 m3)
  3. {
  4.   m3 = m1 * m2;
  5. }
  6. ...   

Code:
  1. ...
  2.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m1')), 1, False, @fEingabe1Matrix);
  3.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m2')), 1, False, @fEingabe2Matrix);
  4.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m3')), 1, False, @fAusgabeMatrix);
  5. ...  

Autor:  glAwesome [ Mo Dez 09, 2013 23:03 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Ja, das geht. Ist das etwa der Versuch, eine eigene Implementierung der Matrixmultiplikation zu umgehen? :wink:
(Du wirst früher oder später sowieso nicht umhin kommen.)

Autor:  mathias [ Mo Dez 09, 2013 23:19 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Nur hat es nicht funktioniert.
Ich probiere gerne Sachen aus, bevor ich was ernsthaftes mache.

Autor:  glAwesome [ Di Dez 10, 2013 09:09 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Also die in GLSL eingebauten Matrixfunktionen funktionieren praktisch per Definition. Es ist daher eine gute Idee, zu prüfen, ob die eigene Implementation das Gleiche tut. Wenn es trotzdem nicht klappt, wie es soll, muss es an was anderem liegen. Entweder du berechnest die Matrizen m1 und m2 falsch oder das, was du mit m3 machst, ist nicht das, was du eigentlich willst. Eine häufige Fehlerquelle ist auch das Durcheinanderbringen von spalten- und zeilenweiser Speicherung (man kann beides machen, aber man muss es einheitlich tun) der Matrizen bzw. der Multiplikationsreihenfolge. Wenn du statt
Code:
  1. m3 = m1 * m2;
schreibst
Code:
  1. m3 = m2 * m1;
hat dies den selben Effekt, als wenn du eine der beiden Matrizen transponieren würdest.

Autor:  OpenglerF [ Di Dez 10, 2013 13:58 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Nicht funktioniert heißt soviel, wie das du etwas falsch gemacht hast. Um dir zu sagen, was du falsch gemacht hast, musst du uns schon sagen, was das Fehlerbild war/ist und wie dein Shader als auch der OpenGL Code aussieht.
Alles selber zu basteln hat zwar sicher einen gewissen Lerneffekt, ist aber uneffizienter und wenn es schon mit den fertigen Funktionen nicht funktioniert auch nicht zielführend.

Autor:  damadmax [ Di Dez 10, 2013 14:54 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

mathias hat geschrieben:
Ist sowas möglich ?

VertexShader:
Code:
  1. ...
  2. void Multi(in mat4 m1, in mat4 m2, out mat4 m3)
  3. {
  4.   m3 = m1 * m2;
  5. }
  6. ...   

Code:
  1. ...
  2.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m1')), 1, False, @fEingabe1Matrix);
  3.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m2')), 1, False, @fEingabe2Matrix);
  4.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m3')), 1, False, @fAusgabeMatrix);
  5. ...  


Seit wann bekommt man auf diesem Weg, etwas aus dem Shader zurück? Hab ich was verpasst?

Autor:  glAwesome [ Di Dez 10, 2013 17:41 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

@damadmax: Aus dem Kontext gerissen wirkt der Schnippsel natürlich etwas merkwürdig. Ich hatte mathias vorher gesagt, dass man alle Transformationen in eine Matrix stecken kann, indem man die Matrizen miteinander multipliziert. Den von dir zitierten Beitrag würde ich daher interpretieren wie: "Kann man das auch in GLSL machen und zwar auf diese Weise?" Da stehen ja schließlich 3 Punkte am Anfang und am Ende...

Autor:  mathias [ Mi Dez 11, 2013 18:22 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

damadmax hat geschrieben:
mathias hat geschrieben:
Ist sowas möglich ?

VertexShader:
Code:
  1. ...
  2. void Multi(in mat4 m1, in mat4 m2, out mat4 m3)
  3. {
  4.   m3 = m1 * m2;
  5. }
  6. ...   

Code:
  1. ...
  2.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m1')), 1, False, @fEingabe1Matrix);
  3.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m2')), 1, False, @fEingabe2Matrix);
  4.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('m3')), 1, False, @fAusgabeMatrix);
  5. ...  


Seit wann bekommt man auf diesem Weg, etwas aus dem Shader zurück? Hab ich was verpasst?


Habe ich das richtig verstanden, man kann nicht auf Funktionen im Shader zugreifen.

Unterdessen habe ich wieder was gelernt:
Code:
  1.   gl_Position = meinMatrix * CameraMatrix * vec4(inPos.xyz + meinMove, 1.0);
  2.   gl_Position = CameraMatrix * meinMatrix * vec4(inPos.xyz + meinMove, 1.0);


Diese beiden Zeilen machen nicht das Gleiche.
Irgendwo habe ich gelesen das beim Matrix rechnen folgendes ist a * b <> b * a.

Autor:  glAwesome [ Mi Dez 11, 2013 18:37 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

mathias hat geschrieben:
Habe ich das richtig verstanden, man kann nicht auf Funktionen im Shader zugreifen.
Du kannst OpenGL nicht sagen: "Führe mal diese GLSL-Funktion mit diesen Parametern aus und sag mir was rauskommt." Falls du das mit zugreifen meintest.

Was aber geht: Du kannst im Shader beliebig viele Funktionen definieren, welche dann von der main()-Funktion oder anderen Funktionen (im selben Shader) aufgerufen werden. So könntest du z.B. deine eigene Matrixmultiplikation auf Korrektheit prüfen. Wenn du z.B. eine TranslationMatrix und eine RotationMatrix hast, kannst du
  • beide per glUniform an den Shader übergeben. Den Shader lässt du beide (mit der von dir geposteten Funktion Multi) multiplizieren und die Vertices mit der resultierenden Matrix transformieren.
  • beide auf der CPU multiplizieren und nur das Resultat an den Shader übergeben. Dies ist die performantere Methode, weil die Matrixmultiplikation nur einmal durchgeführt werden muss, und nicht für jeden Vertex einzeln.
Wenn die Ergebnisse sich unterscheiden, hast du einen Fehler in deiner Implementation.

mathias hat geschrieben:
Irgendwo habe ich gelesen das beim Matrix rechnen folgendes ist a * b <> b * a.
Stimmt, die Matrixmultiplikation ist nicht kommutativ.

Autor:  mathias [ Do Jan 23, 2014 22:39 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Ich würde gerne sowas in der Art machen.:
Code:
  1. uniform vec3 LightPosition = vec3(-2.0, 0.4, -2.1); 


Komischerweise funktioniert dies:

Code:
  1. uniform vec4 VecColor = vec4(1.0, 1.0, 1.0, 1.0);    


Edit:Fehler gefunden.
Code:
  1.   // geht nicht:
  2.  
  3.   LightPosition = (LightPosition * -1.0) - Pos ;
  4.   float distance = length(LightPosition);
  5.   float dif = max(dot(Normal, LightPosition), UmgebungsLicht);
  6.   return dif * (1.0 / (1.0 + (0.25 * distance * distance)));
  7.  
  8.   // geht:
  9.  
  10.   vec3 LP = (LightPosition * -1.0) - Pos ;
  11.   float distance = length(LP);
  12.   float dif = max(dot(Normal, LP), UmgebungsLicht);
  13.   return dif * (1.0 / (1.0 + (0.25 * distance * distance)));    

Autor:  mathias [ Fr Mär 14, 2014 21:15 ]
Betreff des Beitrags:  Re: Variable an Shader übergeben

Wieso wird der ganze Rendervorgang nicht um den Faktor 3 vergrössert ?
Schreibe ich aber -3 anstelle *3, dann wird die ganze Szene verschoben. :roll:

Code:
  1.   gl_Position = CameraMatrix * vec4(inPos, 1.0) * 3.0;
  2.  

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