Wie würdest du denn den Kegel "einfach" zeichnen? Ja ich denke auch das die nur eine textur projezieren. Hinzu kommt noch das deren Lichtkegel mit der Entfernung (sieht man auf den bildern nicht) abnimmt.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Beim Billboarding wird ja 3D über eine 2D-Textur simuliert. OpenGL hat eine Funktion (gluProject) die dir 3D-Koordianten in 2D-Fensterkoordinaten umrechnet. Damit kannst du dann den Anfang des Kegels und die Extrempunkte am Boden in 2D-Fensterkoordinaten ermitteln und z.b. ein Dreieck zwischen diesen in 2D über den Schirm legen und so den Scheinwerferkegel simulieren. Das ist relativ simpel und braucht auch weit weniger Füllrate als dutzende transparente Kegel ineinander zu rendern. Ausserdem hast du so komplette Kontrolle darüber wie der Transparenzverlauf von innen nach aussen gehen soll. Allerdings wäre das jetzt nur mal so auf die Schnelle mein Ansatz für die Kegel, k.a. ob die Anwendung da es auch so macht.
das mit dem Billboarding ist ja eine gute Idee doch dazu müsste ich diese "extrempunkte" am Boden erstmal ausfindig machen?! So einfach ist das dann doch nicht oder? Ich meine wenn die Lampe 90° über einem ebenen Boden ist, kann man das ja einfach berechnen. Doch was ist wenn sie in einem Winkel auf eine ungerade Fläche strahlt, dann wirds schon kompliziert?!
also ich hab meine Lichtkegel nun mit mehreren Kegeln ineinander gelöst. Zwar noch ohne Gobo, aber Step by Step. Aktuell versuch ich erstmal den Scheinwerferspot auf den Boden zu bekommen. Ihr redet von Texturprojektion. Soll ich mir da irgendwie ne Bitmap "malen" und die da "draufklatschen"? Wie kann ich vorgehen?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Ja, wenn du etwas auf deine Szene projezieren willst brauchst du dazu eine passende Textur in der sich dein Projektor quasi von oben gesehn befindet. Dazu renderst du diesen Gobo in eine Textur und projezierst diese dann mittels der eingebauten Texturprojektion auf deine Szene. Dazu gibts Informationen in unserem Wiki, ist aber beides relativ einfach zu implementieren.
Texturprojektion machst du über die Textur-Matrix. In deinem Fall erzeugst du eine Projektionsmatrix die eine 3D-Position in eine Texturkoordinate umwandelt. Das geht ähnlich als würdest du die Szene aus Sicht der Lichtquelle rendern wollen. Der Unterschied ist eben das du glMatrixMode(GL_TEXTURE) setzt und nicht GL_PERSPECTIVE oder GL_MODELVIEW.
Die Transformation sollte so aussehen:
Zuerst die 3D-Position so drehen das du in Richtung der negativen z-Achse blickst, das geht leicht über gluLookAt.
Nun eine Projektionsmatrix die die eigentliche Projektion durchführt. Eine Projektion ist letztlich nichts anderes als durch die Z-Koordinate teilen. Da man in in Matrizen eigentlich nicht dividieren kann missbraucht man die w-Koordinate quasi als Nenner. So kann man die Division aufschieben und braucht am Ende nach dem anwenden der Gesamtmatrix nur einmal durch w teilen. Wenn du die Projektion mit gluPerspective erzeugst kommt da noch ein bisschen verschieben und skalieren dabei.
Jetzt bist du im Raum [-w...w]^3. Also nach der Division durch w wärst du im Einheitswürfel -1...1. Du brauchst also nur etwas skalieren und verschieben um x und y in den Raum [0...1]^2 (bzw. [0...w]^2) zu schieben damit du die gewünschten Texturkoordinaten kriegst.
Alle Matrizen in der richtigen Reihenfolge miteinander multiplizieren und als Texturmatrix setzen. Wenn du Shader benutzt musst du die Texturmatrix dort anwenden und die Division ausführen, mit der FixedFunctionPipeline sollte das automatisch gehen.
Kriege das noch nicht so ganz auf die Reihe mit der Projektion...
Die GL_MODELVIEW Matrix drehe ich mehrfach hin und her. Muss ich nachdem ich auf GL_TEXTURE gestellt habe die gleichen drehungen nochmal machen? Wenn ich mir vorstelle das meine Matrix nun irgendwie in gleicher Sichtposition wie der Lichtkegel ist, dann weis ich immernoch nicht wie ich die "Lichttextur" (erstmal ein weisser Kreis) auf den Boden bzw. auf andere Objekte projeziere?
Muss ich nachdem ich auf GL_TEXTURE gestellt habe die gleichen drehungen nochmal machen?
In der Annahme das du einfach die Vertex-Position als 3D-Texturkoordinaten benutzen, ja.
Zitat:
Kannst du mir ein kleines Beispiel zeigen?
Ich habs nicht ausprobiert und ich bin nicht sonderliche gut im Umgang mit der FixedFunktionPipeline (habe meine eigene Mathelibrary usw), aber vom Prinzip müsste das ungefähr so aussehen:
glPushMatrix(); // Transformation für das Objekt auf das der Scheinwerfer leuchten soll
glMatrixMode(GL_PROJECTION); glPushMatrix(); ...wie beim ganz normalen rendern... glMatrixMode(GL_MODELVIEW); glPushMatrix(); ...wie beim ganz normalen rendern...
// das Objekt rendern auf welches die Textur projiziert werden soll // Die Texturkoordinaten (3D!!!!) müssen den Vertexkoordinaten entsprechen object.render();
mh, danke erstmal für deine Hilfe, doch ich denke das Problem ist, das ich nicht weiß worauf ich die Textur projizieren soll? Ich wüsste nur das man eine Textur an ein Objekt klatschen muss... Ich hab nur die Infos wo der Scheinwerfer (x,y,z) ist, in welche Richtung er leuchtet und mit welchem Abstrahlwinkel (z.B. 19°). Aktuell läuft das bei mir so:
1. Rendern aller Objekte (Raum, Figuren etc.), diese werden mit dem 3ds loader inkl. Texturen geladen 2. In einer Objektlist geordnet meine Scheinwerfer, wo ich den Kegel mit blending rendere.
Um die Ordnung zu wahren wollte ich ebenfalls in den Scheinwerferobjekten die Textur projizieren.,.
Also der normale Ansatz ist eigentlich die komplette Szene mit dem Scheinwerfer als Textur zu rendern. Dabei erzeugt die Texturmatrix eben aus den Vertex-Koordinaten die richtigen Texturkoordinaten. "Für gut" rendert man natürlich nur die Objekte die erstens sichtbar und zweites im Kegel des Scheinwerfers liegen.
Man könnte aber auch eine Art "Deferred Shading" Ansatz wählen so das man die 3D-Position jedes sichtbaren Pixels in einem Framebuffer-Objekt hat. Dann kann man in ein FullScreen-Quad rendern und jeweils diese 3D-Position auslesen, transformieren und dann entsprechend beleuchten. Ohne Shader geht hier aber glaube ich gar nichts.
ich nochmal.. Shader sind glaub ich noch nix für mich.. Wie sollte ich das denn mit mehreren Scheinwerfern hinbekommen? Könntest du mir mal ein lauffähiges Beispiel machen, womit ich ein bisschen herumtesten kann?
Wie sollte ich das denn mit mehreren Scheinwerfern hinbekommen?
Genauso wie mit einem Scheinwerfer. Du hast dann halt nur mehrere Textur-Matrizen und mehrere Scheinwerfer-Texturen gebunden. Shader wären hier sinnvoll, dann kannst du alles auf einmal rendern. Mit der FixedFunctionPipeline renderst du die Szene für jeden Scheinwerfer einzeln mit additivem Blending.
Zitat:
Könntest du mir mal ein lauffähiges Beispiel machen, womit ich ein bisschen herumtesten kann?
Sorry, das ist jetzt nichts was man mal eben in 5min runterschreibt.
Mitglieder in diesem Forum: 0 Mitglieder und 2 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.