Steuerungstasten

nächste Folie (auch Enter oder Spacebar).
vorherige Folie
 d  schaltet das Zeichnen auf Folien ein/aus
 p  wechselt zwischen Druck- und Präsentationsansicht
CTRL  +  vergrößert die Folien
CTRL  -  verkleinert die Folien
CTRL  0  setzt die Größenänderung zurück

Das Weiterschalten der Folien kann ebenfalls durch das Klicken auf den rechten bzw. linken Folienrand erfolgen.

Notation

Typ Schriftart Beispiele
Variablen (Skalare) kursiv $a, b, x, y$
Funktionen aufrecht $\mathrm{f}, \mathrm{g}(x), \mathrm{max}(x)$
Vektoren fett, Elemente zeilenweise $\mathbf{a}, \mathbf{b}= \begin{pmatrix}x\\y\end{pmatrix} = (x, y)^\top,$ $\mathbf{B}=(x, y, z)^\top$
Matrizen Schreibmaschine $\mathtt{A}, \mathtt{B}= \begin{bmatrix}a & b\\c & d\end{bmatrix}$
Mengen kalligrafisch $\mathcal{A}, \{a, b\} \in \mathcal{B}$
Zahlenbereiche, Koordinatenräume doppelt gestrichen $\mathbb{N}, \mathbb{Z}, \mathbb{R}^2, \mathbb{R}^3$

Liste der verwendeten Symbole

Symbol Bedeutung
$\Omega$ Raumwinkel
$\theta$ Polarwinkel im Kugelkoordinatensystem
$\phi$ Azimutwinkel im Kugelkoordinatensystem
$\Phi$ Strahlungsfluss
$I$ Strahlstärke
$E$ Bestrahlungsstärke
$L$ Strahldichte
$\mathrm{f}_r$ BRDF (Bidirectional Reflection Distribution Function)
$\mathrm{f}_d$ Diffuser Anteil der BRDF
$\mathrm{f}_s$ Spekularer Anteil der BRDF

Liste der verwendeten Symbole

Symbol Bedeutung
$\mathbf{n}$ Oberflächennormale
$\mathbf{v}$ Einheitsvektor in Sichtrichtung
$\mathbf{l}$ Einheitsvektor in Richtung der Lichtquelle
$\eta$ Brechungsindex
$F$ Fresnel Reflexionsgrad
$\mathbf{h}$ Winkelhalbierende (halfway-vector) zwischen Licht- und Sichtrichtung
$(\dots)_+$ Rampenfunktion
$\langle \mathbf{a}\cdot \mathbf{b}\rangle$ Skalarprodukt
$\lambda$ Wellenlänge

Licht

  • Licht ist eine gequantelte, elektromagnetische Welle
  • Lichtgeschwindigkeit im Vakuum $c = 299\,792\,458 \frac{\mathrm{m}}{\mathrm{s}}$
  • Der sichtbarer Bereich liegt zwischen 380 bis 770 $\mathrm{nm}$
  • Sichtbares Licht einer bestimmten Wellenlänge entspricht einer Spektralfarbe
light_wavelength

Licht

  • Lichtquellen senden häufig ein breites Spektrum verschiedener Wellenlängen aus
  • Weißes Licht entsteht aus der Überlagerung vieler Wellenlängen (z.B. Tageslicht)
daylight
Spektrale Leistungsdichte von Tageslicht (CIE illuminant D65)
Wellenlänge $\lambda$
Rel.  spektrale  Leistung
Datenquelle für Abbildung:: CIE D65 Reference Spectrum,

Lichttransport

lightpaths
  • Licht wird von eine Lichtquelle emittiert
  • Einige Lichtstrahlen treffen evt. direkt ins Auge andere werden zunächst an einer Objektoberfläche reflektiert
  • Bei der Reflexion an der Objektoberfläche wird typischerweise ein Teil des Lichts absorbiert, d.h. das Licht verändert seine Farbe
  • Treffen die Lichtstrahlen ins Auge, werden Rezeptoren auf der Netzhaut aktiviert und im Gehirn formt sich ein Bild

Farbwahrnehmung: Dreifarbentheorie

Beim Menschen gibt es zwei Systeme von Lichtsinneszellen:

  • System 1: Stäbchen, die ausschließlich auf Hell-Dunkel-Kontraste reagieren
  • System 2: Drei Arten von Farbrezeptoren
    • L-Zapfen
      wavelength_human_eye
      Wellenlänge $\lambda$
      Normalisierte Absorption
    • M-Zapfen
    • S-Zapfen
Datenquelle für Abbildung: J. K. Bowmaker, H. J. A. Dartnall: Visual pigments of rods and cones in a human retina., The Journal of Physiology, Volume 298, Issue 1, Jan. 1980

RGB-Farbraum

rgb_add rgb_interp
  • Additive Mischung von drei Grundfarben (Rot, Grün, Blau)
(Rot, Grün, Blau) Farbe
(1.0, 0.0, 0.0)
(0.0, 1.0, 0.0)
(0.0, 0.0, 1.0)
(1.0, 1.0, 0.0)
(1.0, 0.0, 1.0)
(0.0, 1.0, 1.0)
(0.0, 0.0, 0.0)
(0.5, 0.5, 0.5)
(1.0, 1.0, 1.0)
(0.2, 0.4, 0.0)
(0.8, 0.2, 0.3)

CIE RGB Farbraum

CIE_1931_chromaticity_diagram_CIERGB
alle wahrnehmbaren Farben
CIE RGB mit
positiven $R$, $G$, $B$
$x$
$y$

  • 1931 vom CIE entwickelter Farbraum basierend auf Tests mit Probanden
  • Drei Strahler: 700 nm (rot), 546,1 nm (grün), 435,8 nm (blau)
  • Frage: Können alle wahrnehmbaren Farben aus diesen drei Grundfarben gemischt werden?
  • Ergebnis: Ja, aber nicht alle Koeffizienten positiv
CIE1931_RGBCMF
$\bar{r}(\lambda)$
$\bar{g}(\lambda)$
$\bar{b}(\lambda)$
  • Eine beliebige spektrale Leistungsdichte $S(\lambda)$ kann wie folgt repräsentiert werden:
    ${\small R = \int\limits_0^\infty S(\lambda) \,\bar{r}(\lambda) \,d\lambda \quad\quad G = \int\limits_0^\infty S(\lambda) \,\bar{g}(\lambda) \,d\lambda \quad\quad B = \int\limits_0^\infty S(\lambda) \,\bar{b}(\lambda) \,d\lambda \quad\quad }$

sRGB Farbraum

CIE_1931_chromaticity_diagram_sRGB
  • Aktueller Standard für Monitore, Webseiten, Bilder ohne explizites Farbprofil
  • RGB-Werte liegen im Bereich [0.0, 1.0]
  • Bereich der darstellbaren Farben ist kleiner als bei CIE RGB
  • Lineare Transformation zu CIE RGB, wenn vorher Gamma-Korrektur durchgeführt wird

sRGB Gamma

sRGB_gamma
sRGB Gamma
2.2 Gamma
  • Digitale Bilder verwenden häufig nur 8-Bit (256 Werte) pro Farbkanal
  • Weil das menschliche Sehsystem bei der Unterscheidung von dunkleren Intensitäten besser ist als bei helleren, soll der wahrgenommene Quantisierungsfehler (Rundungsfehler) durch die nicht-lineare Gamma-Funktion verringert werden
  • sRGB-Werte sind näherungsweise linear in der Wahrnehmung aber nicht linear in gemessenen radiometrischen Werten
  • Die Funktion zur Dekodierung eines Farbkanals $C$ von sRGB in den radiometrisch linearen Farbraum lautet:
    ${\small C_\mathrm{linear}= \begin{cases}\dfrac{C_\mathrm{srgb}}{12.92}, & C_\mathrm{srgb}\le0.04045 \\[5mu] \left(\dfrac{C_\mathrm{srgb}+0.055}{1.055}\right)^{\!2.4}, & C_\mathrm{srgb}>0.04045 \end{cases}}$

