Probeklausur 3 - Visual Computing

Übungsklausur (mock exam) zum Kurs "Visual Computing" (HS Darmstadt). Sie ist an Struktur, Themenmix, Schwierigkeit und Punktgewichtung der Original-Klausur WS 2025/2026 angelehnt, enthält aber ausschliesslich neue Aufgaben (kein Überschneiden mit Probeklausur 1 oder 2). Alle Lösungen sind ausklappbar mit vollem Rechenweg, Begründung und Kapitelbezug. Zum Vergleich: Klausur WS2025 (Lösungen) und Probeklausur 1.

Hinweise zur Klausur: Dauer 90 Minuten. Hilfsmittel: ein nicht-programmierbarer Taschenrechner und ein beschriebenes DIN-A4-Blatt. Insgesamt 100 Punkte.


1. Aufgabe: RGB und HSV Farbmodelle (13 Punkte)

Teil a (7 P): Rechnen Sie die folgenden drei Farben aus dem RGB-Modell (Wertebereich [0,1][0,1]) in das HSV-Modell um. Geben Sie jeweils HH (Hue), SS (Saturation) und VV (Value) an und zeigen Sie den Rechenweg. Verwenden Sie fuer den Farbton die allgemeine Hue-Formel (nicht nur die Standardwinkel).

Farbe(R,G,B)(R, G, B)
Farbe 1(1,0, 0,5, 0,0)(1{,}0,\ 0{,}5,\ 0{,}0)
Farbe 2(0,2, 0,2, 0,2)(0{,}2,\ 0{,}2,\ 0{,}2)
Farbe 3(0,0, 0,6, 0,3)(0{,}0,\ 0{,}6,\ 0{,}3)

Teil b (6 P): Rechnen Sie umgekehrt die folgenden zwei Farben aus dem HSV-Modell zurück in RGB (Wertebereich [0,1][0,1]). Zeigen Sie den Rechenweg mit den Hilfsgrössen CC (Chroma), XX und mm.

Farbe(H,S,V)(H, S, V)
Farbe 4(240, 1,0, 0,5)(240^\circ,\ 1{,}0,\ 0{,}5)
Farbe 5(30, 1,0, 1,0)(30^\circ,\ 1{,}0,\ 1{,}0)
Lösung anzeigen

Teil a - Umrechnung RGB nach HSV. Formeln (Kapitel 10): V=max(r,g,b)V = \max(r,g,b),   Δ=maxmin\;\Delta = \max - \min,   S=Δmax\;S = \dfrac{\Delta}{\max} (bzw. 00 falls max=0\max = 0), und der Farbton

H=60{gbΔmod6falls max=rbrΔ+2falls max=grgΔ+4falls max=bH = 60^\circ \cdot \begin{cases} \dfrac{g-b}{\Delta} \bmod 6 & \text{falls } \max = r \\[4pt] \dfrac{b-r}{\Delta} + 2 & \text{falls } \max = g \\[4pt] \dfrac{r-g}{\Delta} + 4 & \text{falls } \max = b \end{cases}

Farbe 1 (1,0, 0,5, 0,0)(1{,}0,\ 0{,}5,\ 0{,}0) - Orange:

  • V=max=1,0V = \max = 1{,}0,   min=0,0\;\min = 0{,}0,   Δ=1,0\;\Delta = 1{,}0
  • S=Δmax=1,01,0=1,0S = \dfrac{\Delta}{\max} = \dfrac{1{,}0}{1{,}0} = 1{,}0
  • max=r\max = r, also H=60gbΔ=600,50,01,0=600,5=30H = 60^\circ \cdot \dfrac{g-b}{\Delta} = 60^\circ \cdot \dfrac{0{,}5 - 0{,}0}{1{,}0} = 60^\circ \cdot 0{,}5 = 30^\circ
  • Ergebnis: [30, 1,0, 1,0]HSV[\,30^\circ,\ 1{,}0,\ 1{,}0\,]_{\text{HSV}} (Orange liegt genau zwischen Rot bei 00^\circ und Gelb bei 6060^\circ).

Farbe 2 (0,2, 0,2, 0,2)(0{,}2,\ 0{,}2,\ 0{,}2) - Grauton:

  • V=0,2V = 0{,}2,   min=max=0,2Δ=0\;\min = \max = 0{,}2 \Rightarrow \Delta = 0
  • S=00,2=0S = \dfrac{0}{0{,}2} = 0
  • Wegen S=0S = 0 ist HH undefiniert (unbunt).
  • Ergebnis: [undef, 0, 0,2]HSV[\,\text{undef},\ 0,\ 0{,}2\,]_{\text{HSV}}

Farbe 3 (0,0, 0,6, 0,3)(0{,}0,\ 0{,}6,\ 0{,}3) - Frühlingsgrün:

  • V=max=0,6V = \max = 0{,}6,   min=0,0\;\min = 0{,}0,   Δ=0,6\;\Delta = 0{,}6
  • S=0,60,6=1,0S = \dfrac{0{,}6}{0{,}6} = 1{,}0
  • max=g\max = g, also H=60(brΔ+2)=60(0,30,00,6+2)=60(0,5+2)=150H = 60^\circ \cdot \left(\dfrac{b-r}{\Delta} + 2\right) = 60^\circ \cdot \left(\dfrac{0{,}3 - 0{,}0}{0{,}6} + 2\right) = 60^\circ \cdot (0{,}5 + 2) = 150^\circ
  • Ergebnis: [150, 1,0, 0,6]HSV[\,150^\circ,\ 1{,}0,\ 0{,}6\,]_{\text{HSV}} (liegt zwischen Grün bei 120120^\circ und Cyan bei 180180^\circ).

Teil b - Umrechnung HSV nach RGB. Formeln (Kapitel 10): C=VSC = V \cdot S,   H=H60\;H' = \dfrac{H}{60^\circ},   X=C(1Hmod21)\;X = C \cdot \bigl(1 - |\,H' \bmod 2 - 1\,|\bigr),   m=VC\;m = V - C. Je nach Sektor von HH':

