PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Was sind Normal Maps?


GUNDAM
2004-09-11, 17:02:59
Ich hab jetzt schon öfters von einer Grafiktechnik namens "Normal Maps" gelesen. Allerdings kann ich mir nix darunter vorstellen. Was soll das sein und wozu ist es gut? Hat das irgendwas mit Leveldesign zu tun?

zeckensack
2004-09-11, 17:16:21
Eine Normale ist immer der Vektor "von der Oberfläche weg". Ein Würfel hat zB sechs Oberflächennormalen, die -- von jeder der sechs Seiten ausgehend -- nach "außen" zeigen.

Eine Normal map speichert nun pro Pixel, wo von der Oberfläche aus "oben" ist, also in welche Richtung die Oberfläche zeigt. Das braucht man für diverse Licht- und Spiegelungsberechnungen an Oberflächen die nicht plan sein sollen, Stichwort: bumpmapping. Für diese Dinge braucht man immer "Auftreffwinkel". Da eine Oberfläche mit Bumps aber gekrümmt sein kann, braucht man "zwischen den Ecken" irgendeine Zusatzinformation, um das korrekt ausrechnen zu können. Und dann nimmt man eben normal maps.

Das ganze ist letztendlich eine Textur, die aber nicht direkt sichtbar ist, sondern nur als Berechnungskrücke für die Lichtintensität und den Spiegelungswinkel genutzt wird.

edit: Winkel => Vektor

GUNDAM
2004-09-11, 18:35:13
THX, ich habs jetzt glaub ich so halbwegs verstanden wofür es gut ist.

Aqualon
2004-09-11, 18:41:35
Das ganze ist letztendlich eine Textur, die aber nicht direkt sichtbar ist, sondern nur als Berechnungskrücke für die Lichtintensität und den Spiegelungswinkel genutzt wird.
Da du von einer Berechnungskrücke sprichst, könnte man das auch auf andere Art lösen?

Aqua

Trap
2004-09-11, 19:01:25
Klar, mit mehr Polygonen.

mrdigital
2004-09-12, 18:21:46
wie wird die Normal Map mit dem Normalenvektor verrechnet?

Coda
2004-09-12, 18:29:17
Die Normalmap gibt dir den Normalenvektor, was willst du da verrechnen?
Du must nur vorher den Lichtvektor in den Tangent-Space bringen...

mrdigital
2004-09-12, 18:45:11
Ja, aber wie sieht der Normalenvektor aus, wenn er in der normalmap gespeichert wird? Stehen da alle 3 koordinaten drin, oder werden da nur zwei angegeben und die 3 Komponente wird implizit gegeben? Und wie wird die normalmap auf das Dreieck projeziert?

Xmas
2004-09-12, 18:53:15
Ja, aber wie sieht der Normalenvektor aus, wenn er in der normalmap gespeichert wird? Stehen da alle 3 koordinaten drin, oder werden da nur zwei angegeben und die 3 Komponente wird implizit gegeben? Und wie wird die normalmap auf das Dreieck projeziert?
Das kann man machen wie man will. 3Dc speichert beispielsweise nur 2 Komponenten, die dritte muss man als
z = sqrt(1-x²-y²)
berechnen. Man kann aber genausogut drei Kanäle nutzen und im vierten (es gibt keine 3-Kanal Texturformate in Hardware, die werden auf 4 erweitert) etwas anderes unterbringen, z.B. die Heightmap für Parallax Mapping.

Wie die Normale und das Dreieck zusammenpassen, hängt von der Art der Daten ab, man kann die Normalen im World Space, Object Space oder Tangent Space angeben. Zur Berechnung der Beleuchtung muss man dann die Position der Lichtquelle, die des Betrachters und die Normale in denselben Raum transformieren.

Asmodeus
2004-09-12, 19:42:11
Da du von einer Berechnungskrücke sprichst, könnte man das auch auf andere Art lösen?

Aqua

Man könnte die interpolierten Normalen auch einfach im Fragmentshader normalisieren und dann für eine pixelgenaue Lichtberechnung benutzen. Leider geht in dem allgemeinen "Jubel" über die ach so leistungsfähige Grafikhardware meist etwas unter, dass für komplexe Szenen, die Fragmentshaderleistung meist nicht ausreicht, um die Normalen "mathematisch korrekt" zu berechnen. Und deshalb geht man eben den Umweg über die Normalmaps. Erkauft sich die leichtere Berechenbarkeit jedoch mit mehr Speicherbedarf und weniger Flexibilität, da jede Normalmap natürlich nur für die für sie bestimmte Polygonoberfläche benutzt werden kann.

