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$

Licht

  • Licht ist eine gequantelte, elektromagnetische Welle
  • Der sichtbarer Bereich liegt zwischen 380 bis 770nm
  • Die Farbe des sichtbaren Lichtes entspricht seiner Wellenlänge
  • Lichtquellen senden häufig ein breites Spektrum aus. Durch die Überlagerung vieler Frequenzen erscheint das Licht weiß (z.B. Tageslicht)
light_wavelength

Lichtwahrnehmung durch das menschliche Auge

lightpaths
  • Licht wird von eine Lichtquelle emittiert
  • Einige Lichtstahlen treffen evt. direkt ins Auge andere werden zunächst an einer Objektoberfläche reflektiert
  • Bei der Reflektion 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
      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

Farbräume

rgb_add
RGB-Farbmodell
  • Ein Farbraum umfasst alle Farben, die innerhalb des Farbmodells darstellbar sind
  • In dieser Vorlesung wird auschießlich der additive RGB-Farbraum (Rot, Grün, Blau) verwendet
  • Es gibt aber auch zahlreiche andere Formate, wie z.B.

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, dividiert durch $r^2$:

    $\Omega = \int\limits_{\mathbf{\unicode[Times]{x3C9}}}d\mathbf{\unicode[Times]{x3C9}} = \frac{S}{r^2}$

  • Obwohl der Raumwinkel eine dimensionslose Größe ist, wird er zur Verdeutlichung in der Einheit "Steradiant" $\mathrm{sr}$ angegeben
  • 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$
  • Zwischen dem differentiellen Raumwinkel $d\mathbf{\unicode[Times]{x3C9}}$ und den Polarwinkeln $\theta$ und $\phi$ besteht folgender Zusammenhang:

    $\Omega = \int\limits_{\mathbf{\unicode[Times]{x3C9}}}d\mathbf{\unicode[Times]{x3C9}} = \int\limits_{\mathbf{\unicode[Times]{x3C9}}}d\theta(\sin \theta \, d\phi)= \int\limits_{\mathbf{\unicode[Times]{x3C9}}}\sin \theta \, d\theta \, d\phi$

Rendering-Gleichung Grundlagen: Lichtstrom

luminous_flux
  • Lichtstrom $\Phi_v$ (luminous flux)
  • Lichtstrom = Lichtmenge 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$: Plancksche Wirkungsquantum
      $c$: Lichtgeschwindigkeit
      $λ$: Wellenlänge
    • Lichtstrom = Summe der Photonen-Energien, die pro Zeitraum $\Delta t$ emittiert werden
  • Einheit Lumen: $[\mathrm{lm}]$. Beispiele:
    • Glühlampe: $1000\,\mathrm{lm}$
    • Leuchtstofflampe: $2000\,\mathrm{lm}$
    • Beamer: $2500\,\mathrm{lm}$

Rendering-Gleichung Grundlagen: Lichtstrom

luminous_intensity
  • Lichtstärke $I_v$ (luminous intensity)
  • Lichtstärke = Lichtstrom pro Raumwinkel
    $\Phi = \frac{d\Phi}{d\omega} \approx \frac{\Delta \Phi}{\Delta \omega}$
  • Lichtstärke = Summe der Photonen-Energien, die pro Zeit und Raumwinkel emittiert werden
  • Einheit: Candela $[\mathrm{cd}]$
  • Wird z.B. benötigt, wenn die Lichtquelle nicht in alle Richtung gleich stark abstrahlt

Rendering-Gleichung Grundlagen: Beleuchtungsstärke

illuminance
  • Beleuchtungsstärke $E_v$ (illuminance) $[\mathrm{lm}/\mathrm{m}^2]$
  • Beleuchtungsstärke = Lichtstrom pro Flächenelement

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

  • Der Lichtstrom kommt dabei aus allen Richtungen der Hemisphäre über der Fläche
  • Einfache Anschauung: einfallende Photonen-Energien pro Zeit pro Flächenelement

Rendering-Gleichung Grundlagen: Leuchtdichte

