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

Aktuelle Zeit: Do Mär 28, 2024 21:38

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



Ein neues Thema erstellen Auf das Thema antworten  [ 36 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: Variable an Shader übergeben
BeitragVerfasst: Mi Dez 04, 2013 18:06 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Mein VertexShader sieht so aus:
Code:
  1. #version 330
  2. // Input vom VBO:
  3. in vec3 inPos;
  4. in vec4 inColor;
  5.  
  6. in float Zoom;
  7.  
  8. // Ausgabe an den Fragmentshader:
  9. out vec4 Color;
  10.  
  11. void main(void)
  12. {
  13.   gl_Position = vec4(inPos, 1.0)+Zoom;
  14.   Color = inColor;
  15. }                  

Wie kann ich einen Wert an Zoom übergeben ?

Wen ich gl_Position = vec4(inPos, 1.0)+1.0; schreibe, dann wird mein Dreiecke obenrechts verkleinert angezeit. Aber ich will das mit meinem Programm machen.

Ich habe es mit glUniform1f probiert.
Code:
  1. procedure TForm1.RenderScene;
  2. begin
  3.   // We just clear color
  4.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  5.  
  6.  
  7.   // Triangle render
  8.   glBindVertexArray(uiVAO[0]);
  9.  
  10.   glUniform1f(glGetUniformLocation(ProgramID, PGLCharARB('Zoom')), 1.0);
  11.   glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  12.  
  13.   // Quad render using triangle strip
  14.   glBindVertexArray(uiVAO[1]);
  15.   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  16.  
  17.   SwapBuffers(DC);
  18. end;      

Was mache ich schon wieder falsch ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Mi Dez 04, 2013 18:27 
Offline
DGL Member

Registriert: Do Dez 29, 2011 19:40
Beiträge: 421
Wohnort: Deutschland, Bayern
Programmiersprache: C++, C, D, C# VB.Net
Werte die von deinen Programm in den Shader wandern sollen, müssen als "uniform" gekennzeichnet werden.
Ersetze das "in" bei "Zoom" durch das Schlüsselwort "uniform".

Und, der Shader wird nicht direkt das machen, was du erreichen willst.
Du führst eine Vektoraddition durch, was erstmal einer Verschiebung entspricht. Anders gesagt, du vergrößerst, X, Y, Z und W um den Wert von "Zoom" was dann am Ende ziemlich komische Ergebnisse liefern wird, wegen der W-Division die anschließend ausgeführt wird. (Nach dem der Vertex Shader ausgeführt wurde, werden im Hintergrund X,Y und Z durch W dividiert. Wenn W 1 ist wie normalerweise, passiert also gar nichts. Wenn man W wie du, verändert könnte man damit eine verschoben inverse Skalierung durchführen, das willst aber eher weniger, nehme ich an.)
Wenn du Verschieben willst, wäre also "vec4(inPos.xyz + Zoom, 1.0);" richtig und "Zoom" müsste ein 3 Komponentenvektor sein. (X, Y und Z halt.)
Oder wenn du skalieren willst(zoomen) müsstest du eine Skalarmultiplikation durchführen: "vec4(inPos.xyz * Zoom, 1.0);"
Wenn du richtig sinnvoll etwas erreichen willst, solltest du dafür auch eher Matrizen verwenden, wie es schon früher die Fixedpipeline tat.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Mi Dez 04, 2013 18:46 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Zum Unterschied von in und uniform im Vertexshader:
  • in-Variablen werden für jeden Vertex mit einem neuen Wert belegt, der aus dem VBO kommt. Wo und wie genau die Vertexdaten im VBO gespeichert sind, legst du mit glVertexAttribPointer fest.
  • uniform-Variablen belegst du einmal durch einen glUniform-Aufruf mit einem Wert. Dieser Wert gilt dann im aktuell gebundenen Program so lange für jeden Vertex, bis wieder glUniform aufgerufen wird.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Mi Dez 04, 2013 19:34 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Vielen Dank für die schnelle Antwort.

Jetzt bewegt sich mein in der X und Y - Achse. Das man in der Z-Achse nichts sieht, nehme ich an, das die Darstellung nicht Proportional ist, sonst würde das Dreieck kleiner und grösser werden.
Code:
  1. #version 330
  2. // Input vom VBO:
  3. in vec3 inPos;
  4. in vec4 inColor;
  5.  
  6. uniform vec3 Zoom;
  7.  
  8. // Ausgabe an den Fragmentshader:
  9. out vec4 Color;
  10.  
  11. void main(void)
  12. {
  13.   gl_Position = vec4(inPos.xyz + Zoom, 1.0);
  14.   Color = inColor;
  15. }

Zoom ist eine Variable die ich mit einer Timerfunktion verändere.
Sollte später zoom[0], zoom[1], zoom[3] werden.
Code:
  1. procedure TForm1.RenderScene;
  2. begin
  3.   // We just clear color
  4.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  5.  
  6.   glUniform3f(glGetUniformLocation(ProgramID, PGLCharARB('Zoom')), zoom[0], zoom[0], zoom[0]);
  7.  
  8.   // Triangle render
  9.   glBindVertexArray(uiVAO[0]);
  10.  
  11.   glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  12.  
  13.   // Quad render using triangle strip
  14.   glBindVertexArray(uiVAO[1]);
  15.   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  16.  
  17.   SwapBuffers(DC);
  18. end;      

Wie kann ich machen, das sich nur das Dreieck bewegt ?
Muss ich das mit den VBOs machen, so wie mit den Farben ?

_________________
OpenGL


Zuletzt geändert von mathias am Do Dez 05, 2013 20:07, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Mi Dez 04, 2013 22:47 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
mathias hat geschrieben:
Jetzt bewegt sich mein in der X und Y - Achse.
Leider fehlt das Subjekt.

mathias hat geschrieben:
Das man in der Z-Achse nichts sieht, nehme ich an, das die Darstellung nicht Proportional ist, sonst würde das Dreieck kleiner und grösser werden.
Das liegt daran, dass du die Vertices nicht mit einer perspektivischen Matrix multiplizierst - also das, was du früher mit gluPerspective eingestellt hast.

mathias hat geschrieben:
Zoom ist eine Variable die ich mit einer Timerfunktion verändere.
Dann ist uniform schon richtig.

mathias hat geschrieben:
Wie kann ich machen, das sich nur das Dreieck bewegt?
Im Gegensatz zum Viereck? Einfach vor dem Rendern des Vierecks nochmal glUniform aufrufen, um Zoom auf 0 zu setzen.


Mir ist nicht ganz klar, was du erreichen möchtest. Als Zoom bezeichnet man üblicherweise einen Effekt, der durch das Verändern des View-Frustums erzielt wird. Beim Hineinzoomen würde man z.B. den Parameter fovy der Funktion gluPerspective verringern. Voraussetzung für Zoom ist eine perspektivische Ansicht, die du momentan nicht hast (deine ist orthogonal). Was du in deinem Shader machst, ist eine Translation. Würdest du das + durch ein * ersetzen, hättest du eine Skalierung. Alles sind verschiedene Effekte.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Do Dez 05, 2013 18:30 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Wen ich meinMatrix als Konstante deklariere (momentan ausgeklammert) bleibt das Dreieck stehen, das ist richtig so.
Will ich aber die Matrix über mein Program in den Shader schicken, kommt gar nichts.
Die Zeile mit meinMove funktioniert.
Code:
  1. #version 330
  2. // Input vom VBO:
  3. in vec3 inPos;
  4. in vec4 inColor;
  5.  
  6. uniform vec3 meinMove;
  7. uniform mat4 meinMatrix;
  8.  
  9. //mat4 meinMatrix =mat4(1.0, 0.0, 0.0, 0.0,  
  10. //                                0.0, 1.0, 0.0, 0.0,  
  11. //                                0.0, 0.0, 1.0, 0.0,  
  12. //                                0.0, 0.0, 0.0, 1.0);
  13.  
  14. // Ausgabe an den Fragmentshader:
  15. out vec4 Color;
  16.  
  17. void main(void)
  18. {
  19.   gl_Position = meinMatrix * vec4(inPos.xyz + meinMove, 1.0);
  20.   Color = inColor;
  21. }

Deklaration fMatrix:
Code:
  1.  fMatrix: array[1..16] of GLfloat =
  2.     (1.0, 0.0, 0.0, 0.0,
  3.     0.0, 1.0, 0.0, 0.0,
  4.     0.0, 0.0, 1.0, 0.0,
  5.     0.0, 0.0, 0.0, 1.0);

Aufruf im Program:
Code:
  1.   glUniform3f(glGetUniformLocation(ProgramID, PGLCharARB('meinMove')), 0, 0, 0);
  2.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('meinMatrix')), SizeOF(fMatrix), False, @fMatrix);
  3.   glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);


