Frage zu Normalmapping und Tangent Space

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Frage zu Normalmapping und Tangent Space

Beitrag von starcow »

Hallo liebe ZFX'ler (:

Ich wollte mich mal dem Thema Normalmapping von der technischen Seite her annehmen. Ich verwende diese Technik zwar oft bei meinen Modellen, habe aber dennoch einige Lücken im Verständnis der Technik. Ich hoffe ihr könnt mir dabei helfen klarheit in die Sache zu bringen.

Folgende Punkte glaube ich Verstanden zu haben:
-> In der Normalmap speichert man in den einzelnen Pixel der Grafik einen Vektor, indem man je einen integer Wert in die Farbkanäle speichert. Diese drei integer Werte repräsentieren einen Punkt im Raum (R = X, G = Y, B = Z). Anhand diesem Punkt im Raum und dem Referenzpunkt (0, 0, 0) lässt sich einen Vektor bilden.
Dieser Vektor lässt sich nun (gleich dem Prinzip von Vertices-Normalen) zur Beleuchtung verwenden.

Stimmt das soweit?

Was ich an der Geschichte nicht verstehe ist, dass dabei immer vom "Tangent Space" gesprochen wird.
Ich habe beobachtet, das in einer Normalmap (R=128, G=128, B=255) als "neutral" gilt.
Meine Schlussfolgerung daraus ist, dass ein Vektor mit diesem Wert, exakt die gleiche Richtung hat, wie die Polygon-Normale.

Bedeutet den dieser Tangentialraum, das immer nur die abweichungen gegenüber der Polygon-Normalen gespeichert werden?

Eine andere offene Frage ist, was beim Normalmapping mit den Vertices-Normal passiert. Werden die dann für die Beleuchtung komplett ignoriert?
Bild
(In diesem Bild entsprechen die Vertices-Normalen der Polygon-Normalen)

Gruss starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von Aramis »

Ja, die Intuition, dass "Abweichungen" gegenueber den geometrischen Normalen gespeichert werden, ist soweit korrekt und auch dein Verstaendnis der RGB-Werte, und wie daraus ein Vektor wird, passt (beachte aber dass normalerweise ein Offset verwendet wird: FarbWert * 2 - 1 ergibt die jeweilige Vektorkomponente).

Rechnerisch betrachtet, existiert an jedem Punkt der Oberflaeche eine Koordinatensystembasis, die sich aus irgendeiner Form von Normalen sowie einer weiteren Richtung - der Tangente - ergibt. Die Wahl des Tangentenvektors ist grundsaetzlich beliebig in der Tangentialebene (die Vektoren in der Normal-Map muessten fuers gleiche Ergebnis dann einfach rotiert werden), in der Praxis waehlt man sie so, dass die Tangenten ueber die gesamte Geometrie moeglichst stetig und "natuerlich" sind. Darueber musst du dir normalerweise nicht viel Gedanken machen, gaengige 3D-Toolchains und -Engines koennen die Tangenten generieren.

Der Vektor aus der Normal-Map (fuer einen bestimmten Punkt auf der Oberflaeche) wird interpretiert als ein Vektor in eben diesem Koordinatensystem. Zur Beleuchtung wird sie wieder in den Welt-Raum transformiert, was eine Matrizenmultiplikation mit der Basismatrix des Raums darstellt. Das ist dann das Anwenden der "Abweichung".

Welche Normale als Basis dient, haengt von der konkreten Anwendung ab. Normalerweise spielen Polygon-Normalen keine Rolle, die Normale an einem Punkt ist dann die Interpolation der umliegenden Vertex-Normalen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von Krishty »

Noch ein Nachtrag: Das macht man alles, weil erlaubt ist, dass sich eine Textur auf dem Modell (oder auf verschiedenen Modellen) wiederholt. Denn sonst hätte man, wenn die selbe Textur auf zwei unterschiedlichen Flächen des Modells in unterschiedliche Richtungen zeigt, *zwei* Normalen pro Texel. Das will man nicht.

Falls man ein Modell hat, auf dem sich die Textur nie wiederholt – wo also jeder Texel nur eine Position und eine Normale hat – kann man in der Normal Map auch direkt Vektoren in Objektkoordinaten speichern statt Tangenten zu suchen und daraus Vertex-Koordinatensysteme zu berechnen. In diesem Fall spricht man von einer Object Space Normal Map. Die gilt nur für ein einziges Modell statt universell verwendbar zu sein, spart dafür aber den ganzen Aufwand, der dir so merkwürdig erscheint.

Die Normal Maps, über die wir hier sprechen, sind hingegen Tangent Space Normal Maps.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von starcow »

Vielen Dank für eure Hilfe!
So langsam dämmert es mir. :)

