Lerne OpenGL. Lektion 6.1. PBR oder physikalisch korrektes Rendern. Theorie

OGL3

Physikalisch korrektes Rendern


PBR oder physikalisch basiertes Rendering ist eine Reihe von Visualisierungstechniken, die auf einer Theorie basieren, die recht gut mit der realen Theorie der Lichtausbreitung ĂŒbereinstimmt. Da der Zweck von PBR eine physikalisch zuverlĂ€ssige Lichtsimulation ist, sieht es im Vergleich zu den zuvor verwendeten Beleuchtungsmodellen Phong und Blinn-Fong viel realistischer aus. Es sieht nicht nur besser aus, sondern bietet auch eine gute AnnĂ€herung an die reale Physik, die es uns (und insbesondere KĂŒnstlern) ermöglicht, Materialien basierend auf den physikalischen Eigenschaften von OberflĂ€chen zu erstellen, ohne auf billige Tricks zurĂŒckgreifen zu mĂŒssen, um die Beleuchtung realistisch erscheinen zu lassen. Der Hauptvorteil dieses Ansatzes besteht darin, dass die von uns erstellten Materialien unabhĂ€ngig von den LichtverhĂ€ltnissen wie geplant aussehen, was nicht ĂŒber andere, nicht ĂŒber PBR-AnsĂ€tze gesagt werden kann.



PBR ist jedoch immer noch eine AnnĂ€herung an die RealitĂ€t (basierend auf den Gesetzen der Physik), weshalb es eher als physikalisch korrektes Rendering als als physikalisches Rendering bezeichnet wird. Damit das Beleuchtungsmodell als physikalisch korrekt bezeichnet werden kann, muss es drei Bedingungen erfĂŒllen (keine Sorge, wir werden sie bald erreichen):

  • Basierend auf einem Modell reflektierender Mikrofacetten
  • Befolgen Sie das Gesetz der Energieerhaltung
  • Verwenden Sie die Doppelstrahl-Reflexionsverteilungsfunktion (BRDF).

In dieser Tutorial-Reihe konzentrieren wir uns auf den PBR-Ansatz, der ursprĂŒnglich bei Disney entwickelt und fĂŒr die Echtzeitvisualisierung durch Epic Games angepasst wurde. Ihr Ansatz, der auf einem metalldielektrischen Arbeitsablauf basiert (engl. Metallischer Arbeitsablauf, konnte keine bessere Übersetzung finden - ca. Hrsg. ), Ist gut dokumentiert, in vielen gĂ€ngigen Motoren weit verbreitet und sieht erstaunlich aus. Am Ende dieses Abschnitts erhalten wir etwas Ähnliches:

Beachten Sie, dass die Artikel in diesem Abschnitt ziemlich fortgeschritten sind. Es wird daher empfohlen, dass Sie sich mit OpenGL und Shader-Beleuchtung gut auskennen. Hier sind einige der Kenntnisse, die Sie benötigen, um diesen Abschnitt zu studieren: Bildpuffer , kubische Karten , Gammakorrektur , HDR und normale Karten . Wir werden auch etwas tiefer in die Mathematik gehen, aber ich verspreche, alles zu tun, um alles so klar wie möglich zu erklÀren.


Modell reflektierender Mikrofacetten


Alle PBR-Techniken basieren auf der Theorie der Mikrogesichter. Diese Theorie besagt, dass jede OberflĂ€che mit hoher VergrĂ¶ĂŸerung als ein Satz mikroskopischer Spiegel dargestellt werden kann, die als MikroflĂ€chen bezeichnet werden. Aufgrund der OberflĂ€chenrauheit können diese Mikrospiegel in verschiedene Richtungen ausgerichtet werden:



Je rauer die OberflĂ€che ist, desto zufĂ€lliger sind die MikroflĂ€chen ausgerichtet. Das Ergebnis dieser Anordnung dieser kleinen Spiegel ist (insbesondere bei Spiegelreflexionen und Reflexionen), dass die einfallenden Lichtstrahlen auf rauen OberflĂ€chen in verschiedene Richtungen gestreut werden, was zu einer breiteren Spiegelreflexion fĂŒhrt. Und umgekehrt: Auf glatten OberflĂ€chen werden die einfallenden Strahlen eher in eine Richtung reflektiert, was zu einer kleineren und schĂ€rferen Blendung fĂŒhrt:



Auf mikroskopischer Ebene gibt es keine absolut glatten OberflĂ€chen. Angesichts der Tatsache, dass die MikroflĂ€chen klein genug sind und wir sie innerhalb unseres Pixelraums nicht unterscheiden können, approximieren wir die OberflĂ€chenrauheit statistisch, indem wir einen Rauheitskoeffizienten einfĂŒhren. Mit diesem Koeffizienten können wir den Anteil der MikroflĂ€chen berechnen, die in Richtung eines bestimmten Vektors ausgerichtet sind h . Dieser Vektor h nichts weiter als ein Medianvektor, der in der Mitte zwischen der Richtung des einfallenden Lichts liegt l und Richtung des Beobachters v . Wir haben bereits in einer Lektion ĂŒber fortgeschrittene Beleuchtung darĂŒber gesprochen , in der wir das VerhĂ€ltnis der Summe der Vektoren definiert haben l und v auf die LĂ€nge des resultierenden Vektors:


h = f r a c l + v | | l + v | | 


Je mehr MikroflÀchen in Richtung des Medianvektors ausgerichtet sind, desto schÀrfer und heller wird das Glanzlicht. Aufgrund des Rauheitskoeffizienten, der zwischen 0 und 1 liegt, können wir die Ausrichtung der MikroflÀchen statistisch approximieren:



Wie Sie sehen können, ergibt ein höherer Wert des Rauheitskoeffizienten einen grĂ¶ĂŸeren Spiegelfleckfleck als ein kleiner und scharfer Fleck auf glatten OberflĂ€chen.


Energieeinsparung.


Die Verwendung der NĂ€herung unter BerĂŒcksichtigung von MikroflĂ€chen bringt bereits eine bestimmte Form der Energieeinsparung mit sich: Die Energie des reflektierten Lichts wird niemals die Energie des einfallenden Lichts ĂŒberschreiten (wenn die OberflĂ€che nicht von selbst leuchtet). Wenn wir das obige Bild betrachten, sehen wir, dass mit zunehmender OberflĂ€chenrauheit der Punkt des reflektierten Lichts zunimmt, gleichzeitig aber seine Helligkeit abnimmt. Wenn die IntensitĂ€t des reflektierten Lichts unabhĂ€ngig von der GrĂ¶ĂŸe des Spots fĂŒr alle Pixel gleich wĂ€re, wĂŒrden rauere OberflĂ€chen viel mehr Energie emittieren, was gegen das Gesetz der Energieerhaltung verstoßen wĂŒrde. Daher sind Spiegelreflexionen auf glatten OberflĂ€chen heller und auf rauen OberflĂ€chen dunkler.


Um Energie zu sparen, mĂŒssen wir eine klare Trennung zwischen der diffusen und der Spiegelkomponente vornehmen. In diesem Moment, wenn ein Lichtstrahl die OberflĂ€che erreicht, wird er in reflektierte und gebrochene Komponenten unterteilt. Die reflektierte Komponente ist direkt reflektiertes Licht und dringt nicht in die OberflĂ€che ein. Wir kennen sie als Spiegelkomponente des Lichts. Die gebrochene Komponente ist Licht, das die OberflĂ€che durchdringt und von dieser absorbiert wird - es ist uns als diffuse Komponente des Lichts bekannt.


Mit der Absorption von Licht sind jedoch einige Nuancen verbunden - dies geschieht nicht sofort, sobald das Licht die OberflĂ€che berĂŒhrt. Aus der Physik wissen wir, dass Licht als ein Photonenstrahl mit Energie beschrieben werden kann, der sich in einer geraden Linie bewegt, bis er infolge einer Kollision mit Hindernissen die gesamte Energie verliert. Jedes Material besteht aus Mikropartikeln, die mit einem Lichtstrahl interagieren können, wie in der folgenden Abbildung gezeigt. Diese Partikel absorbieren bei jeder Kollision einen Teil oder die gesamte Energie des Lichts und wandeln es in WĂ€rme um.



Im allgemeinen Fall wird nicht die gesamte Energie absorbiert, und das Licht streut weiterhin in (ĂŒberwiegend) zufĂ€lligen Richtungen, wo es erneut mit anderen Partikeln kollidiert, bis ihm die Energie ausgeht oder die OberflĂ€che wieder verlĂ€sst. Somit beginnt die OberflĂ€che, Lichtstrahlen wieder zu emittieren, was einen Beitrag in Form der beobachteten (diffusen) Farbe der OberflĂ€che leistet. Mit PBR gehen wir vereinfacht davon aus, dass das gesamte gebrochene Licht ĂŒber einen kleinen Einflussbereich absorbiert und gestreut wird, wobei der Effekt des gestreuten Lichts, das die OberflĂ€che in einem Abstand von diesem Bereich verlĂ€sst, ignoriert wird. Spezielle Shadertechniken, die dies berĂŒcksichtigen, sogenannte Streutechniken unter der OberflĂ€che , verbessern die visuelle QualitĂ€t von Materialien wie Leder, Marmor, Wachs erheblich, sind jedoch hinsichtlich der Leistung teuer.