PS:So wie es aussieht, hat es im Tutorial http://wiki.delphigl.com/index.php/Tutorial_glsl einen kleinen Fehler:
Code:
  1. mat4 MyMatrix = mat4(MyVec4, MyVec4, MyVec4, MyVec4);
  2. mat2 MyMatrix = mat4(1.0, 0.0, 0.0, 0.0,
  3.                      0.0, 1.0, 0.0, 0.0,
  4.                      0.0, 0.0, 1.0, 0.0,
  5.                      0.0, 0.0, 0.0, 1.0);

mat2 müsste mat4 heissen.

_________________
OpenGL


Zuletzt geändert von mathias am Do Dez 05, 2013 20:10, insgesamt 3-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Do Dez 05, 2013 19:04 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
mathias hat geschrieben:
Code:
  1. glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('meinMatrix')), SizeOF(fMatrix), False, @fMatrix);
Der zweite Parameter von glUniformMatrix4fv ist nicht richtig. Du möchtest eine Matrix übergeben, demnach muss dort eine 1 stehen. Die Größe ist ja schon durch das "Matrix4fv" im Funktionsnamen klar.
Ich bin mir nicht sicher, ob der letzte Parameter korrekt ist. In C++ wäre fMatrix selbst schon ein Zeiger auf das Array. @fMatrix[1] sollte auf jeden Fall gehen, denke ich. Aber ich bin wie gesagt kein Pascaler.