luminance
  • Leuchtdichte $L_{v}$ (luminance) $[\mathrm{cd}/\mathrm{m}^2]$
  • Leuchtdichte = Lichtstrom pro Raumwinkel und sichtbarer Fläche

    $L = \frac{d^2\Phi}{d\mathbf{\unicode[Times]{x3C9}}\, \cos(\theta) \,dA} \approx \frac{\Delta \Phi}{\Delta \mathbf{\unicode[Times]{x3C9}}\, \cos(\theta) \,\Delta A}$

  • Die aus Richtung $\theta$ gesehene Fläche erscheint um den Faktor $\cos(\theta)$ verkürzt
  • Anwendung:
    • Entspricht der beobachteten Helligkeit
    • Lichtstrom in Richtung Auge
    shorter
    $\theta$
    $\theta$
    $\Delta A$
    $\cos(\theta) \,dA$
  • Einfache Anschauung: Photonen-Energien pro Zeit, Raumwinkel und sichtbarem Flächenelement

Rendering-Gleichung (rendering equation)

  • Die Rendering-Gleichung berechnet die reflektierte Leuchtdichte $L_o(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o)$ im Flächenpunkt $x$ in Richtung $\mathbf{\unicode[Times]{x3C9}}_o$ durch Integration über die Anteile aller eingehenden Leuchtdichten $L_i(x, \mathbf{\unicode[Times]{x3C9}}_i)$ der Hemisphäre über der Oberfläche

    $L_o(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o) = L_e(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_0) + \int\limits_\Omega f_r(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_i) \underbrace{L_i(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_i) \cos(\theta)d\mathbf{\unicode[Times]{x3C9}}}_{dE_i}$

render_eqn
$\mathbf{x}$
$\theta$
$L_i(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_i)$
$L_o(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o)$
$\Omega$
$\mathbf{n}$
  • $L_e(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_0)$ ist die von der Fläche selbst emittierte Leuchtdichte
  • $\Omega$ ist Gesamtheit aller Winkel der Hemisphäre über der Oberfläche
  • $f_r(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_i)$ ist die sogenannte "Bidirectional Reflection Distribution Function" (BRDF)

BRDF (bidirectional reflection distribution function)

  • Die BRDF beschreibt den winkelabhängigen spektralen Reflexionsfaktor einer Oberfläche durch das Verhältnis von reflektierter Leuchtdichte $dL_o$ zur einfallenden Beleuchtungsstärke $dE_i$

    $f_r(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_i) = \frac{ dL_o(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_i)}{ dE_i(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_i)} $

  • Ändert sich die BRDF $f_r(\mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_i)$ nicht mit $\mathbf{x}$, ist sie eine 4-dimensionale Funktion
  • Durch die Angabe dieser Funktion ist die Reflektionseigenschaft einer Fläche sehr genau beschrieben

BRDF (bidirectional reflection distribution function)

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

Vereinfachung der Rendering-Gleichung

  • Die exakte Auswertung der Rendering-Gleichung ist sehr rechenaufwendig
  • Dies liegt vor allem daran, dass Lichtaustausch zwischen Oberflächen berücksichtigt wird
  • Sehr viel einfacher wird die Gleichung, wenn Licht nur von einer geringen Anzahl von $j$ Lichtquellen mit der Lichtstärke $I_j$ ausgeht und deren Verdeckungen (Schatten) sowie der Lichtaustausch zwischen Oberflächen vernachlässigt wird

$L_o(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o) = \sum \limits_i f_r(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_{ij}) \underbrace{I_j(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_{ij}) \frac{\cos(\theta_{ij})}{r_{xj}^2} }_{E_j}$

Phong BRDF