HH'(R,G,B)(R', G', B')
[0,1)[0,1)(C,X,0)(C, X, 0)
[1,2)[1,2)(X,C,0)(X, C, 0)
[2,3)[2,3)(0,C,X)(0, C, X)
[3,4)[3,4)(0,X,C)(0, X, C)
[4,5)[4,5)(X,0,C)(X, 0, C)
[5,6)[5,6)(C,0,X)(C, 0, X)

Am Ende: (R,G,B)=(R+m, G+m, B+m)(R, G, B) = (R' + m,\ G' + m,\ B' + m).

Farbe 4 (240, 1,0, 0,5)(240^\circ,\ 1{,}0,\ 0{,}5):

  • C=VS=0,51,0=0,5C = V \cdot S = 0{,}5 \cdot 1{,}0 = 0{,}5
  • H=24060=4H' = \dfrac{240}{60} = 4 \Rightarrow Sektor [4,5)[4,5), also (R,G,B)=(X,0,C)(R', G', B') = (X, 0, C)
  • X=C(14mod21)=0,5(101)=0,5(11)=0X = C \cdot \bigl(1 - |\,4 \bmod 2 - 1\,|\bigr) = 0{,}5 \cdot \bigl(1 - |0 - 1|\bigr) = 0{,}5 \cdot (1 - 1) = 0
  • m=VC=0,50,5=0m = V - C = 0{,}5 - 0{,}5 = 0
  • (R,G,B)=(0+0, 0+0, 0,5+0)=(0,0, 0,0, 0,5)(R, G, B) = (0 + 0,\ 0 + 0,\ 0{,}5 + 0) = (0{,}0,\ 0{,}0,\ 0{,}5) - halbhelles Blau. Probe: max=0,5=V\max = 0{,}5 = V ✓, S=0,5/0,5=1S = 0{,}5/0{,}5 = 1 ✓.

Farbe 5 (30, 1,0, 1,0)(30^\circ,\ 1{,}0,\ 1{,}0):

  • C=1,01,0=1,0C = 1{,}0 \cdot 1{,}0 = 1{,}0
  • H=3060=0,5H' = \dfrac{30}{60} = 0{,}5 \Rightarrow Sektor [0,1)[0,1), also (R,G,B)=(C,X,0)(R', G', B') = (C, X, 0)
  • X=C(10,5mod21)=1,0(10,51)=1,0(10,5)=0,5X = C \cdot \bigl(1 - |\,0{,}5 \bmod 2 - 1\,|\bigr) = 1{,}0 \cdot \bigl(1 - |0{,}5 - 1|\bigr) = 1{,}0 \cdot (1 - 0{,}5) = 0{,}5
  • m=1,01,0=0m = 1{,}0 - 1{,}0 = 0
  • (R,G,B)=(1,0, 0,5, 0,0)(R, G, B) = (1{,}0,\ 0{,}5,\ 0{,}0) - reines Orange. Das ist genau die Umkehrung von Farbe 1 aus Teil a ✓.

Kapitelbezug: Kapitel 10: Farbräume.

Typischer Fehler: SS mit VV verwechseln oder VV als Mittelwert berechnen. Merke: V=max(r,g,b)V = \max(r,g,b) (nicht der Durchschnitt), SS ist der relative Abstand von Grau (Δ/max\Delta / \max). Bei der Rückrichtung nicht vergessen, mm am Ende auf alle drei Kanäle zu addieren.


2. Aufgabe: OpenGL Shader (18 Punkte)

Gegeben ist das folgende Shader-Paar:

// Vertex Shader
#version 330
layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 vertex_normal;
layout(location = 2) in vec3 vertex_color;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
out vec3 normalVS;
out vec3 colorVS;
void main() {
    gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(vertex, 1.0);
    normalVS = vertex_normal;
    colorVS = vertex_color;
}
// Fragment Shader
#version 330
in vec3 normalVS;
in vec3 colorVS;
out vec4 fragColor;
uniform float brightness;
void main() {
    fragColor = vec4(colorVS * brightness, 1.0);
}

a (3 P): Worauf verweist der index in layout(location = index)? Welche drei Attribute werden hier gebunden? b (3 P): Was ist eine uniform Variable und welche Zugriffsrechte hat sie im Shader? Worin unterscheidet sich brightness von den Matrix-Uniforms in der Verwendung? c (3 P): Was passiert mit den out-Variablen normalVS und colorVS auf dem Weg vom Vertex- zum Fragment-Shader? Warum sollte eine Normale im Fragment-Shader gegebenenfalls erneut normiert werden? d (3 P): Erklären Sie die Zeile gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(vertex, 1.0);. In welcher Reihenfolge wirken die Matrizen, und wozu dient das 1.0? e (3 P): Erklären Sie die Parameter von gluLookAt(ax,ay,az, bx,by,bz, cx,cy,cz). f (3 P): Was bewirken glEnable(GL_DEPTH_TEST), glDepthFunc(GL_LESS) und glClearDepth(1.0)?