Ansonsten wäre es natürlich schön zu wissen, was du mit der Matrix im Vertexshader anstellst. Du hast doch nicht etwa die Multiplikation vergessen? :wink:

mathias hat geschrieben:
So wie es aussieht, hat es im Tutorial http://wiki.delphigl.com/index.php/Tutorial_glsl einen kleinen Fehler[...]
Stimmt, das ist falsch. Das tolle am Wiki ist: Du kannst es direkt korrigieren. Einfach rechts oben auf "Anmelden" klicken und dich mit deinem Foren-Account einloggen. Dann erscheint neben jeder Überschrift ein "Bearbeiten". Falls was schief gehen sollte, lässt sich die Änderung ganz leicht wieder rückgängig machen, also nur keine Scheu.

Dies ist ein dezenter Hinweis auf meine Signatur, in der Hoffnung, dass kleine Schrift mehr auffält, als fette gelbe. :)

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Do Dez 05, 2013 20:03 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Es lag an der 1.
Die Matrix kann ich jetzt auch Zweidimensional deklarieren.
Code:
  1. const
  2.   fMatrix: array[1..4, 1..4] of GLfloat =
  3.       ((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, 0.0, 0.0, 1.0));
  4.  
  5. ...
  6.  
  7.   glUniformMatrix4fv(glGetUniformLocation(ProgramID, PGLCharARB('meinMatrix')), 1, False, @fMatrix);
  8.  


Zitat:
Ansonsten wäre es natürlich schön zu wissen, was du mit der Matrix im Vertexshader anstellst. Du hast doch nicht etwa die Multiplikation vergessen?

Was meinst du mit der Multiplikation, meinst du weil fMatrix in eine Constante ist ?
Wen es dies ist, währe dies nur als Versuch, ob die Variablen richtig übergeben werden.
Oder habe ich noch einen Fehler in dem VertexShader, aber dort hat es ja ein "*" ?

Code:
  1. gl_Position = meinMatrix * vec4(inPos.xyz + meinMove, 1.0);



PS:Das Wiki konnte ich ändern, ich wusste nicht, das ein normaler User dies auch ändern kann. Bekommt ihr eine Benachrichtigung, wen jemand was ändert ?

_________________
OpenGL


Zuletzt geändert von mathias am Do Dez 05, 2013 20:12, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Do Dez 05, 2013 20:10 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
mathias hat geschrieben:
Oder habe ich noch einen Fehler in dem VertexShader, aber dort hat es ja ein "*" ?
Hoppla, da muss ich mich verguckt haben. Du multiplizierst den vec4 ja schon mit der Matrix. Im nächsten Schritt könntest du die Translation natürlich noch in die Matrix integrieren, damit du dir die Addition im Shader sparen kannst.

