wie dem Vorgänger Thema (viewtopic.php?f=2&t=9209) geht es noch um das Problem der Projektion einer bzw. mehrerer Texturen in eine Szene. Da hier von mehreren "Projektoren" die rede ist, funktioniert die normale Methode nicht, da für jeden Projektor die ganze Szene nochmal gerendert werden müsste. Ich habe hier http://www.ozone3d.net/tutorials/glsl_texturing_p08.php eine Shader Variante gefunden. Ich weiß jedoch nicht wie diesen genau anwenden soll. Anscheinend muss ich die Texturmatrix aus sicht der jeweiligen Lichtquelle und dessen invertierte Matrix übergeben. Hinzu kommt dann noch die zu proj. Textur.
1. Wie erstelle ich diese Matrizen? 2. Wie baue ich den Shader so um, das ich mit einem Durchlauf gleich mehrere "Projektoren" rendern kann
Ich denke das man (vielleicht sogar ich ) wenn das funktioniert, hierfür ein schönes Tutorial schreiben könnte.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Erstellen tust du die Matrizen in dem du für jeden Projektor eine Matrix aus seiner Sicht erstellst, also so wie du normalerweise deine Kameramatrix erstellst. Wenn du nicht direkt selbst eine erstellst kannst du auch "primitiv" zum über glRotate und glTranslate die Sicht des Projektors erstellen und mit glGet die Matrix auslesen lassen. Alternativ kann man auch gluLookAt etc. verwenden. Hier gibt es aber ganz viele Möglichkeiten, kommt halt drauf an wie du es machst. Am besten ist es halt wenn man es direkt über eine eigene Matrix macht und diese dann direkt an den Shader übergibt. Und wie man eine inverse Matrix berechnet findet man u.a. hier.
Und den Shader aus deinem Link anzupassen ist ganz simpel. Du kannst im Shader ja einfach Schleifen nutzen und dann entsprechend addieren. Also zuerst den normalen Lichtanteil einmal berechnen, und dann einfach ne Schleife für alle Projektoren, in denen dann die finale Fragmentfarbe per Addition (oder eigener Berechnung) ermittelt wird und zusammen mit der Grundfarbe nach gl_FragColor geschrieben wird. Aber du musst hier beachten dass GPUs immernoch limitiert sind, und die Schleife nicht zu viele Durchgänge machen sollte, allein wegen der Performance.
P.S. : Die "normale" Methode die du ansprichst (ich denke du meinst die feste Funktionspipeline) funktioniert sehr wohl für mehrere Projektoren. Dort muss man halt mehrere Passes machen bzw. die Projektoren auf mehrere Textureinheiten legen (jede hat ja ne eigene Matrix). Beim Shader kanns dir je nach Grafikkarte und deren Limitationen übrigens auch passieren dass du mehrere Passes machen musst.
mercie schonmal für deine Antwort, also würdest du eher dazu tendieren das ohne Shader zu machen? Oder wie wäre denn der zu erwartende Performance-unterschied?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Ich würds mit Shadern machen, ist letztendlich einfacher und man hat mehr Kontrolle über die Berechnungen, kann eigene Beleuchtungsmodelle und Efekte implementieren, etc. Kommt aber halt auf die Zielplattform an, wenn das auch auf alten Rechner laufen soll kanns u.U. nützlich sein auch nen Renderpfad ohne Shader zu implementieren.
Also ich hab den Shader erstmal unverändert versucht anzuwenden. Quasi nur für einen Projektor. Doch bekomme das einfach nicht so richtig zum laufen.. Bilder angehangen..
In der Renderproc von der Lampe, quasi genau aus deren Sicht, also die ModelViewMatrix wurde mit glRotate, glTranslate etc. bearbeitet, mach ich das hier
Code:
... TexMatrix, InvTexMatrix: TMatrix4f; ... // glMatrixMode(GL_TEXTURE_MATRIX); >> hab ich schon probiert glGetFloatv(GL_MODELVIEW_MATRIX, @TexMatrix); glGetFloatv(GL_MODELVIEW_MATRIX, @InvTexMatrix); MatrixInvert(InvTexMatrix); // glMatrixMode(GL_MODELVIEW); ...
dann in der Hauptrenderproc:
Code:
if ShaderButton.down then begin glDisable(GL_LIGHTING); if (x13d.Objlist[0] is T3DFixture) then begin glUniformMatrix4fv(glGetUniformLocationARB(shader.ProgramObject, 'TexGenMat'), Sizeof(TMatrix4f), false, @(x13d.ObjList[0] as T3DFixture).light.TexMatrix); glUniformMatrix4fv(glGetUniformLocationARB(shader.ProgramObject, 'InvViewMat'), Sizeof(TMatrix4f), false, @(x13d.ObjList[0] as T3DFixture).light.InvTexMatrix); glActiveTexture(GL_TEXTURE0);
So wie das aussieht wird auch das Shaderlicht gerendert, doch ich sehe meine zu Projezierende Textur (einfach ein großer roter Kreis) nirgends... Im Anhang hab ich einmal die Draufsicht mit und ohne den Shader..
Dateianhang:
Draufsicht.JPG
Dateianhang:
Draufsicht_ohne_Shader.JPG
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Sicher dass deine Projektion überhaupt funktioniert? Hast du die Szene mal aus der Sicht des Projektors gerendert um zu sehen ob alles korrekt ist? Und auch geprüft ob die Rückprojektion auch in der richtigen Richtung "abgeschnitten" wird, diese evtl. verkehrt herum läuft und du deshalb nichts siehst? Projektion vorm Auslesen der Matrizen auch korrekt gesetzt (wie im Beispiel)? Und hast du den Shader auch nachm Rendern des Projektors deaktiviert, denn wenn nicht wird ja TexGen der FF deaktiviert und es geht evtl. deshalb nicht.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
ich seh grad (hab ich eben übersehen) dass du die Parameter VOR dem Binden deines Shaderobjektes übergibst, und das klappt nicht. Also binde mal zuerst den Shader und setz dann die Parameter.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Hast du die Projektion mal ohne Shader, also ganz normal über die feste Funktionspipeline implementiert? So kann man nämlich schnell erkennen ob das Problem vom Shader oder kommt oder schon vorher auftritt. Ansonsten ist das alles schwer zu beurteilen, denn da der Shader ja definitiv geht muss dein Problem vorher auftreten bzw. etwas bei der Parameterübergabe falsch laufen.
ich stolper gerade auf dem weg dahin, es mit der FixedFP zu machen.. Doch irgendwie scheint die Matrix nicht ganz zu stimmen... Aktuell versuche ich mit in der während die ModelViewMatrix in der richtigen Richtung (scheinwerferblickrichtung) ist, die MAtrix mit glGetFloatv(GL_MODELVIEW_MATRIX, @TexMatrix); zu speichern und dann der autom. Texturgenerierung so zu übergeben:
Kurze Zwischenfrage: Du liest ja da GL_MODELVIEW_MATRIX aus. Ist den da die Projektion überhaupt drin? Üblicherweise wäre die eigentliche Projektion ja in GL_PROJECTION_MATRIX und in GL_MODELVIEW_MATRIX ja nur der Rotations-/Skalierungs-/Translationsanteil.
Mitglieder in diesem Forum: 0 Mitglieder und 12 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.