Oh boy here we go again!
Krishty hat geschrieben:Automatische Mip-Maps sind dafür (wie sonst auch) nur sehr begrenzt nützlich … du müsstest den Texturwürfel von Hand entsprechend der Kosinusformel schrittweise weichzeichnen. Indem du das Resultat jedes Mal in einer kleineren Mip-Map speicherst, kannst du dann anhand des Mip-Levels die Glätte der Oberfläche einstellen (größte Mip-Map enthält die unveränderte Textur, also perfekt glatt; kleinste Mip-Map enthält die Umgebungsfarbe, also perfekt matt). Möglicherweise ließe sich die Trigonometrie, die das Ganze so aufwändig macht, mit geschickten Wertetabellen performant implementieren.
Klingt plausibel. Siehe auch
hier.
Krishty hat geschrieben:Für die Schattierung müsstest du entweder auf
Umgebungsverdeckung zurückgreifen oder Spherical Harmonics anlegen, die dir für die entsprechende Stelle und Normale die Verdeckungsinformation ausgeben.
Das ist korrekt, ist aber natürlich abhängig davon, wie viele Freiheiten du hast: Wenn die Geometrie dynamisch ist, kann man in der Regel sowohl Ambient Occlusion wie auch PRT ab Schattierung (d.h. PRT mit Schattierung oder PRT mit Schattierung und Interreflexionen) in die Tonne treten; es sei denn, man bastelt sich noch ein paar Tricks zusammen (z.B. Schattenvolumen um die Objekte), welche aber nach meinem letzten Kenntnisstand alle nicht mehr echtzeitfähig waren. Aber das war hier ja eigentlich schon allen klar. ;)
Krishty hat geschrieben:U.U. ließe sich das auch mit dem ersten Schritt – der Auswahl eines genügend großen Ausschnitts zur Beleuchtung – kombinieren.
Nach Renderinggleichung braucht man für einen beliebigen Punkt und für eine beliebige BRDF immer die volle Hemisphäre. Wenn Subsurface-Scattering hinzukommt, braucht man die komplette Sphäre. Einschränkungen bzgl. des Bereichs der eingehenden Beleuchtung können nur bei Beachtung der gerade vorliegenden BRDF vorgenommen werden: Im trivialsten Fall will man eine perfekt spekulare Relexion. In diesem Fall reicht es dann logischerweise aus, einen einzigen Punkt der Cubemap (nämlich in Reflexionsrichtung!) zu sampeln. In diesem Fall ist aber die BRDF (ein einziger Dirac-Stoß in Reflexionsrichtung) aber auch sehr, sehr speziell. Wenn du sagst, das geht auch mit einer Phong-„BRDF“ (Anmerkung: Sie ist keine BRDF, da nicht energieerhaltend), hast du vollkommen recht: Der Träger des Kosinus-Terms (bis zu den Nullstellen – also bis dahin, wo der
\($\max(\cdot, 0)$\)-Term keine Änderung verursacht) ist beschränkt. Damit reicht es aus, aus einem gewissen Teilgebiet der Hemisphäre zu samplen.
Schrompf hat geschrieben:Ich glaube auch, dass Du da noch ein paar falsche Vorstellungen von den Begriffen hast. Sowas wie "Ambient" und "Diffuse" gibt es genau genommen nicht, es sind nur Namen für ein paar Grundsorten von reflektierter Lichtenergie. Image Based Lighting wäre ansonsten tatsächlich der richtige Begriff.
Danke, dass du es sagst. Noch einmal: Ambient-, Diffus- und Spekularterm sind nur vereinfachende Approximationen von bestimmten Beleuchtungsmodellen/BRDFs. Manche Beleuchtungsmodelle kennen diese Terme gar nicht.
Schrompf hat geschrieben:Die richtige Beleuchtungsformel besagt ja für ein Stück Oberfläche in der Welt, wieviel Licht aus welchen Richtungen ins Auge des Betrachters reflektiert wird. Daher enthält die Formel natürlich alle Lichteinflüsse aus der Umgebung. Das wäre Deine CubeMap.
Und dabei wird auch direkt die Approximation klar: Unendlich weit entferntes Licht. Man kann nur mühsam noch zusätzliche lokale Lichtquellen in die Cubemap „reinbaken“. Mit SH geht das (nennt sich dann analytische Lightquellen).
Schrompf hat geschrieben:Wenn Du alle Pixel der CubeMap zusammenrechnen würdest und die CubeMap keine direkten Lichtquellen enthält, wäre das der Ambient-Term in der Phong-Lichtformel.
Nein. Bei jedweder physikalisch korrekter Betrachtungsweise ist der Ambient-Term 0 (man hat höchstens noch einen emissiven Term). Der Ambient-Term, den man normalerweise als Approxmation einsetzt, ist eine Approximation von was? Genau: Der Differenz zwischen dem globalen und dem lokalem Beleuchtungsmodell. Hier nehmen wir aber nur ein Objekt unter unendlich weit entfernter Beleuchtung an. Da gibt es keine Differenz zwischen lokalem und globalem Beleuchtungsmodell (wenn man PRT Schattierung oder Interreflexionen außen vorlässt –
das wäre hier die globale Beleuchtung). Alle Farbwerte für den Ambient-Term zusammenrechnen ergibt auch so leider nicht viel Sinn: Denn du hast die Farbwerte ja bereits für das, was du den diffusen Term nennst, verwendet; die würdest du dann doppelt addieren. (Soll ich vielleicht einfach Ambient → Diffus und Diffus → Spekular als Ersetzung vornehmen? ;) Dann stimmt's nämlich. :))
Schrompf hat geschrieben:Wenn Du - Krishtys Empfehlung folgend - alle Pixel in der CubeMap mit dem cos()-Term auf alle Nachbarn überträgst und die CubeMap nur die direkten Lichtquellen als helle Flecken enthält, bekommst Du den Diffuse-Term.
Ich dachte jetzt an den Spekularterm. Egal. ;)
Schrompf hat geschrieben:Das sind jetzt alles ziemlich vereinfachte Beispiele, für die mich Leute mit Kenntnis von der Materie wahrscheinlich schlagen wollen, aber sie sollen andeuten, dass die CubeMap wirklich alle nötigen Informationen enthält und Image Based Lighting der korrekte Ansatz für Dein Thema ist. Die Phong-Formel ist nur eine Vereinfachung des Ganzen und wird halt gern genommen, weil sie eben gerade so einfach zu berechnen ist und akzeptable Ergebnisse bringt.
Sekundiert.
Wenn man die Approximation durch eine reine Cubemap in Kauf nimmt, ist das, was alledem noch am nächsten kommt, ist
das hier. Das ist natürlich noch zu rechenintensiv.
Das Problem ist doch eher, wie man das alles effizient hinkriegt. Soll heißen: Am Ende darf man nur aus einer 2D-Textur (sei das jetzt eine Cubemap oder parabolische Spheremap oder was auch immer) samplen; diese hat man aber vorberechnet. Um's mal platt zu sagen:
Wir haben mit der Cubemap die eingehende Beleuchtung. Das Integral mit BDRF und mit Kosinus-Term verwuschtet das zu einer ausgehenden Beleuchtung. Diese ausgehende Beleuchtung wollen wir nun wiederum in einer Textur speichern! Das Problem ist jetzt aber, dass wenn wir das in einer 2D-Textur speichern wollen, die resultierende reflektierte Beleuchtung maximal zweiparametrisch sein darf!! Dies ist nur für bestimmte BRDFs erfüllt! (Die Renderinggleichung hat ja z.B. noch die Betrachtungsrichtung als Parameter). Im allgemeinen ist das nur mit einer 5D-Textur möglich.
So weit ich das sehe, ist die zweiparametrische Speicherung insbesondere mit der Phong-BRDF möglich – in einer bestimmten Formulierung aber (ich habe nun schon so viele Beleuchtungsmodelle gesehen, die meinen „Phong“ zu sein; es ist schon nicht mehr feierlich). Erstmal das
Phong-Modell in Wikipedia-Notation genommen, und dann auf die eigene Notation umgestellt:
\($$\begin{align}\displaystyle k_s \cdot \frac{(\mathbf R \cdot \mathbf V)^m}{\mathbf L \cdot \mathbf N} &= \displaystyle k_s \cdot \frac{(r_{\mathbf n}(\omega_i)^\ast \mathbf v)^m}{\omega_i\!\,^\ast \mathbf n} \\
&= \displaystyle k_s \cdot \frac{(\omega_i\!\,^\ast r_{\mathbf n}(\mathbf v))^m}{\omega_i\!\,^\ast \mathbf n} \end{align}$$\)Bei mir ist
\(${}^*$\) (wie auch in allen meinen anderen Posts) das Standard-Skalarprodukt. Das
\($\mathbf L$\) wurde durch
\($ω_i$\) ersetzt (Standardname in der Renderinggleichung). Das einzig Verbleibende ist das
\($r_{\mathbf n}(ω_i)$\): Das ist der am Vektor
\($\mathbf n$\) gespiegelte Vektor
\($ω_i$\), d.h. einfach die reflektierte Lichtrichtung a.k.a. die ausgehende Lichtrichtung (denn wir spiegeln die eingehende Lichtrichtung am Normalenvektor). Das zweite Gleichheitszeichen gilt, weil das Skalarprodukt bilinear ist, also gilt:
\($$\begin{align}r_{\mathbf n}(\mathbf x_1)\!\,^\ast \mathbf x_2 &= (2\cdot \mathbf n^\ast \mathbf x_1 \cdot \mathbf n - \mathbf x_1)^\ast \mathbf x_2 \\
&= 2 \cdot (\mathbf n^\ast \mathbf x_1 \cdot \mathbf n)^\ast \mathbf x_2 - \mathbf x_1\,\!^\ast \mathbf x_2 \\
&= 2 \cdot (\mathbf n^\ast \mathbf x_2 \cdot \mathbf n)^\ast \mathbf x_1 - \mathbf x_2\,\!^\ast \mathbf x_1 \\
&= \mathbf x_1\!\,^\ast r_{\mathbf n}(\mathbf x_2)
\end{align}$$\)Was man jetzt machen kann, ist folgendes:
\($$\begin{align}\underbrace{L_r(\mathbf x, \omega_r)}_{\small \text{Ausgehende Beleuchtung}} &= L_r(\mathbf x, \mathbf v, \mathbf n), \text{ da } \omega_r = \mathbf v \\
&= \smash{\int_\Omega \underbrace{k_s \cdot \frac{(\omega_i\!\,^\ast r_{\mathbf n}(\mathbf v))^m}{\omega_i\!\,^\ast \mathbf n}}_{\small \text{Phong-„BRDF“}} \underbrace{\vphantom{\frac{(r(n)^\ast \omega_i)^m}{n^\ast \omega_i}}L_i(\mathbf x, \omega_i)}_{\small \text{Eingehende Beleuchtung}} \hspace{-5 pt} \cos(\vartheta_i) \, \underbrace{\mathrm d\omega_i}_{\small \text{Raumwinkel}}} \\[20 pt]
&= \int_\Omega k_s \cdot (\omega_i\!\,^\ast r_{\mathbf n}(\mathbf v))^m \, L_i(\mathbf x, \omega_i) \, \mathrm d\omega_i
\end{align}$$\)Das ist die Renderinggleichung für diese Phong-„BDRF“. Welt-Position
\($\mathbf x$\). Betrachtungsrichtung a.k.a. ausgehende Lichtrichtung
\($ω_r = \mathbf v$\). Normalenvektor
\($\mathbf n$\) der Geometrie bei
\($\mathbf x$\). Integration über die komplette Hemisphäre
\($\Omega$\). Die Umformung, die ich da gemacht habe, ist einfach die beiden Standardskalarprodukte (der Nenner vom Bruch und den Kosinusterm) herauszukürzen. Das
\($ω_i$\) ist der Raumwinkel der eingehenden Lichtrichtung. Kann man sich am einfachsten (wenn auch mathematisch nicht ganz korrekt) als ein Vektor in eine Richtung
\($(\vartheta_i, \varphi_i)$\) in Polarkoordinaten vorstellen.
Lasst mich das ganze nun mal kurz umschreiben:
\($$\begin{align} L_r(\mathbf x, r_{\mathbf n}(\mathbf v)) &= \displaystyle \int_\Omega k_s \cdot (\omega_i\!\,^\ast r_{\mathbf n}(\mathbf v))^m \, L_i(\mathbf x, \omega_i) \, \mathrm d\omega_i
\end{align}$$\)Nehmen wir jetzt auch noch unsere Position
\($\mathbf x$\) für alle Vertizes im Zentrum des Objektes an (wieder eine Approximation!) kriegen wir:
\($$\begin{align} L_r(r_{\mathbf n}(\mathbf v)) &= \displaystyle k_s \cdot \int_\Omega (\omega_i\!\,^\ast r_{\mathbf n}(\mathbf v))^m \, L_i(\mathbf x, \omega_i) \, \mathrm d\omega_i
\end{align}$$\)Wenn wir jetzt linke Seite betrachten, sehen wir ganz was tolles: Das Teil hängt nur noch von
\($r_{\mathbf n}(\mathbf v)$\) ab! Warum ist das toll? Weil der reflektierte Betrachtungsvektor zweidimensional ist (eben nur die Reflexion vom einem zweidimensionalem Vektor, der zum Augpunkt zeigt)! Damit hat man für diesen Spezialfall einer Phong-„BRDF“ eine zweiparametrische Parametrisierung des
reflektierten Lichtes gefunden. Also kann man die Cubemap vorverarbeiten und wieder in einer 2D-Textur abspeichern. Und das ist es, was wir de-facto für eine Phong-BRDF mit spekularem Koeffizienten
\($m$\) vorberechnen müssen.
So, das war der spekulare Anteil von der Phong-BRDF. Nun noch schnell der diffuse Anteil, der ist nun aber trivial:
\($$\begin{align}L_r(\mathbf n) &= \displaystyle \int_\Omega k_d \cdot L_i(\mathbf x, \omega_i) \cos(\vartheta_i) \, \mathrm d\omega_i \\
&= \displaystyle k_d \cdot \int_\Omega L_i(\mathbf x, \omega_i) \cdot \omega_i\,\!^\ast\mathbf n \, \mathrm d\omega_i \end{align}$$\)Damit hat man
einen konstanten Wert eine 2D-Textur (parametrisiert mittels des Normalenvektors) für den Diffus-Term und eine 2D-Textur für den spekularen Lookup (eine 2D-Textur pro Spekular-Exponent
\($m$\), parametrisiert mittels des reflektierten Betrachtungsrichtungsvektors). Ich kann das auch alles noch weiter erklären; einfach an den entsprechenden Stellen nachfragen. ;)
Krishty hat geschrieben:Was du für diffuse Reflexion suchst, ist das Licht, das aus der kompletten Hemisphäre auf die Oberfläche trifft und von ihr reflektiert wird. Du musst also theoretisch über die komplette Hemisphäre, jeweils mit dem Kosinus des Winkels zwischen Normale und Einfallsrichtung multipliziert, integrieren. Das ist so ähnlich wie ein niedrigeres Mip-Level zu wählen, nur eben mit dem Kosinus dazwischen.
Sekundiert, siehe nun oben. ;)
Krishty hat geschrieben:Ambiente Reflexion gibt es nicht.
Sekundiert.
(Wie man das genau für eine BRDF mit Halfway-Vektor, d.h. Cook-Torrance oder Ashikhmin oder Blinn-Phong, macht, weiß ich noch nicht. So sollte es zumindest für Phong und das LaFortune-Modell klappen.)
(Ohne angeberisch klingen zu wollen: Ich fühle mich in Sachen globaler Beleuchtungsrechnung, Monte-Carlo-Integration und Photonmapping eigentlich relativ fit. Solltet ihr mal einem dieser Themen begegnen, und euch denken „oh, hier hat man ja nur Ahnung von Echtzeitrendering“ – nope; einfach fragen. :3)