Weitere Farbräume

Abbildung von CIE XYZ Farbraum zur CIE-Normfarbtafel

Rendering-Gleichung

Rendering-Gleichung Grundlagen: Raumwinkel

steradian
$r$
$r^2$
$\Omega=1\,\mathrm{sr}$
solidangle
  • Der Raumwinkel $\Omega$ einer beliebigen Fläche $A$ entspricht dem Quotienten der Fläche $S$, die sich ergibt, wenn $A$ auf eine Kugel vom Radius $r$ projiziert wird, und $r^2$:

    $\Omega = \int\limits_{\omega}d\omega = \frac{S}{r^2}$

  • Obwohl der Raumwinkel eine dimensionslose Größe ist, wird er zur Verdeutlichung in der Einheit "Steradiant" $\mathrm{sr}$ angegeben
  • Der Raumwinkel einer Fläche mit konstanter Größe nimmt quadratisch mit dem Abstand vom Kugelzentrum ab
  • Beispiel: Ein Raumwinkel von $\Omega=1\,\mathrm{sr}$ umschließt auf einer Kugel mit dem Radius $1\,\mathrm{m}$ eine Fläche von $1\,\mathrm{m}^2$. Dieselbe Fläche bei doppeltem Radius ergibt $\Omega=\frac{1}{4}\,\mathrm{sr}$
  • Zwischen dem differentiellen Raumwinkel $d\omega$ und den Kugelkoordinaten $\theta$ und $\phi$ besteht der Zusammenhang:

    $\Omega = \int\limits_{\omega}d\omega = \int\limits_{\omega}d\theta(\sin \theta \, d\phi)= \int\limits_{\phi}\int\limits_{\theta}\sin \theta \, d\theta \, d\phi$

Rendering-Gleichung Grundlagen: Strahlungsfluss

luminous_flux
  • Strahlungsfluss $\Phi$ (radiant flux)
  • Strahlungsfluss =
    Strahlungsenergie pro Zeit

    $\Phi = \frac{dQ}{dt} \approx \frac{\Delta Q}{\Delta t}$

  • Einfache Anschauung:
    • Jedes Photon hat die Energie $E_{\small\mathrm{photon}}=\frac{h \, c}{\lambda}$ mit
      $h$: Plancksches Wirkungsquantum
      $c$: Lichtgeschwindigkeit
      $\lambda$: Wellenlänge
    • Strahlungsfluss = Summe der Photonen-Energien, die pro Zeitraum $\Delta t$ emittiert werden
  • Einheit: Watt $[\mathrm{W}] = [\frac{\mathrm{J}}{\mathrm{s}}]$

Rendering-Gleichung Grundlagen: Strahlstärke

luminous_intensity
  • Strahlstärke $I$ (radiant intensity)
  • Strahlstärke = Strahlungsfluss pro Raumwinkel
    $I = \frac{d\Phi}{d\omega} \approx \frac{\Delta \Phi}{\Delta \omega}$
  • Strahlstärke = Summe der Photonen-Energien, die pro Zeit und Raumwinkel emittiert werden
  • Einheit: Watt pro Steradiant $[\frac{\mathrm{W}}{\mathrm{sr}}]$
  • Wird z.B. benötigt, wenn die Lichtquelle nicht in alle Richtung gleich stark abstrahlt

Rendering-Gleichung Grundlagen: Bestrahlungsstärke

illuminance
  • Bestrahlungsstärke $E$ (irradiance)
  • Bestrahlungsstärke = Strahlungsfluss pro Flächenelement

    $E = \frac{d\Phi}{dA} \approx \frac{\Delta \Phi}{\Delta A}$

  • Der Strahlungsfluss kommt dabei aus allen Richtungen der Hemisphäre über der Fläche
  • Einheit: Watt pro Quadratmeter $[\frac{\mathrm{W}}{\mathrm{m}^2}]$
  • Einfache Anschauung: einfallende Photonen-Energien pro Zeit pro Flächenelement

Rendering-Gleichung Grundlagen: Strahldichte

luminance
  • Strahldichte $L$ (radiance)
  • Strahldichte = Strahlungsfluss pro Raumwinkel und sichtbarer Fläche

    $L = \frac{d^2\Phi}{d\omega\, \cos(\theta) \,dA} \approx \frac{\Delta \Phi}{\Delta \omega\, \cos(\theta) \,\Delta A}$

  • Die aus Richtung $\theta$ gesehene Fläche erscheint um den Faktor $\cos(\theta)$ verkürzt
  • Anwendung:
    • Entspricht der beobachteten Helligkeit
    • Strahlungsfluss in Richtung Auge
    shorter
    $\theta$
    $\theta$
    $\Delta A$
    $\cos(\theta) \,dA$
  • Einfache Anschauung: Photonen-Energien pro Zeit, Raumwinkel und sichtbarem Flächenelement
  • Einheit: Watt pro Steradiant pro Quadratmeter $[\frac{\mathrm{W}}{\mathrm{sr}\, \mathrm{m}^2}]$

Rendering-Gleichung (Rendering Equation)

  • Die Rendering-Gleichung berechnet die reflektierte Strahldichte $L_o(\mathbf{v})$ im Oberflächenpunkt $\mathbf{x}$ mit Normale $\mathbf{n}$ in Richtung $\mathbf{v}$ durch Integration über die Anteile aller eingehenden Strahldichten $L_i(\mathbf{l})$ der Hemisphäre über der Oberfläche

    $L_o(\mathbf{v}) = L_e(\mathbf{v}) + \int\limits_\Omega \mathrm{f}_r(\mathbf{v}, \mathbf{l})\, \, \underbrace{L_i(\mathbf{l}) \cos(\theta) \, d\omega}_{dE(\mathbf{l})}$

render_eqn
$\mathbf{x}$
$\theta$
$L_i(\mathbf{l})$
$L_o(\mathbf{v})$
$\Omega$
$\mathbf{n}$
  • $L_o(\mathbf{v})$ ausgehende Strahldichte
  • $L_e(\mathbf{v})$ ist die von der Fläche selbst emittierte Strahldichte
  • $L_i(\mathbf{l})$ eingehende Strahldichte
  • $E(\mathbf{l})$ Bestrahlungsstärke
  • $\mathrm{f}_r(\mathbf{v}, \mathbf{l})$ ist die sogenannte "Bidirectional Reflection Distribution Function" (BRDF)
  • $\Omega$ ist der Raumwinkel der Halbkugel über der Oberfläche

BRDF

BRDF (Bidirectional Reflection Distribution Function)

  • Die BRDF beschreibt den winkelabhängigen spektralen Reflexionsfaktor einer Oberfläche durch das Verhältnis von reflektierter Strahldichte $L_o$ zur einfallenden Bestrahlungsstärke $E$

    $\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = \frac{ dL_o(\mathbf{v})} { dE(\mathbf{l})} $

  • Eingehende Richtung $\mathbf{l}$ und ausgehende Richtung $\mathbf{v}$ können jeweils mit den Winkeln $\theta$ und $\phi$ parametrisiert werden. Somit ist die BRFD eine 4-dimensionale Funktion
  • Durch die Angabe dieser 4D-Funktion ist die Reflexionseigenschaft einer Fläche sehr genau beschrieben

BRDF (Bidirectional Reflection Distribution Function)

  • Die "Form" der BRDF bestimmt die Reflexionseigenschaften einer Oberfläche
glossyTodiffuse
glossyTodiffuse

