PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dynamisches Light-Mapping


Corrail
2004-04-28, 20:28:20
Hello!

Ich hab mir ein paar Gedanken über eine Belichtungsmethode (ich nenne sie hier mal dynamisches Lightmapping) gemacht:

Man nehme:
Ein texturiertes Model, wo sich kein Polygon auf der Textur überlappt. Also jedes Polygon hat seinen eigenen Teil auf der Textur. Das Model muss noch pro Vertex folgende Daten haben: Vertex-Position, Normal, Tangent, Binormal, Textur-Koordinate.

Möglichkeit 1
So, wenn das Model geladen wird werden zwei floating-point Texturen erzeugt. Eine, die die Vertex-Positionen speichert und eine die die Normal-Vektoren (in Object-Space umgerechnet) speichert. Und zwar soll, wenn ein Vertex die Koordinaten (a,b,c) und die Textur-Koordinaten (s,t) hat in der neuen Textur an der Stelle (s,t) der Wert (a,b,c) stehen. Analog dazu soll auch die neue Normal-Map erzeugt werden. Die lässt sich eigentlich ziehmlich einfach mit Shader und MRT realisieren, indem man im Vertex-Shader sagt die Output-Vertex-Position ist gleich der Tex-Koordinate. Und im Pixel-Shader wird dann der Rest berechnet. Man kann da auch eine Bump-Map vom Model nehmen und miteinfließen lassen usw.

Wenn das Objekt gerendert werden soll wird zuerst eine Lightmap erzeugt, indem man ein Pixelshader alle Licht-Berechnungen macht. Die Daten bekommt der Pixel-Shader von den am Anfang erzeugten Position und Normal Texturen.

So, wenn das fertig ist kann man ganz einfach das Objekt mit der Lightmap rendern. Der Pixel-Shader ist dann ein einfacher Texture-Sampling-Shader.

Möglichkeit 2

Wie Möglcihkeit 1, nur dass am Anfang keine Position und Normal Texturen erstellt werden.
Der Vertex-Shader bei der Erstellung der Lightmap ist ungefähr so, wie der Vertex Shader bei der Erstellung der Position und Normal Texturen bei Möglichkeit 1. Der Pixel Shader berechnet aber direkt die Lightmap.


Vorteil von Möglichkeit 1:
Vertex Shader bei Lightmap-Erstellung ist kurz und simpel und es muss nur ein Viereck gerendert werden
Nachteil von Möglichkeit 1:
Pixel Shader bei Lightmap-Erstellung muss alle Vertex-Transformationen übernehmen

Vorteil von Möglichkeit 2:
Vertex Shader bei Lightmap-Erstellung ist komplexer und es müssen mehrere Dreiecke gerendert werden
Nachteil von Möglichkeit 2:
Pixel Shader bei Lightmap-Erstellung ist einfach, da er keine Vertex-Transformationen übernehmen muss


Gut, aber wofür der Aufwand?
Ich hab mir folgendes überlegt: Wenn man eine Umgebung hat, die viele reflektierende Objekte beinhaltet so müsste ich die Umgebung x-mal durch einen möglicher Weise teuren Pixelshader laufen lassen. So lass ich pro Objekt einmal ein Pixelshader seine Arbeit tun und verwende dann einfach einen Texture-Sampling-Shader.
Ein weiterer Vorteil ist, dass man eine bessere Kontrolle über das hat, was man gerade rendern will. Ich kann genau bestimmen wie groß die Lightmap sein soll und weiß daher wieviele Pixel gerendert werden. Noch dazu kann ich einfach LoD implementieren indem ich entweder die größe der Lightmap ändere oder die Lightmap nur jedes x-te Frame neu erstelle.

Was haltet ihr davon?

PS: Ich weiß nicht, ob diese Technik schon mal wo beschrieben wurde. Ich hatte einfach diese Idee und wollt sie mal posten. ;D

Neo69
2004-05-03, 00:29:10
ich bin zwar nur absoluter laie auf dem gebiet, aber dann schreibt dir wenigstens mal jemand was als Antwort :-)

Beim Lesen hab ich mich erst gewundert, was das bringen soll, den Pixelshader die Lichtberechnungen in eine Lightmap schreiben zu lassen, und nicht in den Framebuffer, weil man ja quasi schon fertig ist.

Frage: Müsste die Floating-Point-Lightmap gefiltert werden? Wenn ja, dann ginge das ja nur mit dem NV40 oder? - wie sähe es denn da mit der Performance aus, also ganz allgemein, wie schnell ist das FP-Texture-Filterung?

