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$

Bildbasierte Beleuchtung

  • Bei der bildbasierten Beleuchtung (engl. "Image-based Lighting") wird die emittierte Strahldichte $L_i$ der Umgebung durch ein sphärische Umgebungsbild (engl. "Environment Map") angegeben
envmap
$s$
$t$
$0.0$
$1.0$
$1.0$
$0.0$
$0.0$
$\pi$
$\pi$
$0.0$
$-\pi$
$\theta$
$\phi$
Quelle: : HDR Umgebungsbild von HDRI Haven, CC0

Environment Map

spherical_coord
$y$
$x$
$z$
$\mathbf{p}$
$\phi$
$\theta$
  • Zusammenhang zwischen Texturkoordinaten $(s, t)$ und Kugelkoordinaten $(\phi, \theta):$
    $\begin{align} s &= 0.5 - \frac{\phi}{2\pi} \\ &= 0.5 - \frac{1}{2\pi} \operatorname{arctan2}(y, x)\\ t &= 1.0 - \frac{1}{\pi} \theta \\ &= 1.0 - \frac{1}{\pi} \arccos(z) = \frac{1}{\pi} \arccos(-z) \end{align}$
  • Beispiel: Envmap
    vec2 directionToSphericalEnvmap(vec3 dir) {
      float s = 0.5 - atan(dir.y, dir.x) / (2.0 * PI);
      float t = 1.0 / (PI) * acos(-dir.z);
      return vec2(s, t);
    }

BRDF vs. Environment Map Sampling

ibl_brdf_vs_envmap_sampling05
Environment map
Radiance
BRDF

Wiederholung: Rendering-Gleichung

$L_o(\mathbf{v}) = L_e(\mathbf{v}) + \int\limits_{\Omega_h} \mathrm{f}_r(\mathbf{v}, \mathbf{l})\, \, \underbrace{L_i(\mathbf{l}) \cos(\theta) \, d\omega}_{dE(\mathbf{l})}$
Ausgehende Strahldichte
Eingehende Strahldichte
Emittierte Strahldichte
Raumwinkel
(Halbraum)
BRDF
Bestrahlungsstärke
render_eqn
$\mathbf{x}$
$\theta$
$L_i(\mathbf{l})$
$L_o(\mathbf{v})$
$\Omega_h$
$\mathbf{n}$

Wiederholung: Importance Sampling

  • Mit Importance Sampling kann jedes Integral auch durch folgende Summe approximiert werden:
    $\int\limits_a^b \mathrm{f}(x) \,dx \approx \frac{1}{N} \sum\limits_{n=1}^{N} \frac{\mathrm{f}(x_n)}{\mathrm{p}(x_n)}$
    Dabei ist $\mathrm{p}(x)$ eine beliebige Wahrscheinlichkeitsdichtefunktion (WDF), die folgende Bedingung erfüllen muss
    $\int\limits_a^b \mathrm{p}(x) \, dx = 1$
  • Theoretisch wäre das beste WDF (mit dem geringsten Fehler der Approximation)
    $\mathrm{p}(x) = \frac{\mathrm{f}(x)}{ \int_a^b \mathrm{f}(x)}$
    was bedeutet, dass die WDF der Form der Funktion folgen sollte (d.h. die Dichte sollte höher sein, wenn die Funktionswerte höher sind).

Sampling von Environment Maps

solidangle
  • Rendering-Gleichung (ohne den Emissionsterm):
    $\begin{align}L_o(\mathbf{v}) &= \int\limits_{\Omega_h} \mathrm{f}_r(\mathbf{v}, \mathbf{l})\, \, L_i(\mathbf{l}) \cos(\check{\theta}) \, d\omega\\ & = \int\limits_{0}^{2\pi}\, \int\limits_{0}^{\pi/2} \mathrm{f}_r(\mathbf{v}, \mathbf{l})\, \, L_i(\mathbf{l}) \cos(\check{\theta}) \sin(\check{\theta})\, d\check{\theta} \, d\check{\phi}\\ & = \int\limits_{0}^{2\pi}\, \int\limits_{0}^{\pi} \underbrace{\mathrm{f}_r(\mathbf{v}, \mathbf{l})\, \, L_i(\mathbf{l}) \, (\cos(\check{\theta}))_{\small +} \sin(\theta)}_{\mathrm{f}( \phi, \theta)} \, d\theta \, d\phi\\ &\approx \ \frac{1}{N} \sum_{n=1}^{N} \frac{\mathrm{f}( \phi_n, \theta_n)}{\mathrm{p}( \phi_n, \theta_n)}\\ &= \frac{1}{N} \sum_{n=1}^{N} \frac{\mathrm{f}_r(\mathbf{v}, \mathbf{l})\,\,L_i(\mathbf{l}) \, (\cos(\check{\theta}))_{\small +} \sin(\theta_n)}{\mathrm{p}( \phi_n, \theta_n)}\end{align}$

