Probeklausur 4 - Visual Computing (erhöhter Schwierigkeitsgrad)

Übungsklausur (mock exam) zum Kurs "Visual Computing" (HS Darmstadt) mit erhöhtem Schwierigkeitsgrad. Sie folgt Struktur, Themenmix und Punktgewichtung der Original-Klausur WS 2025/2026, verlangt aber mehr mehrstufige Rechenschritte (mehr Zwischenrechnungen, gedrehte Dreiecke, Rotation um einen Punkt, Phong mit echten 3D-Vektoren, volle Hue-Formel). Alle Aufgaben sind neu und überschneiden sich nicht mit Probeklausur 1, 2 oder 3. Lösungen sind ausklappbar mit vollem Rechenweg. 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 (9 P): Rechnen Sie die folgenden drei Farben aus dem RGB-Modell (Wertebereich [0,1][0,1]) exakt in das HSV-Modell um. Verwenden Sie die vollständige Hue-Formel (nicht nur "reine" Primärfarben ablesen) und zeigen Sie jeden Schritt: VV, SS und HH.

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,6, 0,4)(0{,}2,\ 0{,}6,\ 0{,}4)
Farbe 3(0,3, 0,0, 0,6)(0{,}3,\ 0{,}0,\ 0{,}6)

Teil b (4 P): Eine Grafik zeigt auf schwarzem Hintergrund drei Quadrate: Orange (1,0, 0,5, 0,0)(1{,}0,\ 0{,}5,\ 0{,}0), Türkis (0,0, 0,5, 0,5)(0{,}0,\ 0{,}5,\ 0{,}5) und Mittelgrau (0,5, 0,5, 0,5)(0{,}5,\ 0{,}5,\ 0{,}5). Geben Sie für jede Region die HSV-Kanalwerte an und begründen Sie, warum man keinen einzelnen Kanal findet, der alle vier Regionen (inkl. Hintergrund) eindeutig unterscheidet.

Lösung anzeigen

Teil a - vollständige RGB-nach-HSV-Umrechnung. Formeln (Kapitel 10) mit max=max(R,G,B)\max = \max(R,G,B), min=min(R,G,B)\min = \min(R,G,B), Δ=maxmin\Delta = \max - \min:

V=max,S={0max=0Δmaxsonst,H=60{GBΔmod6max=RBRΔ+2max=GRGΔ+4max=BV = \max, \qquad S = \begin{cases} 0 & \max = 0 \\ \dfrac{\Delta}{\max} & \text{sonst} \end{cases}, \qquad H = 60^\circ \cdot \begin{cases} \dfrac{G-B}{\Delta} \bmod 6 & \max = R \\ \dfrac{B-R}{\Delta} + 2 & \max = G \\ \dfrac{R-G}{\Delta} + 4 & \max = B \end{cases}

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

  • max=R=1,0\max = R = 1{,}0, min=0,0\min = 0{,}0, Δ=1,0\Delta = 1{,}0
  • V=1,0V = 1{,}0
  • S=1,01,0=1,0S = \dfrac{1{,}0}{1{,}0} = 1{,}0
  • max=RH=60GBΔ=600,50,01,0=600,5=30\max = R \Rightarrow H = 60^\circ \cdot \dfrac{G-B}{\Delta} = 60^\circ \cdot \dfrac{0{,}5 - 0{,}0}{1{,}0} = 60^\circ \cdot 0{,}5 = \mathbf{30^\circ} (Orange)
  • Ergebnis: [30, 1,0, 1,0]HSV[30^\circ,\ 1{,}0,\ 1{,}0]_{\text{HSV}}

Farbe 2 (0,2, 0,6, 0,4)(0{,}2,\ 0{,}6,\ 0{,}4):

  • max=G=0,6\max = G = 0{,}6, min=0,2\min = 0{,}2, Δ=0,4\Delta = 0{,}4
  • V=0,6V = 0{,}6
  • S=0,40,6=230,667S = \dfrac{0{,}4}{0{,}6} = \dfrac{2}{3} \approx 0{,}667
  • max=GH=60(BRΔ+2)=60(0,40,20,4+2)=60(0,5+2)=150\max = G \Rightarrow H = 60^\circ \cdot \left(\dfrac{B-R}{\Delta} + 2\right) = 60^\circ \cdot \left(\dfrac{0{,}4 - 0{,}2}{0{,}4} + 2\right) = 60^\circ \cdot (0{,}5 + 2) = \mathbf{150^\circ}
  • Ergebnis: [150, 0,667, 0,6]HSV[150^\circ,\ 0{,}667,\ 0{,}6]_{\text{HSV}} (Farbton zwischen Grün 120120^\circ und Cyan 180180^\circ)

Farbe 3 (0,3, 0,0, 0,6)(0{,}3,\ 0{,}0,\ 0{,}6):

  • max=B=0,6\max = B = 0{,}6, min=0,0\min = 0{,}0, Δ=0,6\Delta = 0{,}6
  • V=0,6V = 0{,}6
  • S=0,60,6=1,0S = \dfrac{0{,}6}{0{,}6} = 1{,}0
  • max=BH=60(RGΔ+4)=60(0,30,00,6+4)=60(0,5+4)=270\max = B \Rightarrow H = 60^\circ \cdot \left(\dfrac{R-G}{\Delta} + 4\right) = 60^\circ \cdot \left(\dfrac{0{,}3 - 0{,}0}{0{,}6} + 4\right) = 60^\circ \cdot (0{,}5 + 4) = \mathbf{270^\circ}
  • Ergebnis: [270, 1,0, 0,6]HSV[270^\circ,\ 1{,}0,\ 0{,}6]_{\text{HSV}} (Farbton zwischen Blau 240240^\circ und Magenta 300300^\circ, also Violett)

Teil b - HSV-Kanalwerte. Türkis (0,0,5,0,5)(0,0{,}5,0{,}5): max=0,5\max = 0{,}5 (G und B gleich), min=0S=1\min = 0 \Rightarrow S = 1, H=180H = 180^\circ (Cyan). Mittelgrau: max=minS=0\max = \min \Rightarrow S = 0, HH undefiniert. Schwarz: V=0V = 0, S=0S = 0, HH undefiniert.

RegionHHSSVV
Hintergrund (Schwarz)undef (0)00
Orange3030^\circ11
Türkis180180^\circ10{,}5
Mittelgrauundef (0)00{,}5

Begründung (kein einzelner Kanal reicht):

  • VV trennt Orange (11) vom Rest, aber Türkis und Mittelgrau haben beide V=0,5V = 0{,}5 und sind ununterscheidbar.
  • SS trennt die bunten (S=1S = 1) von den unbunten Regionen (S=0S = 0), aber Schwarz und Mittelgrau haben beide S=0S = 0, Orange und Türkis beide S=1S = 1.
  • HH trennt Orange (3030^\circ) von Türkis (180180^\circ), ist aber bei Schwarz und Mittelgrau undefiniert (gleich dargestellt).

Erst die Kombination aus mindestens zwei Kanälen (z.B. VV und SS) trennt alle vier Regionen eindeutig. Das ist der Kern der HSV-Zerlegung: Buntheit (SS), Helligkeit (VV) und Farbton (HH) sind entkoppelt.

Kapitelbezug: Kapitel 10: Farbräume, Kapitel 3: Farben und Primitive.

Typischer Fehler: Bei max=G\max = G oder max=B\max = B den falschen Zweig der Hue-Formel nehmen oder die Konstante +2+2 bzw. +4+4 vergessen. Merke: +0+0 (rot-dominant), +2+2 (grün-dominant), +4+4 (blau-dominant), jeweils mal 6060^\circ. Ausserdem: S=Δ/maxS = \Delta/\max, nicht Δ\Delta allein.


2. Aufgabe: OpenGL Shader mit Beleuchtung (19 Punkte)

Gegeben ist ein Shader-Paar, das die diffuse Beleuchtung pro Fragment berechnet:

// Vertex Shader
#version 330
layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 vertex_normal;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
out vec3 normalVS;
void main() {
    gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(vertex, 1.0);
    normalVS = vertex_normal;
}
// Fragment Shader
#version 330
in vec3 normalVS;
out vec4 color;
uniform vec3 lightDir;   // normiert, zeigt von der Oberflaeche zur Lichtquelle
uniform vec3 objColor;
void main() {
    vec3 N = normalize(normalVS);
    float diff = max(dot(N, normalize(lightDir)), 0.0);
    color = vec4(objColor * diff, 1.0);
}

a (3 P): Worauf verweist der index in layout(location = index)? Welche zwei Attribute werden hier gebunden? b (3 P): Was ist eine uniform Variable und welche Zugriffsrechte hat sie im Shader? Warum ist lightDir als uniform und nicht als in-Attribut deklariert? c (4 P): Warum wird normalVS im Fragment-Shader mit normalize(...) erneut normiert, obwohl die Vertex-Normalen bereits Einheitslänge hatten? d (3 P): Erklären Sie die Zeile float diff = max(dot(N, normalize(lightDir)), 0.0);. Welches Beleuchtungsgesetz steckt dahinter und wozu dient das max(..., 0.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: 00 = Position (vertex), 11 = Normale (vertex_normal).

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* gesetzt und per Variablenname adressiert wird. Im Shader ist sie READ-ONLY. lightDir ist ein uniform, weil die Lichtrichtung für das ganze Objekt gleich ist (ändert sich nicht von Vertex zu Vertex). Ein in-Attribut würde dagegen pro Vertex einen eigenen Wert aus dem VBO lesen, was hier unnötig wäre.

c) Der out-Wert normalVS wird bei der Rasterisierung linear über das Dreieck interpoliert, bevor er als in im Fragment-Shader ankommt. Die lineare Interpolation zweier Einheitsvektoren ergibt aber im Allgemeinen einen Vektor mit Länge <1< 1 (der interpolierte Vektor "hängt durch"). Für das Skalarprodukt NL=cosα\vec{N}\circ\vec{L} = \cos\alpha muss N\vec{N} aber wieder normiert sein, sonst wäre die berechnete Helligkeit systematisch zu dunkel. Deshalb normalize erneut im Fragment-Shader.

d) Das ist das Lambert-Gesetz (diffuse Reflexion): Die Helligkeit ist proportional zu cosα=NL\cos\alpha = \vec{N}\circ\vec{L}, dem Skalarprodukt aus normierter Flächennormale N\vec{N} und normiertem Lichtvektor L\vec{L}. Das max(..., 0.0) klemmt negative Werte auf 00: Zeigt die Lichtquelle hinter die Fläche (α>90\alpha > 90^\circ, also cosα<0\cos\alpha < 0), soll die Fläche nicht "negativ beleuchtet" (und schon gar nicht abgezogen) werden, sondern schlicht unbeleuchtet (00) bleiben.

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, Kapitel 9: Visualisierungstechniken.

Typischer Fehler: Annehmen, eine im Vertex-Shader normierte Normale bleibe nach der Interpolation normiert. Interpolation erhält die Richtung näherungsweise, aber nicht die Länge, daher die erneute Normierung pro Fragment.


3. Aufgabe: Affine Transformationen und Rotation um einen Punkt (16 Punkte)

Teil a (6 P): Eine 2D-Szene "Eiswaffel" wird aus zwei Basiselementen aufgebaut: 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:

  • Kugel: ein Kreis mit Radius 1,21{,}2, Zentrum bei (0, 1,5)(0,\ 1{,}5).
  • Waffel: ein Dreieck, das nach unten zeigt (Spitze unten) und doppelt so hoch wie breit ist, Spitze bei etwa (0, 2)(0,\ -2).

Geben Sie für jedes Blatt die nötigen Transformationen samt Parametern in korrekter Reihenfolge an. Begründen Sie bei der Waffel die Reihenfolge von Skalierung, Rotation und Translation.

Teil b (10 P): Ein Punkt P=(4, 2)P = (4,\ 2) soll um 9090^\circ gegen den Uhrzeigersinn um den Drehpunkt C=(1, 1)C = (1,\ 1) (nicht um den Ursprung) gedreht werden.

  1. Stellen Sie die drei benötigten Matrizen in homogenen Koordinaten (3×33\times3) auf: T(C)T(-C), R(90)R(90^\circ), T(C)T(C).
  2. Berechnen Sie die kombinierte Matrix M=T(C)R(90)T(C)M = T(C)\cdot R(90^\circ)\cdot T(-C).
  3. Wenden Sie MM auf PP an und bestätigen Sie das Ergebnis mit einer geometrischen Probe. Zeigen Sie, dass eine Drehung um den Ursprung ein anderes Ergebnis liefert.
Lösung anzeigen

Teil a - Transformationen pro Blatt.

  • Kugel: Einheitskreis (r=1r=1) auf r=1,2r=1{,}2 vergrössern, dann an die Position schieben -> Skalierung(1,2, 1,2)(1{,}2,\ 1{,}2), danach Translation(0, 1,5)(0,\ 1{,}5). Erst skalieren (um den Ursprung), dann verschieben, sonst würde der Abstand zum Ursprung mitskaliert.

  • Waffel: drei Schritte in dieser Reihenfolge (von innen nach aussen):

    1. Skalierung(1, 2)(1,\ 2) - nicht-uniform, macht das Dreieck doppelt so hoch (Spitze wandert von (0,1)(0,1) auf (0,2)(0,2)), Breite bleibt.
    2. Rotation(180)(180^\circ) - dreht die Spitze nach unten (auf (0,2)(0,-2)).
    3. Translation(0, 0)(0,\ 0) - hier keine weitere Verschiebung nötig, die Spitze liegt bereits bei (0,2)(0,-2).

    Reihenfolge-Begründung: Skalierung und Rotation wirken relativ zum Ursprung. Würde man zuerst verschieben und dann rotieren/skalieren, drehte bzw. streckte sich das Dreieck um den Ursprung statt um seine eigene Mitte. Bei Spaltenvektoren gilt M=TRSM = T\cdot R\cdot S, d.h. die zuerst anzuwendende Transformation (SS) steht ganz rechts (direkt am Punkt).

Vererbung: Kind-Objekte erben die Transformationen des Elternknotens Eiswaffel. Eine gemeinsame Transformation (z.B. die ganze Waffel kippen) notiert man einmal am Elternknoten; sie wird mit den blattspezifischen Matrizen verkettet.

Teil b - Rotation um den Punkt C=(1,1)C = (1,1).

1. Matrizen aufstellen. Für φ=90\varphi = 90^\circ: cos90=0\cos 90^\circ = 0, sin90=1\sin 90^\circ = 1.

T(C)=(101011001),R=(010100001),T(C)=(101011001)T(-C) = \begin{pmatrix} 1 & 0 & -1 \\ 0 & 1 & -1 \\ 0 & 0 & 1 \end{pmatrix},\quad R = \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix},\quad T(C) = \begin{pmatrix} 1 & 0 & 1 \\ 0 & 1 & 1 \\ 0 & 0 & 1 \end{pmatrix}