Ich denke um zu wissen, ob deine Idee was taugt, müsste man schauen wie sehr es auffällt, wenn bei bestimmten Objekten (die weiter weg sind) diese Lightmap eben nur, wie du schon sagtest, in geringerer Auflösung oder nicht jedes Frame zu erzeugen.

Das wüsste ich aber auch nicht einzuschätzen, ob das vom Speed her etwas bringen würde, darauf kommt es ja an, inwieweit das schneller ist als einfach alles gleich zu beleuchten, ohne eine Lightmap noch dazwischen.

Muh-sagt-die-Kuh
2004-05-03, 01:19:50
Original geschrieben von Corrail
Gut, aber wofür der Aufwand?
Ich hab mir folgendes überlegt: Wenn man eine Umgebung hat, die viele reflektierende Objekte beinhaltet so müsste ich die Umgebung x-mal durch einen möglicher Weise teuren Pixelshader laufen lassen. So lass ich pro Objekt einmal ein Pixelshader seine Arbeit tun und verwende dann einfach einen Texture-Sampling-Shader.Bei einer statischen Szene funktioniert das, allerdings kann man dann auch gleich statische Environment-Maps verwenden.
Ein weiterer Vorteil ist, dass man eine bessere Kontrolle über das hat, was man gerade rendern will. Ich kann genau bestimmen wie groß die Lightmap sein soll und weiß daher wieviele Pixel gerendert werden.MIP-Mapping funktioniert doch auch mit Lightmaps. Noch dazu kann ich einfach LoD implementieren indem ich entweder die größe der Lightmap ändere oder die Lightmap nur jedes x-te Frame neu erstelle.
Was haltet ihr davon?

PS: Ich weiß nicht, ob diese Technik schon mal wo beschrieben wurde. Ich hatte einfach diese Idee und wollt sie mal posten. ;D Pixel-Shader kommen eigentlich nur bei dynamischer Beleuchtung zum Einsatz, Lightmaps bei statischer...wo deine Technik Vorteile gegenüber diesen Beiden Methoden bietet ist mir noch etwas schleierhaft.

Corrail
2004-05-03, 08:57:15
Original geschrieben von Neo69
Frage: Müsste die Floating-Point-Lightmap gefiltert werden? Wenn ja, dann ginge das ja nur mit dem NV40 oder? - wie sähe es denn da mit der Performance aus, also ganz allgemein, wie schnell ist das FP-Texture-Filterung?


Nein, es müste hier keine FP Texture gefiltert werden, da in die Floating Point Texturen nur dazu gebraucht werden um die dynamischen Lightmaps zu erstellen. Also wird von Textur auf eine andere Textur gerendert. Der einzige Fall, wo hier FP Texturen gefiltert werden müssen ist wenn die Position und Normal Textur z.B. die Größe 512x512 hat und ich aber nur eine 128x128 Lightmap erzeugen will.


Ich denke um zu wissen, ob deine Idee was taugt, müsste man schauen wie sehr es auffällt, wenn bei bestimmten Objekten (die weiter weg sind) diese Lightmap eben nur, wie du schon sagtest, in geringerer Auflösung oder nicht jedes Frame zu erzeugen.


Das ist klar, das müsste man ausprobieren. Bin bis jetzt aber leider noch nicht dazu gekommen.


Das wüsste ich aber auch nicht einzuschätzen, ob das vom Speed her etwas bringen würde, darauf kommt es ja an, inwieweit das schneller ist als einfach alles gleich zu beleuchten, ohne eine Lightmap noch dazwischen.


Vom Speed her wird es sich NUR was bringen, wenn das Objekt pro Frame öfter als einmal gerendert wird. Wenn man angenommen in eine 256x256 Lightmap rendered frisst der Pixel-Shader 65000 Pixel. Das Objekt müsste schon recht groß sein, damit es diese Anzahl an Pixel einnimmt, wenn ich es normal rendere. Also wenn ich ein Objekt nur ein mal pro Frame rendere bringt es sicher keinen Speed Vorteil. Wenn das Objekt allerdings reflektiert wird (Spiegel, Wasser, ...) und ich es öfter rendern muss dann sehe ich da sehr wohl Vorteile.


Bei einer statischen Szene funktioniert das, allerdings kann man dann auch gleich statische Environment-Maps verwenden.


Das ist mir schon klar, aber das wäre klassisches Light-Mapping was ich hier nicht haben will. Was ich hier beschrieben habe ist eine Möglichkeit des dynamischen Belichtens. Ich verwende zwar Lightmaps, erzeuge die aber jedes (oder jedes x-te) Frame neu.