ZusĂ€tzliche Feinheiten treten auf, wenn Licht auf MetalloberflĂ€chen gebrochen und reflektiert wird. MetalloberflĂ€chen interagieren anders mit Licht als nichtmetallische (d. H. Dielektrika). Sie gehorchen denselben Gesetzen der Brechung und Reflexion, mit einer Ausnahme: Alles gebrochene Licht wird von der OberflĂ€che absorbiert, ohne zu streuen, nur spiegelreflektiertes Licht bleibt ĂŒbrig; Mit anderen Worten, MetalloberflĂ€chen haben keine diffuse Farbe. Aufgrund dieses offensichtlichen Unterschieds zwischen Metallen und Dielektrika werden sie im PBR-Förderer, in den wir im Verlauf dieses Artikels weiter gehen, unterschiedlich verarbeitet.


Dieser Unterschied zwischen reflektiertem und gebrochenem Licht fĂŒhrt uns zu einer weiteren Beobachtung hinsichtlich der Energieeinsparung: Ihre Werte schließen sich gegenseitig aus. Die Energie des reflektierten Lichts kann vom Material nicht absorbiert werden. Daher ist die von der OberflĂ€che in Form von gebrochenem Licht absorbierte Energie die verbleibende Energie nach BerĂŒcksichtigung des reflektierten Lichts.
Wir verwenden dieses VerhÀltnis, indem wir zuerst den reflektierten Teil als Prozentsatz der Energie der einfallenden Strahlen berechnen, die von der OberflÀche reflektiert werden, und dann den Anteil des gebrochenen Lichts direkt von der reflektierten, als:


float kS = calculateSpecularComponent(...); // /  float kD = 1.0 - kS; // /  

Auf diese Weise lernen wir dank des Gesetzes der Energieerhaltung die Bedeutung sowohl der reflektierten als auch der gebrochenen Teile. Bei diesem Ansatz wird weder der gebrochene (diffuse) noch der reflektierte Teil 1,0 ĂŒberschreiten, wodurch sichergestellt wird, dass ihre Gesamtenergie den Wert der einfallenden Lichtenergie nicht ĂŒberschreitet, den wir in frĂŒheren Lektionen nicht berĂŒcksichtigen konnten.


Reflexionsgleichung


Das Obige fĂŒhrt uns zu der sogenannten Rendering-Gleichung : Eine komplexe Gleichung, die von sehr klugen Leuten erfunden wurde und heute das beste Modell fĂŒr die Simulation von Beleuchtung ist. PBR folgt streng einer spezifischeren Version dieser Gleichung, die als Reflexionsgleichung bekannt ist . Um PBR gut zu verstehen, ist es wichtig, zunĂ€chst die Reflexionsgleichung vollstĂ€ndig zu verstehen:


Lo(p, omegao)= int limit Omegafr(p, omegai, omegao)Li(p, omegai)n cdot omegaid omegai


Zuerst sieht es beĂ€ngstigend aus, aber wir werden es nach und nach teilweise auseinander nehmen, und Sie werden sehen, wie langsam es Sinn macht. Um diese Gleichung zu verstehen, mĂŒssen wir etwas tiefer in die Radiometrie gehen. Radiometrie ist die Wissenschaft der Messung elektromagnetischer Strahlung (einschließlich sichtbarem Licht). Es gibt mehrere radiometrische GrĂ¶ĂŸen, mit denen wir die Beleuchtung messen können, aber wir werden nur eine verwenden, die sich auf die Reflexionsgleichung bezieht, die als Energieluminanz (englische Strahlung) bekannt ist und hier mit dem Buchstaben L bezeichnet wird. EI wird verwendet, um die GrĂ¶ĂŸe oder IntensitĂ€t des Lichts zu quantifizieren. aus einer bestimmten Richtung kommen. EJ wiederum ist eine Kombination mehrerer physikalischer GrĂ¶ĂŸen, und damit wir uns das leichter vorstellen können, werden wir uns auf jede einzelne konzentrieren.


Strahlungsfluss


Strahlungsfluss (  Phi ) ist die Leistung der durch Licht ĂŒbertragenen Energie, gemessen in Watt. Die Gesamtenergie des Lichts besteht aus vielen Begriffen fĂŒr verschiedene WellenlĂ€ngen, von denen jeder seiner eigenen Farbe des Spektrums entspricht. Die von der Lichtquelle emittierte Energie kann in diesem Fall als Funktion aller dieser WellenlĂ€ngen dargestellt werden. WellenlĂ€ngen von 390 nm bis 700 nm bilden den sichtbaren Teil des Spektrums, dh Strahlung in diesem Bereich kann vom menschlichen Auge wahrgenommen werden. Im Bild unten sehen Sie die Werte der Energien fĂŒr verschiedene WellenlĂ€ngen, aus denen das Tageslicht besteht:



Der Strahlungsfluss entspricht fĂŒr alle WellenlĂ€ngen der FlĂ€che unter dem Diagramm dieser Funktion. Die direkte Verwendung von LichtwellenlĂ€ngen als Eingabe in Computergrafiken ist unpraktisch, daher greifen wir auf eine vereinfachte Darstellung des Strahlungsflusses zurĂŒck, anstatt eine Funktion aller WellenlĂ€ngen, ein Triplett von Farben, bekannt als RGB (oder, wie wir es normalerweise nennen, die Farbe der Beleuchtung) zu verwenden. Eine solche Ansicht fĂŒhrt zu einem gewissen Informationsverlust, wirkt sich jedoch insgesamt geringfĂŒgig auf das endgĂŒltige Bild aus.


Raumwinkel


Raumwinkel bezeichnet mit  omega gibt uns die GrĂ¶ĂŸe oder FlĂ€che der Figur, die auf die Einheitskugel projiziert wird. Sie können es sich als eine Richtung vorstellen, die ein Volumen von:



Stellen Sie sich vor, Sie befinden sich in der Mitte einer Kugel und schauen in Richtung der Figur. Die GrĂ¶ĂŸe der resultierenden Silhouette ist ein Raumwinkel.


StrahlungsintensitÀt


Die StrahlungsstĂ€rke misst die Menge des Strahlungsflusses pro Raumwinkel oder die StĂ€rke einer Lichtquelle pro FlĂ€cheneinheit, die durch den Raumwinkel definiert wird. Beispielsweise bedeutet fĂŒr eine omnidirektionale Lichtquelle, die gleichmĂ€ĂŸig in alle Richtungen emittiert, die Strahlungskraft die Energie des Lichts pro bestimmten Bereich (Raumwinkel):



Die Gleichung, die die StĂ€rke der Strahlung beschreibt, sieht folgendermaßen aus:


I= fracd Phid omega


, wobei I der Strahlungsfluss f pro Raumwinkel ist d omega


Wenn wir den Strahlungsfluss, die Kraft und den Raumwinkel kennen, können wir die Energiehelligkeitsgleichung beschreiben, die die gesamte beobachtete Energie im Bereich A beschreibt, begrenzt durch den Raumwinkel O fĂŒr Licht durch Kraft  Phi


L= fracd2 PhidAd omega cos theta



Die Energiehelligkeit ist die radiometrische Lichtmenge in einem Bereich, die vom Einfallswinkel abhĂ€ngt.  theta (Winkel zwischen der Lichtrichtung und der Normalen zur OberflĂ€che) durch cos theta : Licht ist schwĂ€cher, wenn es entlang der OberflĂ€che emittiert wird, und stĂ€rker, wenn es senkrecht dazu steht. Dies Ă€hnelt unseren Berechnungen fĂŒr diffuses Licht im Tutorial zu den Grundlagen der Beleuchtung seitdem cos theta nichts weiter als ein Skalarprodukt zwischen der Lichtrichtung und dem Normalenvektor zur OberflĂ€che:

 float cosTheta = dot(lightDir, N); 

Die Energiehelligkeitsgleichung ist fĂŒr uns sehr nĂŒtzlich, da sie die meisten physikalischen GrĂ¶ĂŸen enthĂ€lt, die uns interessieren. Wenn wir annehmen, dass der Raumwinkel ω und die FlĂ€che A infinitesimal sind, können wir mit dem EE den Fluss eines Lichtstrahls pro Punkt im Raum messen. Auf diese Weise können wir den EI eines einzelnen Lichtstrahls berechnen, der auf einen einzelnen Punkt (Fragment) wirkt. Wir ĂŒbersetzen tatsĂ€chlich den Raumwinkel  omega in Richtungsvektor  omega und A auf den Punkt p . Somit können wir den EI in unseren Shadern direkt verwenden, um den Beitrag eines einzelnen Lichtstrahls fĂŒr jedes Fragment zu berechnen.


Wenn es um EE geht, interessieren wir uns normalerweise fĂŒr das gesamte einfallende Licht, das auf den Punkt p fĂ€llt, der die Summe des gesamten EE darstellt und als BestrahlungsstĂ€rke bezeichnet wird. Wenn wir den EI und die Bestrahlung kennen, können wir zur Reflexionsgleichung zurĂŒckkehren:


Lo(p, omegao)= int limit Omegafr(p, omegai, omegao)Li(p, omegai)n cdot omegaid omegai


Jetzt wissen wir das L in der Rendering-Gleichung ist der EI fĂŒr einen Punkt auf der OberflĂ€che p und einen unendlich kleinen Raumwinkel des einfallenden Lichts  omegai , die als Eingangsrichtungsvektor betrachtet werden kann  omegai . Denken Sie daran, dass Energie mit multipliziert wird cos theta - der Winkel zwischen der Einfallsrichtung des Lichts und der Normalen zur OberflĂ€che, der in der Reflexionsgleichung des Produkts ausgedrĂŒckt wird n cdot omegai . Die Reflexionsgleichung berechnet die Summe der reflektierten EI Lo(p, omegao) Punkte p in Richtung ωo Dies ist die ausgehende Richtung zum Beobachter. Oder sonst: Lo misst die reflektierte BestrahlungsstĂ€rke eines Punktes p wenn von  omegao .


Da die Reflexionsgleichung auf der Bestrahlung basiert, die die Summe aller einfallenden Strahlung ist, messen wir das Licht nicht nur aus einer einfallenden Lichtrichtung, sondern aus allen einfallenden Lichtrichtungen innerhalb der HemisphĂ€re  Omega zentriert bei p . Es kann als eine halbe Kugel beschrieben werden, die entlang der OberflĂ€chennormalen ausgerichtet ist n ::



Um die Summe aller Werte innerhalb der Region oder im Fall einer Halbkugel das Volumen zu berechnen, integrieren wir die Gleichung in alle eingehenden Richtungen d omegai innerhalb der HemisphĂ€re  Omega . Da es sowohl fĂŒr die Rendergleichung als auch fĂŒr die Reflexionsgleichung keine analytische Lösung gibt, werden wir das Integral numerisch lösen. Dies bedeutet, dass wir Ergebnisse fĂŒr kleine diskrete Schritte der Halbkugelreflexionsgleichung erhalten  Omega und mittle sie ĂŒber die GrĂ¶ĂŸe der Stufe. Dies nennt man die Riemannsche Summe , die wir grob mit folgendem Code darstellen können:


 int steps = 100; float sum = 0.0f; vec3 P = ...; vec3 Wo = ...; vec3 N = ...; float dW = 1.0f / steps; for(int i = 0; i < steps; ++i) { vec3 Wi = getNextIncomingLightDir(i); sum += Fr(P, Wi, Wo) * L(P, Wi) * dot(N, Wi) * dW; } 

dW fĂŒr jeden einzelnen Schritt kann als betrachtet werden d omegai in der Reflexionsgleichung. Mathematisch d omegai ist das Differential, mit dem wir das Integral berechnen, und obwohl es nicht dasselbe wie dW im Code ist (da dies ein diskreter Schritt der Riemann-Summe ist), können wir es zur Vereinfachung der Berechnung als solches betrachten. Denken Sie daran, dass die Verwendung diskreter Schritte immer einen ungefĂ€hren Betrag ergibt, nicht den genauen Wert des Integrals. Ein aufmerksamer Leser wird feststellen, dass wir die Genauigkeit der Riemannschen Summe erhöhen können, indem wir die Anzahl der Schritte erhöhen.


Die Reflexionsgleichung summiert die Strahlung aller einfallenden Lichtrichtungen  omegai HemisphĂ€re  Omega das erreicht den Punkt p und gibt die Menge des reflektierten Lichts zurĂŒck Lo in Richtung des Betrachters. Die einfallende Strahlung kann von Lichtquellen stammen, mit denen wir bereits vertraut sind, oder von Umgebungskarten, die den EI jeder einfallenden Richtung bestimmen, ĂŒber die wir im IBL-Tutorial sprechen werden.


Jetzt ist das einzige Unbekannte auf der linken Seite das Symbol fr , bekannt als BRDF- Funktion oder Zweistrahl -Reflexionsfunktion , die den Wert der einfallenden Strahlung basierend auf den Eigenschaften des OberflÀchenmaterials skaliert (oder wiegt).


BRDF


BRDF ist eine Funktion, die die Richtung des einfallenden Lichts akzeptiert.  omegai Richtung zum Betrachter  omegao normal zur OberflĂ€che n und Parameter a , das ist die OberflĂ€chenrauheit. BRDF approximiert ungefĂ€hr, wie viel jeder einzelne Lichtstrahl ist  omegai trĂ€gt unter BerĂŒcksichtigung der Materialeigenschaften zum endgĂŒltigen reflektierten Licht einer opaken OberflĂ€che bei. Wenn die OberflĂ€che beispielsweise vollstĂ€ndig glatt ist (fast wie ein Spiegel), gibt die BRDF-Funktion fĂŒr alle einfallenden Lichtstrahlen 0,0 zurĂŒck  omegai mit Ausnahme eines mit dem gleichen Winkel (nach Reflexion) wie der Strahl  omegao fĂŒr die die Funktion 1.0 zurĂŒckgibt.