Idee: erst CC in den Ursprung schieben (T(C)T(-C)), dort um 9090^\circ drehen (RR), dann zurückschieben (T(C)T(C)).

2. Kombinierte Matrix. Zuerst RT(C)R\cdot T(-C):

RT(C)=(010100001)(101011001)=(011101001)R\cdot T(-C) = \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 1 & 0 & -1 \\ 0 & 1 & -1 \\ 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 0 & -1 & 1 \\ 1 & 0 & -1 \\ 0 & 0 & 1 \end{pmatrix}

Dann M=T(C)(RT(C))M = T(C)\cdot\bigl(R\cdot T(-C)\bigr):

M=(101011001)(011101001)=(012100001)M = \begin{pmatrix} 1 & 0 & 1 \\ 0 & 1 & 1 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 0 & -1 & 1 \\ 1 & 0 & -1 \\ 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 0 & -1 & 2 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}

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

MP=(012100001)(421)=(0412+2114+02+011)=(041)M\,\vec{P} = \begin{pmatrix} 0 & -1 & 2 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 4 \\ 2 \\ 1 \end{pmatrix} = \begin{pmatrix} 0\cdot4 - 1\cdot2 + 2\cdot1 \\ 1\cdot4 + 0\cdot2 + 0\cdot1 \\ 1 \end{pmatrix} = \begin{pmatrix} 0 \\ 4 \\ 1 \end{pmatrix}

