Generelle Frage zu Normalmaps
-
Ishildur schrieb:
@Gameco
Hei danke dir vielmals für deine Antwort. Eine Frage habe ich noch. Was bringen denn Normalen mit negativen Vorzeichen im Tangentspace? Ich meine, im ungünstigen Fall werden dann plötzlich Faces beleuchtet, die eigentlich von der Lichtquelle abgewandt sind. Hast du da ein konkretes Anwendungsbeispiel?In einer Tangent-Space Normal-Map stehen doch keine Normalen drin
Ein Kanal speichert den Multiplikator für die Tangente und einer den für die Binormale.
Du rechnest jaadjustedNormal = normal + (tangent * (map.R - 0.5) * scale) + (binormal * (map.G - 0.5) * scale); // kann sein dass R und G vertauscht sind, hab das nimmer so genau im kopf adjustedNormal = normalize(adjustedNormal);
Und damit man die Normale in alle Richtungen verschieben kann, muss der Multiplikator dabei natürlich auch negativ werden können.
-
Es geht um negative Koordinaten. Es wär etwas blöd wenn die Normalen nur in Richtung der positiven u und v Achse zeigen könnten oder?
-
hustbaer schrieb:
In einer Tangent-Space Normal-Map stehen doch keine Normalen drin.
Eigentlich schon. Genaugenommen handelt es sich um die Koordinaten der Normalen im Tangentspace codiert in Offset Binary. Ich denke worauf du anspielst geht wohl eher in Richtung einer Methode zur Kompression der Normalmap!?
-
dot schrieb:
hustbaer schrieb:
In einer Tangent-Space Normal-Map stehen doch keine Normalen drin.
Eigentlich schon. Genaugenommen handelt es sich um die Koordinaten der Normalen im Tangentspace codiert in Offset Binary.
Nein, gar nicht, nichtmal eigentlich.
Ein Objekt hat ja mehr als nur eine Tangente, daher auch mehr als einen Ausgangswert auf den der "Offset" angewendet wird. Eine Tangent-Space Normal-Map die z.B. einen Schriftzug modelliert, eine sandige Oberfläche oder dergleichen, lässt sich auf jedes beliebige Objekt draufmachen. Unabhängig von der Form und den "ursprünglichen" Normalen des Objekts.
Eine Tangent-Space Normal-Map speichert Deltas, oder Offsets wie du es nennst. Und Offsets sind keine Tangenten.Ich kann ja auch nicht sagen ein .wav File mit lauter Nullen speichert Bad von Michael Jackson, nur halt als Offsets aufs Original. Das macht keinen Sinn.
EDIT: mir ist schon klar was du meinst, und ich denke es ist Ansichtssache. Ich weigere mich nur es so zu sehen wie du
Warum ich es für "falsch" halte hab ich ja denke ich erklärt. Wie du allerdings darauf kommst dass ich mich irgendwie auf Kompression beziehen könnte, ist mir nicht ganz klar.
-
@hustbear
Was du da machst ist IMHO Bumpmapping und nicht Normalmapping?float3 Normal = normalize(mul(float3x3(Tan,Nrm,Bit),tex2D(NormalSampler,Tex).rbg-0.5f));
Das ist IMHO Normalmapping (mit Beleuchtung im Objectspace)
Bei der Normalmapping Technik werden IMHO keine Normalen "adjusted" sondern für jedes Fragment komplett neu gesetzt, die Vertexnormale hat mit der schliesslich verwendeten Normalen für die Beleuchtung nichts mehr zu tun und dient nur noch als einer der drei Basisvektoren des Tangenspace...
-
@hustbear
Was du da machst ist IMHO Bumpmapping und nicht Normalmapping?Wenn man diese Unterscheidung treffen willst, dann vermutlich ja.
Allerdings wird so-gut wie überall wo ich was über Tangent-Space Normal-Mapping gelesen habe es so gemacht wie ich es skizziert habe.
Von daher hab' ich einfach mal angenommen das sei die Art & Weise wie "man es macht". Wieder was dazugelerntWas Du beschreibst macht natürlich auch Sinn, da damit die Einschränkung fällt dass man keine zu "steilen" Normalen abbilden kann.
Spucken denn deine Tools (Modeler, Renderer, ...) solche 3-dimensionalen Tangent-Space Normal-Maps aus?
Bei der Normalmapping Technik werden IMHO keine Normalen "adjusted" sondern für jedes Fragment komplett neu gesetzt, die Vertexnormale hat mit der schliesslich verwendeten Normalen für die Beleuchtung nichts mehr zu tun und dient nur noch als einer der drei Basisvektoren des Tangenspace...
OK, jetzt verstehe ich glaube ich auch wie dot darauf kommt, dass die Tangent-Space Normal-Map wirklich Normalen speichert. Obwohl ich es immer noch nicht so ausdrücken würde, aber egal.
Und jetzt verstehe ich glaube ich auch was du mit "Normalen mit negativen Vorzeichen im Tangentspace" meinst. Oder vielleicht auch nicht
Von deiner Formel ausgehend... die Möglichkeit negative Vorzeichen für B und G (Multiplikator für Tangente und Binormale) abbilden zu können braucht man auf jeden Fall. Sonst wärst du ja wirklich auf 1/8 aller möglichen Richtungen beschränkt - was schon ein wenig wenig wäre.
Die Möglichkeit negativer Vorzeichen für R (Multiplikator für die Tangente) braucht man vermutlich wirklich selten. Allerdings ist es IMO einfacher, und aus Symmetriegründen auch "schöner" es gleich wie bei den anderen zwei Komponenten zu machen.
-
@hustbear
Allerdings ist es IMO einfacher, und aus Symmetriegründen auch "schöner" es gleich wie bei den anderen zwei Komponenten zu machen.
Ja jetzt wo du es sagst, kann mich dem nur beipflichten
-
Ishildur schrieb:
@Gameco
Hei danke dir vielmals für deine Antwort. Eine Frage habe ich noch. Was bringen denn Normalen mit negativen Vorzeichen im Tangentspace? Ich meine, im ungünstigen Fall werden dann plötzlich Faces beleuchtet, die eigentlich von der Lichtquelle abgewandt sind. Hast du da ein konkretes Anwendungsbeispiel?selbst ohne negative normalen in der normalmap passiert es oft dass du beleuchtung von faces siehst die dir eigentlich abgefand sind, weil du nur normalen hast und keine hoehen.
-
hustbaer schrieb:
Ishildur schrieb:
@Gameco
Hei danke dir vielmals für deine Antwort. Eine Frage habe ich noch. Was bringen denn Normalen mit negativen Vorzeichen im Tangentspace? Ich meine, im ungünstigen Fall werden dann plötzlich Faces beleuchtet, die eigentlich von der Lichtquelle abgewandt sind. Hast du da ein konkretes Anwendungsbeispiel?In einer Tangent-Space Normal-Map stehen doch keine Normalen drin
Ein Kanal speichert den Multiplikator für die Tangente und einer den für die Binormale.
Du rechnest jaadjustedNormal = normal + (tangent * (map.R - 0.5) * scale) + (binormal * (map.G - 0.5) * scale); // kann sein dass R und G vertauscht sind, hab das nimmer so genau im kopf adjustedNormal = normalize(adjustedNormal);
Und damit man die Normale in alle Richtungen verschieben kann, muss der Multiplikator dabei natürlich auch negativ werden können.
was glaubst du weshalb das normalmap heisst
klar stehen da normalen drinne, und deiner formal nach koennte die adjusted normal nie negativ werden, sogar 90grad zur seite waere nicht moeglich. aber solche normalmaps gib es.
Normalmaps werden ja nicht nur aus bump/heightmaps generiert, sondern auch von einigen tools indem sie von highpoly auf lowpoly mappen. z.B. (ich glaube das heisst) ATI Melody oder Cryteks polybump.
-
hustbaer schrieb:
@hustbear
Was du da machst ist IMHO Bumpmapping und nicht Normalmapping?Wenn man diese Unterscheidung treffen willst, dann vermutlich ja.
Allerdings wird so-gut wie überall wo ich was über Tangent-Space Normal-Mapping gelesen habe es so gemacht wie ich es skizziert habe.
ich denke dass du dich verlesen haben musst;)
die ganz alten "bumpmapping" demos haben naemlich (wegen der mangelnden rechenzeit), statt die normale zu transformieren, im vertexshader die light direction in den tangentspace gedreht (z.b. die ersten geforce256 demos).
dort hat man dann mittels einer cubemap die light direction normalisiert und ein dot product (und das war schon die ganze "bumpmap hardware die dazu kam") mit der normalmap im tangentspace gemacht.
Erst mit der zeit wurde es sparsammer einmal die normale der normalmap in den worldspace zu rotieren. (bzw haben ein paar spiele die lichtquelle in den objectspace rotiert und die normalmap war dann auch im objects space abgespeichert, um noch ein paar instructions zu sparen, auf kosten von texturspeicher).Spucken denn deine Tools (Modeler, Renderer, ...) solche 3-dimensionalen Tangent-Space Normal-Maps aus?
*nods*
lustigerweise macht man das bei CG renderings fuer filme usw durchaus so wie du das gesagt hast. Artist stecken eine bumpmap rein (also graustufen, 1 channel) und eine "petrubnormal" funktion biegt diese dann.
Das schoene daran ist, dass das auch mit prozeduralen funktionen geht (eigentlich dort sogar noch viel besser, weil die meist kontinuierlich und unendlich detailiert sind).
-
rapso schrieb:
lustigerweise macht man das bei CG renderings fuer filme usw durchaus so wie du das gesagt hast. Artist stecken eine bumpmap rein (also graustufen, 1 channel) und eine "petrubnormal" funktion biegt diese dann.
Das schoene daran ist, dass das auch mit prozeduralen funktionen geht (eigentlich dort sogar noch viel besser, weil die meist kontinuierlich und unendlich detailiert sind).Nicht nur dass man es prozedural machen kann, man kann so Bump-Maps (oder Height-Maps oder wie auch immer man das nennt) auch total einfach in jedem Bildbearbeitungsprogramm malen und wie benötigt anpassen. Ein wenig Weichzeichner da, ein wenig Nachschärfen dort...
Allerdings kann man sich dann immer noch aussuchen, ob man eine "echte" 3D Tangent-Space Normal-Map haben will, oder eine 2D Variante (wie auch immer man die dann korrekt bezeichnet <- kann auch gleich als Frage aufgefasst werden: wie nennt man das dann korrekt?).
-
Ah, kanns sein dass du irgendwie Normalmaps mit dudv Maps verwechselt hast!?
-
@dot
werden dudv maps verwenwendet, um Normalmapping zusammen mit Displacementmapping zu verwenden?
-
Nein dudv Maps werden normalerweise für Environment Bumpmapping verwendet.
Für Displacementmapping brauchst du eine normale Heightmap/Displacementmap, also ein Graustufenbild in dem das Displacement drin steht...
-
@dot
Ja aber wenn ich dynamisches displacement mapping verwende dann muss ich ja den Tangentspace in jedem Frame neu berechnen. Besser ist es IMHO, diesen in einer Map speichern, die zur Displacementmap passt und einfach auslesen
-
Du meinst also eine Map die die Tangentspace Basisvektoren enthält? Das ist dann aber keine Normalmap!? Außerdem halte ich ein dynamisches Berechnen des Tagentspace im Shader für garnichtmal so abwegig wenn ich schon Displacement Mapping betreibe, evtl. könnte man da sogar wertvolle Bandbreite sparen...
-
@dot
Hehe, ein interessanter Gedanke!Kommt halt darauf an, ob die Applikation eher Vertexbound oder FSB Bound ist. Das perverse ist ja, dass sich dies im weiteren Verlauf der Entwicklung jederzeit ändern kann uns auch von Enduser zu Endusersystem