BRDF (Bidirectional Reflection Distribution Function)

  • Die BRDF eines bestimmten Materials kann gemessen und in einer 4D Tabelle abgelegt werden
  • Die Tabellen sind in Material-Datenbanken zu finden
  • 4D Tabellen benötigen viel Speicher und die Materialien lassen sich nicht direkt editieren
  • Daher werden in der Praxis meist parametrische BRDF Modelle verwendet (Phong, Blinn-Phong, Cook-Torrance usw.)

BRDF Eigenschaften

  • Immer positiv
    $\mathrm{f}_r(\mathbf{v}, \mathbf{l}) \ge 0 \quad \forall \, \mathbf{v}, \mathbf{l} \in \Omega$
  • Helmholtz Reziprozität:
    $\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = \mathrm{f}_r(\mathbf{l}, \mathbf{v})$
    d.h. eingehende und ausgehende Richtungen können vertauscht werden
  • Energieerhaltung:
    $\int\limits_\Omega \mathrm{f}_r(\mathbf{v}, \mathbf{l})\, \cos(\theta) d\omega \le 1$

Vereinfachung der Rendering-Gleichung

  • Die exakte Auswertung der Rendering-Gleichung ist sehr rechenaufwendig
  • Die ausgehende Strahldichte $L_o$ der einen (unendlich kleinen) Oberfläche ist eingehende Strahldichte $L_i$ bei allen anderen. Selbst wenn alle Strahldichten einmal ausgetauscht sind, geht es rekursiv immer weiter.
  • Sehr viel einfacher wird die Gleichung, wenn der Lichtaustausch zwischen Oberflächen vernachlässigt wird und nur das sogenannte "direkte" Licht berücksichtigt wird, das von einer geringen Anzahl $j$ von Lichtquellen ausgeht
  • Mit Bestrahlungsstärke $E_j$ der Lichtquelle $j$ ergibt sich dann eine einfache Summe:
    $L_o(\mathbf{v}) = L_e(\mathbf{v}) + \sum \limits_j \mathrm{f}_r(\mathbf{v}, \mathbf{l}) \, E_j(\mathbf{l})$
  • Wie die Bestrahlungsstärke $E$ einer Lichtquelle berechnet werden kann, werden wir später sehen. Bis dahin verwenden wir eine einfache Richtungslichtquelle mit der Bestrahlungsstärke:
    $E = E_\perp \cos(\theta)$
  • Zunächst befassen wir uns mit verschiedenen parametrischen BRDF Modellen

Phong BRDF

Phong BRDF

phong_angles
$\mathbf{x}$
$\theta$
$\alpha$
$\mathbf{v}$
$-\mathbf{l}$
$\mathbf{r}$
$\mathbf{n}$
  • Einfaches nicht-physikalisches BRDF Modell [Phong 1975]
  • Überlagerung von diffuser + spekularer Reflexion
    $\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = \mathrm{f}_d(\mathbf{v}, \mathbf{l}) + \mathrm{f}_s(\mathbf{v}, \mathbf{l})$
  • Die diffuse Reflexion erzeugt eine konstante Strahldichte in alle Richtungen
    $\mathrm{f}_d(\mathbf{v}, \mathbf{l}) = k_d$
  • Die spekulare Reflexion wird durch einen cos-Lobe approximiert, der Exponent $n_s$ kontrolliert die Rauheit der Oberfläche
    $\mathrm{f}_s(\mathbf{v}, \mathbf{l}) = k_s \cos(\alpha)^{n_s}$
    mit
    $\cos \alpha = \langle \mathbf{v} \cdot \mathbf{r}\rangle$
  • Je größer der Exponent $n_s$, desto stärker wird das reflektierte Licht gebündelt (glattere Oberfläche)

Phong BRDF

  • Laut Reflexionsgesetz hat die Reflexionsrichtung den gleichen Winkel zur Oberflächennormalen wie die Lichtrichtung
    Einfallswinkel = Ausfallwinkel
  • Die Relektionsrichtung $\mathbf{r}$ berechnet sich daher aus der Oberflächennormalen $\mathbf{n}$ und der Lichtrichtung $\mathbf{l}$ durch:
    $\mathbf{r} = 2 \,(\mathbf{l}^\top \mathbf{n}) \, \mathbf{n} - \mathbf{l}$
    reflect_angles
    $-\mathbf{l}$
    $\mathbf{r}$
    $\mathbf{n}$
  • In GLSL steht zur Berechnung der Reflexionsrichtung $\mathbf{r}$ die Funktion reflect zur Verfügung
    vec3 reflectDir = reflect(-lightDir, normal);

Phong BRDF

$-\mathbf{l}$
$\mathbf{r}$
$\mathbf{v}$
$\mathbf{n}$

$\mathbf{l}$     $\mathbf{v}$    $k_d$    $k_s$    $n_s$

$\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = k_d + k_s \langle \mathbf{v} \cdot \mathbf{r}\rangle^{n_s}$

Beispiel: Phong BRDF mit einer Richtungslichtquelle

  • Beispiel: Um ein 3D Modell mit nur einer Richtungslichtquelle und der Phong BRDF zu rendern, muss insgesamt folgende Funktion implementiert werden:
    $\begin{align} L_o(\mathbf{v}) &= L_e(\mathbf{v}) + \mathrm{f}_r(\mathbf{v}, \mathbf{l}) \,\, E_\perp \cos(\theta) \\ &= L_e(\mathbf{v}) + \left(k_d + k_s \,\cos(\alpha)^{n_s} \right) \,\, E_\perp \cos(\theta)\\ &= L_e(\mathbf{v}) + \left(k_d + k_s \,\,\langle \mathbf{v} \cdot \mathbf{r}\rangle^{n_s} \right) \, E_\perp \,\,\left(\langle \mathbf{l} \cdot \mathbf{n}\rangle\right)_+\\ \end{align}$
phong_angles
$\mathbf{x}$
$\theta$
$\alpha$
$\mathbf{v}$
$-\mathbf{l}$
$\mathbf{r}$
$\mathbf{n}$
  • Dabei soll nur ein Beitrag entstehen, wenn die Oberfläche zum Licht zeigt. Daher steht $(x)_+$ für die Rampenfunktion
    $(x)_+ = \begin{cases} x & \,\,:\,\, x \ge 0 \\ 0 & \,\,:\,\, 0 < 0 \end{cases}$
    diese kann in GLSL implementiert werden mit
    x = max(x, 0.0);

Beispiel: Phong BRDF mit einer Richtungslichtquelle

$-\mathbf{l}$
$\mathbf{r}$
$\mathbf{v}$
$\mathbf{n}$

$\mathbf{l}$     $\mathbf{v}$    $k_d$    $k_s$    $n_s$

$L_o(\mathbf{v}) = \left(k_d + k_s \langle \mathbf{v} \cdot \mathbf{r}\rangle^{n_s}\right) \, E_\perp \,\,\left(\langle \mathbf{l} \cdot \mathbf{n}\rangle\right)_+$

Ambiente Komponente (Umgebungslicht)

  • Durch die Vereinfachung der Rendering-Gleichung sind indirekte Beleuchtungen nicht modelliert
  • Das hat zur Folge, dass nicht direkt beleuchtete Szenenteile nicht sichtbar sind
  • Daher wird die fehlende indirekte Beleuchtung, durch eine konstante Strahldichte $L_a$ approximiert
  • Dabei ist $L_a$ diejenige Strahldichte, die das ambiente Licht auf einer ideal weißen Oberfläche erzeugen würde