Lösung anzeigen

a) Der index gibt die Vertex-Attribut-Position (vertex attribute index) an, aus der das Attribut im VAO/VBO gelesen wird. Er entspricht dem index in glVertexAttribPointer(index, ...) bzw. glEnableVertexAttribArray(index). Hier werden gebunden: 00 = Position (vertex), 11 = Normale (vertex_normal), 22 = Vertexfarbe (vertex_color).

b) Eine uniform Variable ist eine globale, für alle Vertices bzw. Fragmente eines Draw-Calls konstante Eingabe, die von der Anwendung (CPU) per glUniform* / glUniformMatrix*fv gesetzt und per Variablenname (via glGetUniformLocation) adressiert wird. Im Shader ist sie READ-ONLY. In der Verwendung gibt es keinen prinzipiellen Unterschied: brightness wird mit glUniform1f gesetzt, die Matrizen mit glUniformMatrix4fv; beide sind pro Draw-Call konstant. brightness ist nur ein einzelner Skalar (float), die Matrizen sind 4×44\times4-Werte (mat4).

c) Beide out-Werte des Vertex-Shaders werden bei der Rasterisierung automatisch über das Primitiv (Dreieck) interpoliert (perspektivisch korrekt) und kommen als gleichnamige in-Variablen im Fragment-Shader an. Die Kopplung erfolgt über gleichen Namen und Typ. Eine Normale sollte im Fragment-Shader erneut mit normalize() normiert werden, weil die lineare Interpolation zweier Einheitsvektoren im Allgemeinen keinen Einheitsvektor mehr ergibt (die interpolierte Länge ist meist kleiner als 11), was Beleuchtungsrechnungen verfälschen würde.

d) Bei Spaltenvektoren werden die Matrizen von rechts nach links angewendet:

gl_Position=PVM(vertex, 1,0)\texttt{gl\_Position} = \mathbf{P} \cdot \mathbf{V} \cdot \mathbf{M} \cdot (\text{vertex},\ 1{,}0)

Zuerst bringt die Model-Matrix M\mathbf{M} den Vertex vom lokalen ins Weltkoordinatensystem, dann die View-Matrix V\mathbf{V} ins Kamerakoordinatensystem, zuletzt die Projektions-Matrix P\mathbf{P} in den Clip-Raum. Das 1.0 homogenisiert die 3D-Position zu einem vec4 mit w=1,0w = 1{,}0; nur mit w=1w = 1 wirken die Translationsanteile (letzte Spalte der 4×44\times4-Matrizen). Ein reiner Richtungsvektor (z.B. eine Normale) bekäme stattdessen w=0w = 0.

e) gluLookAt definiert die View-Matrix über drei Vektoren:

  • a = Augpunkt / Kameraposition (eye) - wo die Kamera steht.
  • b = Blickpunkt / Zielpunkt (center) - wohin die Kamera schaut.
  • c = Up-Vektor (up) - welche Richtung "oben" ist.

f)

  1. glEnable(GL_DEPTH_TEST) schaltet den Tiefentest (z-Buffer-Test) ein.
  2. glDepthFunc(GL_LESS) legt fest, dass ein Fragment nur gezeichnet wird, wenn sein Tiefenwert kleiner (also näher an der Kamera) ist als der bereits gespeicherte.
  3. glClearDepth(1.0) setzt den Wert, mit dem der Tiefenpuffer beim Löschen gefüllt wird (1,01{,}0 = maximale, weiteste Entfernung), damit jedes reale Fragment den Test zunächst besteht.

Kapitelbezug: Kapitel 6: Shaderprogrammierung, Kapitel 7: Kameras, Kapitel 8: Rendering-Pipeline.

Tipp: Die interpolierte Normale immer im Fragment-Shader neu normieren. Und: uniform (konstant pro Draw-Call, per Name adressiert) sauber von in-Vertex-Attributen (variieren pro Vertex, per location-Index adressiert) trennen.


3. Aufgabe: Affine Transformationen (16 Punkte)

Teil a (6 P): Eine 2D-Szene "Segelboot-Symbol" soll aus zwei Basiselementen aufgebaut werden: Kreis (Einheitskreis, Radius 11, Zentrum Ursprung) und Dreieck (Basis von 1-1 bis 11 auf der x-Achse, Spitze bei (0,1)(0,1)). Zielszene:

  • Sonne: ein Kreis mit Radius 1,51{,}5, Zentrum im Ursprung.
  • Kleiner Kreis (Bullauge): ein Kreis mit Radius 0,50{,}5, Zentrum bei (1, 1)(1,\ 1).
  • Segel: ein Dreieck, um 9090^\circ im Uhrzeigersinn gedreht (Spitze zeigt danach nach rechts), doppelt so gross, Zentrum bei (2, 0)(-2,\ 0).

Geben Sie für jedes der drei Blätter die nötigen Transformationen samt Parametern und in der richtigen Reihenfolge an. Erläutern Sie kurz die Vererbung im Szenegraphen.

