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 ;)
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 network • my 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
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
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 network • my 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
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
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 network • my 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
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.
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!
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.)
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.
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 network • my 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
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!
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 network • my 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
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.
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 network • my 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
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.
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast
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.