Gruss, Carsten.

Coda
2004-09-12, 19:55:37
Was genau möchtest du uns mitteilen? Woraus willst du die Normalen berechnen? Aus der Diffuse-Textur geht das sicher nicht.

Wenn man Bump-Mapping will, muss man die Normalen irgendwo speichern, das hat nix mit der Leistungsfähigkeit von Grafikkarten zu tun.

Xmas
2004-09-12, 20:05:08
Man könnte die interpolierten Normalen auch einfach im Fragmentshader normalisieren und dann für eine pixelgenaue Lichtberechnung benutzen. Leider geht in dem allgemeinen "Jubel" über die ach so leistungsfähige Grafikhardware meist etwas unter, dass für komplexe Szenen, die Fragmentshaderleistung meist nicht ausreicht, um die Normalen "mathematisch korrekt" zu berechnen. Und deshalb geht man eben den Umweg über die Normalmaps. Erkauft sich die leichtere Berechenbarkeit jedoch mit mehr Speicherbedarf und weniger Flexibilität, da jede Normalmap natürlich nur für die für sie bestimmte Polygonoberfläche benutzt werden kann.

Gruss, Carsten.
Mit interpolierten Normalen bekommt man aber keine Oberflächenstruktur, die Flächen sind einfach glatt. Normal Maps benutzt man nicht, um sich das Normalisieren interpolierter Vertexnormalen zu sparen, sondern um Strukturen darzustellen. Auch die Normalen aus Normal Maps muss man u.U. nochmal normalisieren. Und Tangent Space Normal Maps können auf jeder Fläche eingesetzt werden.

Asmodeus
2004-09-12, 20:10:36
Was genau möchtest du uns mitteilen? Woraus willst du die Normalen berechnen? Aus der Diffuse-Textur geht das sicher nicht.

Wenn man Bump-Mapping will, muss man die Normalen irgendwo speichern, das hat nix mit der Leistungsfähigkeit von Grafikkarten zu tun.

Pro Vertex kann eine Normale übertragen werden, genauso wie ja Texturkoordinaten pro Vertex übertragen werden. Und genauso wie Texturkoordinaten im Fragmentprogramm zwischen den Vertices interpoliert werden um die Textur auf die Fläche zu mappen können auch die Normalen interpoliert werden. Wenn die Normalen pro Vertex normalisiert vorlagen, gilt für die interpolierten Normalen leider nicht mehr, dass sie normalisiert sind. Deshalb müssen sie im Fragmentprogramm nochmals normalisiert werden. Per Befehl geht das glaube ich erst seit der GeforceFX Generation, vorher nur über Cubemaps zur Normalisierung. Hat man dann die normalisierten, interpolierten Normalen für jedes Pixel kann man sie weiter zur Berechnung nutzen. Leider kostet die pixelweiste Normalisierung so viel Rechenpower, dass es für komplexe Szenen kaum anwendbar ist und deshalb auf Normalmaps zurückgegriffen wird.

Gruss, Carsten.

Asmodeus
2004-09-12, 20:15:52
Mit interpolierten Normalen bekommt man aber keine Oberflächenstruktur, die Flächen sind einfach glatt. Normal Maps benutzt man nicht, um sich das Normalisieren interpolierter Vertexnormalen zu sparen, sondern um Strukturen darzustellen. Auch die Normalen aus Normal Maps muss man u.U. nochmal normalisieren. Und Tangent Space Normal Maps können auf jeder Fläche eingesetzt werden.

Da hast Du recht, ohne Zusatzinformation bekommt man einfach glatte Flächen. Nur könnte man diese Zusatzinformation zum Beispiel per Textur einlesen, wobei dafür sicher weniger Daten nötig wären, als um die gesamte Normale in einer Textur zu speichern.
Die Tangent Space Normal Maps können zwar auf jeder Fläche eingesetzt werden, aber ich meinte vielmehr, dass eine Normalmap, die für eine Hausfassade erstellt wurde eben dann auch nur für diese Hausfassade benutzt werden kann und nicht für die Hautstruktur eines Elephanten oder so. Somit steigt der Speicherbedarf eben, gegenüber der rein mathematischen Variante.

Gruss, Carsten.