Wiederholung: Inversionsmethode

  1. Berechne die Verteilungsfunktion aus der Wahrscheinlichkeitsdichtefunktion (WDF):
    $\mathrm{P}(x) = \int\limits_{-\infty}^x p(\tilde{x}) \,d\tilde{x}$
  2. Berechne die Inverse der Verteilungsfunktion $\,\mathrm{P}^{-1}(u)$
  3. Erzeuge gleichverteile Zufallswerte $u \in [0, 1]$
  4. Berechne Zufallszahlen $x$ gemäß $\mathrm{p}(x)$ mit der Inversen der Verteilungsfunktion
    $x = \mathrm{P}^{-1}_x(u)$

Inversionsmethode bei einer 2D Wahrscheinlichkeitsdichte

marginal
$x$
$y$
$p(x, y)$
$p_x(x)$
$p_y(y)$
marginal2
$p(x | y)$
  • Die Inversionsmethode kann auch bei einer zweidimensionalen WDF $p(x, y)$ angewendet werden
  1. Dazu zunächst die Randdichte für eine Dimension berechnen, z.B. für $y\,$:
    $\mathrm{p}_y(y) = \int \mathrm{p}(x, y) \,dx$
  2. Berechne die bedingte Wahrscheinlichkeit für die andere Dimension:
    $\mathrm{p}(x | y) = \frac{\mathrm{p}(x, y)}{\mathrm{p}_y(y)}$
  3. Verwende die bekannte Inversionsmethode jeweils für die zwei 1D WDFs $\mathrm{p}_y(y)$ und $\mathrm{p}(x | y)$

Texturkoordinaten zu Kugelkoordinaten

$\begin{align}\phi &= 2\pi \,(0.5 - s) \\ \theta &= \pi \, (1.0 - t) \end{align}$

envmap
$s$
$t$
$0.0$
$0.5$
$1.0$
$1.0$
$0.0$
$0.0$
$\pi$
$\pi$
$0.0$
$-\pi$
$\theta$
$\phi$
Source: : HDR environment map from HDRI Haven, CC0

Transformation von Wahrscheinlichkeitsdichten

  • Wird eine mehrdimensionale Zufallsvariable $\mathbf{x} = (x_1, x_2, \dots, x_n)^\top$ mit einer mehrdimensionalen bijektiven (=eineindeutigen) Funktion
    $\mathbf{y} = \mathrm{f}(\mathbf{x}) = (\mathrm{f}_1(\mathbf{x}), \mathrm{f}_2(\mathbf{x}), \dots, \mathrm{f}_n(\mathbf{x}))^\top$
    abgebildet, so gilt für die WDF
    $\mathrm{p}(\mathbf{y}) = \frac{1}{|\mathtt{J}_f(\mathbf{x})|} \mathrm{p}(\mathbf{x})$
    dabei ist $|\mathtt{J}_f(\mathbf{x})|$ die Determinate der Jacobi-Matrix
    $\mathtt{J}_f(\mathbf{x}) = \begin{bmatrix} \frac{\partial f_1}{\partial x_1} & \dots & \frac{\partial f_1}{\partial x_n} \\ \vdots & \ddots & \vdots \\ \frac{\partial f_n}{\partial x_1} & \dots & \frac{\partial f_n}{\partial x_n} \end{bmatrix}$