Muh-sagt-die-Kuh
2004-05-03, 12:57:02
Original geschrieben von Corrail
Das ist mir schon klar, aber das wäre klassisches Light-Mapping was ich hier nicht haben will. Was ich hier beschrieben habe ist eine Möglichkeit des dynamischen Belichtens. Ich verwende zwar Lightmaps, erzeuge die aber jedes (oder jedes x-te) Frame neu. Richtig....und genau da ist, meiner Meinung nach, der Haken:

Die Lightmaps jedes x-te Frame neu zu erzeugen führt zwangsläufig zu längeren Perioden inkorrekter Beleuchtung in einer dynamischen Szene, sie jedes Frame zu berechnen ist wenig sinnvoll, da kann man gleich einen normalen Pixel-Shader benutzen.

Corrail
2004-05-03, 13:21:58
Nein, das stimmt nicht ganz. Das mit dem jedes x-te Frame die Lightmap neu erzeugen wäre nur sinnvoll für Objekte die ein niedriges LoD haben. z.B. Objekte die im Framebuffer nur wenig Pixel verbrauchen (also weit weg sind). Die Anzahl der Pixel, die ein Objekt in Anspruch nimmt kann man einfach mit Occlusion Culling (bei OpenGL mit ARB_occlusion_query) herrausfinden. Für Objekte die mehr Pixel in Anspruch nehmen hat das nicht wirklich viel Sinn, da es für das Auge zu leicht erkennbar ist.

Wolfgang Engel
2004-05-03, 19:28:31
Hi Corrail,
hast Du schon mal in Deferred Shading reingeschaut? Ich glaube das ist es, was Du realisieren willst.

Schau Dir das mal an ... Dean Calver hat dazu einen guten Artikel auf www.beyond3d.com.

Grüsse Wolf

Demirug
2004-05-03, 20:00:05
Original geschrieben von Wolfgang Engel
Hi Corrail,
hast Du schon mal in Deferred Shading reingeschaut? Ich glaube das ist es, was Du realisieren willst.

Schau Dir das mal an ... Dean Calver hat dazu einen guten Artikel auf www.beyond3d.com.

Grüsse Wolf

Zuerst einmal ein herzliche Willkommen.

Ich sehe da zwar bestimmte Ähnlichkeiten mit Deferred Shading aber auch Unterschiede.

Beim Deferred Shading ermittelt man die Normalen, Decals usw. ja einmal pro Frame und lässt das ganze mit einem Finalen PS zum entgültigen Frame verrechnen. Wenn ich Corrail allerdings richtig verstanden haben dann will ja diese Informtionen pro Objekt speichern und eine Lightmap pro Objekt erzeugen.

Corrail, ich sehe bei deiner Idee das Problem das die FP-Texturen zuviel Speicher und Bandbreite fressen und dir dort einen Flaschenhals sondergleichen erzeugen. Zudem wirst du gerade bei entfernten Objekten ja tendenziel viel zu viel Informationen für die Lightmaps berrechnets die dann nie gebraucht werden.

Hast du schon mal daran gedacht einfach die entgültige Farbe für die Pixel eines Objekts direkt zu speichern. Bei DOOM 1 hat man diesen Trick benutzt um das Texturieren zu vereinfachen. Mit diesem Trick muss man nämlich immer nur noch eine Textur pro Objekt auftragen.

Corrail
2004-05-03, 22:56:58
Hi Corrail,
hast Du schon mal in Deferred Shading reingeschaut? Ich glaube das ist es, was Du realisieren willst.

Schau Dir das mal an ... Dean Calver hat dazu einen guten Artikel auf www.beyond3d.com.

Grüsse Wolf


Hallo!
Nicht ganz, diese Technik hätte zwar Parallelen zu Deferred Shading ist aber nicht das gleiche. Das Problem was ich bei Deferred Shading sehe ist, wenn man mehrere Shader verwendet, die alle verschiedene Daten brauchen.

Corrail, ich sehe bei deiner Idee das Problem das die FP-Texturen zuviel Speicher und Bandbreite fressen und dir dort einen Flaschenhals sondergleichen erzeugen. Zudem wirst du gerade bei entfernten Objekten ja tendenziel viel zu viel Informationen für die Lightmaps berrechnets die dann nie gebraucht werden.

Ja, das stimmt. Aber auf der anderen Seite braucht man pro Objekt keine weiteren Daten mehr speichern wie z.B. Normalvektoren oder Tangentenvektoren usw.
Das wäre aber nur bei der ersten Methode zutreffend. Bei der zweiten Methode erzeuge ich die dynamische Lightmap direkt aus den Objektdaten (Vertex, Normal, TexCoords, Tangenten, ...) und berechne nicht vorher FP Texturen.