mathias hat geschrieben:
Das Wiki konnte ich ändern, ich wusste nicht, das ein normaler User dies auch ändern kann. Bekommt ihr eine Benachrichtigung, wen jemand was ändert?
Schön, dass es geklappt hat. Jeder, der einen Artikel beobachtet (Haken beim Bearbeiten setzen), bekommt eine Benachrichtigung.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Do Dez 05, 2013 20:17 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Im nächsten Schritt könntest du die Translation natürlich noch in die Matrix integrieren, damit du dir die Addition im Shader sparen kannst.

Zuerst muss ich mich schlau machen, wie das mit den Matrixwerten funktioniert. Wichtig war, das die Matrix richtig in den Shader geschrieben wird, sonst nützt alles probieren mit der Matrix nichts.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: Do Dez 05, 2013 20:23 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Die Matrizen sind in den entsprechenden Wiki-Artikeln erklärt:
glTranslate, glRotate, glScale, gluPerspective

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: So Dez 08, 2013 17:38 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ich habe mir Rotate Funktionen geschrieben, welche auch gut funktionieren.
Nur funktioniert dies nur global über alle Körper. Mit der original Funktion glRotate konnte man lokal ein Element drehen.
Wen ich das immer noch manchen will, sehe ich nur einen Weg, die Koordinaten des Elementes zu ändern.

Oder gibt es da eine Unterstützung von OpenGL ?

Code:
  1. type
  2.   fTMatrix = array[1..4, 1..4] of GLfloat;  
  3.  
  4. procedure RotateX(var Matrix: fTMatrix; Winkel: GLfloat);
  5. var
  6.   y, z: GLfloat;
  7.   i: integer;
  8. begin
  9.   for i := 1 to 3 do
  10.   begin
  11.     y := Matrix[i, 2];
  12.     z := Matrix[i, 3];
  13.     Matrix[i, 2] := y * cos(Winkel) - z * sin(Winkel);
  14.     Matrix[i, 3] := y * sin(Winkel) + z * cos(Winkel);
  15.   end;
  16. end;
  17.  
  18. procedure RotateY(var Matrix: fTMatrix; Winkel: GLfloat);
  19. var
  20.   x, z: GLfloat;
  21.   i: integer;
  22. begin
  23.   for i := 1 to 3 do
  24.   begin
  25.     x := Matrix[i, 1];
  26.     z := Matrix[i, 3];
  27.     Matrix[i, 1] := x * cos(Winkel) - z * sin(Winkel);
  28.     Matrix[i, 3] := x * sin(Winkel) + z * cos(Winkel);
  29.   end;
  30. end;
  31.  
  32. procedure RotateZ(var Matrix: fTMatrix; Winkel: GLfloat);
  33. var
  34.   x, y: GLfloat;
  35.   i: integer;
  36. begin
  37.   for i := 1 to 3 do
  38.   begin
  39.     x := Matrix[i, 1];
  40.     y := Matrix[i, 2];
  41.     Matrix[i, 1] := x * cos(Winkel) - y * sin(Winkel);
  42.     Matrix[i, 2] := x * sin(Winkel) + y * cos(Winkel);
  43.   end;
  44. end;    

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: So Dez 08, 2013 18:39 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Die Matrixfunktionen aus GL1.0 ersetzen nicht einfach die aktuelle Matrix durch eine Rotations-/Translationsmatrix. Sie mulitplizieren die aktuelle Matrix mit der neu berechneten.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: So Dez 08, 2013 22:40 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Habe ich das recht verstanden, wen ich mehrere Objekte, z.B. Würfel, jedes einzeln drehen will, muss die Ratation direkt auf die Eckpunkte des Objekts anwenden und dies ohne Shader.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Variable an Shader übergeben
BeitragVerfasst: So Dez 08, 2013 22:48 
Offline
DGL Member

Registriert: Do Dez 29, 2011 19:40
Beiträge: 421
Wohnort: Deutschland, Bayern
Programmiersprache: C++, C, D, C# VB.Net
Nein. Die Shader sind dafür da, Daten auf der Grafikkarte zu verarbeiten, ohne die CPU zu beanspruchen.
Du musst einfach die Matrix im Shader nach für jedes zu renderende Modell neu setzen.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 13 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.071s | 19 Queries | GZIP : On ]