Transformation von Wahrscheinlichkeitsdichten

  • Zusammenhang zwischen Texturkoordinaten $(s, t)$ und Kugelkoordinaten $(\phi, \theta)$:
    $\begin{align}\phi &= 2\pi \,(0.5 - s) \\ \theta &= \pi \, (1.0 - t) \end{align}$
  • Die Jacobi-Matrix lautet:
    $\mathtt{J} = \begin{bmatrix} \frac{\partial \phi}{\partial s} & \frac{\partial \phi}{\partial t} \\ \frac{\partial\theta}{\partial s} & \frac{\partial \theta}{\partial t} \end{bmatrix} = \begin{bmatrix} -2\pi & 0\\ 0 & -\pi \end{bmatrix} $
  • Somit lautet die Determinante der Jacobi-Matrix: $|\mathtt{J}| = 2 \pi^2$
  • Rendering-Gleichung:
    $\begin{align}L_o(\mathbf{v}) &= \int\limits_{0}^{2\pi}\, \int\limits_{0}^{\pi}\underbrace{ \mathrm{f}_r(\mathbf{v}, \mathbf{l})\,L_i(\mathbf{l}) \, (\cos(\check{\theta}))_{\small +} \sin(\theta)}_{\mathrm{f}( \phi, \theta)} \, d\theta \, d\phi\\ &\approx \ \frac{1}{N} \sum_{n=1}^{N} \frac{\mathrm{f}( \phi_n, \theta_n)}{\mathrm{p}( \phi_n, \theta_n)} = \frac{1}{N} \sum_{n=1}^{N} \frac{\mathrm{f}( \phi_n, \theta_n)}{\mathrm{p}(s_n, t_n)} 2 \pi^2 \end{align}$

Importance Sampling von Environment Maps

  • Das Umgebungsbild wird in ein Grauwertbild $\mathrm{g}(s, t)$ umgewandelt
  • Die Parametrisierung des Bilds erfolgt in Texturkoordinaten $(s, t)$
  • Das Bild hat $S \times T$ Pixel und eckige Klammern $\mathrm{g}[x, y]$ bedeuten Zugriff auf das jeweilige Pixel
  • Das Integral über das gesamte Grauwertbild ist:
    $\int\limits_0^1 \int\limits_0^1 \mathrm{g}(s, t) \,ds \, dt \approx\sum\limits_{y=0}^{T-1} \sum\limits_{x=0}^{S-1} \mathrm{g}[x, y] \underbrace{\Delta s}_{\frac{1}{S}} \underbrace{\Delta t}_{\frac{1}{T}} = \underbrace{\frac{1}{S\,T}\sum\limits_{y=0}^{T-1} \sum\limits_{x=0}^{S-1} \mathrm{g}[x,y]}_{\tiny \mbox{vorberechneter Mittelwert}} = A$
  • Damit gilt für die 2D Wahrscheinlichkeitsdichte
    $\mathrm{p}(s, t) = \frac{\mathrm{g}(s, t)}{A}$
    mit
    $A = \underbrace{\frac{1}{S\,T}\sum\limits_{y=0}^{T-1} \sum\limits_{x=0}^{S-1} \mathrm{g}[x,y]}_{\tiny \mbox{vorberechneter Mittelwert}} = \frac{1}{T}\sum\limits_{y=0}^{T-1} \underbrace{\frac{1}{S} \sum\limits_{x=0}^{S-1} \mathrm{g}[x,y]}_{\tiny \mbox{vorberechnete Zeilenmittelwerte}} $

Importance Sampling von Environment Maps

  • Die Randdichte bezüglich $t$ berechnet sich zu
    $\mathrm{p}_t(t) = \int\limits_0^1 \mathrm{p}(s, t) \,ds = \int\limits_0^1 \frac{\mathrm{g}(s, t)}{A} \,ds \approx \mathrm{p}_t[y] = \frac{1}{A} \underbrace{\frac{1}{S}\sum\limits_{x=0}^{S-1} \mathrm{g}[x, y]}_{\tiny \mbox{vorberechnete Zeilenmittelwerte}}$
  • Die zugehörige Verteilungsfunktion lautet
    $\mathrm{P}_t(t) = \int\limits_{0}^t \mathrm{p}_t(\tilde{t}) \,d\tilde{t} \approx \mathrm{P}_t[y] = \frac{1}{T}\sum\limits_{\tilde{y}=0}^y\mathrm{p}_t[\tilde{y}]$
  • Die Verteilungsfunktion kann nicht invertiert werden, da folgende Funktion nicht nach der gleichverteilten Zufallsvariable $u \in [0, 1]$ aufgelöst werden kann
    $u = \mathrm{P}_t[y] = \frac{1}{T}\sum\limits_{\tilde{y}=0}^y\mathrm{p}_t[\tilde{y}]$
    Daher wird im Shader über $\tilde{y}$ gelaufen bis $u$ erreicht ist. Das zugehörige $y$ ist die Bildzeile $Y$, in der der Abtastwert genommen wird

