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$

Schatten

  • Um spiegelnde oder glänzende Oberfläche zu modellieren reichen die bisher verwendeten lokalen Beleuchtungsmodelle nicht aus
  • Die lokalen Beleuchtungsmodelle approximieren das einfallende Licht mit einer (oder mehreren) Lichtquellen. Sie vernachlässigen jedoch, dass Licht ebenfalls von anderen Oberflächen reflektiert werden kann bevor es auf den gerade betracheten Oberflächenpunkt trifft
  • Für spiegelnden oder glänzenden Oberfläche liefert die lokalen Beleuchtungsmodelle allein keine überzeugenden Ergebnisse, da die reflektieren Objekte nicht sichtbar sind

Planare Schatten

planar_shadow_z
Projektion auf Ebene $z=0$
  • Idee: Projektion des Objekts auf eine planare Ebene
  • Z.B. einfache Parallelprojektion auf die Ebene $z=0$ mit folgender Matrix:
    $\mathtt{T}_{\tiny \mbox{shadow}} = \begin{bmatrix}1 & 0& 0 & 0\\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 &1\end{bmatrix}$
  • Diese Transformation muss im Weltkoordinantensystem angewendet werden, d.h.
    $\underline{\tilde{\mathbf{P}}} = \mathtt{A} \, \underbrace{\mathtt{T}_{\mathrm{\small cam}}^{-1} \, \mathtt{T}_{\tiny \mbox{shadow}} \, \mathtt{T}_{\mathrm{\small obj}}}_{\mathtt{T}_{\mathrm{\small modelview}}} \, \underline{\mathbf{P}}$
  • Projiziertes Objekt zusätzlich zur ursprünglichen Szene mit schwarzer Farbe malen

Jim Blinn (1988): "Me and my (fake) shadow"

fake_shadow
  • Projektion des verdeckenden Objekts auf eine planare Fläche bei gegebener Position einer Punktlichtquelle
  • Projiziertes Objekt zusätzlich zur ursprünglichen Szene mit schwarzer Farbe malen

Jim Blinn (1988): "Me and my (fake) shadow"

fake_shadow_blinn
$x$
$z$
Stützpunkt $\mathbf{P}=(p_x, p_y, p_z)^\top$
projizierter Stützpunkt $\tilde{\mathbf{P}}=(\tilde{p}_x, \tilde{p}_y, \tilde{p}_z)^\top$
Lichtquelle $\mathbf{L}=(l_x, l_y, l_z)^\top$
  • Bei gegebener Position der Lichtquelle $\mathbf{L}=(l_x, l_y, l_z)^\top$ berechnet sich der auf die Ebene $z=0$ projizierter Stützpunkt $\tilde{\mathbf{P}}=(\tilde{p}_x, \tilde{p}_y, \tilde{p}_z)^\top$ aus dem originalen Stützpunkt $\mathbf{P}=(p_x, p_y, p_z)^\top$ mit Hilfe des Strahlensatzes (siehe Abbildung) zu:
    $\frac{\tilde{p}_x - l_x}{l_z} = \frac{p_x - l_x}{l_z - p_z} \Leftrightarrow \tilde{p}_x = \frac{p_x - l_x}{l_z - p_z} l_z+ l_x = \frac{p_x l_z - l_x l_z + l_x l_z - l_x p_z}{l_z - p_z} = \frac{l_z p_x - l_x p_z}{l_z - p_z}$
Reference: James F. Blinn, Me and my (fake) shadow, IEEE Computer Graphics and Applications, Jan 1988, Vol 8, Issue 1 / Jim Blinn's Corner: A Trip Down the Graphics Pipeline, Page 53