Beispiel: Phong BRDF mit einer Richtungslichtquelle

  • Die ambiente Komponente $k_a$ kann der emittierten Strahldichte hinzuaddiert werden. Ist die emittierte Strahldichte ansonsten gleich Null, ergibt sich:
    $L_e = k_a$
  • Insgesamt gibt es also drei Anteile:
    $\quad \quad \quad k_a \quad \quad \quad + \quad k_d E_\perp \cos(\theta) \quad + k_s \cos(\alpha)^{n_s} E_\perp \cos(\theta) = \quad L_o(\mathbf{v})$
    phong
    Ambient Diffus Spekular
  • Da es sich um ein nicht-physikalisches Modell handelt, kann der Nutzer die Parameter $k_a$, $k_d$, $k_s$ und den Exponenten $n_s$ frei einstellen
  • Je größer der Exponent $n_s$, desto stärker wird das reflektierte Licht gebündelt (glattere Oberfläche)

Beispiel: Phong BRDF mit einer Richtungslichtquelle

opengl_opengl_shaderphongbrdf

Beispiel: Phong BRDF in GLSL

Vertex Shader:
#version 140
in vec3 position;
in vec2 texcoord;
in vec3 normal;

uniform mat4 projection;
uniform mat4 modelview;
uniform mat4 normalMat;

out vec2 tc;
out vec3 fn;
out vec3 vertPos;

void main(){
  tc = texcoord;
  fn = vec3(normalMat * vec4(normal, 0.0));
  vec4 vertPos4 = modelview * vec4(position, 1.0);
  vertPos = vec3(vertPos4) / vertPos4.w;
  gl_Position = projection * modelview * vec4(position, 1.0);
}

Beispiel: Phong BRDF in GLSL

Fragment Shader:
#version 140
out vec4 outColor;

in vec2 tc;
in vec3 fn;
in vec3 vertPos;

uniform int mode;
uniform vec3 lightDirection;

const vec4 ambientColor = vec4(0.01, 0.0, 0.0, 1.0);
const vec4 diffuseColor = vec4(0.25, 0.0, 0.0, 1.0);
const vec4 specularColor = vec4(1.0, 1.0, 1.0, 1.0);
const float shininess = 20.0;
const vec4 lightColor = vec4(1.0, 1.0, 1.0, 1.0);
const float irradiPerp = 1.0;

vec3 phongBRDF(vec3 lightDir, vec3 viewDir, vec3 normal, 
          vec3 phongDiffuseCol, vec3 phongSpecularCol, float phongShininess) {
  vec3 color = phongDiffuseCol;
  vec3 reflectDir = reflect(-lightDir, normal);
  float specDot = max(dot(reflectDir, viewDir), 0.0);
  color += pow(specDot, phongShininess) * phongSpecularCol;
  return color;
}

void main() {
  vec3 lightDir = normalize(-lightDirection);
  vec3 viewDir = normalize(-vertPos);
  vec3 n = normalize(fn);

  vec3 radiance = ambientColor.rgb;
  
  float irradiance = max(dot(lightDir, n), 0.0) * irradiPerp;
  if(irradiance > 0.0) {
    vec3 brdf = phongBRDF(lightDir, viewDir, n, 
                          diffuseColor.rgb, specularColor.rgb, shininess);
    radiance += brdf * irradiance * lightColor.rgb;
  }

  radiance = pow(radiance, vec3(1.0 / 2.2) ); // gamma correction
  outColor.rgb = radiance;
  outColor.a = 1.0;
}

Shading im Weltkoordinatensystem

  • Das vorangegangene Beispiel transformiert die Normalen in das Kamerakoordinatensystem und führt dort das Shading aus (dies entspricht dem Vorgehen in der OpenGL Fixed-Function-Pipeline)
  • Das bedeutet, dass die globale Lichtrichtung ebenfalls im Kamerakoordinatensytem vorliegen muss. Daher muss bei bewegter Kamera die Lichtrichtung im Host-Code dynamisch transformiert werden und an den Shader per uniform-Variable übergeben werden (wie im vorangegangene Beispiel gezeigt)
  • Da der Trend zu immer mehr Lichtquellen in einer Szene geht, kann es vorteilhaft sein, das Shading stattdessen im globalen Koordinatensystem durchzuführen
  • Statt viele Lichtquellen in das Kamerakoordinatensystem zu transformieren, muss dann nur die eine Kameraposition in das globale Weltkoordinatensystem transformiert werden
  • Um das Shading im Weltkoordinatensystem durchzuführen, müssen die Normalen natürlich ebenfalls in diesen Raum transformiert werden

Shading im Weltkoordinatensystem

  • Um Normalen im Weltkoordinatensystem zu berechnen, muss die Modelview Matrix im Shader aufgeteilt werden:
    $\underline{\tilde{\mathbf{P}}} = \mathtt{A} \, \underbrace{\mathtt{T}_{\mathrm{\small cam}}^{-1} \, \mathtt{T}_{\mathrm{\small obj}}}_{\mathtt{T}_{\mathrm{\small modelview}}} \, \underline{\mathbf{P}}$
  • Im folgenden Beispiel ist:
    • mat4 cameraProjection die Transformation $\mathtt{A}$ vom Kamerakoordinatensystem in die Bildebene der Kamera
    • mat4 cameraLookAt die Transformation $\mathtt{T}_{\mathrm{\small cam}}^{-1}$ vom Weltkoordinatensystem ins Kamerakoordinatensystem
    • mat4 meshTransform die Transformation $\mathtt{T}_{\mathrm{\small obj}}$ vom lokalen Koordinatensystem ins Weltkoordinatensystem
    • mat4 meshTransformTransposedInverse die Transformation $\mathtt{T}_{\mathrm{\small obj}}^{-\top}$ der Normalen ins Weltkoordinatensystem

Beispiel: Phong Shading im Weltkoordinatensystem

Vertex Shader: PhongBrdfWorldSpace.vert
#version 140
in vec3 position;
in vec2 texcoord;
in vec3 normal;

uniform mat4 cameraLookAt;
uniform mat4 cameraProjection;
uniform mat4 meshTransform;
uniform mat4 meshTransformTransposedInverse;

out vec2 tc;
out vec3 wfn;
out vec3 vertPos;

void main(){
  tc = texcoord;
  wfn = vec3(meshTransformTransposedInverse * vec4(normal, 0.0));
  vec4 vertPos4 = meshTransform * vec4(position, 1.0);
  vertPos = vec3(vertPos4) / vertPos4.w;
  gl_Position = cameraProjection * cameraLookAt * vertPos4;
}

Beispiel: Phong Shading im Weltkoordinatensystem

Fragment Shader: PhongBrdfWorldSpace.frag
#version 140
out vec4 outColor;

in vec2 tc;
in vec3 wfn;
in vec3 vertPos; 

uniform int mode;
uniform vec3 cameraPosition; 

const vec3 lightDirection = vec3(0.0, -1.0, -1.0);
const vec4 ambientColor = vec4(0.01, 0.0, 0.0, 1.0);
const vec4 diffuseColor = vec4(0.25, 0.0, 0.0, 1.0);
const vec4 specularColor = vec4(1.0, 1.0, 1.0, 1.0);
const float shininess = 20.0;
const vec4 lightColor = vec4(1.0, 1.0, 1.0, 1.0);
const float irradiPerp = 1.0;

vec3 phongBRDF(vec3 lightDir, vec3 viewDir, vec3 normal, 
          vec3 phongDiffuseCol, vec3 phongSpecularCol, float phongShininess) {
  vec3 color = phongDiffuseCol;
  vec3 reflectDir = reflect(-lightDir, normal);
  float specDot = max(dot(reflectDir, viewDir), 0.0);
  color += pow(specDot, phongShininess) * phongSpecularCol;
  return color;
}