phong_angles
$\mathbf{x}$
$\theta$
$\alpha$
$\mathbf{\unicode[Times]{x3C9}}_o$
$\mathbf{\unicode[Times]{x3C9}}_i$
$\mathbf{\unicode[Times]{x3C9}}_r$
$\mathbf{n}$
  • Einfaches nicht-physikalisches BRDF Modell [Phong 1975]
  • Überlagerung von diffuser + spekularer Reflexion
  • Die spekulare Reflexion wird durch einen cos-Lobe approximiert, der Exponent $n$ kontrolliert die Rauheit der Oberfläche
    $f_r(\mathbf{x}, \mathbf{\unicode[Times]{x3C9}}_o, \mathbf{\unicode[Times]{x3C9}}_{ij}) = \rho_d \frac{1}{\pi} + \rho_s \cos^n \alpha$
    mit $\cos \alpha = \mathbf{\unicode[Times]{x3C9}}_o^\top \mathbf{\unicode[Times]{x3C9}}_r$
  • Die Relektionsrichtung $\mathbf{\unicode[Times]{x3C9}}_r$ berechnet sich aus der Oberflächennormalen $\mathbf{n}$ und der Lichtrichtung $\mathbf{\unicode[Times]{x3C9}}_i$ durch:
    reflect_angles
    $\mathbf{\unicode[Times]{x3C9}}_i$
    $\mathbf{\unicode[Times]{x3C9}}_r$
    $\mathbf{n}$
    $\mathbf{\unicode[Times]{x3C9}}_r = 2 \,(-\mathbf{\unicode[Times]{x3C9}}_i^\top \mathbf{n}) \, \mathbf{n} + \mathbf{\unicode[Times]{x3C9}}_i$
  • In GLSL steht zur Berechnung der Reflektionsrichtung $\mathbf{\unicode[Times]{x3C9}}_r$ die Funktion reflect zur Verfügung

Beispiel: Phong BRDF per Vertex mit GLSL

opengl_opengl_shaderphongbrdf

Beispiel: Phong BRDF per Vertex mit GLSL

Vertex Shader:
#version 140
in vec3 inputPosition;
in vec2 inputTexCoord;
in vec3 inputNormal;

uniform mat4 projection, modelview, normalMat;
uniform int mode;

out vec4 forFragColor;

const vec3 lightPos = vec3(1.0, 1.0, 1.0);
const vec3 diffuseColor = vec3(0.5, 0.0, 0.0);
const vec3 specColor = vec3(1.0, 1.0, 1.0);

void main(){
    gl_Position = projection * modelview * 
                  vec4(inputPosition, 1.0);

    // all following gemetric computations are performed in the
    // camera coordinate system (aka eye coordinates)
    vec3 normal = vec3(normalMat * vec4(inputNormal, 0.0));
    vec4 vertPos4 = modelview * vec4(inputPosition, 1.0);
    vec3 vertPos = vec3(vertPos4) / vertPos4.w;
    vec3 lightDir = normalize(lightPos - vertPos);
    vec3 reflectDir = reflect(-lightDir, normal);
    vec3 viewDir = normalize(-vertPos);

    float lambertian = max(dot(lightDir, normal), 0.0);
    float specular = 0.0;

    if(lambertian > 0.0) {
       float specAngle = max(dot(reflectDir, viewDir), 0.0);
       specular = pow(specAngle, 4.0);

       // the exponent controls the shininess (try mode 2)
       if(mode == 2)  specular = pow(specAngle, 16.0);

       // according to the rendering equation we would need 
       // to multiply with the the "lambertian", but this has
       // only little visual effect
       if(mode == 3) specular *= lambertian;

       // switch to mode 4 to turn off the specular component
       if(mode == 4) specular *= 0.0;
    }
    
    forFragColor = vec4(lambertian*diffuseColor + 
                        specular*specColor, 1.0);
}

Beispiel: Phong BRDF per Vertex mit GLSL

Fragment Shader:
#version 140

in vec4 forFragColor;
out vec4 outputColor;

void main() {
    outputColor = forFragColor;
}

Beispiel: Phong BRDF mit GLSL

  • Bei der gezeigten Implementierung wird im Vertex-Shader ein Farbwert berechnet, der im Rasterisierer interpoliert wird und im Fragment-Shader lediglich weitergereicht wird
  • Dies ist zwar sehr effizient, produziert jedoch bei einem 3D-Modell mit wenigen Stützpunkten visuelle Artefakte, die besonders in der spekularen Komponente sichtbar werden
  • Lösung: Berechnung der Position und Normalen im Vertex-Shader und Berechnung des Farbwerts im Fragment-Shader
  • Achtung: Die durch den Rasterizierer interpolierte Normale muss im Fragment-Shader wieder auf die Länge 1 normiert werden

Beispiel: Phong BRDF per Fragment mit GLSL

opengl_opengl_shaderphongbrdfforfrag

Beispiel: Phong BRDF per Fragment mit GLSL

