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

Aktuelle Zeit: Mo Jul 21, 2025 14:36

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



Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Fr Mai 02, 2008 12:18 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Hey Leute!

Also ich bin völlig neu in der Shaderprogrammierung, also seid gnädig mit mir :)
Gibt es eine Möglichkeit, Shader einzusetzen, ohne damit die bisherige Pipeline zu ersetzen? Ich meine, wenn ich Shader einsetzen wollte, dann muss ich doch alles unglaublich viel nachbauen, um Blending, Alphatest, Multitexturing etc. wieder zu bekommen, oder hab ich das falsch verstanden? Wie macht ihr sowas?

Bitte dran denken, dass das Gebiet für mich ziemlich neu ist ;)


Viele Grüße,

Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 12:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Leider bleibt viel von der Pipeline erhalten.

Der Vertexshader setzt da an, wo die Vertices transformiert werden, also die ganzen Matrixoperationen sind ausgeschaltet, aber die haste mit zwei zeilen nachgebaut.

Der Fragmentshader setzt da an, wo ein Fragment (Pixel) seine Farbe bekommt. Das heißt, vor dem Blending und vor dem Alphatest, er ersetzt die Texturierung. Du musst also die Texturen dann selber zusammenrechnen (wenn du Multitexturing hast) oder eben nur auslesen und draufpappen.

In den Shadern hast du mehrere Dinge zur verfügung, wie z.B. den vom Programm übergebenen Vertex oder die Texturkoordinaten, sowie alle Lichtkonstanten und noch viel mehr.

Für dich als Shadereinsteiger ist Tutorial glsl im Wiki als Nachschlagewerk und Einstieg auf jeden fall zu empfehlen. Später schauste dir dann auch noch Tutorial glsl2 an.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 12:40 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Bekomm ich denn irgendwo Shader-Code her, der Blending/Alphatest, Multitexturing, OGL-Nebel im Shader stehen hat?
Es ist irgendwie blöd, sich die Standard-OpenGL-Fkt. neu bauen zu müssen :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 14:07 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Wie gesagt, Blending und Alphatest bleiben erhalten. Der Nebel soweit ich weiss auch.

vertexshader:
Code:
  1. varying vec4 vpos;
  2.  
  3. void main(void)
  4. {
  5.   vpos            = gl_Vertex;
  6.   gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
  7.   gl_TexCoord[0]  = gl_MultiTexCoord0;
  8.   gl_FrontColor   = gl_Color;
  9. }


fragmentshader:
Code:
  1. uniform sampler2D tex0;
  2. varying vec4 vpos;
  3.  
  4. void main(void)
  5. {
  6.   gl_FragColor = texture2D(tex0, vec2(gl_TexCoord[0]));
  7. }


Das wäre zum beispiel ein einfacher Shader, der nichts weiter tut als die Fragmente ganz normal zu texturieren (mit genau einer textur).

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 15:11 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Okay, langsam durchblicke ich es :) Wenn ich im Fragmentshader die FragColor noch mit gl_Color multipliziere, dann funktioniert auch der glColor()-Aufruf. Leider funktioniert meine Texturenmatrix jetzt nicht mehr und der Code
Code:
  1.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  2.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

hat leider keine Auswirkung mehr. Aber ich werde mal ein bisschen probieren!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 17:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Um die Texturmatrix zu nutzen, musst du die Koordinaten der Textur vorher noch mit der Matrix multiplizieren:

vertexshader:
Code:
  1.  
  2. varying vec4 vpos;
  3. varying mat4 texmat;
  4.  
  5. void main(void)
  6. {
  7.   texMat = gl_TextureMatrix[0];  
  8.   vpos = gl_Vertex;
  9.   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
  10.   gl_TexCoord[0] = gl_MultiTexCoord0;
  11.   gl_FrontColor = gl_Color;
  12. }