Also P=(0, 4)P' = (0,\ 4).

Geometrische Probe: PP relativ zu CC: PC=(41, 21)=(3, 1)P - C = (4-1,\ 2-1) = (3,\ 1). Drehung um 9090^\circ CCW: (x,y)(y,x)(x,y)\mapsto(-y,x), also (3,1)(1, 3)(3,1)\mapsto(-1,\ 3). Zurückschieben +C+C: (1+1, 3+1)=(0, 4)(-1+1,\ 3+1) = (0,\ 4) ✓ - stimmt mit MPM\,\vec{P} überein.

Drehung um den Ursprung (zum Vergleich): (4,2)(y,x)=(2, 4)(0, 4)(4,2)\mapsto(-y,x) = (-2,\ 4) \neq (0,\ 4). Der Drehpunkt verschiebt das Ergebnis: um CC landet PP bei (0,4)(0,4), um den Ursprung bei (2,4)(-2,4).

Kapitelbezug: Kapitel 5: Transformationen (homogene Koordinaten, Rotation um einen Punkt, Verkettung, Nicht-Kommutativität).

Typischer Fehler: Bei der Rotation um einen Punkt das Zurückschieben T(C)T(C) vergessen oder T(C)T(-C) und T(C)T(C) vertauschen. Merke die Sandwich-Form M=T(C)RT(C)M = T(C)\cdot R\cdot T(-C): erst hin zum Ursprung, drehen, wieder zurück.


4. Aufgabe: Beleuchtung nach Phong mit 3D-Vektoren (16 Punkte)