Vertex Shader:
#version 140
in vec3 inputPosition;
in vec2 inputTexCoord;
in vec3 inputNormal;

uniform mat4 projection, modelview, normalMat;

out vec3 normalInterp;
out vec3 vertPos;

void main(){
    gl_Position = projection * modelview * vec4(inputPosition, 1.0);
    vec4 vertPos4 = modelview * vec4(inputPosition, 1.0);
    vertPos = vec3(vertPos4) / vertPos4.w;
    normalInterp = vec3(normalMat * vec4(inputNormal, 0.0));
}

Beispiel: Phong BRDF per Fragment mit GLSL

Fragment Shader:
#version 140
in vec3 normalInterp;
in vec3 vertPos;

out vec4 outputColor;

uniform int mode;

const vec3 lightPos = vec3(1.0,1.0,1.0);
const vec3 diffuseColor = vec3(0.5, 0.0, 0.0);
const vec3 specColor = vec3(1.0, 1.0, 1.0);

void main() {

    vec3 normal = normalize(normalInterp);
    vec3 lightDir = normalize(lightPos - vertPos);

    float lambertian = max(dot(lightDir,normal), 0.0);
    float specular = 0.0;

    if(lambertian > 0.0) {

       vec3 reflectDir = reflect(-lightDir, normal);
       vec3 viewDir = normalize(-vertPos);

       float specAngle = max(dot(reflectDir, viewDir), 0.0);
       specular = pow(specAngle, 4.0);

       // the exponent controls the shininess (try mode 2)
       if(mode == 2)  specular = pow(specAngle, 16.0);

       // according to the rendering equation we would need 
       // to multiply with the the "lambertian", but this has
       // only little visual effect
       if(mode == 3) specular *= lambertian;

       // switch to mode 4 to turn off the specular component
       if(mode == 4) specular *= 0.0;

    }
    outputColor = vec4( lambertian*diffuseColor +
                        specular*specColor, 1.0);
}

Lokale Beleuchtungsmodelle

  • Lokale Beleuchtungsmodelle berechnen die in einem Punkt der Objektoberfläche wahrnehmbare Leuchtdichte
  • Die Leuchtdichte (bzw. der Farbwert) ergibt sich durch Auswerten des einfallenden Lichts aus den Lichtquellen und dem Reflexionsverhalten der Objektflächen
  • Ziel: Mit minimalem Rechenaufwand möglichst realitätsnahe Renderings erzeugen
  • Dazu wird die Approximation der physikalische Gesetzmäßigkeiten in Kauf genommen
  • Sekundäre Effekte, wie der Strahlungsaustausch benachbarter Flächen, werden nicht berücksichtigt

Lokales Beleuchtungsmodell von Phong

  • Für $J$ Lichtquellen erhält man nach dem Phong‘schen Beleuchtungsmodell:
    $L_{\mathrm{phong}} = L_{\mathrm{amb}} + \sum \limits_{j=1}^J L_{\mathrm{diff}\, j} + L_{\mathrm{spec}\, j}$
    phong
  • Die einzelnen Terme werden im Folgenden erläutert

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 Leuchtdichte $L_a$ approximiert
  • Dabei ist $L_a$ diejenige Leuchtdichte, die das ambiente Licht auf ideal weißem Papier erzeugen würde
  • Abhängig vom Reflektionsgrad $\rho_a \in [0;1]$ der aktuellen betrachteten Oberfläche ergibt sich:
    $L_{\mathrm{amb}} = \rho_a L_a$

Diffuse Komponente

phong_angles
$\mathbf{x}$
$\theta$
$\alpha$
$\mathbf{\unicode[Times]{x3C9}}_o$
$\mathbf{\unicode[Times]{x3C9}}_i$
$\mathbf{\unicode[Times]{x3C9}}_r$
$\mathbf{n}$
  • Lambert‘sches Cosinusgesetz
  • Resultierende Leuchtdichte hängt ab vom Einfallswinkel $\theta$ (der Winkel zwischen Flächennormalen und Vektor zur Lichtquelle):
    $L_{\mathrm{diff}} = \rho_d L_d \cos \theta$
  • Dabei ist $L_d$ die bei senkrechtem Einfall auf ideal weißem Papier bewirkte Leuchtdichte und $\rho_d \in [0;1]$ der Reflektionsgrad der Oberfläche