Ich verstehe jetzt zwar, weshalb das speichern von Normalen im Tagentenraum sinnvoll ist - verstehe aber den Tangentenraum selbst noch nicht richtig.
Aramis hat geschrieben:Rechnerisch betrachtet, existiert an jedem Punkt der Oberflaeche eine Koordinatensystembasis...
-> Punkt heisst, an jedem Vertices?
Aramis hat geschrieben:die sich aus irgendeiner Form von Normalen sowie einer weiteren Richtung - der Tangente - ergibt. Die Wahl des Tangentenvektors ist grundsaetzlich beliebig in der Tangentialebene
Also nutze ich die Normale des Vertices und eben diese Tangente des Vertices, um damit zwei Achsen dieses neuen "Custom-Koordinaten-Systemes" zu bilden?
Es klingt bestimmt etwas blöd, doch irgendwie kann ich mir noch nicht wirklich was sinnvolles darunter vorstellen.

Bild

Verständnishalber habe ich in Softimage eine Kugel erstellt und Tangenten darauf angewendet. Für die Tangenten (die sich leider nicht wie die Normalen im Viewport direkt darstellen lassen) existiert eine Art Smoothing Funktion.
Diese Smoothing Funktion scheint irgendwie die Tangenten zu beeinflussen.
Die Kugel auf der linken Seite hat den Wert 0 / Die Kugel auf der rechten Seite hat den Wert 180
Die Kugel hat UV's die ich zuvor erstellt habe.


Gerade an den UV-Seams sind die Farbänderungen teils sehr aprupt. Inwieweit hängen diese Tangenten mit den UV's zusammen? Oder anders gefragt; Wie lassen sich diese Farbänderungen an den UV-Seams erklären?
Krishty hat geschrieben:Noch ein Nachtrag: Das macht man alles, weil erlaubt ist, dass sich eine Textur auf dem Modell (oder auf verschiedenen Modellen) wiederholt. Denn sonst hätte man, wenn die selbe Textur auf zwei unterschiedlichen Flächen des Modells in unterschiedliche Richtungen zeigt, *zwei* Normalen pro Texel. Das will man nicht.
Danke für diesen Hinweis. Diese Frage ist tatsächlich gleich bei mir aufgetaucht. Ich verstehe nun auf was das hinausläuft.
Wenn ich z.b einen rechteckigen Innenraum als einzelnes Modell habe, kann ich darauf keine sich-wiederholende Wandtextur anwenden, deren Normalmap im Object Space ist.
Aus dem einfachen Grund, weil die vier Seitenwände in vier verschiedene Richtungen zeigen. Mit einer Textur deren Normalmap im Tangent-Space ist, kann ich Texturwiederholungen einsetzten.
Aber was meinst du mit *zwei" Normalen pro Texel. Du kriegst doch auch mit einer Normalmap im Object-Space schliesslich nur eine Normale pro Texel. ?

Gruss starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von Krishty »

Ich meinte, dass bei einer Tangent Space Normal Map jeder Punkt in vier verschiedenen Koordinatensystemen verwendet würde. Hättest du eine Object Space Normal Map, wäre sie vier Mal so groß und die Normalen wären vierfach drin, nur in unterschiedliche Richtungen. So in etwa :)

Was Aramis mit den Tangenten meinte, war, glaube ich: Jeder Punkt (nicht nur jedes Vertex, sondern alles, was du als Pixel auf dem Bildschirm sehen kannst) hat eine Normale. Im 3D-Raum kannst du dir nun eine beliebige Achse senkrecht dazu aussuchen (es gibt unendlich viele) und hast eine Tangente. Dann berechnest du den Vektor, der senkrecht auf beiden steht (die Bitangente), und hast ein vollwertiges 3D-Koordinatensystem, in welchem du die Normal Map ausrechnest / malst / produzierst eben.

Für gewöhnlich nimmt man aber nicht irgendeine der unendlich vielen möglichen Tangenten, sondern diejenige, die exakt in Richtung der Texturkoordinaten verläuft (die UV-Koordinaten der Vertices kennst du ja, also kannst du auch die Richtung berechnen, in der U größer wird. Das ist deine Tangente). So stimmt die Tangente immer mit dem Vektor überein, der auf der Textur nach rechts zeigt (und die Bitangente mit dem Vektor, der auf der Textur nach oben zeigt). Das erlaubt dir, auf der Normal Map einen Vektor z.B. nach rechts zu vermerken und auf dem Modell dargestellt zeigt er tatsächlich in die Richtung, die auf der Textur "rechts" ist; egal, wie die Textur gedreht ist.

Um das mit deinem Kugel-Schnappschuss zu erklären muss aber ein Experte ran.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Specialist
Establishment
Beiträge: 135
Registriert: 29.08.2003, 14:22
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von Specialist »

Krishty hat geschrieben:Ich meinte, dass bei einer Tangent Space Normal Map jeder Punkt in vier verschiedenen Koordinatensystemen verwendet würde. Hättest du eine Object Space Normal Map, wäre sie vier Mal so groß und die Normalen wären vierfach drin, nur in unterschiedliche Richtungen. So in etwa :)

Was Aramis mit den Tangenten meinte, war, glaube ich: Jeder Punkt (nicht nur jedes Vertex, sondern alles, was du als Pixel auf dem Bildschirm sehen kannst) hat eine Normale. Im 3D-Raum kannst du dir nun eine beliebige Achse senkrecht dazu aussuchen (es gibt unendlich viele) und hast eine Tangente. Dann berechnest du den Vektor, der senkrecht auf beiden steht (die Bitangente), und hast ein vollwertiges 3D-Koordinatensystem, in welchem du die Normal Map ausrechnest / malst / produzierst eben.