Xmas
2004-09-12, 20:16:07
Pro Vertex kann eine Normale übertragen werden, genauso wie ja Texturkoordinaten pro Vertex übertragen werden. Und genauso wie Texturkoordinaten im Fragmentprogramm zwischen den Vertices interpoliert werden um die Textur auf die Fläche zu mappen können auch die Normalen interpoliert werden. Wenn die Normalen pro Vertex normalisiert vorlagen, gilt für die interpolierten Normalen leider nicht mehr, dass sie normalisiert sind. Deshalb müssen sie im Fragmentprogramm nochmals normalisiert werden. Per Befehl geht das glaube ich erst seit der GeforceFX Generation, vorher nur über Cubemaps zur Normalisierung. Hat man dann die normalisierten, interpolierten Normalen für jedes Pixel kann man sie weiter zur Berechnung nutzen. Leider kostet die pixelweiste Normalisierung so viel Rechenpower, dass es für komplexe Szenen kaum anwendbar ist und deshalb auf Normalmaps zurückgegriffen wird.
Niemand benutzt Normal Maps nur als Ersatz für die Normalisierung von interpolierten Vertex-Normalen. Wo hast du denn das her?

Und seit NV40 ist das Normalisieren von Vektoren pro Pixel so billig, dass es schon fast fahrlässig wäre es nicht zu tun.

Asmodeus
2004-09-12, 20:21:39
Niemand benutzt Normal Maps nur als Ersatz für die Normalisierung von interpolierten Vertex-Normalen. Wo hast du denn das her?

Und seit NV40 ist das Normalisieren von Vektoren pro Pixel so billig, dass es schon fast fahrlässig wäre es nicht zu tun.

Ich glaube, wir sprechen da aneinander vorbei. Allgemein, und auf die Spieleindustrie bezogen hast Du natürlich vollkommen recht. Für andere Anwendungsgebiete (Visualisierung extrem grosser Datenmengen) ist es jedoch nach wie vor ein Problem pro Pixel zu normalisieren. Und dafür reicht dann auch die Leistung der NV40 Generation nicht aus.

Gruss, Carsten.

Coda
2004-09-12, 20:22:05
Da hast Du recht, ohne Zusatzinformation bekommt man einfach glatte Flächen. Nur könnte man diese Zusatzinformation zum Beispiel per Textur einlesen, wobei dafür sicher weniger Daten nötig wären, als um die gesamte Normale in einer Textur zu speichern.
Eine normal map ist eine Textur. Meinst du per 8-bit Heightmap? Das wäre enorm teuer und würde gegenüber 3dc nicht viel Speicher sparen.
Nochmals: Du kannst die normale in einem Punkt NICHT aus der Diffuse Textur erzeugen.

Xmas
2004-09-12, 20:22:46
Da hast Du recht, ohne Zusatzinformation bekommt man einfach glatte Flächen. Nur könnte man diese Zusatzinformation zum Beispiel per Textur einlesen, wobei dafür sicher weniger Daten nötig wären, als um die gesamte Normale in einer Textur zu speichern.
Ja, man kann statt Normalen als 3-Komponenten-Vektoren zu speichern auch nur X und Y verwenden (3Dc oder DXT5 helfen noch dabei) und Z errechnen, oder aber Height Maps mit nur einem Höhenwert nehmen.
Nur braucht man bei der Lichtberechnung ja Normalen, keine Höhenwerte, weshalb Normal Maps eben Vorteilhafter sind.

Die Tangent Space Normal Maps können zwar auf jeder Fläche eingesetzt werden, aber ich meinte vielmehr, dass eine Normalmap, die für eine Hausfassade erstellt wurde eben dann auch nur für diese Hausfassade benutzt werden kann und nicht für die Hautstruktur eines Elephanten oder so. Somit steigt der Speicherbedarf eben, gegenüber der rein mathematischen Variante.
"Rein mathematisch" kannst du aber das Relief einer Elefantenhaut oder eine Hausfassade nur schwer nachbilden. Manche Texturen kann man nicht prozedural erzeugen. Insofern ist die rein mathematische Variante keine Alternative.

Xmas
2004-09-12, 20:26:06
Ich glaube, wir sprechen da aneinander vorbei. Allgemein, und auf die Spieleindustrie bezogen hast Du natürlich vollkommen recht. Für andere Anwendungsgebiete (Visualisierung extrem grosser Datenmengen) ist es jedoch nach wie vor ein Problem pro Pixel zu normalisieren. Und dafür reicht dann auch die Leistung der NV40 Generation nicht aus.