BRDF approximiert die Reflexions- und Brechungseigenschaften eines Materials basierend auf der zuvor erwĂ€hnten Theorie der MikroflĂ€chen. Damit das BRDF physikalisch plausibel ist, muss es dem Gesetz der Energieerhaltung entsprechen, dh die Gesamtenergie des reflektierten Lichts sollte niemals die Energie des einfallenden Lichts ĂŒberschreiten. Technisch gesehen wird das Blinn-Fong-Modell als BRDF angesehen, das dasselbe akzeptiert  omegai und  omegao am Eingang. Das Blinn-Fong-Modell wird jedoch nicht als physikalisch korrekt angesehen, da es nicht die Einhaltung des Energieerhaltungsgesetzes garantiert. Es gibt mehrere physikalisch korrekte BRDFs, um die OberflĂ€chenreaktion auf Beleuchtung zu approximieren. Fast alle Echtzeit-Grafik-Pipelines verwenden jedoch das BRDF, das als Cook-Torrance BRDF bekannt ist .


Cook-Torrens BRDF enthÀlt sowohl einen diffusen als auch einen Spiegelteil:


fr=kdflambert+ksfcook−torrance


hier kd - gebrochener Anteil der einfallenden Lichtenergie, ks - reflektiert. Die linke Seite des BRDF enthĂ€lt den diffusen Teil der Gleichung, der hier als bezeichnet wird flambert . Dies ist die sogenannte Lambert-Streuung. Es Ă€hnelt dem, was wir fĂŒr diffuses Licht verwendet haben, und ist konstant:


flambert= fracc pi


wo c - Albedo oder OberflĂ€chenfarbe (diffuse OberflĂ€chentextur). Division durch  pi benötigt, um das gestreute Licht zu normalisieren, da das zuvor angegebene Integral, das BRDF enthĂ€lt, mit multipliziert wird  pi (Wir werden dies im IBL-Tutorial erfahren).


Sie werden ĂŒberrascht sein, wie diese Lambertsche Streuung wie der Ausdruck fĂŒr diffuses Licht aussieht, den wir zuvor verwendet haben: Die OberflĂ€chenfarbe multipliziert mit dem Skalarprodukt zwischen der OberflĂ€chennormalen und der Richtung des Lichts. Das Skalarprodukt ist noch vorhanden, wird aber aus BRDF abgeleitet, da wir es haben n cdot omegai im Integral Lo .

Es gibt verschiedene Gleichungen fĂŒr den diffusen Teil von BRDF, die realistischer aussehen, aber in Bezug auf die Leistung teurer sind. DarĂŒber hinaus, wie die Epic Games feststellten: Lambertsche Streuung ist fĂŒr die meisten Echtzeit-Rendering-Zwecke ausreichend.


Der Spiegelanteil des Cook-Torrens BRDF ist leicht verbessert und wird beschrieben als:


fcook−torrance= fracDFG4( omegao cdotn)( omegai cdotn)


Es besteht aus drei Funktionen und einem Standardisierungskoeffizienten im Nenner. Jeder der Buchstaben D, F und G reprÀsentiert eine bestimmte Art von Funktion, die sich einem bestimmten Teil der Reflexionseigenschaften der OberflÀche annÀhert. Sie sind als Normalverteilungsfunktion (NDF), Fresnel-Gleichung und Geometriefunktion bekannt:

  • Normalverteilungsfunktion: AnnĂ€herung an die Anzahl der OberflĂ€chenmikroflĂ€chen entlang des Medianvektors basierend auf der OberflĂ€chenrauheit; Dies ist die Hauptfunktion zur AnnĂ€herung an MikroflĂ€chen.
  • Geometriefunktion: Beschreibt die Selbstschattierungseigenschaft von MikroflĂ€chen. Wenn die OberflĂ€che ziemlich rau ist, können einige MikroflĂ€chen der OberflĂ€che andere ĂŒberlappen, wodurch die von der OberflĂ€che reflektierte Lichtmenge verringert wird.
  • Fresnel-Gleichung: beschreibt den OberflĂ€chenreflexionskoeffizienten unter verschiedenen Winkeln.