Teil b (10 P): Ein Punkt P=(2, 2)P = (2,\ 2) soll erst um den Faktor (2, 1)(2,\ 1) skaliert und danach um 9090^\circ gegen den Uhrzeigersinn um den Ursprung gedreht werden.

  1. Stellen Sie die Skalierungsmatrix SS und die Rotationsmatrix RR in homogenen Koordinaten (3×33\times3) auf.
  2. Berechnen Sie die kombinierte Matrix M=RSM = R \cdot S und wenden Sie sie auf PP an (Probe).
  3. Zeigen Sie, dass die umgekehrte Reihenfolge SRS \cdot R ein anderes Ergebnis liefert (Nicht-Kommutativität).
Lösung anzeigen

Teil a - Transformationen pro Blatt (Basiselemente sind Einheitskreis und Standarddreieck):

  • Sonne: Einheitskreis (r=1r=1) auf r=1,5r=1{,}5 vergrössern, Zentrum bleibt im Ursprung -> Skalierung(1,5, 1,5)(1{,}5,\ 1{,}5).
  • Kleiner Kreis: Einheitskreis auf r=0,5r=0{,}5 verkleinern, dann an die Position schieben -> Skalierung(0,5, 0,5)(0{,}5,\ 0{,}5), danach Translation(1, 1)(1,\ 1). Reihenfolge beachten: erst skalieren (um den Ursprung), dann verschieben, sonst wird der Abstand zum Ursprung mitskaliert.
  • Segel: Standarddreieck um 9090^\circ im Uhrzeigersinn drehen (das entspricht Rotation(90)(-90^\circ)), auf doppelte Grösse Skalierung(2, 2)(2,\ 2), dann an die Position Translation(2, 0)(-2,\ 0). Anwendungsreihenfolge am Objekt: erst Skalierung, dann Rotation, dann Translation.

Vererbung: Im Szenegraphen erben Kind-Objekte die Transformationen ihres Elternknotens. Eine Transformation, die auf alle Teile wirken soll (z.B. das ganze Boot verschieben), notiert man einmal am Elternknoten Segelboot; sie wird mit den blattspezifischen Transformationen zur akkumulierten Matrix verkettet. Bei Spaltenvektoren steht die Wurzel-Transformation dabei ganz links (wirkt als äusserste, zuletzt angewandte Transformation).

Teil b - homogene Transformation.

1. Matrizen aufstellen. Skalierung mit (sx,sy)=(2,1)(s_x, s_y) = (2, 1) und Rotation mit φ=90\varphi = 90^\circ (cos90=0\cos 90^\circ = 0, sin90=1\sin 90^\circ = 1):

S=(200010001),R=(cosφsinφ0sinφcosφ0001)=(010100001)S = \begin{pmatrix} 2 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}, \qquad R = \begin{pmatrix} \cos\varphi & -\sin\varphi & 0 \\ \sin\varphi & \cos\varphi & 0 \\ 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}

2. Kombinierte Matrix M=RSM = R \cdot S. Zuerst skalieren, dann rotieren, also steht SS rechts (direkt am Punkt):

M=RS=(010100001)(200010001)=(010200001)M = R \cdot S = \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 2 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 0 & -1 & 0 \\ 2 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}

Anwendung auf P=(2, 2, 1)T\vec{P} = (2,\ 2,\ 1)^T:

MP=(010200001)(221)=(0212+022+02+01)=(241)M\,\vec{P} = \begin{pmatrix} 0 & -1 & 0 \\ 2 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 2 \\ 2 \\ 1 \end{pmatrix} = \begin{pmatrix} 0\cdot2 - 1\cdot2 + 0 \\ 2\cdot2 + 0\cdot2 + 0 \\ 1 \end{pmatrix} = \begin{pmatrix} -2 \\ 4 \\ 1 \end{pmatrix}

Also P=(2, 4)P' = (-2,\ 4).

Probe (schrittweise): Skalierung zuerst: (2,2)(2,1)=(4, 2)(2,2) \cdot (2,1) = (4,\ 2). Dann Rotation 9090^\circ CCW: (y, x)=(2, 4)(-y,\ x) = (-2,\ 4) ✓ - stimmt mit MPM\,\vec{P} überein.

3. Umgekehrte Reihenfolge SRS \cdot R:

SR=(200010001)(010100001)=(020100001)S \cdot R = \begin{pmatrix} 2 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 0 & -2 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix} (SR)P=(020100001)(221)=(04+02+0+01)=(421)(S\cdot R)\,\vec{P} = \begin{pmatrix} 0 & -2 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 2 \\ 2 \\ 1 \end{pmatrix} = \begin{pmatrix} 0 - 4 + 0 \\ 2 + 0 + 0 \\ 1 \end{pmatrix} = \begin{pmatrix} -4 \\ 2 \\ 1 \end{pmatrix}

Also P=(4, 2)(2, 4)P'' = (-4,\ 2) \neq (-2,\ 4). Probe: erst Rotation (2,2)(2,2)(2,2) \to (-2, 2), dann Skalierung (2,1)(4,2)(2,1) \to (-4, 2) ✓. Die Matrixmultiplikation ist nicht kommutativ: RSSRR \cdot S \neq S \cdot R.

Kapitelbezug: Kapitel 5: Transformationen (homogene Koordinaten, Rotations- und Skalierungsmatrix, Szenegraph, Nicht-Kommutativität).

Typischer Fehler: Die zuerst anzuwendende Transformation links statt rechts notieren. Bei Spaltenvektoren steht die erste Transformation direkt am Punkt, also ganz rechts. Ausserdem: 9090^\circ im Uhrzeigersinn entspricht φ=90\varphi = -90^\circ (also sin(90)=1\sin(-90^\circ) = -1).