Gruss, Carsten.
FP16-Normalisierung ist auf NV40 "umsonst", mit 2 Takten Latenz. Wenn die Leistung dann nicht ausreicht, dann ist sie auch ohne Normalisieren unbrauchbar.

Asmodeus
2004-09-12, 20:28:38
FP16-Normalisierung ist auf NV40 "umsonst", mit 2 Takten Latenz. Wenn die Leistung dann nicht ausreicht, dann ist sie auch ohne Normalisieren unbrauchbar.

Ja, und genau das sind Dinge, mit denen man sich so rumschlägt. Dinge die unbrauchbar oder zu langsam sind, dann trotzdem zum Laufen zu bringen :wink:

Gruss, Carsten.

Coda
2004-09-12, 20:30:43
Ich versteh dein Problem immer noch nicht.
Du must entweder Height speichern und daraus die Normale berechnen oder eben einen Normalmap benützen, eine andere Lösung gibt es nicht.

Gast
2004-09-12, 21:35:45
muss ich zusätzlich noch ein materialobjekt für das polygon spezifizieren, um überhaupt die auswirkungen von normal mapping zu sehen?

Xmas
2004-09-12, 21:55:54
muss ich zusätzlich noch ein materialobjekt für das polygon spezifizieren, um überhaupt die auswirkungen von normal mapping zu sehen?
Ich bin mir zwar nicht sicher von welcher Engine du redest, aber da die Normalmap selbst ja nur ein Oberflächenrelief darstellt, ist sie ohne "Material" recht nutzlos.

Asmodeus
2004-09-13, 09:39:26
Ich versteh dein Problem immer noch nicht.
Du must entweder Height speichern und daraus die Normale berechnen oder eben einen Normalmap benützen, eine andere Lösung gibt es nicht.

Du kannst doch jederzeit bei jedem geometrischen Modell pro Vertex eine Normale abspeichern. Diese Normalen müssen natürlich bei der Erstellung des Modells mit berechnet werden und werden dann eben pro Vertex einfach wie die Texturkoordinaten mit im Vertexbuffer, oder der Displayliste abgespeichert.
Wenn Du diese Normalen dann genau wie die Texturkoordinaten über den Vertexshader an den Fragmentshader weitergibst können sie interpoliert und pro Pixel verwendet werden.

Oder bezog sich Deine Frage noch auf etwas ganz anderes?

Gruss, Carsten.

zeckensack
2004-09-13, 16:09:32
Du kannst doch jederzeit bei jedem geometrischen Modell pro Vertex eine Normale abspeichern. Diese Normalen müssen natürlich bei der Erstellung des Modells mit berechnet werden und werden dann eben pro Vertex einfach wie die Texturkoordinaten mit im Vertexbuffer, oder der Displayliste abgespeichert.
Wenn Du diese Normalen dann genau wie die Texturkoordinaten über den Vertexshader an den Fragmentshader weitergibst können sie interpoliert und pro Pixel verwendet werden.Sie sind dann aber eben interpoliert. Alles schön rund, aber eben auch glatt. Da ist nichts mit Strukturen, die feiner aufgelöst sind als das Mesh. Wenn du auf die Weise feine Oberflächendetails abbilden willst, verbrauchst du tonnenweise vertices, und damit auch Speicher, Bandbreite und Transformationsleistung.

Normal mapping (oder ganz allgemein "bump mapping") ist eben eine Technik, um mit vertretbarem Speicherverbrauch fein aufgelöste Lichtberechnungen zu bekommen, weil man eben die anderweitig notwendigen vertices durch eine kompaktere (Textur-)Darstellung ersetzt. Dadurch wird das erst sinnvoll möglich.

Deswegen "Krücke". Das ändert nichts daran, dass die Krücke praktikabler ist als die "konventionellen" Alternativen.

Asmodeus
2004-09-13, 16:26:27
Sie sind dann aber eben interpoliert. Alles schön rund, aber eben auch glatt. Da ist nichts mit Strukturen, die feiner aufgelöst sind als das Mesh. Wenn du auf die Weise feine Oberflächendetails abbilden willst, verbrauchst du tonnenweise vertices, und damit auch Speicher, Bandbreite und Transformationsleistung.

Normal mapping (oder ganz allgemein "bump mapping") ist eben eine Technik, um mit vertretbarem Speicherverbrauch fein aufgelöste Lichtberechnungen zu bekommen, weil man eben die anderweitig notwendigen vertices durch eine kompaktere (Textur-)Darstellung ersetzt. Dadurch wird das erst sinnvoll möglich.