Jede dieser Funktionen ist eine AnnĂ€herung an ihr physikalisches Äquivalent, und fĂŒr sie gibt es verschiedene Implementierungen, die auf eine genauere AnnĂ€herung an das zugrunde liegende physikalische Modell abzielen. Einige liefern realistischere Ergebnisse, andere sind in Bezug auf die Leistung effektiver. Brian Caris von Epic Games hat viel ĂŒber verschiedene Arten von Approximationen geforscht, ĂŒber die Sie hier mehr erfahren können. Wir werden die gleichen Funktionen wie in Unreal Engine 4 von Epic Games verwenden, nĂ€mlich: Trowbridge-Reitz GGX fĂŒr D, Fresnel-Schlick- NĂ€herung fĂŒr F und Smiths Schlick-GGX fĂŒr G.


Normalverteilungsfunktion


Die Normalverteilungsfunktion D approximiert statistisch die relative OberflĂ€che der MikroflĂ€chen, die genau entlang des Medianvektors ausgerichtet sind h . Es gibt viele NDFs, die die statistische AnnĂ€herung der Gesamtausrichtung von MikroflĂ€chen unter BerĂŒcksichtigung einiger Rauheitsparameter bestimmen. Wir werden eine verwenden, die als Trowbridge-Reitz GGX bekannt ist:


NDFGGXTR(n,h, alpha)= frac alpha2 pi((n cdoth)2( alpha2−1)+1)2


hier h Ist der Medianvektor,  alpha - Wert der OberflĂ€chenrauheit. Wenn wir uns entscheiden h Als Medianvektor zwischen der Normalen zur OberflĂ€che und der Richtung des Lichts und anschließender Änderung des Rauheitsparameters erhalten wir das folgende Bild:



Wenn die Rauheit klein ist (d. H. Die OberflĂ€che ist glatt), sind die in Richtung des Medianvektors orientierten MikroflĂ€chen in einem kleinen Radius konzentriert. Aufgrund dieser hohen Konzentration ergibt NDF einen sehr hellen Fleck. Auf einer rauen OberflĂ€che, auf der MikroflĂ€chen in zufĂ€lligeren Richtungen ausgerichtet sind, finden Sie eine viel grĂ¶ĂŸere Anzahl von MikroflĂ€chen, die in Richtung des Medianvektors ausgerichtet sind h befindet sich jedoch in einem grĂ¶ĂŸeren Radius, wodurch die Sonderfarbe grauer wird.


Im GLSL-Code sieht die Normalverteilungsfunktion von Trowbridge-Reitz GGX ungefĂ€hr so ​​aus:


 float DistributionGGX(vec3 N, vec3 H, float a) { float a2 = a*a; float NdotH = max(dot(N, H), 0.0); float NdotH2 = NdotH*NdotH; float nom = a2; float denom = (NdotH2 * (a2 - 1.0) + 1.0); denom = PI * denom * denom; return nom / denom; } 

Geometriefunktion


Die Geometriefunktion nĂ€hert sich statistisch der relativen OberflĂ€che an, wo sich ihre mikroskopischen UnregelmĂ€ĂŸigkeiten ĂŒberlappen, wodurch das Eindringen von Lichtstrahlen verhindert wird.



Wie im Fall von NDF akzeptiert die Geometriefunktion den OberflÀchenrauheitskoeffizienten als Eingabe, was in diesem Fall Folgendes bedeutet: Bei raueren OberflÀchen ist die Wahrscheinlichkeit einer Schattierung von MikroflÀchen höher. Die Geometriefunktion, die wir verwenden werden, ist eine Kombination der GGX- und Schlick-Beckmann-NÀherungen und wird als Schlick-GGX bezeichnet:


GSchlickGGX(n,v,k)= fracn cdotv(n cdotv)(1−k)+k


Hier k ist eine Umbenennung  alpha abhĂ€ngig davon, ob wir die Geometriefunktion fĂŒr Direktbeleuchtung oder IBL-Beleuchtung verwenden:


kdirect= frac( alpha+1)28


kIBL= frac alpha22


Bitte beachten Sie, dass der Wert  alpha kann variieren, je nachdem, wie Ihr Motor die Rauheit ĂŒbersetzt  alpha . In den folgenden Lektionen werden wir detailliert diskutieren, wie und wo diese Neuzuweisung relevant wird.


Um die Geometrie effektiv zu approximieren, mĂŒssen wir sowohl die Blickrichtung (ĂŒberlappende Geometrie) als auch den Richtungsvektor des Lichts (Selbstbeschattung der Geometrie) berĂŒcksichtigen. Wir können beide FĂ€lle mit der Smith-Methode betrachten :


G(n,v,l,k)=Gsub(n,v,k)Gsub(n,l,k)