Für gewöhnlich nimmt man aber nicht irgendeine der unendlich vielen möglichen Tangenten, sondern diejenige, die exakt in Richtung der Texturkoordinaten verläuft (die UV-Koordinaten der Vertices kennst du ja, also kannst du auch die Richtung berechnen, in der U größer wird. Das ist deine Tangente). So stimmt die Tangente immer mit dem Vektor überein, der auf der Textur nach rechts zeigt (und die Bitangente mit dem Vektor, der auf der Textur nach oben zeigt). Das erlaubt dir, auf der Normal Map einen Vektor z.B. nach rechts zu vermerken und auf dem Modell dargestellt zeigt er tatsächlich in die Richtung, die auf der Textur "rechts" ist; egal, wie die Textur gedreht ist.

Um das mit deinem Kugel-Schnappschuss zu erklären muss aber ein Experte ran.
Die beste Erklärung, die ich seit langem gesehen habe. EInfach erklärt, ohne viel Schnickschnack und unnötigen Mathekram. Sauber!
Und hier eine mit Mathekram, vielleicht hilft es dir bei der Umsetzung: http://www.terathon.com/code/tangent.html
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von starcow »

Danke nochmals für die Ausführung.

Kann man demnach sagen, das wenn ich eine Normalmap auf ein Objekt anwende, ich die Vertices-Normalen nicht mehr benötige? Einfach weil mit einer Normalmap sowieso jeder Pixel des Objektes einzeln beleuchtet wird?

Wenn ich eure Antworten jetzt richtig verstanden habe, brauche ich für die Berechnung der Object-Space-Normalmap folgendes:
- Lowpoly Model
- Highpoly Model
- Cage (Also die Hülle / Poly-Mesh für die Berechnungen)
Mit diesen Drei Objekten kann ich eine Object-Space-Normalmap berechnen und - das ist jetzt für mich der entscheidene Punkt - das Ergebnis fällt dabei immer gleich aus.

Um eine Tangent-Space-Normalmap zu berechnen, muss ich aber erst noch die Tangenten erzeugen. Und je nachdem wie ich das tue, ist das Ergebnis der Normalmap ein anderes.

Wäre es da nicht eine gute Idee, immer zuerst eine Object-Space-Normalmap zu erzeugen? Und erst danach - in einem zweiten Schritt - die Tangent-Space-Normalmap auf Basis der zuvor erstellen Object-Space-Normalmap? Für diesen Schritt bräuchte man dann nur noch das Lowpoly Model und die Object-Space-Normalmap.

Einfach aus dem Grund, weil die Object-Space-Normalmap "nicht falsch", oder durch eine ungünstige Tangenten-Kalkulation suboptimal sein kann.
Diesen Part könnte ich dann auch der technischen Abteilung überlassen, denen ich nur noch das Lowpoly-Model und die Object-Space-Normalmap übergebe :). Die könnten dann die Tangenten so wählen, wie es für ihre Zwecke (Engine) am günstigsten ist.

Was denkt ihr dazu?

Gruss starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von starcow »

Hier nochmals ein kleines Update aus aktuellem Anlass:

Ich hab jetzt einige Dinge ausprobiert und bin dabei auf dieses Tool gestossen.

-> http://handplane3d.com/

Dieses Freeware Tool berechnet aus einem Mesh und einer Object-Space-Normalmap eine Tangent-Space-Normalmap.
Dabei kann man wählen welche Engine man mit dieser Tanget-Space-Normalmap füttern will.
Erwähnenswert ist, das die Ergebnisse teils recht deutlich voneinander abweichen, je nach Engine-Output-Format. Nicht mal in einzelnen Software-Linien (Maya 2012 / Maya 2014) ist das Ergebnis deckungsgleich.

Mir scheint es, das eine Tangent-Space-Normalmap (wenn man den Anspruch an ein korrektes Shading hat) ziemlich spezifisch auf die Engine angepasst sein muss.
Und falls ich jetzt richtig kombiniere, ist das bei einer Object-Space-Normalmap definitiv nicht der Fall - was meiner Meinung nach einen entscheidenden Vorteil gegenüber der Tanget-Space-Normalmap darstellt.

Gruss starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: Frage zu Normalmapping und Tangent Space

Beitrag von starcow »

Ich habe inzwischen einen genauen Vergleich zwischen einer Object- und Tangent-Spaced-Normalmap angestellt.
Unabhängig von den gewählten Prozess-Settings (Object-Spaced-Normalmap zu Tangent-Spaced-Normalmap), sind die Ergebnisse nie 100% deckungsgleich.
Meine Frage an euch ist daher, ob es prinzipbedingt überhaupt möglich ist ein pefektes Ergebnis mit einer Tangent-Space Normalmap zu erhalten.

Bild

Gruss starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Antworten