Deswegen "Krücke". Das ändert nichts daran, dass die Krücke praktikabler ist als die "konventionellen" Alternativen.

Genau, und wenn man aber sowieso "tonnenweise" Vertices visualisiert wäre es eben schön, auch die "konventionelle" Methode performant benutzen zu können. :wink: Denn dann ist eindeutig der Zeit- und Speicheraufwand noch grösser, wenn man auf Normalmaps angewiesen ist.

Gruss, Carsten.

zeckensack
2004-09-13, 16:47:49
Genau, und wenn man aber sowieso "tonnenweise" Vertices visualisiert wäre es eben schön, auch die "konventionelle" Methode performant benutzen zu können. :wink: Denn dann ist eindeutig der Zeit- und Speicheraufwand noch grösser, wenn man auf Normalmaps angewiesen ist.

Gruss, Carsten.Ja, aber ich denke hier liegt eben das Missverständnis zwischen dir und Coda.
Wenn du Meshes mit einem Vertex pro Millimeter hast, dann brauchst du normal mapping nicht mehr, um das visuelle Ergebnis zu verbessern. Allerdings wird die Performance wahrscheinlich ziemlich grauenhaft sein ;)

Du könntest dir allerdings überlegen, ob du nicht mit normal maps den Detailgrad in akzeptablem Rahmen halten, und damit Vertex-Leistung einsparen kannst. Es ist eben ein Tausch zwischen Geometrieauflösung und Lichtauflösung. Für sowas kann man sich auch Tools kaufen oder selbst schreiben, die das hochaufgelöste Mesh vereinfachen und "nebenbei" die normal maps erzeugen. Man muss die Dinger ja nicht selber malen.

Bei Spiele-Content kommt man eher aus der anderen Richtung. Dort herrschen eher verträgliche Polycounts vor, und man ist auf der Suche nach Möglichkeiten die Details noch weiter zu steigern, ohne auf ein belegbar schlecht performendes Anforderungsprofil ala Unigraphics umzusteigen.

Für Modeller/Editor/CAD-Software mag es der korrekte Weg sein, einfach Millionen an vertices auf das Problem zu werfen, für die reine Visualisierung eines "fertigen" Objekts IMO eher nicht.

edit:
OT@Coda: Schau hier (http://www.forum-3dcenter.org/vbulletin/showthread.php?t=163650&perpage=20&page=4) nochmal rein. Ich habe dir nach enormer Verspätung nun endlich den fraglichen VS-Code gepostet.

Asmodeus
2004-09-13, 16:59:20
Ja, aber ich denke hier liegt eben das Missverständnis zwischen dir und Coda.
Wenn du Meshes mit einem Vertex pro Millimeter hast, dann brauchst du normal mapping nicht mehr, um das visuelle Ergebnis zu verbessern. Allerdings wird die Performance wahrscheinlich ziemlich grauenhaft sein ;)


Ja, das Wort grauenhaft beschreibt die Performance ganz gut ;)


Du könntest dir allerdings überlegen, ob du nicht mit normal maps den Detailgrad in akzeptablem Rahmen halten, und damit Vertex-Leistung einsparen kannst. Es ist eben ein Tausch zwischen Geometrieauflösung und Lichtauflösung. Für sowas kann man sich auch Tools kaufen oder selbst schreiben, die das hochaufgelöste Mesh vereinfachen und "nebenbei" die normal maps erzeugen. Man muss die Dinger ja nicht selber malen.

Bei Spiele-Content kommt man eher aus der anderen Richtung. Dort herrschen eher verträgliche Polycounts vor, und man ist auf der Suche nach Möglichkeiten die Details noch weiter zu steigern, ohne auf ein belegbar schlecht performendes Anforderungsprofil ala Unigraphics umzusteigen.

Für Modeller/Editor/CAD-Software mag es der korrekte Weg sein, einfach Millionen an vertices auf das Problem zu werfen, für die reine Visualisierung eines "fertigen" Objekts IMO eher nicht.

Ist eben das alte Problem gerade bei der Modellierung und Visualisierung von Pflanzen. Wenn ein Blatt oder Grashalm gebogen ist, dann braucht es ein gewisses Minimum an Vertices, damit die Sache auch so aussieht, wie sie aussehen soll. Und mit Hilfe einer Normalmap oder ähnlichem bekommt man diese Art von "Details" eben leider kaum.

Gruss, Carsten.