void main() {
  vec3 lightDir = normalize(-lightDirection);
  vec3 viewDir = normalize(cameraPosition - vertPos);
  vec3 n = normalize(wfn);

  vec3 radiance = ambientColor.rgb;
  
  float irradiance = max(dot(lightDir, n), 0.0) * irradiPerp;
  if(irradiance > 0.0) {
    vec3 brdf = phongBRDF(lightDir, viewDir, n, 
                          diffuseColor.rgb, specularColor.rgb, shininess);
    radiance += brdf * irradiance * lightColor.rgb;
  }

  radiance = pow(radiance, vec3(1.0 / 2.2) ); // gamma correction
  outColor.rgb = radiance;
  outColor.a = 1.0;
} 

Modifizierte Phong BRDF

  • Ein Problem bei der ursprünglichen Phong BRDF ist, dass das Prinzip der Energieerhaltung nicht erfüllt wird. In der Realität kann nicht mehr Strahldichte reflektiert werden als empfangen wurde. Somit muss gelten:
    $\int\limits_\Omega \underbrace{\left(\mathrm{f}_d(\mathbf{v}, \mathbf{l}) + \mathrm{f}_s(\mathbf{v}, \mathbf{l})\right)}_{\mathrm{f}_r(\mathbf{v}, \mathbf{l})}\, \cos(\theta) d\omega \le 1$
  • Integration über den Halbraum für den diffusen Anteil:
    $\begin{align}\int\limits_\Omega \mathrm{f}_d(\mathbf{v}, \mathbf{l})\, \cos(\theta) d\omega = \int\limits_{0}^{2\pi}\, \int\limits_{0}^{\pi/2} k_d \cos(\theta) \sin(\theta) \, d\theta \, d\phi &= 2\pi \,k_d \Bigg[\frac{-\cos^2(\theta)}{2}\Bigg]_{0}^{\pi/2} \\ &= k_d \, \pi = \rho_d \end{align}$
  • Integration über den Halbraum für den spekularen Anteil:
    $\int\limits_\Omega \mathrm{f}_s(\mathbf{v}, \mathbf{l})\, \cos(\theta) d\omega = \int\limits_{0}^{2\pi}\, \int\limits_{0}^{\pi/2} k_s \cos(\theta)^{n_s} \cos(\theta) \sin(\theta) \, d\theta \, d\phi = k_s \frac{2 \pi}{n_s+2} = \rho_s$
  • Wird die Bedingung $\rho_d + \rho_s \le 1$ eingehalten, ist die Energieerhaltung erfüllt

Modifizierte Phong BRDF

  • Durch Einsetzen von $k_d$ und $k_s$ in die ursprüngliche Phong BRDF ergibt sich die energieerhaltende modifizierte Phong BRDF:
    $\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = \rho_d \frac{1}{\pi} + \rho_s \frac{n_s+2}{2 \pi} \,\cos(\alpha)^{n_s} $
    mit
    $\rho_d + \rho_s \le 1$
modified_phong
$\mathrm{f}_s$
Winkel in Grad

Modifizierte Phong BRDF in GLSL

#define RECIPROCAL_PI 0.3183098861837907
#define RECIPROCAL_2PI 0.15915494309189535

vec3 modifiedPhongBRDF(vec3 lightDir, vec3 viewDir, vec3 normal, 
                  vec3 phongDiffuseCol, vec3 phongSpecularCol, float phongShininess) {
  vec3 color = phongDiffuseCol * RECIPROCAL_PI;
  vec3 reflectDir = reflect(-lightDir, normal);
  float specDot = max(dot(reflectDir, viewDir), 0.001);
  float normalization = (phongShininess + 2.0) * RECIPROCAL_2PI; 
  color += pow(specDot, phongShininess) * normalization * phongSpecularCol;
  return color;
}

Beispiel: Modified Phong BRDF mit Texturen

shader_stone_demon

Blinn-Phong BRDF

Blinn-Phong BRDF

blinn_angles
$\mathbf{x}$
$\theta$
$\mathbf{v}$
$-\mathbf{l}$
$\mathbf{h}$
$\mathbf{n}$
  • Von Jim Blinn auf der SIGGRAPH 1977 veröffentlicht [Blinn 1977]
  • Statt des reflektierten Strahls wird die Winkelhalbierende $\mathbf{h}$ (halfway-vector) verwendet:
    $\mathbf{h} = \frac{\mathbf{l} +\mathbf{v}}{|\mathbf{l} +\mathbf{v}|}$
    $\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = k_d + k_s \, \langle\mathbf{h} \cdot \mathbf{n}\rangle^{n_s} $
  • Schneller, da die Berechnung des reflektierten Strahls vermieden wird
  • Näher an der Physik als das originale Phong Modell, da Reziprozität der BRDF erfüllt $\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = \mathrm{f}_r(\mathbf{l}, \mathbf{v})$
  • Der Exponent $n_s$ bestimmt wieder die Bündelung des Lichts (größeres $n_s$ für glattere Oberfläche)
  • Wenn auch noch ein ambienter Anteil $k_a$ hinzukommt, wird auch vom "Blinn-Phong-Beleuchtungsmodell" gesprochen. Dies ist sehr weit verbreitet und wird auch von der OpenGL Fixed-Function-Pipeline unterstützt.

Blinn-Phong BRDF

$-\mathbf{l}$
$\mathbf{h}$
$\mathbf{v}$
$\mathbf{n}$

$\mathbf{l}$     $\mathbf{v}$    $k_d$    $k_s$    $n_s$

$\mathrm{f}_r(\mathbf{v}, \mathbf{l}) = k_d + k_s \langle \mathbf{h} \cdot \mathbf{n}\rangle^{n_s}$

Beispiel: Blinn-Phong BRDF in GLSL

opengl_shaderblinnphong
Blinn-Phong
opengl_shaderblinn_vs_phong
Phong

Beispiel: Blinn-Phong BRDF in GLSL

vec3 blinnPhongBRDF(vec3 lightDir, vec3 viewDir, vec3 normal, 
            vec3 phongDiffuseCol, vec3 phongSpecularCol, float phongShininess) {
  vec3 color = phongDiffuseCol;
  vec3 halfDir = normalize(viewDir + lightDir);
  float specDot = max(dot(halfDir, normal), 0.0);
  color += pow(specDot, phongShininess) * phongSpecularCol;
  return color;
}

Mikrofacetten BRDF

Mikrofacetten BRDF

microfacet_model
Mikrofacetten
Makroskopisches Verhalten
$\mathbf{v}$
$-\mathbf{l}$
$\mathbf{h}$
$\mathbf{n}$
  • Mathematische Modellierung der Oberfläche aus Mikrofacetten (sehr viel kleiner als ein Pixel). Je rauer die Oberfläche, desto unterschiedlicher ist deren Orientierung [Cook Torrance 1981]
  • Grundlage für viele aktuelle physik-basierte Renderverfahren ("Physically-Based Rendering", PBR) [Disney 2012] [Unreal Engine 2013] [Frostbite 2014]
  • Die BRDF des spekularen Anteils lautet:
    $\Large \mathrm{f}_s(\mathbf{v}, \mathbf{l}) = \frac{\mathrm{F}(\mathbf{v},\mathbf{h})\,\mathrm{D}(\mathbf{h})\,\mathrm{G}(\mathbf{l}, \mathbf{v})}{4\,\,\langle\mathbf{n} \cdot \mathbf{l}\rangle\,\,\langle\mathbf{n} \cdot \mathbf{v}\rangle}$
    mit
    • $\mathrm{F}$: Fresnel Reflexionsgrad
    • $\mathrm{D}$: Verteilung der Mikrofacetten (Rauheit, "Normal distribution function", NDF)
    • $\mathrm{G}$: Geometriefaktor (Selbstverschattung)

Fresnel Reflexion

  • Das Verhältnis von reflektierter und transmittierter Strahlungs­energie hängt vom Einfallswinkel der Lichtstrahlen und den Brechungsindizes der beteiligten Materialien ab