Spekulare Komponente

  • Gerichtet diffuse Reflexion (spekulare Reflexion)
  • In der Natur gibt es nur selten Materialien, die ideale spiegelnd oder diffus sind
  • Typischerweise gibt es ein deutliches Maximum in Richtung der ideal spiegelnden Reflexion, wobei dieser Anteil keiner wird, je weiter der Winkel von der idealen Reflektionsrichtung entfernt ist
  • Daher wird im Phong Beleuchtungsmodell eine Aufteilung in einen blickrichtungsunabhängigen, diffusen Anteil (Index $d$) und einen blickrichtungsabhängigen Anteil (Index $s$) vorgenommen
glossyTodiffuse
ideal spiegelnd
(perfekt glatt)
glänzend
(etwas rau)
weniger glänzend
(rauer)
diffus
(sehr rau)

Spekulare Komponente

phong_angles
$\mathbf{x}$
$\theta$
$\alpha$
$\mathbf{\unicode[Times]{x3C9}}_o$
$\mathbf{\unicode[Times]{x3C9}}_i$
$\mathbf{\unicode[Times]{x3C9}}_r$
$\mathbf{n}$
  • Von Phong vorgeschlagenes empirisches Modell enthält zusätzliche spekulare Leuchtdichte
  • Diese ist abhängig vom Winkel $\alpha$ zwischen reflektiertem Strahl $\mathbf{\unicode[Times]{x3C9}}_r$ und Richtung zum Beobachter $\mathbf{\unicode[Times]{x3C9}}_o$:

    $L_{\mathrm{spec}} = \rho_s L_s \cos^n \alpha$

  • Je größer der Exponent $n$, desto stärker wird das reflektierte Licht gebündelt (weniger raue Oberfläche)

Beispiel: Das Beleuchtungsmodell von Phong mit GLSL

opengl_shaderphongfull1 opengl_shaderphongfull2 opengl_shaderphongfull3 opengl_shaderphongfull4

Beispiel: Das Beleuchtungsmodell von Phong mit GLSL

Fragment Shader:
#version 140
in vec3 normalInterp;
in vec3 vertPos;

out vec4 outputColor;

uniform int mode;

const vec3 lightPos = vec3(1.0,1.0,1.0);
const vec3 ambientColor = vec3(0.1, 0.0, 0.0);
const vec3 diffuseColor = vec3(0.5, 0.0, 0.0);
const vec3 specColor = vec3(1.0, 1.0, 1.0);

void main() {
    vec3 normal = normalize(normalInterp);
    vec3 lightDir = normalize(lightPos - vertPos);
    vec3 reflectDir = reflect(-lightDir, normal);
    vec3 viewDir = normalize(-vertPos);

    float lambertian = max(dot(lightDir,normal), 0.0);
    float specular = 0.0;

    if(lambertian > 0.0) {
       float specAngle = max(dot(reflectDir, viewDir), 0.0);
       specular = pow(specAngle, 4.0);
    }
    outputColor = vec4(ambientColor +
                      lambertian*diffuseColor +
                      specular*specColor, 1.0);

    // only ambient
    if(mode == 2) outputColor = vec4(ambientColor, 1.0);
    // only diffuse
    if(mode == 3) outputColor = vec4(lambertian*diffuseColor,1.0);
    // only specular
    if(mode == 4) outputColor = vec4(specular*specColor, 1.0);

}

Blinn-Phong Beleuchtungsmodell

blinn_angles
$\mathbf{x}$
$\theta$
$\mathbf{\unicode[Times]{x3C9}}_o$
$\mathbf{\unicode[Times]{x3C9}}_i$
$\mathbf{h}$
$\mathbf{n}$
  • Wurde von Jim Blinn auf der SIGGRAPH 1977 veröffentlicht
  • Schneller, da die Berechnung des reflektierten Strahls vermieden wird
  • Näher an der Physik als das originale Phong Modell, da höherer spekularer Anteil für flache Einstrahl/Betrachtungswinkel
  • Statt des reflektierten Strahls wird die Winkelhalbierende $\mathbf{h}$ (halfway-vector) verwendet:
    $\mathbf{h} = \frac{(-\mathbf{\unicode[Times]{x3C9}}_i) \,+\, \mathbf{\unicode[Times]{x3C9}}_o}{|(-\mathbf{\unicode[Times]{x3C9}}_i)\,+\, \mathbf{\unicode[Times]{x3C9}}_o|}$
    $L_{\mathrm{spec}} = \rho_s L_s (\mathbf{h}^\top \mathbf{n})^n $
  • Der Exponent $n$ bestimmt wieder die Bündelung des Lichts (größes $n$ für glattere Oberfläche)

