Ich versuche, einen einfachen projektiven Textur-Mapping-Ansatz zu implementieren, indem ich Shader in OpenGL 3+ verwende. Obwohl es einige Beispiele im Web gibt, habe ich Probleme, ein funktionierendes Beispiel mit Shadern zu erstellen.
Ich plane tatsächlich, zwei Shader zu verwenden, einen, der eine normale Szenenzeichnung erstellt, und einen anderen für die projektive Texturzuordnung. Ich habe eine Funktion zum Zeichnen einer Szene void ProjTextureMappingScene::renderScene(GLFWwindow *window)
und ich benutze glUseProgram (), um zwischen Shadern zu wechseln. Die normale Zeichnung funktioniert gut. Es ist mir jedoch unklar, wie ich die projektive Textur auf einen bereits texturierten Würfel auftragen soll. Muss ich irgendwie einen Stencil-Puffer oder ein Framebuffer-Objekt verwenden (der Rest der Szene sollte davon nicht betroffen sein)?
Ich glaube auch nicht, dass meine projektiven Textur-Mapping-Shader korrekt sind, da das zweite Mal, wenn ich einen Würfel rendere, Schwarz angezeigt wird. Außerdem habe ich versucht, mit Farben zu debuggen, und nur die t
-Komponente des Shaders scheint nicht Null zu sein (der Würfel erscheint also grün). Ich überschreibe das texColor
im Fragment-Shader unten nur für Debugging-Zwecke.
VertexShader
%Vor%FragmentShader
%Vor%Erstellung einer TexGen Matrix
%Vor%Würfel erneut rendern
Es ist mir auch unklar, wie die Modellansicht des Würfels aussehen soll? Sollte es die Ansichtsmatrix vom Diaprojektor (wie es jetzt ist) oder vom normalen Ansichtsprojektor verwenden? Gegenwärtig wird der Würfel in der Mitte der Szenenansicht schwarz (oder grün, wenn debuggen) gerendert, wie es vom Diaprojektor erscheinen würde (Ich habe einen Umschalt-Hotkey gemacht, damit ich sehen kann, was der Diaprojektor "sieht"). Der Würfel bewegt sich auch mit der Ansicht. Wie bekomme ich die Projektion auf den Würfel selbst?
%Vor%Wechseln Sie zwischen Hauptszenenkamera und Diaprojektorkamera
%Vor%Ich habe das Problem gelöst. Ein Problem, das ich hatte, war, dass ich die Matrizen in den zwei Kamerasystemen verwechselte (Welt- und projektive Texturkamera). Wenn ich jetzt die Uniformen für den projektiven Textur-Mapping-Teil anlege, verwende ich die korrekten Matrizen für die MVP-Werte - die gleichen, die ich für die Welt-Szene verwende.
%Vor% Außerdem ist die invViewMatrix nur die Umkehrung der Ansichtsmatrix und nicht der Modellansicht (das hat das Verhalten in meinem Fall nicht geändert, da das Modell eine Identität war, aber es ist falsch). Für mein Projekt wollte ich nur ein paar Objekte mit projektiven Texturen selektiv rendern. Um dies zu tun, muss ich für jedes Objekt sicherstellen, dass das aktuelle Shader-Programm für projektive Texturen mit glUseProgram(projectiveTextureMappingProgramID)
ist. Als nächstes berechne ich die erforderlichen Matrizen für dieses Objekt:
Zurück zu den Shadern, der Vertex-Shader ist korrekt, außer dass ich die UV-Texturkoordinaten ( inCoord
) für das aktuelle Objekt neu hinzugefügt und in texCoord
gespeichert habe.
Für den Fragment-Shader habe ich die Hauptfunktion so geändert, dass die projektive Textur geklammert wird, so dass sie sich nicht wiederholt (ich konnte sie nicht mit der Client-Seite GL_CLAMP_TO_EDGE
arbeiten) und verwende auch die Standard-Objekttextur und UV-Koordinaten für den Fall, dass der Projektor nicht das gesamte Objekt bedeckt (ich habe auch die Beleuchtung aus der projektiven Textur entfernt, da sie in meinem Fall nicht benötigt wird):
Wenn du feststeckst und aus irgendeinem Grund die Shader nicht zum Laufen bringen kannst, kannst du dir ein Beispiel im "OpenGL 4.0 Shading Language Cookbook" (Texturen Kapitel) anschauen - ich habe es wirklich vermisst, bis ich es selbst funktionierte .
Zusätzlich zu all dem oben genannten war eine große Hilfe beim Debuggen, wenn der Algorithmus korrekt arbeitet, das Zeichnen des Kegelstumpfs (als Drahtmodell) für die projektive Kamera. Ich habe einen Shader zum Frustum-Zeichnen verwendet. Der Fragment-Shader weist nur eine Farbe zu, während der Vertex-Shader unten mit Erklärungen aufgeführt ist:
%Vor%Die Uniformen werden so verwendet (stellen Sie sicher, dass Sie die richtigen Matrizen verwenden):
%Vor%Um die für den Vertex-Shader des Frustums benötigten Eingabevertices zu erhalten, können Sie folgende Schritte ausführen, um die Koordinaten zu erhalten (fügen Sie sie dann einfach zu Ihrem Vertex-Array hinzu):
%Vor%Nachdem alles gesagt und getan ist, ist es schön zu sehen, wie es aussieht:
Wie Sie sehen können, habe ich zwei projektive Texturen aufgetragen, eine von einem Biohazard-Bild auf Blenders Suzanne-Affenkopf und eine Smiley-Textur auf dem Boden und einem kleinen Würfel. Sie können auch sehen, dass der Würfel teilweise von der projektiven Textur bedeckt ist, während der Rest mit seiner Standardtextur angezeigt wird. Schließlich können Sie den grünen Kegelstumpf für die Projektorkamera sehen - und alles sieht korrekt aus.