Importance Sampling von Environment Maps

  • Nachdem nun die Bildzeile $Y$ des Abtastwerts feststeht, muss mittels der bedingten Wahrscheinlichkeit $\mathrm{p}_s(s|t)$ die Bildspalte gefunden werden
  • Die bedingte Wahrscheinlichskeitdichte lautet:
    $\mathrm{p}_s(s|t) = \frac{\mathrm{p}(s, t)}{\mathrm{p}_t(t)} \approx \mathrm{p}_s[x] = \frac{\frac{\mathrm{g}[x, Y]}{A}}{\frac{1}{A}\frac{1}{S}\sum\limits_{x=0}^{S-1} \mathrm{g}[x, Y]} = \frac{\mathrm{g}[x, Y]}{\frac{1}{S}\sum\limits_{x=0}^{S-1} \mathrm{g}[x, Y]} $
  • Die zugehörige Verteilungsfunktion lautet
    $\mathrm{P}_s(s) = \int\limits_{0}^s \mathrm{p}_s(\tilde{s})\,d\tilde{s} \approx \mathrm{P}_s[x] = \frac{1}{S}\sum\limits_{\tilde{x}=0}^x\mathrm{p}_s[\tilde{x}]$
  • Auch diese Verteilungsfunktion kann nicht invertiert werden, da die Funktion nicht nach der gleichverteilten Zufallsvariable $v \in [0, 1]$ aufgelöst werden kann
    $v = \mathrm{P}_s[x] = \frac{1}{S}\sum\limits_{\tilde{x}=0}^x\mathrm{p}_s[\tilde{x}]$
    Daher wird im Shader über $\tilde{x}$ gelaufen bis $v$ erreicht ist. Das zugehörige $x$ ist die gesuchte Bildspalte $X$ für den Abtastpunkt

Beispiel: Sampling einer Environment Map in GLSL

iblsample

Beispiel: Sampling einer Environment Map in GLSL

vec2 sampleEnvmap(sampler2D envmap, sampler2D rowAvg, 
        float totalAvg, vec2 random) {

  ivec2 texSize = textureSize(rowAvg, 0);
  float sumY = 0.0;
  float prevSumY = 0.0;
  float ra = 1.0;
  int y = 0;
  for(y = 0; y < texSize.y; y++) {
    ra = texelFetch(rowAvg, ivec2(0, y), 0).r;
    float pt = ra / totalAvg;
    sumY += pt / float(texSize.y);
    if(sumY >= random.y) {
      break;
    }
    prevSumY = sumY;
  }
  float subPixelY = (random.y - prevSumY) / (sumY - prevSumY);

  ivec2 envSize = textureSize(envmap, 0);
  float sumX = 0.0;
  float prevSumX = 0.0;
  int xx = 0;
  for(xx= 0; xx < envSize.x; xx++) {
    vec3 rgb = pow(texelFetch(envmap, ivec2(xx, y), 0).rgb, vec3(2.2));
    float gray = dot(vec3(0.2989, 0.5866, 0.1145), rgb);
    float ps = gray / ra;
    sumX += ps / float(envSize.x);
    if(sumX >= random.x) {
      break;
    }
    prevSumX = sumX;
  }
  float subPixelX = (random.x - prevSumX) / (sumX - prevSumX);

  return vec2((float(xx) + subPixelX) / float(envSize.x), 
              (float(y) + subPixelY) / float(texSize.y));
}

Beispiel: Bildbasierte Beleuchtung

ibl
  • Beispiel: IBL

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)