4. Aufgabe: Beleuchtung nach Phong (15 Punkte)

An einem Oberflächenpunkt PP steht eine Punktlichtquelle, eine Kamera blickt auf PP. Gerechnet wird einkanalig auf einer Skala 00 bis 11.

Teil a (4 P): Nennen Sie die vier für das Phong-Reflexionsmodell nötigen (normierten) Vektoren an PP und geben Sie an, zwischen welchen Vektoren die Winkel α\alpha und β\beta gemessen werden.

Teil b (6 P): Berechnen Sie die Helligkeit der diffusen und der spekularen Reflexion an PP für α=45\alpha = 45^\circ, β=60\beta = 60^\circ und Glanzexponent k=4k = 4 (Material- und Lichtkonstanten =1= 1). Zeigen Sie den Rechenweg.

Teil c (5 P): Nun mit realistischen Konstanten: diffuses Material Md=0,6M_d = 0{,}6, spekulares Material Ms=0,9M_s = 0{,}9, Lichtfarbe Li=1,0L_i = 1{,}0, globales Ambient La=0,2L_a = 0{,}2. Berechnen Sie die Gesamthelligkeit an PP mit der vollständigen Phong-Formel. Was bewirkt ein grösserer Exponent kk?

Lösung anzeigen

Teil a - benötigte Vektoren (alle normiert) an PP:

  • N\vec{N} = Normale der Oberfläche.
  • L\vec{L} = Lichtvektor, zeigt von PP zur Lichtquelle.
  • R\vec{R} = Reflexionsvektor, Spiegelung von L\vec{L} an N\vec{N}.
  • V\vec{V} = Sicht-/Blickvektor, zeigt von PP zur Kamera.

Winkel: α\alpha liegt zwischen N\vec{N} und L\vec{L} (steuert die diffuse Reflexion, cosα=NL\cos\alpha = \vec{N}\circ\vec{L}); β\beta liegt zwischen R\vec{R} und V\vec{V} (steuert die spekulare Reflexion, cosβ=RV\cos\beta = \vec{R}\circ\vec{V}).

Teil b - diffuse und spekulare Helligkeit (Konstanten =1= 1):

Diffuse Reflexion (Lambert):

Idiff=cosα=cos45=220,707I_{diff} = \cos\alpha = \cos 45^\circ = \frac{\sqrt{2}}{2} \approx \mathbf{0{,}707}

Spekulare Reflexion (Phong):

Ispec=coskβ=cos4(60)I_{spec} = \cos^{k}\beta = \cos^{4}(60^\circ)

Rechenweg: cos60=0,5\cos 60^\circ = 0{,}5, also

cos4(60)=(0,5)4=116=0,0625\cos^{4}(60^\circ) = (0{,}5)^{4} = \frac{1}{16} = \mathbf{0{,}0625}

Teil c - vollständige Phong-Formel (einkanalig, eine Lichtquelle):

I=MdLa+(Mdcosα+Mscoskβ)LiI = M_d \cdot L_a + \left(M_d \cdot \cos\alpha + M_s \cdot \cos^{k}\beta\right)\cdot L_i

Einsetzen mit cosα=0,707\cos\alpha = 0{,}707 und cos4β=0,0625\cos^{4}\beta = 0{,}0625:

I=0,60,2+(0,60,707+0,90,0625)1,0I = 0{,}6 \cdot 0{,}2 + \left(0{,}6 \cdot 0{,}707 + 0{,}9 \cdot 0{,}0625\right)\cdot 1{,}0 I=0,12+(0,4243+0,0563)=0,12+0,4806=0,60I = 0{,}12 + \left(0{,}4243 + 0{,}0563\right) = 0{,}12 + 0{,}4806 = \mathbf{0{,}60}

Die Gesamthelligkeit an PP beträgt also rund 0,600{,}60 (ambienter Sockel 0,120{,}12, diffus 0,420{,}42, spekular 0,060{,}06).

Wirkung von kk: Ein grösserer Glanzexponent kk macht das spekulare Glanzlicht kleiner und härter (schärferer, konzentrierterer Glanzpunkt), weil coskβ\cos^{k}\beta mit steigendem kk ausserhalb von β=0\beta = 0 schneller gegen null fällt. Kleines kk ergibt ein grosses, weiches Highlight (matte Oberfläche).

Kapitelbezug: Kapitel 9: Visualisierungstechniken (Phong-Reflexionsmodell).

Typischer Fehler: α\alpha und β\beta vertauschen (α\alpha misst N\vec{N} zu L\vec{L}, β\beta misst R\vec{R} zu V\vec{V}) oder den Exponenten kk fälschlich auf den diffusen Term anwenden. kk gehört ausschliesslich zum spekularen Term. Ausserdem: der ambiente Term MdLaM_d\cdot L_a steht ausserhalb der Summe und hat keinen cos\cos-Faktor.


5. Aufgabe: Farbinterpolation im Dreieck (12 Punkte)

Ein Dreieck hat die Vertices v1=(2,2)v_1 = (2,2) mit Farbe Rot [1,0,0][1,0,0], v2=(8,2)v_2 = (8,2) mit Farbe Grün [0,1,0][0,1,0] und v3=(5,8)v_3 = (5,8) mit Farbe Blau [0,0,1][0,0,1]. Gesucht ist der interpolierte RGB-Farbwert im Punkt p=(5, 3)p = (5,\ 3).