An einem Oberflächenpunkt PP sind gegeben (alle in einem gemeinsamen Koordinatensystem, Skala 00 bis 11):

  • Flächennormale N=(0, 0, 1)\vec{N} = (0,\ 0,\ 1),
  • Lichtvektor (von PP zur Lichtquelle) L=(0, 0,6, 0,8)\vec{L} = (0,\ 0{,}6,\ 0{,}8),
  • Blickvektor (von PP zur Kamera) V=(0,6, 0, 0,8)\vec{V} = (0{,}6,\ 0,\ 0{,}8).

Alle drei Vektoren sind bereits normiert.

Teil a (4 P): Nennen Sie die vier für Phong nötigen Vektoren. Berechnen Sie cosα=NL\cos\alpha = \vec{N}\circ\vec{L} und den Reflexionsvektor R=2(NL)NL\vec{R} = 2(\vec{N}\circ\vec{L})\,\vec{N} - \vec{L}. Bestätigen Sie R=1|\vec{R}| = 1.

Teil b (6 P): Berechnen Sie die diffuse Helligkeit IdiffI_{diff} und die spekulare Helligkeit IspecI_{spec} (Konstanten =1= 1) mit dem Glanzexponenten k=3k = 3. Nutzen Sie cosβ=RV\cos\beta = \vec{R}\circ\vec{V}.

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

Lösung anzeigen

Teil a - Vektoren und Reflexion. Die vier normierten Vektoren an PP sind N\vec{N} (Normale), L\vec{L} (Lichtvektor zur Quelle), R\vec{R} (Reflexionsvektor) und V\vec{V} (Blickvektor zur Kamera).

cosα=NL=(0)(0)+(0)(0,6)+(1)(0,8)=0,8\cos\alpha = \vec{N}\circ\vec{L} = (0)(0) + (0)(0{,}6) + (1)(0{,}8) = \mathbf{0{,}8}

Reflexionsvektor:

R=2(NL)NL=20,8(0,0,1)(0, 0,6, 0,8)=(0, 0, 1,6)(0, 0,6, 0,8)=(0, 0,6, 0,8)\vec{R} = 2(\vec{N}\circ\vec{L})\,\vec{N} - \vec{L} = 2\cdot0{,}8\cdot(0,0,1) - (0,\ 0{,}6,\ 0{,}8) = (0,\ 0,\ 1{,}6) - (0,\ 0{,}6,\ 0{,}8) = (0,\ -0{,}6,\ 0{,}8)

Länge: R=02+(0,6)2+0,82=0,36+0,64=1=1|\vec{R}| = \sqrt{0^2 + (-0{,}6)^2 + 0{,}8^2} = \sqrt{0{,}36 + 0{,}64} = \sqrt{1} = 1

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

Diffus (Lambert): Idiff=cosα=0,8I_{diff} = \cos\alpha = \mathbf{0{,}8}.

Spekular (Phong): zuerst cosβ\cos\beta:

cosβ=RV=(0)(0,6)+(0,6)(0)+(0,8)(0,8)=0,64\cos\beta = \vec{R}\circ\vec{V} = (0)(0{,}6) + (-0{,}6)(0) + (0{,}8)(0{,}8) = 0{,}64 Ispec=coskβ=0,643=0,640,640,64=0,40960,640,262I_{spec} = \cos^{k}\beta = 0{,}64^{3} = 0{,}64\cdot0{,}64\cdot0{,}64 = 0{,}4096\cdot0{,}64 \approx \mathbf{0{,}262}

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

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

Einsetzen mit cosα=0,8\cos\alpha = 0{,}8 und cos3β=0,262\cos^{3}\beta = 0{,}262:

I=0,60,2+(0,60,8+0,90,262)1,0I = 0{,}6\cdot0{,}2 + \bigl(0{,}6\cdot0{,}8 + 0{,}9\cdot0{,}262\bigr)\cdot1{,}0 I=0,12+(0,48+0,2359)=0,12+0,71590,836I = 0{,}12 + \bigl(0{,}48 + 0{,}2359\bigr) = 0{,}12 + 0{,}7159 \approx \mathbf{0{,}836}

Die Gesamthelligkeit an PP beträgt rund 0,840{,}84 (ambienter Sockel 0,120{,}12, diffus 0,480{,}48, spekular 0,2360{,}236).