fragmentshader
Code:
  1. uniform sampler2D tex0;
  2. varying vec4 vpos;
  3. varying mat4 texmat;
  4.  
  5. void main(void)
  6. {
  7.   vec4 tcoord;
  8.   vec4 color;
  9.   tcoord = texMat * gl_TexCoord[0];
  10.   color = gl_Color;
  11.   color = color * texture2D(tex0, vec2(tcoord));
  12.   gl_FragColor = color;
  13. }
  14.  


So sollte das klappen.

Hast du die Textur auch als Uniform gesetzt (mit glUniform1i und glGetUniformLocation) oder hast du gerade einfach nur glück?

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 19:31 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Ja, ich benutze Multi-Texturing, und muss dafür an die Uniform-Variable ja mit glUniformi() für die Textur ja die TMU übergeben. Klappt leider nicht so ganz.


VertexShader:
Code:
  1.  
  2. varying vec4 vpos;
  3. varying mat4 texMat;  
  4. void main(void)
  5. {
  6.   texMat           = gl_TextureMatrix[0];    
  7.   vpos              = gl_Vertex;
  8.   gl_Position     =  gl_ModelViewProjectionMatrix * gl_Vertex;
  9.   gl_TexCoord[0]  = gl_MultiTexCoord0;
  10.   gl_TexCoord[1]  = gl_MultiTexCoord1;
  11.   gl_FrontColor   = gl_Color;
  12. }
  13.  


FragmentShader:
Code:
  1.  
  2. varying mat4 texMat;
  3. vec4 tcoord[2];
  4. uniform sampler2D tex0;
  5. uniform sampler2D tex1;
  6. varying vec4 vpos;
  7. void main(void)
  8. {  
  9.   tcoord[0] = texMat * gl_TexCoord[0];
  10.   tcoord[1] = texMat * gl_TexCoord[1];
  11.   gl_FragColor = gl_Color * texture2D(tex0, vec2(tcoord[0]))         *texture2D(tex1, vec2(tcoord[1]));
  12. }
  13.  


Jetzt übergebe ich ja die Textureinheitsangaben für tex0 und tex1 mit
Code:
  1. glUniform1i(glGetUniformLocation(ProgramObject, @tex1), 1);

Ist doch richtig so, oder? Damit mein Shader weiß, welche Textureinheit jetzt Texturkoordinaten bekommt. Leider funktioniert das nicht. Ich bekomme zwar zwei Texturen mit den richtigen Texturkoordinaten, aber:

1. Die Textur wird trotz des Befehls glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
nicht "gewrappt". Man sieht sie nur in einer Ecke...
2. Meine zweite Textur ist normalerweise eine Detailtextur. Hier wird jedoch wieder die Textur von der ersten Schicht draufgepackt.

Woran könnte es liegen?


Übrigens danke Lord Horazont für den Code. Das hilft ungemein!

Viele Grüße,
Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 19:50 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Am shader code gibt es einige dinge zu verbesser:

Die Texturmatrixmultiplakationen umbeding im Vertexshader ausführen, da diese den shader sonst um einiges langsamer machen.

Möglicher weise macht es mehr sinn beide texturen zu addieren anstat sie zu multiplizieren, jedoch ist dies vom inhalt der detailtextur abhängig.


Bei
glUniform1i(glGetUniformLocation(ProgramObject,"tex1"), 1);
muss man darauf auchten, das das program auch aktiv ist, da sich glUniform1i(...) auf das aktive programm und nicht auf da was als argument von "ProgramObject" übergeben wurde. (Das war wohl ein unvollkommener verzuch zwanghaft am prinzip der statemaschine festzuhalten.)

_________________
Lumina plattform unabhängige GLSL IDE


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 02, 2008 20:12 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
@Rüdiger:
Was ist tex1 bei deinem glGetUniformLocation Aufruf für eine Variable? Du musst da einen String übergeben, der den Namen der Uniformvariable enthält, z.B.
Code:
  1. glUniform1i(glGetUniformLocation(ProgramObject, 'tex0'), 0);
  2. glUniform1i(glGetUniformLocation(ProgramObject, 'tex1'), 1);