Teil 1 (4 P): Beschreiben Sie das Vorgehen (baryzentrische Interpolation). Teil 2 (8 P): Berechnen Sie den Farbwert nachvollziehbar. Führen Sie die Probe w1+w2+w3=1w_1 + w_2 + w_3 = 1 durch.

Lösung anzeigen

Teil 1 - Vorgehen. Innerhalb eines Dreiecks werden die Vertexfarben über baryzentrische Gewichte (barycentric weights = Flächenverhältnisse) interpoliert. Für jeden Vertex ist das Gewicht der Anteil der gegenüberliegenden Teildreiecksfläche an der Gesamtfläche:

wi=AiAges,w1+w2+w3=1w_i = \frac{A_i}{A_{ges}}, \qquad w_1 + w_2 + w_3 = 1

Der Farbwert ist dann die gewichtete Summe c(p)=w1c1+w2c2+w3c3\vec{c}(p) = w_1\,\vec{c}_1 + w_2\,\vec{c}_2 + w_3\,\vec{c}_3. Die Dreiecksfläche berechnet man mit

A=12xa(ybyc)+xb(ycya)+xc(yayb).A = \tfrac12\,\bigl|x_a(y_b - y_c) + x_b(y_c - y_a) + x_c(y_a - y_b)\bigr|.

Teil 2 - Rechnung.

Gesamtfläche mit v1=(2,2)v_1=(2,2), v2=(8,2)v_2=(8,2), v3=(5,8)v_3=(5,8):

Ages=122(28)+8(82)+5(22)=1212+48+0=1236=18A_{ges} = \tfrac12\,|\,2(2-8) + 8(8-2) + 5(2-2)\,| = \tfrac12\,|-12 + 48 + 0| = \tfrac12 \cdot 36 = 18
  • A1=(p,v2,v3)A_1 = \triangle(p, v_2, v_3) mit p=(5,3)p=(5,3): 125(28)+8(83)+5(32)=1230+40+5=1215=7,5w1=7,518=512\tfrac12\,|\,5(2-8) + 8(8-3) + 5(3-2)\,| = \tfrac12\,|-30 + 40 + 5| = \tfrac12\cdot 15 = 7{,}5 \Rightarrow w_1 = \dfrac{7{,}5}{18} = \dfrac{5}{12}
  • A2=(v1,p,v3)A_2 = \triangle(v_1, p, v_3): 122(38)+5(82)+5(23)=1210+305=1215=7,5w2=7,518=512\tfrac12\,|\,2(3-8) + 5(8-2) + 5(2-3)\,| = \tfrac12\,|-10 + 30 - 5| = \tfrac12\cdot 15 = 7{,}5 \Rightarrow w_2 = \dfrac{7{,}5}{18} = \dfrac{5}{12}
  • A3=(v1,v2,p)A_3 = \triangle(v_1, v_2, p): 122(23)+8(32)+5(22)=122+8+0=126=3w3=318=16\tfrac12\,|\,2(2-3) + 8(3-2) + 5(2-2)\,| = \tfrac12\,|-2 + 8 + 0| = \tfrac12\cdot 6 = 3 \Rightarrow w_3 = \dfrac{3}{18} = \dfrac{1}{6}

Probe: 512+512+16=512+512+212=1212=1\dfrac{5}{12} + \dfrac{5}{12} + \dfrac{1}{6} = \dfrac{5}{12} + \dfrac{5}{12} + \dfrac{2}{12} = \dfrac{12}{12} = 1

Farbwert:

c(p)=512[1,0,0]+512[0,1,0]+16[0,0,1]=[512, 512, 16][0,42, 0,42, 0,17]\vec{c}(p) = \tfrac{5}{12}[1,0,0] + \tfrac{5}{12}[0,1,0] + \tfrac{1}{6}[0,0,1] = \left[\tfrac{5}{12},\ \tfrac{5}{12},\ \tfrac{1}{6}\right] \approx [0{,}42,\ 0{,}42,\ 0{,}17]

Der Punkt liegt tief (nahe der Basiskante v1v2v_1 v_2) und weit von v3v_3 (Blau) entfernt, deshalb sind Rot- und Grünanteil gleich gross und der Blauanteil klein.

Kapitelbezug: Kapitel 8: Rendering-Pipeline (lineare Farbinterpolation im Dreieck).

Tipp: Immer die Probe wi=1\sum w_i = 1 machen. Das Gewicht wiw_i gehört zur gegenüberliegenden Teilfläche AiA_i (nicht zu der Teilfläche, die viv_i enthält). Liegt pp nahe an viv_i, muss wiw_i gross sein.


6. Aufgabe: Bildverarbeitung, lokale Operatoren (16 Punkte)

a (3 P): Warum muss die Grösse von Faltungskerneln aus ungeraden Zahlen (3×33\times3, 5×55\times5, ...) bestehen? Was bewirkt der folgende Kernel, und was ist an seiner Koeffizientensumme bemerkenswert?

F=(121000121)F = \begin{pmatrix} 1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \end{pmatrix}

b (5 P): Wenden Sie den Laplace-Operator auf die folgende Rastergrafik an. Der Kernel lässt sich nur auf die inneren Pixel anwenden; geben Sie die Ergebnismatrix mit Rechenweg an.