Jim Blinn (1988): "Me and my (fake) shadow"

  • Damit gilt:
    $\tilde{p}_x = \frac{l_z p_x - l_x p_z}{l_z - p_z} \quad \quad\tilde{p}_y = \frac{l_z p_y - l_y p_z}{l_z - p_z} \quad \quad\tilde{p}_z = 0$
  • Bei Verwendung von homogene Koordinaten kann diese Abbildungsvorschrift ebenfalls als projektive $4 \times 4$ Matrix geschrieben werden:
    $ \tilde{\underline{\mathbf{P}}} = \begin{pmatrix}\tilde{x}\\ \tilde{y} \\ \tilde{z} \\ \tilde{w} \end{pmatrix}= \underbrace{\begin{bmatrix}l_z & 0& -l_x & 0\\ 0 & l_z & -l_y & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & -1 & l_z\end{bmatrix}}_{\mathtt{T}_{\tiny \mbox{shadow}} } \begin{pmatrix}p_x\\p_y\\p_z\\1\end{pmatrix}$

    $\tilde{\underline{\mathbf{P}}} = \begin{pmatrix}\tilde{x}\\ \tilde{y} \\ \tilde{z} \\ \tilde{w} \end{pmatrix} \in \mathbb{H}^3 \quad \longmapsto \quad \tilde{\mathbf{P}} = \begin{pmatrix} \tilde{p}_x\\ \tilde{p}_y\\ \tilde{p}_z \end{pmatrix} = \begin{pmatrix}\frac{\tilde{x}}{\tilde{w}}\\\frac{\tilde{y}}{\tilde{w}}\\\frac{\tilde{z}}{\tilde{w}} \end{pmatrix} \in \mathbb{R}^3 $

  • Bei Anwendung im globalen Koordinatensystem ergibt sich wieder insgesamt:
    $\underline{\tilde{\mathbf{P}}} = \mathtt{A} \, \mathtt{T}_{\mathrm{\small cam}}^{-1} \, \mathtt{T}_{\tiny \mbox{shadow}} \, \mathtt{T}_{\mathrm{\small obj}}\, \underline{\mathbf{P}}$

Jim Blinn (1988): "Me and my (fake) shadow"

  • Projektion auf $z=0$:
    $ \mathtt{T}_{\tiny \mbox{shadow}} = \begin{bmatrix}l_z & 0& -l_x & 0\\ 0 & l_z & -l_y & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & -1 & l_z\end{bmatrix}$
  • Projektion auf $y=0$:
    $ \mathtt{T}_{\tiny \mbox{shadow}} = \begin{bmatrix}l_y & -l_x &0& 0\\ 0 & 0 & 0 & 0 \\ 0 & -l_z & l_y & 0 \\ 0 & -1 & 0 & l_y\end{bmatrix}$
  • Projektion auf $x=0$:
    $ \mathtt{T}_{\tiny \mbox{shadow}} = \begin{bmatrix}0 & 0 &0& 0\\ -l_y & l_x & 0 & 0 \\ -l_z & 0 & l_x & 0 \\ -1 & 0 & 0 & l_x\end{bmatrix}$

Beispiel: Planarer (projizierter) Schatten

fake_shadow

Planarer (projizierter) Schatten mit ambientem Anteil

  • Eigentlich sollte der ambiente Anteil des Beleuchtungsmodells im Schatten sichtbar bleiben
  • Dazu muss die Szene jedoch zweifach gerendert werden
    • 1. Durchgang: Diffuser und spekularer Anteil inklusive Schatten
    • 2. Durchgang: Nur ambienter Anteil ohne Schatten
fake_shadow_ambient_two_pass
Diffuser und spekularer Anteil
Ambienter Anteil
Ergebnis
+
=

Planarer (projizierter) Schatten mit ambientem Anteil

fake_shadow_ambient_two_pass_alt
Ergebnis
Projektion in Textur
  • Alternativ kann die Projektion des verdeckenden Objekts auch in eine Textur gerendert werden
  • Diese Textur kann dann im Shader, der die Ebene zeichnet, verwendet werden, um zu entscheiden, ob nur der ambiente Anteil oder das vollständigem Beleuchtungsmodell ausgewertet wird

Planare Schatten

  • Vorteile
    • Leichte Implementierung
    • Schnelle Berechnung
    • Weitere Beschleunigung möglich, wenn das verdeckenden Objekt durch ein Modell mit weniger Details approximiert wird
  • Nachteile
    • Nur planare Empfängerflächen
    • Keine Selbstverschattung

