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
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