20208080
20208080
20208080
20208080

c (4 P): Berechnen Sie den Median für das folgende 3×33\times3-Fenster und vergleichen Sie ihn mit dem Mittelwert. Was zeigt das Beispiel?

303231
33534
313032

d (4 P): Bestimmen Sie für die folgende Binärgrafik (X = Vordergrund, . = Hintergrund) die Anzahl der Zusammenhangskomponenten (ZHK) einmal mit N4- und einmal mit N8-Nachbarschaft. Begründen Sie den Unterschied.

X...X
.X.X.
..X..
.X.X.
X...X
Lösung anzeigen

a - ungerade Kernelgrösse und Wirkung von FF. Ein ungerader Kernel (3×33\times3, 5×55\times5, ...) hat ein eindeutiges Zentrum. Nur so lässt sich das Faltungsergebnis genau einem Ausgangspixel zuordnen, und der Kernel ist symmetrisch um dieses Zentrum (kein Halbpixel-Versatz).

FF ist der Sobel-Operator in y-Richtung: er bildet die gewichtete Differenz zwischen der oberen und der unteren Zeile (obere Zeile ++, untere Zeile -, mittlere Spalte doppelt gewichtet). Er ist ein Kanten-/Ableitungsoperator (erste Ableitung in vertikaler Richtung) und hebt damit horizontale Kanten hervor (Grauwertsprünge von oben nach unten). Bemerkenswert: die Koeffizientensumme ist 00 (1+2+1121=01+2+1-1-2-1 = 0). Deshalb liefert er in konstanten Flächen den Wert 00 und reagiert nur an Kanten; er braucht keine weitere additive Grauwertkorrektur, um konstante Bereiche auf 00 abzubilden.

b - Laplace-Operator.

FL=(010141010),g(i,j)=4g(i,j)gobenguntenglinksgrechtsF_L = \begin{pmatrix} 0 & -1 & 0 \\ -1 & 4 & -1 \\ 0 & -1 & 0 \end{pmatrix}, \qquad g'(i,j) = 4\,g(i,j) - g_{\text{oben}} - g_{\text{unten}} - g_{\text{links}} - g_{\text{rechts}}

Bei einem 3×33\times3-Kernel auf einem 4×44\times4-Bild bleiben die 2×22\times2 inneren Pixel (Zeilen/Spalten 11 und 22, von 00 gezählt):

  • Pixel (1,1)=20(1,1) = 20: 42020202080=80140=604\cdot20 - 20 - 20 - 20 - 80 = 80 - 140 = \mathbf{-60} (oben 2020, unten 2020, links 2020, rechts 8080)
  • Pixel (1,2)=80(1,2) = 80: 48080802080=320260=604\cdot80 - 80 - 80 - 20 - 80 = 320 - 260 = \mathbf{60} (oben 8080, unten 8080, links 2020, rechts 8080)
  • Pixel (2,1)=20(2,1) = 20: 42020202080=80140=604\cdot20 - 20 - 20 - 20 - 80 = 80 - 140 = \mathbf{-60}
  • Pixel (2,2)=80(2,2) = 80: 48080802080=320260=604\cdot80 - 80 - 80 - 20 - 80 = 320 - 260 = \mathbf{60}
Ergebnis=(60606060)\text{Ergebnis} = \begin{pmatrix} -60 & 60 \\ -60 & 60 \end{pmatrix}

Die Ergebnismatrix zeigt links und rechts der senkrechten Kante (Sprung 208020 \to 80 zwischen Spalte 11 und 22) betragsgleiche Ausschläge mit Vorzeichenwechsel (Nulldurchgang genau an der Kante). Konstante Bereiche ohne inneren Nachbarwechsel gäben 00.

c - Median vs. Mittelwert.

Die 9 Werte sortiert: 5, 30, 30, 31, 31, 32, 32, 33, 345,\ 30,\ 30,\ 31,\ 31,\ 32,\ 32,\ 33,\ 34.

Der Median ist der 5. Wert (g4g_4): 31\mathbf{31}.

Der Mittelwert ist

30+32+31+33+5+34+31+30+329=258928,7\frac{30+32+31+33+5+34+31+30+32}{9} = \frac{258}{9} \approx 28{,}7

Aussage: Das Störpixel 55 (Pfeffer-Rauschen, dunkler Ausreisser) zieht den Mittelwert nach unten auf 28,7\approx 28{,}7, obwohl alle echten Nachbarn um 3131 liegen. Der Median (3131) entspricht dem tatsächlichen lokalen Grauwert und ignoriert den Ausreisser vollständig, weil dieser beim Sortieren an den Rand (g0g_0) wandert und daher nie als Median g4g_4 gewählt wird. Der Median ist hier klar überlegen und erzeugt zudem keine neuen Grauwerte.

d - Zusammenhangskomponenten (ZHK). Alle 9 Vordergrundpixel liegen auf den beiden Diagonalen eines "X" und berühren sich untereinander nur diagonal: Positionen (Zeile, Spalte): (0,0),(0,4),(1,1),(1,3),(2,2),(3,1),(3,3),(4,0),(4,4)(0,0),(0,4),(1,1),(1,3),(2,2),(3,1),(3,3),(4,0),(4,4).

  • N4-Nachbarschaft (nur oben/unten/links/rechts): Kein Vordergrundpixel hat einen 4-Nachbarn, der ebenfalls Vordergrund ist (alle Verbindungen sind diagonal). Jedes Pixel ist also eine eigene Komponente -> 9 ZHK\mathbf{9\ \text{ZHK}}.
  • N8-Nachbarschaft (zusätzlich die 4 Diagonalen): Beide Diagonalen sind lückenlos diagonal verbunden und treffen sich im Zentrum (2,2)(2,2). Das gesamte "X" bildet eine einzige Komponente -> 1 ZHK\mathbf{1\ \text{ZHK}}.