Beispiel: Blinn-Phong Beleuchtungsmodell mit GLSL

opengl_shaderblinnphong
Blinn-Phong (mode = 1)
opengl_shaderblinn_vs_phong
Phong (mode = 2)

Beispiel: Blinn-Phong Beleuchtungsmodell mit GLSL

Fragment Shader:
#version 140
in vec3 normalInterp;
in vec3 vertPos;

out vec4 outputColor;

uniform int mode;
uniform vec3 lightPos;

const vec3 ambientColor = vec3(0.1, 0.0, 0.0);
const vec3 diffuseColor = vec3(0.5, 0.0, 0.0);
const vec3 specColor = vec3(1.0, 1.0, 1.0);

void main() {

    vec3 normal = normalize(normalInterp);
    vec3 lightDir = normalize(lightPos - vertPos);

    float lambertian = max(dot(lightDir,normal), 0.0);
    float specular = 0.0;

    if(lambertian > 0.0) {

       vec3 viewDir = normalize(-vertPos);

       // this is blinn phong
       vec3 halfDir = normalize(lightDir + viewDir);
       float specAngle = max(dot(halfDir, normal), 0.0);
       specular = pow(specAngle, 16.0);
       
       // this is phong (for comparison)
       if(mode == 2) {
         vec3 reflectDir = reflect(-lightDir, normal);
         specAngle = max(dot(reflectDir, viewDir), 0.0);
         // note that the exponent is different here
         specular = pow(specAngle, 4.0);
       }
    }

    outputColor = vec4(ambientColor +
                       lambertian * diffuseColor +
                       specular * specColor, 1.0);
}

Lichtquellen

lighttypes_directional
Punktlichtquelle
lighttypes_spot
Strahler
lighttypes_directional
Richtungslichtquelle
lighttypes_env
Umgebungsbeleuchtung

Punktlichtquelle

pointlight
  • In alle Richtungen gleichmäßig sendend (isotrop)
  • Typische Parameter
    • 3D Position
    • Lichtstärke $I(\lambda)$ in Candela
  • im Abstand $R$ erzielt diese Lichtquelle eine Beleuchtungsstärke
    $E = \frac{I}{R^2} \cos \theta$
    dabei ist $\theta$ der Einfallswinkel (zwischen Flächennormale und Lichteinfallsrichtung)
pointlightmax

Beispiel: Blinn-Phong Shading mit einer Punktlichtquelle

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

Strahler

spot
  • Lichtausbreitung auf bestimmten Raumwinkel (Lichtkegel) beschränkt
  • Abfall der Lichtstä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}$
  • Lichtstärke:
    $I = I_0 \cos^n \beta$
  • Typische Parameter:
    • 3D Position $\mathbf{p}$
    • Hauptausstrahlrichtung $\mathbf{d}$
    • Lichtstärke in Hauptausstrahlrichtung $I_0(\lambda)$
    • Maximaler Winkel $\beta_{\tiny \mbox{ max}}$
    • Bündelungs-Exponent $n$

Beispiel: Blinn-Phong Shading mit mehreren Strahlern

Beispiel: Blinn-Phong Shading mit mehreren Strahlern

Fragment Shader:
#version 140
in vec3 normalInterp;
in vec3 vertPos;

out vec4 outputColor;

uniform int mode;

struct LightSource {
  vec3 position;
  vec3 color;
  float constantAttenuation;
  float linearAttenuation;
  float quadraticAttenuation;
  float spotCutoff, spotExponent;
  vec3 spotDirection;
};

const int maxNumberOfLights = 3;
uniform int numberOfLights;
uniform LightSource lights[maxNumberOfLights];