fresnel_example
Bildquelle: Blue Lounger Beside Swimming Pool, CC0, public domain

Fresnel Reflexion: Dielektrika

  • Licht wird mit einer winkelabhängigen relativen Häufigkeit entweder reflektiert, transmittiert oder absorbiert
  • Der reflektierte Anteil wird an den Mikrofacetten gestreut. Makroskopisch entsteht daraus der spekulare Anteil der Reflexion.
  • Der transmittierte Anteil wird bei opaken Materialien unter der Oberfläche zufällig abgelenkt, teilweise absorbiert (Wellenlängen abhängig) und tritt unter verschiedenen Winkel wieder aus. Makroskopisch entsteht daraus der diffuse Anteil der Reflexion.
  • Je mehr Licht reflektiert wird, desto weniger Licht wird transmittiert und desto kleiner ist demnach der diffuse Anteil
dielectric
Mikrofacetten
Makroskopisches Verhalten
$\mathbf{n}$
Spekularer Anteil
Diffuser Anteil

Fresnel Reflexion: Metalle

  • In Metallen wird der transmittierte Anteil absorbiert, d.h. es gibt keine diffuse Reflexion
  • Der reflektierte Anteil ist von der Wellenlänge abhängig, daher ist der spekulare Anteil farbig
metals
Mikrofacetten
Makroskopisches Verhalten
$\mathbf{n}$
Spekularer Anteil

Fresnel Reflexionsgrad

fresnel_reflection
$\eta_1$
$\eta_2$
$\theta_1$
$\theta_1$
$\theta_2$
$\mathrm{F}$
$1-\mathrm{F}$
  • Reflektierter Anteil:
    $\begin{align} \mathrm{F}_{\tiny\mbox{para}} &= \frac{\eta_2 \cos \theta_1 - \eta_1 \cos \theta_2}{\eta_2 \cos \theta_1 + \eta_1 \cos \theta_2}\\ \mathrm{F}_{\tiny\mbox{perp}} &= \frac{\eta_2 \cos \theta_2 - \eta_1 \cos \theta_1}{\eta_2 \cos \theta_2 + \eta_1 \cos \theta_1}\\ \mathrm{F} &= \frac{1}{2} \left(\mathrm{F}_{\tiny \mbox{para}}^2 + \mathrm{F}_{\tiny\mbox{perp}}^2\right) \end{align}$
  • Refraktierter Anteil: $1 - F$
  • Bei einem Übergang von optisch dünneren zum optisch dichteren Medium ($\eta_1 < \eta_2$), wird der Strahl hin zur Normalen gebrochen. Im anderen Fall weg von der Normalen.
  • Der mathematische Zusammenhang zwischen Einfallswinkel $\theta_1$ und dem Winkel des gebrochenen Strahls $\theta_2$ lautet:
    $\eta_1 \sin(\theta_1) = \eta_2 \sin(\theta_2)$

Fresnel Reflexionsgrad (Dielektrika)

Material Brechungsindex $\mathrm{F}_0$
Vakuum 1,0 0%
Luft 1,000292 ≈ 0%
Wasser 1,333 2%
Glass 1,5 4%
Plastik 1,5 bis 1,58 4% bis 5%
Diamant 2,42 17,24%
  • Dabei ist $\mathrm{F}_0$ der Reflexionsgrad für den senkrechten Lichteinfall $\theta_1 = 0$:
    $\mathrm{F}_0 = \frac{(\eta_2 - \eta_1)^2}{(\eta_2 + \eta_1)^2} $

Fresnel Reflexionsgrad (Metalle)

Metall $\mathrm{F}_0$ (Linear, Float) $\mathrm{F}_0$ (sRGB, 8-bit) Farbe
Titan (0.542, 0.497, 0.449) (194, 187, 179)
Chrom (0.549, 0.556, 0.554) (196, 197, 196)
Eisen (0.562, 0.565, 0.578) (198, 198, 200)
Nickel (0.660, 0.609, 0.526) (212, 205, 192)
Platin (0.673, 0.637, 0.585) (214, 209, 201)
Kupfer (0.955, 0.638, 0.538) (250, 209, 194)
Palladium (0.733, 0.697, 0.652) (222, 217, 211)
Zink (0.664, 0.824, 0.850) (213, 234, 237)
Gold (1.022, 0.782, 0.344) (255, 229, 158)
Aluminium (0.913, 0.922, 0.924) (245, 246, 246)
Silber (0.972, 0.960, 0.915) (252, 250, 245)
Quelle: Naty Hoffman: Physics and Math of Shading, SIGGRAPH 2015 Course: Physically Based Shading in Theory and Practice

Fresnel Reflexionsgrad

  • Beim Mikrofacetten-Modell wird als Winkel $\theta_1$ der Winkel zwischen Sichtrichtung $\mathbf{v}$ und Halbvektor $\mathbf{h}$ verwendet, weil nur diejenigen Mikrofacetten, die den makroskopischen Halbvektor als Normale haben, einen Reflexionsbeitrag in Sichtrichtung haben
  • Laut [Cook Torrance 1981] berechnet sich der Reflexionsgrad für $\eta_1 = 1$ gemäß:
    $\begin{align}c &= \langle\mathbf{v} \cdot \mathbf{h}\rangle \\ g &= \sqrt{\eta_2^2+ c^2 - 1}\\ F_{\tiny \mbox{Cook-Torrance}}(\mathbf{v}, \mathbf{h}) &= \frac{1}{2} \left( \frac{g - c}{g + c} \right)^2 \left( 1 + \left( \frac{ c\,(g + c) - 1 }{ c\,(g - c)+ 1 } \right)^2 \right) \end{align}$
microfacet_model_sidebyside
Mikrofacetten
Makroskopisches Verhalten
$\mathbf{v}$
$-\mathbf{l}$
$\mathbf{h}$
$\mathbf{n}$

Fresnel Reflexionsgrad

  • Alternativ kann auch die schneller zu berechnende Schlick Approximation [Schlick 1994] des Reflexionsgrads verwendet werden:
    $F_{\tiny \mbox{Schlick}}(\mathbf{v}, \mathbf{h}) = \mathrm{F}_0 + \left(1.0 − \mathrm{F}_0\right) \left(1.0 − \langle\mathbf{v} \cdot \mathbf{h}\rangle \right)^5$
  • Die Abbildung zeigt den Vergleich für Glass mit $\mathrm{F}_0 = 0.04$
fresnel_vs_schlick
$F_{\tiny \mbox{Cook-Torrance}}$
$F_{\tiny \mbox{Schlick}}$
Winkel in Grad
Reflexionsgrad

Verteilung der Mikrofacetten (NDF)

  • Abhängig von der Rauheit der Oberfläche ändert sich die Verteilung der Mikrofacetten
  • Bei einer rauhen Oberfläche ist die Verteilung um die Oberflächennormale breiter gestreut
  • Für die Verteilung gibt es in der Literatur [Walter et al. 2007] verschiedene Vorschläge:
    compare_blinn_beckmann_ggx
    $\mathrm{D}_{\tiny \mbox{Blinn}}(\mathbf{h}) = \frac{1}{ \pi \alpha^2 } \langle\mathbf{n} \cdot \mathbf{h}\rangle^{n_s}$   mit   $n_s = 2\alpha^{-2} - 2$
    $\mathrm{D}_{\tiny \mbox{Beckmann}}(\mathbf{h}) = \frac{1}{ \pi \alpha^2 \langle\mathbf{n} \cdot \mathbf{h}\rangle^4 } \exp{ \left( \frac{ \langle\mathbf{n} \cdot \mathbf{h}\rangle^2 - 1}{\alpha^2 \langle\mathbf{n} \cdot \mathbf{h}\rangle^2} \right) }$
    $\mathrm{D}_{\tiny \mbox{GGX}}(\mathbf{h}) = \frac{\alpha^2}{\pi \left(\langle\mathbf{n} \cdot \mathbf{h}\rangle^2 (\alpha^2-1)+1\right)^2}$
  • Dabei gilt $\alpha = r_p^2$ mit der wahrgenommenen Rauheit $r_p$ im Intervall [0.0, 1.0]