Wirkung von kk: Ein grösserer Glanzexponent kk macht das Glanzlicht kleiner und härter (schärferer Glanzpunkt), weil coskβ\cos^{k}\beta ausserhalb von β=0\beta = 0 mit steigendem kk schneller gegen null fällt. Beispiel hier: 0,6430,2620{,}64^{3} \approx 0{,}262, aber 0,64200,000050{,}64^{20} \approx 0{,}00005 - der spekulare Beitrag verschwindet fast überall ausser exakt in Spiegelrichtung.

Kapitelbezug: Kapitel 9: Visualisierungstechniken (Phong-Reflexionsmodell), Kapitel 4: Vektoren (Skalarprodukt, Reflexion).

Typischer Fehler: Beim Reflexionsvektor das Vorzeichen verdrehen (R=2(NL)NL\vec{R} = 2(\vec{N}\circ\vec{L})\vec{N} - \vec{L}, nicht L2()N\vec{L} - 2(\ldots)\vec{N}) oder vergessen, dass RN=NL\vec{R}\circ\vec{N} = \vec{N}\circ\vec{L} immer gilt. Ausserdem: der ambiente Term MdLaM_d\cdot L_a steht ausserhalb der Klammer und hat keinen cos\cos-Faktor.


5. Aufgabe: Farbinterpolation im gedrehten Dreieck (10 Punkte)

Ein Dreieck hat die Vertices v1=(1, 1)v_1 = (1,\ 1) mit Farbe Rot [1,0,0][1,0,0], v2=(7, 3)v_2 = (7,\ 3) mit Farbe Grün [0,1,0][0,1,0] und v3=(3, 7)v_3 = (3,\ 7) mit Farbe Blau [0,0,1][0,0,1]. Das Dreieck ist im Raster schräg gelegen (kein rechter Winkel an einer Achse). Gesucht ist der interpolierte RGB-Farbwert im Punkt p=(4, 4)p = (4,\ 4).

Teil 1 (4 P): Beschreiben Sie das Vorgehen (baryzentrische Interpolation) und die verwendete Flächenformel. Teil 2 (6 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=1,c(p)=w1c1+w2c2+w3c3w_i = \frac{A_i}{A_{ges}}, \qquad w_1 + w_2 + w_3 = 1, \qquad \vec{c}(p) = w_1\vec{c}_1 + w_2\vec{c}_2 + w_3\vec{c}_3

Die Fläche eines Dreiecks (a,b,c)(a,b,c) 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|.

Diese Formel funktioniert für beliebig gedrehte Dreiecke (die Achsenlage spielt keine Rolle).

Teil 2 - Rechnung.

Gesamtfläche mit v1=(1,1)v_1=(1,1), v2=(7,3)v_2=(7,3), v3=(3,7)v_3=(3,7):

Ages=121(37)+7(71)+3(13)=124+426=1232=16A_{ges} = \tfrac12\,|\,1(3-7) + 7(7-1) + 3(1-3)\,| = \tfrac12\,|-4 + 42 - 6| = \tfrac12\cdot32 = 16
  • A1=(p,v2,v3)A_1 = \triangle(p, v_2, v_3) mit p=(4,4)p=(4,4): 124(37)+7(74)+3(43)=1216+21+3=128=4w1=416=14\tfrac12\,|\,4(3-7) + 7(7-4) + 3(4-3)\,| = \tfrac12\,|-16 + 21 + 3| = \tfrac12\cdot8 = 4 \Rightarrow w_1 = \dfrac{4}{16} = \dfrac14
  • A2=(v1,p,v3)A_2 = \triangle(v_1, p, v_3): 121(47)+4(71)+3(14)=123+249=1212=6w2=616=38\tfrac12\,|\,1(4-7) + 4(7-1) + 3(1-4)\,| = \tfrac12\,|-3 + 24 - 9| = \tfrac12\cdot12 = 6 \Rightarrow w_2 = \dfrac{6}{16} = \dfrac38
  • A3=(v1,v2,p)A_3 = \triangle(v_1, v_2, p): 121(34)+7(41)+4(13)=121+218=1212=6w3=616=38\tfrac12\,|\,1(3-4) + 7(4-1) + 4(1-3)\,| = \tfrac12\,|-1 + 21 - 8| = \tfrac12\cdot12 = 6 \Rightarrow w_3 = \dfrac{6}{16} = \dfrac38

Probe: 14+38+38=28+38+38=88=1\dfrac14 + \dfrac38 + \dfrac38 = \dfrac{2}{8} + \dfrac{3}{8} + \dfrac{3}{8} = \dfrac{8}{8} = 1

Farbwert:

c(p)=14[1,0,0]+38[0,1,0]+38[0,0,1]=[14, 38, 38]=[0,25, 0,375, 0,375]\vec{c}(p) = \tfrac14[1,0,0] + \tfrac38[0,1,0] + \tfrac38[0,0,1] = \left[\tfrac14,\ \tfrac38,\ \tfrac38\right] = [0{,}25,\ 0{,}375,\ 0{,}375]

Der Punkt liegt gleich weit von v2v_2 und v3v_3 und etwas näher an der v2v3v_2 v_3-Kante als an v1v_1, daher überwiegen Grün und Blau zu gleichen Teilen, Rot ist am schwächsten.

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. Die Betragsstriche in der Flächenformel nicht vergessen, sonst können bei gedrehten Dreiecken negative "Flächen" entstehen.


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

a (3 P): Was bewirkt der folgende Faltungskern? Begründen Sie über die Koeffizientensumme.

F=(111181111)F = \begin{pmatrix} -1 & -1 & -1 \\ -1 & 8 & -1 \\ -1 & -1 & -1 \end{pmatrix}

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

2020100100
206080100
208060100
2020100100

c (4 P): Berechnen Sie den Median für das folgende 3×33\times3-Fenster und vergleichen Sie ihn mit dem Mittelwert. Warum ist der Median hier robuster?

3020034
323331
35304

d (3 P): Bestimmen Sie die Anzahl der Zusammenhangskomponenten (ZHK) der folgenden Binärgrafik (X = Vordergrund) einmal für die N4- und einmal für die N8-Nachbarschaft.

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

a) Koeffizientensumme. Die Summe der Koeffizienten ist 8+8(1)=08 + 8\cdot(-1) = 0. Ein Kern mit Summe 00 liefert auf konstanten Flächen den Wert 00 (keine Änderung wird ausgegeben) und schlägt nur an Grauwertsprüngen aus. Es handelt sich um einen Laplace-artigen Kantenoperator (zweite Ableitung) mit 8er-Nachbarschaft: Das Zentrum (+8+8) wird mit der Summe aller acht Nachbarn (1-1 je Nachbar) verglichen. Er hebt Kanten in allen Richtungen (auch diagonal) hervor.