Denn wenn du bei beiden Samplern die gleiche Textur bekommst, ist das ein sehr sicheres Zeichen dafür, dass bei der Uniform-Location was nicht stimmt.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 03, 2008 11:08 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Danke euch beiden!

Es lag tatsächlich beim Übergeben der Uniform-Variable... Ich dachte, PChar würde durch einen Pointer auf String ersetzt werden können.

Ich muss sagen, trotz dieser Schwierigkeiten machts schon Spaß :) Ich hab im VertexShader spaßeshalber mal die noise-Funktion addiert - lustige Effekte durch nur einen Befehl!


Viele Grüße,
Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 03, 2008 12:12 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Rüdiger hat geschrieben:
Ich dachte, PChar würde durch einen Pointer auf String ersetzt werden können.

Das geht, aber dafür musst du entweder auf das erste Zeichen zeigen (mit @tex0[1]) oder in Delphi auf PChar casten (mit PChar(tex0)).

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 03, 2008 13:13 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Gut, ich habs jetzt einfach mit PChar als Übergabetyp geregelt.

Ich steh nun wieder vor einem neuen Problem:

Meine Shader:

Vertexshader:
Code:
  1.  
  2. varying vec4 tcoord[2];
  3. void main(void)
  4. {
  5.   gl_Position   = gl_ModelViewProjectionMatrix * gl_Vertex;
  6.   tcoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
  7.   tcoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
  8.   gl_FrontColor = gl_Color;
  9. }
  10.  


Fragmentshader:
Code:
  1.  
  2. varying vec4 tcoord[2];
  3. uniform sampler2D tex0;
  4. uniform sampler2D tex1;
  5.  
  6. void main(void)
  7. {  
  8.   gl_FragColor = gl_Color * texture2D(tex0,vec2(tcoord[0]))*
  9.   texture2D(tex1,vec2(tcoord[1]));
  10. }
  11.  


Die beiden funktionieren so auch schon ganz gut. Ich habe Multitexturing ja aktiv - doch wenn ich jetzt mein Gras rendere, das nur eine Textur hat und mithilfe des Alphatests geblendet wird, dann geschieht das nicht. Das Gras bleibt einfach unsichtbar. Meine anderen Flächen sind normal sichtbar. Wenn ich die Shader so weit abändere, dass die zweite Texturstufe nicht benutzt wird, dann funktioniert es wieder.

Hat jemand eine Ahnung?


Achja, ganz wichtig: Kann ich Shader auch abschalten, also z.B. nur für einen Teil meiner Szene benutzen? Das muss doch gehen, oder? Quasi das Pendant zu glUseProgram.

Viele Grüße,
Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 03, 2008 14:11 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
glUseProgram mit Parameter 0 sollte funktionieren.

Das Problem liegt glaube ich darin, dass du als Alpha-Wert bei einer nicht existenten Textur von texture2D ein 0 bekommst. was passiert bei der multiplikation mit 0? es kommt 0 raus, d.h. dein Alphatest blendet dir die fragmente raus (ich hoffe, ich irre mich da jetz nicht).
Als lösung könntest du eine weiße Textur mit vollem Alpha verwenden und in die zweite Textureinheit schieben.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 03, 2008 14:20 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
Im Grunde ist ja das schöne am Shader ja, dass du den Alphawert beliebig aus jeder Quelle berechnen kannst. In deinem Fall könntest du zB. nur den Alphawert aus der ersten Textur nehmen, oder zB. den Roten Kanal deiner 2. Textur als Alphawert benutzen. Oder ihn einfach immer auf einen festen Wert, zB. 1.0 setzen.

Im Übrigen kannst du einen Alphatest auch direkt in den Shader integrieren - das Schlüsselwort "discard;" verhindert, dass das Fragment (= Pixel) gezeichnet wird. Allerdings ist bei SM2-Karten Vorsicht geboten, da die alle darauf folgenden Befehle noch ausführen, aber dann verwerfen.

MfG


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 05, 2008 13:51 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Okay, vielen Dank für Eure Infos!


Viele Grüße,

Rüdiger


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 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.009s | 14 Queries | GZIP : On ]