Cubemap

  • Eine Möglichkeit zur Speicherung alle möglichen einfallenden Stahlen $\mathbf{\omega}_i$ ist die Verwendung einer Cubemap (oder einer Spheremap)
  • Dazu wird ein Würfel um den gewählten repräsentativen Punkt gelegt und die einfallende Leuchtdichte abgelegt
  • Zur Berechung des Beitrags der Reflexion, wird die Reflexionsrichtung mittels der Oberflächennormalen des betrachteten Punkts berechnet und diese Richtung in der Cubemap nachgeschlagen
cubemap

Environment-Lighting

  • Idee: Bilder einer realen Umgebung können verwendet werden, um virtuelle Objekte zu beleuchten
  • Dazu werden viele einzelne Aufnahmen einer rotierenden Kamera verwendet, um die Cubemap bzw. Spheremap der Umgebung zu erstellen
cubemap

Spheremap der realen Umgebung

Cubemap der realen Umgebung

Erzeugung einer Cubemap in OpenGL

  • Eine Cubemap ist eine spezielle Textur, die mit dem Target GL_TEXTURE_CUBE_MAP gekennzeichnet wird:
    GLuint textureID;
    glGenTextures( 1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
  • Die Cubemap besteht aus sechs 2D Bildern (für jede Seite des Würfels eins), wobei die Bilddaten folgendermaßen übergeben werden:
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, ..., imgData1);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, ..., imgData2);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, ..., imgData3);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, ..., imgData4);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, ..., imgData5);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, ..., imgData6);

Erzeugung einer Cubemap in OpenGL

cubemap_RT.png
GL_TEXTURE_CUBE_MAP_POSITIVE_X
cubemap_LF.png
GL_TEXTURE_CUBE_MAP_NEGATIVE_X
cubemap_UP.png
GL_TEXTURE_CUBE_MAP_POSITIVE_Y
cubemap_DN.png
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
cubemap_BK.png
GL_TEXTURE_CUBE_MAP_POSITIVE_Z
cubemap_FR.png
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z

Beispiel: Environment-Lighting mittels Cubemaps

opengl_envlight

Beispiel: Environment-Lighting mittels Cubemaps

Vertex Shader:
#version 140
in vec3 inputPosition;
in vec2 inputTexCoord;
in vec3 inputNormal;
uniform mat4 projection, view, modelTrans, normalMat;
out vec3 normalInterp;
out vec3 vertPos;

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

Beispiel: Environment-Lighting mittels Cubemaps

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

out vec4 outputColor;

uniform samplerCube myTexture;
uniform int mode;
uniform vec3 eyePos;

const vec3 baseColor = vec3(0.4, 0.4, 0.4);

void main() {
  vec3 normal = normalize(normalInterp);
  vec3 diffuseColor = vec3(textureLod(myTexture, normal, 5));
  vec3 viewDir = vertPos - eyePos;
  vec3 r = reflect(viewDir, normal);
  // also try the following to generate refraction
  // vec3 r = refract(viewDir, normal,0.95);
  vec3 specColor = vec3(texture(myTexture,normalize(r)));

  float diffuseMix = 0.7;
  float specMix = 0.5;

  // no diffuse, no spec
  if(mode == 2) {
    diffuseMix = 0.0;
    specMix = 0.0;
  }

  // only diffuse
  if(mode == 3) {
    diffuseMix = 1.0;
    specMix = 0.0;
  }

  // only specular
  if(mode == 4) {
    diffuseMix = 0.0;
    specMix = 1.0;
  }

  vec3 color = mix(baseColor,diffuseColor*baseColor,diffuseMix);
  color = mix(color, specColor + color, specMix);

  outputColor = vec4(color, 1.0);
}

Dynamische Erzeugung einer Cubemap

  • Eine Cubemap der Umgebung kann auch dynamisch erzeugt werden, so dass z.B. Reflexionen von bewegten Objekten richtig dargestellt werden
  • Dazu wird die Szene sechs mal gerendert (jeweils einmal für jede Seite des Würfels) und die Kameraparameter für jeden Renderdurchgang entsprechend gesetzt (Kamera mit Öffnungswinkel von 90 Grad blickt in +X, -X, +Y, -Y, +Z und -Z-Richtung)
dyncubemap

Beispiel: Dynamische Cubemaps

opengl_dynamiccubemap

Gibt es Fragen?

questions

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


Weitere Vorlesungsfolien