const vec3 ambientColor = vec3(0.0, 0.0, 0.0);
const vec3 diffuseColor = vec3(0.5, 0.0, 0.0);
const vec3 specColor = vec3(1.0, 1.0, 1.0);

void main() {

    vec3 normal = normalize(normalInterp);
    vec3 contrib = ambientColor;

    for(int i=0; i < maxNumberOfLights; i++) {

      vec3 lightVec = (lights[i].position - vertPos);
      float d = length(lightVec); // distance to light

      vec3 lightDir = normalize(lightVec);

      // attenuation due to spot
      float attenuation = dot(-lightDir,lights[i].spotDirection);
      if(attenuation < lights[i].spotCutoff) {
         attenuation = 0.0;
      }else{
         attenuation = pow(attenuation, lights[i].spotExponent);
      }

      // atttenuation due to distance fall off
      attenuation *= 1.0 / (lights[i].constantAttenuation +
                            lights[i].linearAttenuation * d +
                            lights[i].quadraticAttenuation *d*d);

      float lambertian = max(dot(lightDir,normal), 0.0);
      float specular = 0.0;

      if(lambertian > 0.0) {

          vec3 viewDir = normalize(-vertPos);

          // this is blinn phong
          vec3 halfDir = normalize(lightDir + viewDir);
          float specAngle = max(dot(halfDir, normal), 0.0);
          specular = pow(specAngle, 16.0);
       }
       vec3 lightContrib = lambertian * diffuseColor;
       lightContrib += specular * specColor;
       lightContrib *= lights[i].color;
       lightContrib *= attenuation;

       contrib += lightContrib;
    }

    outputColor = vec4(contrib, 1.0);
}

Richtungslichtquelle

directional
$\mathbf{d}$
  • Mit Richtungslichtquellen können weit entfernte Lichtquellen (z.B. die Sonne) simuliert werden
  • Parameter:
    • Lichtausbreitungsrichtung: $\mathbf{d}$
    • Bestrahlungsstärke: $E_{v}(\lambda)$
  • Alle Lichtstrahlen treffen mit derselben Richtung $\mathbf{d}$ in der Szene auf

Umgebungsbeleuchtung

env
  • Umgebungsbeleuchtung berücksichtigt Licht aus allen Richtungen
  • Oft wird dabei die emittierte Leuchtdichte $L_i$ der Umgebung durch ein sphärische Umgebungsbild angegeben (Image-based Lighting)
  • Selbst ohne Verdeckungen zu Berücksichtigen müssten laut Rendering-Gleichung für ein Oberflächenpunkt alle einfallenden Leuchtdichten $L_i$ mit der BRDF multipliziert werden. Dies ist wäre aber für eine Echtzeitberechnung zu aufwendig.
  • Bei gegegebener parametrisierter BRDF, z.B. Phong BRDF, können die Integrale jedoch vorberechnet werden und parameterisiert abgespeichter werden (Pre-Filtered Environment Map)
  • So könnte z.B. bei der Phong-BRDF, der diffuse Anteil durch die Normalenrichtung parametrisiert und der spekulare Anteil durch die Reflektionsrichtung parametrisiert in einem sphärischen Umgebungsbild abgelegt werden
  • Häufig werden dabei die Ergebnisse für verschiedene Phong-Glanz-Exponenten $n$ in den Mipmap-Leveln einer Textur gespeichert

Beispiel: Beleuchtung mit einer Spherical Environment Map

  • In diesem Beispiel wird eine sehr einfache Variante einer Pre-Filtered Environment Map verwendet
  • Diffuse und spekulare Spheremap ergeben sich durch Tiefpassfilterung/Skalierung eines 360 Grad Photos
  • Für die diffuse Reflektion muss ein größerer Winkelbereich integriert werden, daher wird für die diffuse Spheremap eine stärkere Tiefpassfilterung angewendet
opengl_shaderblinnphong
Diffuse Spheremap
opengl_shaderblinnphong
Spekulare Spheremap
Bildquelle: Pixabay user MyBranding, CC0, public domain

Beispiel: Beleuchtung mit einer Spherical Environment Map

imagebasedlighting

Gibt es Fragen?

questions

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


Weitere Vorlesungsfolien