Verwendung der Smith-Methode mit Schlick-GGX als Gsub ergibt folgendes Bild mit unterschiedlicher Rauheit R:



Die Geometriefunktion ist ein Faktor zwischen [0.0, 1.0], wobei Weiß (oder 1.0) keine Schattierung der MikroflĂ€chen bedeutet und Schwarz (oder 0.0) eine vollstĂ€ndige Schattierung der MikroflĂ€chen bedeutet.


In GLSL wird eine Geometriefunktion in den folgenden Code konvertiert:


 float GeometrySchlickGGX(float NdotV, float k) { float nom = NdotV; float denom = NdotV * (1.0 - k) + k; return nom / denom; } float GeometrySmith(vec3 N, vec3 V, vec3 L, float k) { float NdotV = max(dot(N, V), 0.0); float NdotL = max(dot(N, L), 0.0); float ggx1 = GeometrySchlickGGX(NdotV, k); float ggx2 = GeometrySchlickGGX(NdotL, k); return ggx1 * ggx2; } 

Fresnel-Gleichung


Die Fresnel-Gleichung beschreibt das VerhÀltnis von reflektiertem und gebrochenem Licht, das von dem Winkel abhÀngt, unter dem wir die OberflÀche betrachten. Wenn Licht auf eine OberflÀche trifft, gibt uns die Fresnel-Gleichung den Prozentsatz des reflektierten Lichts basierend auf dem Winkel, unter dem wir diese OberflÀche sehen. Aus diesem ReflexionsverhÀltnis und dem Energieerhaltungsgesetz können wir direkt den gebrochenen Teil des Lichts erhalten, der gleich der verbleibenden Energie ist.


Jede OberflĂ€che oder jedes Material weist ein Grundreflexionsvermögen auf , das beim direkten Betrachten der OberflĂ€che beobachtet wird. Wenn Sie jedoch die OberflĂ€che in einem Winkel betrachten, werden alle Reflexionen deutlicher. Sie können dies selbst ĂŒberprĂŒfen, indem Sie Ihren senkrechten Holz- oder Metalltisch zuerst senkrecht und dann in einem Winkel von nahezu 90 Grad betrachten. Sie werden sehen, dass Reflexionen viel deutlicher werden. Theoretisch reflektieren alle OberflĂ€chen das Licht vollstĂ€ndig, wenn sie von ihnen in einem idealen Winkel von 90 Grad betrachtet werden. Dieser Effekt wird als Fresnel bezeichnet und durch die Fresnel-Gleichung beschrieben .


Die Fresnel-Gleichung ist recht komplex, kann aber glĂŒcklicherweise mit der Fresnel-Schlick-NĂ€herung vereinfacht werden:


FSchlick(h,v,F0)=F0+(1−F0)(1−(h cdotv))5


F0 stellt das grundlegende Reflexionsvermögen der OberflÀche dar, das wir unter Verwendung von sogenannten Brechungsindizes oder IORs (Brechungsindizes) berechnen. Wie Sie auf der OberflÀche der Kugel sehen können, ist die Blickrichtung nÀher an den Grenzen der sichtbaren Kugel (dem Winkel zwischen der Blickrichtung und dem Median), wie Sie auf der OberflÀche der Kugel sehen können 90 ), , , :



, . , - . (), , . , ( F0 ) ( 0 , ) -, , .


. , , :



: 0.17, , , ( ) 0.5 1.0. , “”, F0 RGB ( ).


, metallic workflow: , (metalness), , .


: , ; , . , 0.0 1.0. - , , , . , .

F0 , , - , , . :


 vec3 F0 = vec3(0.04); F0 = mix(F0, surfaceColor.rgb, metalness); 

, . , F0 . 0.04 . , , , F0 . , , .


- :


 vec3 fresnelSchlick(float cosTheta, vec3 F0) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); } 

cosTheta .


-


BRDF - :


Lo(p,ωo)=∫Ω(kdcπ+ksDFG4(ωo⋅n)(ωi⋅n))Li(p,ωi)n⋅ωidωi


. , , F . ks , , ks . , :


Lo(p,ωo)=∫Ω(kdcπ+DFG4(ωo⋅n)(ωi⋅n))Li(p,ωi)n⋅ωidωi


, PBR. , , . , , .


PBR


, PBR, , , PBR. , PBR, . , : , .


, PBR, :



: , . , . , ; .


: , , . , , .


: . , PBR-, , : .


: , . . , . PBR- , , (1.0 — ) .


AO (ambient occlusion) : AO . , , . AO , . . , 3D-.


. PBR, , . , PBR, PBR-, , , .


Verwandte Materialien


Source: https://habr.com/ru/post/de426123/


All Articles