Geometriefaktor

  • Abhängig vom der Einfallsrichtung des Lichts und der Sichtrichtung des Betrachters kommt es an den Mikrofacetten zu Abschattung und Maskierung des Lichts
  • [Blinn 1977] und [Cook Torrance 1981] nehmen V-förmige Kerben an und leiten so einen Geometriefaktor $0 \le G \le 1$ ab.
    geometry_term
    Keine Beeinträchtigung
    Maskierung
    Abschattung
    $\mathbf{n}$
    $-\mathbf{l}$
    $\mathbf{v}$
    $\mathbf{h}$
    $\mathbf{n}$
    $-\mathbf{l}$
    $\mathbf{v}$
    $\mathbf{h}$
    $\mathbf{n}$
    $-\mathbf{l}$
    $\mathbf{v}$
    $\mathbf{h}$
    $\mathrm{G}_{\tiny \mbox{Cook-Torrance}}(\mathbf{l}, \mathbf{v}) = \operatorname{min}\left( 1, \frac{ 2 \langle\mathbf{n} \cdot \mathbf{h}\rangle \langle\mathbf{n} \cdot \mathbf{v}\rangle }{ \langle\mathbf{v} \cdot \mathbf{h}\rangle}, \frac{ 2 \langle\mathbf{n} \cdot \mathbf{h}\rangle \langle\mathbf{n} \cdot \mathbf{l}\rangle }{ \langle\mathbf{v} \cdot \mathbf{h}\rangle} \right)$