b) Laplace-Operator (4er-Nachbarschaft).

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, 00-indiziert):

  • Pixel (1,1)=60(1,1) = 60: oben 2020, unten 8080, links 2020, rechts 8080: 46020802080=240200=404\cdot60 - 20 - 80 - 20 - 80 = 240 - 200 = \mathbf{40}
  • Pixel (1,2)=80(1,2) = 80: oben 100100, unten 6060, links 6060, rechts 100100: 4801006060100=320320=04\cdot80 - 100 - 60 - 60 - 100 = 320 - 320 = \mathbf{0}
  • Pixel (2,1)=80(2,1) = 80: oben 6060, unten 2020, links 2020, rechts 6060: 48060202060=320160=1604\cdot80 - 60 - 20 - 20 - 60 = 320 - 160 = \mathbf{160}
  • Pixel (2,2)=60(2,2) = 60: oben 8080, unten 100100, links 8080, rechts 100100: 4608010080100=240360=1204\cdot60 - 80 - 100 - 80 - 100 = 240 - 360 = \mathbf{-120}
Ergebnis=(400160120)\text{Ergebnis} = \begin{pmatrix} 40 & 0 \\ 160 & -120 \end{pmatrix}

Deutung: Pixel (1,2)(1,2) ergibt 00, weil es genau zwischen dunklem und hellem Bereich ausgeglichen liegt; die grossen Beträge bei (2,1)(2,1) und (2,2)(2,2) markieren die stärksten lokalen Grauwertsprünge.

c) Median vs. Mittelwert. Die 9 Werte sortiert: 4, 30, 30, 31, 32, 33, 34, 35, 2004,\ 30,\ 30,\ 31,\ 32,\ 33,\ 34,\ 35,\ 200.

Der Median ist der 5. Wert: 32\mathbf{32}.

Der Mittelwert ist

30+200+34+32+33+31+35+30+49=429947,7\frac{30+200+34+32+33+31+35+30+4}{9} = \frac{429}{9} \approx \mathbf{47{,}7}

Robustheit: Das Fenster enthält zwei Ausreisser, ein Salz-Pixel (200200) und ein Pfeffer-Pixel (44). Der Mittelwert wird durch das helle 200200 auf 48\approx 48 hochgezogen, obwohl fast alle Werte um 3232 liegen. Der Median 3232 ignoriert beide Ausreisser vollständig, weil sie beim Sortieren an die Ränder (g0=4g_0 = 4, g8=200g_8 = 200) wandern und nie die mittlere Position g4g_4 einnehmen. Deshalb ist der Median bei Impulsrauschen klar überlegen.