Begründung: N8 verbindet zusätzlich diagonal berührende Pixel, deshalb ergibt dasselbe Bild mit N8 immer gleich viele oder weniger Komponenten als mit N4. Diagonale "Ketten" zerfallen bei N4 in lauter Einzelpixel, bei N8 verschmelzen sie.

Kapitelbezug: Kapitel 12: Bildverarbeitung - Lokale Operatoren (Faltung, Kantenoperatoren, Median, Segmentierung, ZHK).

Typischer Fehler: Beim Median den Durchschnitt statt des sortierten Mittelwerts bilden - der Median ist der Rang g4g_4, keine Rechnung. Beim Laplace das Randproblem übersehen: ein 3×33\times3-Kernel ohne Randbehandlung liefert aus einem 4×44\times4-Bild eine 2×22\times2-Ergebnismatrix. Bei den ZHK die Nachbarschaftsdefinition (N4 vs N8) genau beachten.


7. Aufgabe (Zusatz): Grauwerttransformation und Projektion (10 Punkte)

Nach einer Faltung liegen die Pixelwerte im Intervall [3, 9][-3,\ 9]. Gesucht sind lineare Grauwerttransformationen der Form g(i,j)=e(i,j)mult+addg'(i,j) = e(i,j)\cdot \text{mult} + \text{add}.

a (4 P): Bilden Sie [3, 9][-3,\ 9] auf den Grauwertbereich [0, 48][0,\ 48] ab. Wie verändert sich das Histogramm? b (4 P): Bilden Sie [3, 9][-3,\ 9] auf [5, 11][5,\ 11] ab. Ist das Ergebnis kontrastreicher oder kontrastärmer? Begründung. c (2 P): Nennen Sie die Parameter von glm::perspective(a, b, c, d).

Lösung anzeigen

Allgemein: mult=gmaxgminemaxemin\text{mult} = \dfrac{g'_{max} - g'_{min}}{e_{max} - e_{min}}; add\text{add} so wählen, dass emine_{min} auf gming'_{min} fällt (bekannten Punkt einsetzen und auflösen).

a) [3, 9][0, 48][-3,\ 9] \to [0,\ 48]:

mult=4809(3)=4812=4,add=04(3)=12\text{mult} = \frac{48 - 0}{9 - (-3)} = \frac{48}{12} = 4, \qquad \text{add} = 0 - 4\cdot(-3) = 12 g=4e+12\boxed{g' = 4\,e + 12}

Probe: 34(3)+12=0-3 \mapsto 4\cdot(-3)+12 = 0 ✓,   949+12=48\;9 \mapsto 4\cdot9+12 = 48 ✓.

Histogramm: Wegen mult=4>1\text{mult} = 4 > 1 wird der Wertebereich gespreizt (gestreckt). Die Balkenform bleibt erhalten, es entstehen aber Lücken (Kammform), weil benachbarte ganzzahlige Eingabewerte auf um 44 auseinanderliegende Ausgabewerte abgebildet werden. Der Kontrast steigt.

b) [3, 9][5, 11][-3,\ 9] \to [5,\ 11]:

mult=1159(3)=612=0,5,add=50,5(3)=5+1,5=6,5\text{mult} = \frac{11 - 5}{9 - (-3)} = \frac{6}{12} = 0{,}5, \qquad \text{add} = 5 - 0{,}5\cdot(-3) = 5 + 1{,}5 = 6{,}5 g=0,5e+6,5\boxed{g' = 0{,}5\,e + 6{,}5}

Probe: 30,5(3)+6,5=5-3 \mapsto 0{,}5\cdot(-3)+6{,}5 = 5 ✓,   90,59+6,5=11\;9 \mapsto 0{,}5\cdot9+6{,}5 = 11 ✓.

Kontrast: Wegen mult=0,5<1\text{mult} = 0{,}5 < 1 wird der Wertebereich gestaucht, das Ergebnis ist kontrastärmer (die Grauwertspanne schrumpft von 1212 auf 66).

c) glm::perspective(a, b, c, d):

  • a = fovy (vertikaler Öffnungswinkel / field of view in y)
  • b = aspect (Seitenverhältnis Breite/Höhe)
  • c = zNear (Abstand der nahen Clipping-Ebene)
  • d = zFar (Abstand der fernen Clipping-Ebene)

Kapitelbezug: Kapitel 11: Bildbearbeitung - Punktoperatoren (lineare Grauwerttransformation, Histogramm), Kapitel 7: Kameras (perspektivische Projektion).

Typischer Fehler: add falsch bestimmen. Sichere Methode: mult\text{mult} aus den Intervallbreiten berechnen, dann einen bekannten Punkt (z.B. emine_{min}) einsetzen und nach add auflösen. Faustregel: mult>1\text{mult} > 1 spreizt (mehr Kontrast), mult<1\text{mult} < 1 staucht (weniger Kontrast).


Klausur WS2025 (Lösungen) · Probeklausur 1 · Kapitelübersicht