Geometriefaktor

  • Ein weiteres bekanntes Model aus [Smith 1967] setzt den Geometriefaktor aus einem Anteil für die Lichtrichtung und einem für die Sichtrichtung zusammen:
    $\mathrm{G}_{\tiny \mbox{Smith}}(\mathbf{l}, \mathbf{v}) = \mathrm{G}_1(\mathbf{l}) \mathrm{G}_1(\mathbf{v}) $
  • Verschiedenen $\mathrm{G}_1$ gemäß [Walter et al. 2007] sind:
    $\mathrm{G}_{1\ \tiny \mbox{Beckmann}}(\mathbf{v}) =\left\{ \begin{array}{l l} \frac{ 3.535 \,c \,+ \,2.181 \,c^2 }{ 1 \,+ \,2.276 \,c \,+ \,2.577 \,c^2 } & : \,\, c < 1.6\\ 1 & : \,\, c \ge 1.6\\ \end{array} \right.$    mit   $c = \frac{\langle\mathbf{n} \cdot \mathbf{v}\rangle}{ \alpha \sqrt{1 - \langle\mathbf{n} \cdot \mathbf{v}\rangle^2} }$
    $\mathrm{G}_{1\ \tiny \mbox{GGX}}(\mathbf{v}) = \frac{ 2 \, \langle\mathbf{n} \cdot \mathbf{v}\rangle }{ \langle\mathbf{n} \cdot \mathbf{v}\rangle + \sqrt{ \alpha^2 + (1 - \alpha^2)\langle\mathbf{n} \cdot \mathbf{v}\rangle^2 } }$
  • Schnell zu berechnende Approximation [Schlick 1994] für die GGX Variante:
    $\mathrm{G}_{1\ \tiny \mbox{Schlick-GGX}}(\mathbf{v}) =\frac{\langle\mathbf{n} \cdot \mathbf{v}\rangle}{\langle\mathbf{n} \cdot \mathbf{v}\rangle(1 - k) + k }$    mit   $k = \frac{\alpha}{2}$

Geometriefaktor

geometry_term_backmann_ggx
$\mathrm{G}_{1\ \tiny \mbox{Beckmann}}$
$\mathrm{G}_{1\ \tiny \mbox{GGX}}$
$\mathrm{G}_{1\ \tiny \mbox{Schlick-GGX}}$
$r_p = 0.00$
$r_p = 0.25$
$r_p = 0.50$
$r_p = 0.75$
$r_p = 1.00$
$\alpha = r_p^2$

Beispiel: GGX Mikrofacetten BRDF in GLSL

opengl_shader_ggx_microfactet_brdf

Beispiel: GGX Mikrofacetten BRDF in GLSL

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

float D_GGX(float NoH, float roughness) {
  float alpha = roughness * roughness;
  float alpha2 = alpha * alpha;
  float NoH2 = NoH * NoH;
  float b = (NoH2 * (alpha2 - 1.0) + 1.0);
  return alpha2 / (PI * b * b);
}
float G1_GGX_Schlick(float NoV, float roughness) {
  //float r = roughness; // original
  float r = 0.5 + 0.5 * roughness; // Disney remapping
  float k = (r * r) / 2.0;
  float denom = NoV * (1.0 - k) + k;
  return max(NoV, 0.001) / denom;
}

float G_Smith(float NoV, float NoL, float roughness) {
  float g1_l = G1_GGX_Schlick(NoL, roughness);
  float g1_v = G1_GGX_Schlick(NoV, roughness);
  return g1_l * g1_v;
}

vec3 microfacetBRDF(in vec3 L, in vec3 V, in vec3 N, 
              in vec3 baseColor, in float metallicness, 
              in float fresnelReflect, in float roughness) {
     
  vec3 H = normalize(V + L); // half vector

  // all required dot products
  float NoV = clamp(dot(N, V), 0.0, 1.0);
  float NoL = clamp(dot(N, L), 0.0, 1.0);
  float NoH = clamp(dot(N, H), 0.0, 1.0);
  float VoH = clamp(dot(V, H), 0.0, 1.0);     
  
  // F0 for dielectics in range [0.0, 0.16] 
  // default FO is (0.16 * 0.5^2) = 0.04
  vec3 f0 = vec3(0.16 * (fresnelReflect * fresnelReflect)); 
  // in case of metals, baseColor contains F0
  f0 = mix(f0, baseColor, metallicness);

  // specular microfacet (cook-torrance) BRDF
  vec3 F = fresnelSchlick(VoH, f0);
  float D = D_GGX(NoH, roughness);
  float G = G_Smith(NoV, NoL, roughness);
  vec3 spec = (F * D * G) / (4.0 * max(NoV, 0.001) * max(NoL, 0.001));
  
  // diffuse
  vec3 rhoD = baseColor;
  rhoD *= vec3(1.0) - F; // if not specular, use as diffuse (optional)
  rhoD *= (1.0 - metallicness); // no diffuse for metals
  vec3 diff = rhoD * RECIPROCAL_PI;
  
  return diff + spec;
}

Lichtquellen

lighttypes_directional
Punktlichtquelle
lighttypes_spot
Strahler
lighttypes_directional
Richtungslichtquelle
lighttypes_env
Umgebungsbeleuchtung

Punktlichtquelle

pointlight
  • In alle Richtungen gleichmäßig sendend (isotrop)
  • Keine Ausdehnung (infinitesimal klein)
  • Vereinfachendes mathematisches Modell, nicht exakt physikalisch
  • Typische Parameter
    • 3D Position
    • Strahlungsfluss $\Phi$ in Watt $[\mathrm{W}]$
pointlightmax

Punktlichtquelle

pointlight
$\mathbf{n}$
$-\mathbf{l}$
$-\mathbf{l}$
$\cos(\theta)dA$
$\theta$
$\theta$
$E_\perp$
$dA$
$dA$
  • Für ein Raumwinkelelement gilt $d\omega = \frac{dA}{r^2}$.
    Damit erzielt eine Punktlichtquelle bei
    Strahlstärke $I$ im Abstand $r$ eine senkrechte Bestrahlungsstärke von
    $E_\perp = \frac{d\Phi}{dA} = \frac{d\Phi}{d\omega \,r^2} = \frac{I}{r^2}$
  • Bei einem Einfallswinkel $\theta$ verringert sich die Fläche um $\cos(\theta)$. Damit gilt:
    $E = E_\perp \cos(\theta) = \frac{I}{r^2} \cos(\theta) = \frac{I}{r^2} \langle\mathbf{n} \cdot \mathbf{l}\rangle$

Punktlichtquelle

  • Da die Punktlichtquelle in alle Richtungen gleichmäßig sendet, besteht zwischen der Strahlstärke $I$ und dem Strahlungsfluss $\Phi$ die Beziehung:
    $\begin{align} &\Phi = \int\limits_{\Omega} I \, d\omega = \int\limits_{0}^{2\pi}\, \int\limits_{0}^{\pi} I\, \sin(\theta) \, d\theta \, d\phi = I \Bigg[-\cos(\theta)\Bigg]_{0}^{\pi} \left(\int\limits_{0}^{2\pi}d\phi\right) = 4\pi \, I\\ \Leftrightarrow & I = \frac{\Phi}{4\pi} \end{align} $
  • Damit gilt für die Bestrahlungsstärke aus senkrechter Richtung im Abstand $r$:
    $E_\perp = \frac{I}{r^2} = \frac{\Phi}{4\pi \,r^2}$
  • bzw. bei Einfallswinkel $\theta$:
    $E = E_\perp \cos(\theta) = \frac{\Phi}{4\pi \,r^2} \cos(\theta) = \frac{\Phi}{4\pi \,r^2} \langle\mathbf{n} \cdot \mathbf{l}\rangle$

Beispiel: Blinn-Phong Shading mit einer Punktlichtquelle

shaderphongpointlight
  • Position der Punktlichtquelle wird als weiße Kugel dargestellt
  • Bestrahlungsstärke nimmt quadratische mit der Distanz von der Lichtquelle ab

Strahler

spot
  • Lichtausbreitung auf bestimmten Raumwinkel (Lichtkegel) beschränkt
  • Abfall der Strahlstärke vom größten Wert $I_0$ in die Hauptausstrahlrichtung zum Rand gemäß:
    $I = I_0 \cos^n(\beta)$
    dabei ist $\beta$ der Winkel zwischen der betrachteten Richtung und der Hauptausstrahlrichtung
  • Der Exponent $n$ bestimmt wieder die Bündelung des Lichts
strahlermax

Strahler

spot
$\mathbf{d}$
$\mathbf{p}$
  • Strahlstärke:
    $I = I_0 \cos^n(\beta)$
    mit Strahlstärke in Hauptausstrahlrichtung $I_0$
  • Typische Parameter:
    • 3D Position $\mathbf{p}$
    • Hauptausstrahlrichtung $\mathbf{d}$
    • Strahlungsfluss $\Phi$ in Watt $[\mathrm{W}]$
    • Maximaler Winkel $\beta_{\tiny \mbox{ max}}$
    • Bündelungs-Exponent $n$

Strahler

  • Zwischen der Strahlstärke $I$ und dem Strahlungsfluss $\Phi$ besteht die Beziehung:
    $\begin{align} &\Phi = \int\limits_{0}^{2\pi}\, \int\limits_{0}^{\beta_{\tiny \mbox{ max}}} I_0\, \cos^{n}(\theta) \sin(\theta) \, d\theta \, d\phi = 2\pi \Bigg[\frac{-\cos^{n+1}(\theta)}{n+1}\Bigg]_{0}^{\beta_{\tiny \mbox{ max}}} \, I_0 \\ & \quad = \frac{2\pi}{n+1} \left(1 - \cos^{n+1}(\beta_{\tiny \mbox{ max}}) \right) \, I_0 \\ \Leftrightarrow & I_0 = \frac{n+1}{2\pi \left(1 - \cos^{n+1}(\beta_{\tiny \mbox{ max}}) \right)} \Phi \end{align} $
  • Damit gilt für die Bestrahlungsstärke bei Einfallswinkel $\theta$ im Abstand $r$:
    $E = E_\perp \cos(\theta) = \frac{I}{r^2} \cos(\theta) = \frac{I_0}{r^2} \cos^{n} (\beta)\cos(\theta)= \frac{\Phi}{2\pi r^2}\frac{(n+1) \cos^{n}(\beta)\cos(\theta)}{\left(1 - \cos^{n+1}(\beta_{\tiny \mbox{ max}}) \right)}$
  • Für $n = 1$ und $\beta_{\tiny \mbox{ max}} = \frac{\pi}{2}$:
    $E = \frac{\Phi}{\pi r^2} \cos(\beta)\cos(\theta) =\frac{\Phi}{\pi r^2} \langle-\mathbf{l}\cdot \mathbf{d}\rangle \langle\mathbf{n} \cdot \mathbf{l}\rangle$

Richtungslichtquelle

directional
$-\mathbf{l}$
  • Mit Richtungslichtquellen können weit entfernte Lichtquellen (z.B. die Sonne) simuliert werden
  • Parameter:
    • Lichtausbreitungsrichtung: $-\mathbf{l}$
    • Senkrechte Bestrahlungsstärke: $E_\perp$
  • Alle Lichtstrahlen treffen mit derselben Richtung in der Szene auf und erzeugen eine Beleuchtungstärke von
    $E = E_\perp \cos(\theta) = E_\perp \langle\mathbf{n} \cdot \mathbf{l}\rangle$

Umgebungsbeleuchtung

env
  • Umgebungsbeleuchtung berücksichtigt Licht aus allen Richtungen
  • Oft wird dabei die emittierte Strahldichte $L_i$ der Umgebung durch ein sphärisches Umgebungsbild angegeben (Image-based Lighting)
    ⟶ siehe nächstes Kapitel

Referenzen

  • [Phong 1975] Bui-T. Phong: Illumination for computer generated pictures. Communications of the ACM, 18(6):311-317, June 1975
  • [Blinn 1977] James F. Blinn: Models of light reflection for computer synthesized pictures. SIGGRAPH 1977, pp. 192-198, July 1977
  • [Cook Torrance 1981] R. L. Cook and K. E. Torrance: A reflectance model for computer graphics. TOG 1(1):7-24, Jan. 1981.
  • [Disney 2012] Brent Burley: Physically Based Shading at Disney SIGGRAPH 2012 SIGGRAPH 2012 Course: Practical Physically Based Shading in Film and Game Production
  • [Unreal Engine 2013] Brian Karis: Real Shading in Unreal Engine 4, SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice
  • [Frostbite 2014] S. Lagarde, C. de Rousiers: Moving Frostbite to PBR, SIGGRAPH 2014 Course: Physically Based Shading in Theory and Practice

Referenzen

  • [Schlick 1994] Christophe Schlick: An Inexpensive BRDF Model for Physically-Based Rendering. Computer Graphics Forum, 13 (3), 233–246, 1994.
  • [Walter et al. 2007] B. Walter, S. R. Marschner, H. Li, K. E. Torrance: Microfacet Models for Refraction through Rough Surfaces. Eurographics Symposium on Rendering, 2007.
  • [Smith 1967] B. Smith: Geometrical shadowing of a random rough surface. IEEE Transactions on Antennas and Propagation 15(5):668-671, Sep. 1967

Gibt es Fragen?

questions

Anregungen oder Verbesserungsvorschläge können auch gerne per E-Mail an mich gesendet werden: Kontakt

Weitere Vorlesungsfolien

Folien auf Englisch (Slides in English)