d) Zusammenhangskomponenten. Es gibt 99 Vordergrundpixel (X), die eine diagonale "X"-Figur bilden:

(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 (nur oben/unten/links/rechts): Kein X hat einen direkten (nicht-diagonalen) X-Nachbarn, alle Kontakte sind rein diagonal. Also ist jedes X isoliert -> 9 Komponenten.
  • N8 (zusätzlich Diagonalnachbarn): Beide Diagonalen sind lückenlose Ketten, die sich im Zentrum (2,2)(2,2) treffen: (0,0)-(1,1)-(2,2)-(3,3)-(4,4)(0,0)\text{-}(1,1)\text{-}(2,2)\text{-}(3,3)\text{-}(4,4) und (0,4)-(1,3)-(2,2)-(3,1)-(4,0)(0,4)\text{-}(1,3)\text{-}(2,2)\text{-}(3,1)\text{-}(4,0). Über das gemeinsame Zentrum sind alle 99 Pixel verbunden -> 1 Komponente.

Das zeigt anschaulich: dasselbe Bild hat mit N8 gleich viele oder weniger ZHK als mit N4 (hier extrem: 99 gegenüber 11).

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

Typischer Fehler: Beim Median den Durchschnitt statt des Rangs g4g_4 bilden. Bei der ZHK-Zählung diagonale Kontakte fälschlich schon bei N4 als verbunden werten - diagonale Nachbarn zählen erst bei N8.


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

Nach einer Faltung liegen die Pixelwerte im Intervall [5, 15][-5,\ 15]. 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 [5, 15][-5,\ 15] auf den Grauwertbereich [0, 200][0,\ 200] ab. Prüfen Sie zusätzlich, auf welchen Wert der Eingabewert e=5e = 5 abgebildet wird. Wie verändert sich das Histogramm? b (4 P): Bilden Sie [5, 15][-5,\ 15] auf [80, 90][80,\ 90] ab. Ist das Ergebnis kontrastreicher oder kontrastärmer? Begründung. c (2 P): Nennen Sie die Parameter von glm::perspective(a, b, c, d). Warum muss der dritte Parameter echt grösser als 00 sein?

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) [5, 15][0, 200][-5,\ 15] \to [0,\ 200]:

mult=200015(5)=20020=10,add=010(5)=50\text{mult} = \frac{200 - 0}{15 - (-5)} = \frac{200}{20} = 10, \qquad \text{add} = 0 - 10\cdot(-5) = 50 g=10e+50\boxed{g' = 10\,e + 50}

Probe: 510(5)+50=0-5 \mapsto 10\cdot(-5)+50 = 0 ✓,   151015+50=200\;15 \mapsto 10\cdot15+50 = 200 ✓.

Zusatzwert: e=5105+50=100e = 5 \mapsto 10\cdot5 + 50 = \mathbf{100} (die Intervallmitte 55 landet erwartungsgemäss in der Mitte von [0,200][0,200]).

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

b) [5, 15][80, 90][-5,\ 15] \to [80,\ 90]:

mult=908015(5)=1020=0,5,add=800,5(5)=80+2,5=82,5\text{mult} = \frac{90 - 80}{15 - (-5)} = \frac{10}{20} = 0{,}5, \qquad \text{add} = 80 - 0{,}5\cdot(-5) = 80 + 2{,}5 = 82{,}5 g=0,5e+82,5\boxed{g' = 0{,}5\,e + 82{,}5}

Probe: 50,5(5)+82,5=80-5 \mapsto 0{,}5\cdot(-5)+82{,}5 = 80 ✓,   150,515+82,5=90\;15 \mapsto 0{,}5\cdot15+82{,}5 = 90 ✓.

Kontrast: Wegen mult=0,5<1\text{mult} = 0{,}5 < 1 wird der Wertebereich gestaucht (von Breite 2020 auf Breite 1010), das Ergebnis ist kontrastärmer. Alle Grauwerte drängen sich um 8585 zusammen, das Bild wirkt flau.

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)

zNear\text{zNear} muss echt grösser als 00 sein, weil die perspektivische Projektion durch zz dividiert (perspektivische Division). Bei zNear=0\text{zNear} = 0 käme eine Division durch null vor, ausserdem läge die Projektionsebene in der Kamera selbst. Zu kleine zNear\text{zNear}-Werte führen zudem zu ungünstiger Verteilung der Tiefenwerte und damit zu z-Fighting.

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) - unabhängig davon, wo das Zielintervall liegt.


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