Answer to Question 1
a) Die Farben des orange-roten Sonnenuntergangs können auf dem Monitor mit dem Gamut A'' kräftiger wirken, da dieser Gamut weiter in den roten und orangen Bereich des Chromatizitätsdiagramms hineinreicht als der Gamut A'.

b) Ich würde im Chromatizitätsdiagramm den Bereich markieren, der sowohl vom Gamut A' als auch vom Gamut B überdeckt wird. Das sind alle Chromatizitätswerte innerhalb der Schnittmenge der beiden Gamuts.

c) Die Chromatizitätswerte x und y berechnen sich aus den Tristimuluswerten X, Y, Z wie folgt:
x = X / (X + Y + Z) = 0.5 / (0.5 + 0.3 + 0.2) = 0.5
y = Y / (X + Y + Z) = 0.3 / (0.5 + 0.3 + 0.2) = 0.3
Ich würde den Punkt mit den Koordinaten (0.5, 0.3) in das Chromatizitätsdiagramm eintragen.

d) Der gekrümmte Rand des Chromatizitätsdiagramms repräsentiert die Spektralfarben, also die Farben reiner Wellenlängen des sichtbaren Lichts.

e) Um die vollgesättigte Farbvalenz zur Farbe c zu bestimmen, würde ich eine Gerade vom Weißpunkt w durch den Punkt c ziehen, bis diese Gerade den Rand des Chromatizitätsdiagramms schneidet. Der Schnittpunkt repräsentiert die gesuchte vollgesättigte Farbvalenz.





****************************************************************************************
****************************************************************************************




Answer to Question 2
a) Hier ist meine Einschätzung, ob die gezeigten Lichttransportpfade (1) bis (4) durch Whitted-Style Raytracing erzeugt werden können:

(1) Ja, dieser Pfad kann erzeugt werden. Es handelt sich um einen einfachen Primärstrahl, der direkt die Wand trifft. Die diffuse Reflexion an der Wand wird durch Whitted-Style Raytracing unterstützt.

(2) Ja, dieser Pfad kann erzeugt werden. Der Primärstrahl trifft den Glasblock und wird gebrochen. Die Brechung (Transmission) wird durch Whitted-Style Raytracing unterstützt.  

(3) Nein, dieser Pfad kann nicht erzeugt werden. Nach der Brechung am Glasblock müsste der Strahl an der Wand diffus reflektiert werden und dann erneut den Glasblock passieren. Whitted-Style Raytracing verfolgt Strahlen aber nicht rekursiv nach einer diffusen Reflexion weiter.

(4) Nein, dieser Pfad kann nicht erzeugt werden. Es handelt sich um einen Kaustik, der durch Brechung am Glasblock und anschließende diffuse Reflexion am Boden entsteht. Whitted-Style Raytracing unterstützt keine Kaustiken, da nach der diffusen Reflexion keine weiteren Strahlen verfolgt werden.

b) Ich würde die Bildebene wie folgt in farbige Bereiche unterteilen:

Der Bereich um r1 wäre rot gefärbt, da hier die Wand direkt sichtbar ist.

Der Bereich zwischen r2 und r3 wäre weiß, da hier durch den Glasblock die weiße Lichtquelle sichtbar ist. 

Der restliche Bereich der Bildebene wäre schwarz, da aufgrund der Einschränkungen von Whitted-Style Raytracing weder indirekte Beleuchtung des Bodens (r4) noch die durch den Glasblock gebrochenen Strahlen, die die Wand treffen (r3), zum Bild beitragen.





****************************************************************************************
****************************************************************************************




Answer to Question 3
a) Die Abbildungen zeigen folgende Komponenten des Phong-Beleuchtungsmodells:
(a) Ambiente Beleuchtung: Konstante Helligkeit unabhängig vom Winkel
(b) Diffuse Beleuchtung: Maximale Helligkeit bei senkrechtem Lichteinfall, Abnahme mit flacherem Winkel
(c) und (d) Spekulare Highlights: Spitze um die Richtung der idealen Reflexion, Breite abhängig vom Glanzparameter

b) Der Modellparameter, der die Variation zwischen (c) und (d) verursacht, ist der Glanzparameter (oft als Shininess oder Specular Exponent bezeichnet). Ein höherer Glanzwert in (d) führt zu einem schmaleren und intensiveren Highlight im Vergleich zu (c). Visuell äußert sich dies durch eine "glänzendere" Oberfläche mit schärferen Reflexionen in (d).

c) Bei Gouraud Shading wird das Beleuchtungsmodell an den 3 Eckpunkten des Dreiecks ausgewertet und die Farbwerte dann über die Fläche interpoliert. Daher sind bei Gouraud Shading 3 Auswertungen nötig.

Bei Phong Shading wird das Beleuchtungsmodell für jedes der 5 bedeckten Pixel separat ausgewertet, basierend auf interpolierten Normalen. Somit sind bei Phong Shading 5 Auswertungen erforderlich - eine pro Pixel.

Der Unterschied entsteht, da Gouraud Shading die Beleuchtung nur an den Vertices berechnet, während Phong Shading dies pixelweise macht und so eine detailliertere Beleuchtung erzeugt.





****************************************************************************************
****************************************************************************************




Answer to Question 4
a) Für Strahl 1 ist die Traversierungsreihenfolge: A, B, C, D
   Für Strahl 2 ist die Traversierungsreihenfolge: A, E, F

b) Ich würde die Hüllkörper in der unteren Abbildung wie folgt skizzieren:
   - Der Hüllkörper A wird vergrößert, um alle Geometrie einzuschließen.
   - Die Hüllkörper B und E werden ebenfalls vergrößert und leicht verschoben, um die veränderte Geometrie optimal zu umschließen.  
   - Die Hüllkörper C, D und F bleiben unverändert, da sich die Geometrie in diesen Bereichen nicht verändert hat.

c) Vorteil: Die bestehende Hierarchie kann wiederverwendet werden, was Rechenzeit bei der Erstellung der neuen Hüllkörper-Hierarchie spart.
   Nachteil: Die Hüllkörper sind nicht mehr optimal an die Geometrie angepasst, was zu mehr Überlappungen und somit potentiell mehr Schnittpunkttests führt.

d) Zwei Alternativen zu achsenparallelen Boxen:
   1. Kugeln (Bounding Spheres)
      Vorteil: Schnellere Schnittpunkttests, da nur Abstand zum Mittelpunkt getestet werden muss.
      Nachteil: Schlechtere Anpassung an die Geometrie, mehr Überlappungen.
   2. Orientierte Boxen (Oriented Bounding Boxes, OBB) 
      Vorteil: Bessere Anpassung an die Geometrie als achsenparallele Boxen.
      Nachteil: Aufwändigere Schnittpunkttests und Erstellung der Hüllkörper.





****************************************************************************************
****************************************************************************************




Answer to Question 5
a) Die affine Transformation M, die das Objekt wie in der Abbildung transformiert, kann durch Multiplikation der Matrizen B und A gebildet werden: M = B \u00b7 A. Zuerst wird das Objekt durch A gespiegelt und dann durch B nach rechts verschoben.

b) Die schrittweise Transformation des Objekts durch die Matrizen F, C und B sieht folgendermaßen aus:
1. F: Das Objekt wird um 180 Grad um die z-Achse gedreht.
2. C: Das Objekt wird an der yz-Ebene gespiegelt.
3. B: Das Objekt wird entlang der x-Achse nach rechts verschoben.

c) Nein, die Normalen von o werden bei der Transformation mit der Matrix T = E \u00b7 C \u00b7 F nicht richtig transformiert. Die Matrizen E und F enthalten Skalierungen, die die Länge und Richtung der Normalen verändern. Um Normalen korrekt zu transformieren, muss die Inverse Transponierte der Matrix T' verwendet werden, also (T'^(-1))^T. Diese Matrix transformiert die Normalen so, dass sie senkrecht zu den transformierten Flächen bleiben.





****************************************************************************************
****************************************************************************************




Answer to Question 6
a) Zwei Alternativen zu bilinearer Interpolation bei Texturen aus der Vorlesung sind:
- Nearest-Neighbor-Interpolation (Pixelwiederholung)
- Trilineare Interpolation in Verbindung mit Mip-Mapping

b) Für die gegebenen Stellen (x, y) ergeben sich folgende Interpolationsgewichte:

(x, y) = (1/4, 1/2):
w0,1 = 3/8
w1,1 = 1/8  
w0,0 = 3/8
w1,0 = 1/8

(x, y) = (2/3, 1/4):
w0,1 = 1/6
w1,1 = 1/2
w0,0 = 1/12
w1,0 = 1/4

c) Die Auflösungsstufe bei Mip-Mapping sollte idealerweise so gewählt werden, dass die Größe eines Texels in etwa der projizierten Größe eines Pixels entspricht.
Probleme bei nicht idealer Wahl:
- Zu hohe Auflösung: Aliasing-Artefakte
- Zu niedrige Auflösung: Unschärfe, Detailverlust

d) Die Halbierung der Auflösung pro Stufe ist akzeptabel, da der Flächeninhalt eines Pixels in der Textur sich etwa vervierfacht, wenn sich der Abstand zur Kamera verdoppelt. Somit reicht eine Halbierung der Texturauflösung aus, um die projizierte Pixelgröße beizubehalten.

e) Da λ1 + λ2 = 0.9 < 1 ist, liegt x innerhalb des Dreiecks v1, v2, v3. Wäre die Summe größer 1, würde x außerhalb liegen. Somit ist ein Schnittpunkt des Strahls mit dem Dreieck gegeben.

f) Für den Punkt x' = x + 1/2 (v2 - v1) ergeben sich folgende baryzentrische Koordinaten:

λ'1 = λ1 - 1/2 = 0 
λ'2 = λ2 + 1/2 = 0.9
λ'3 = 1 - λ'1 - λ'2 = 0.1

Der Punkt x' liegt also auf der Kante v2v3 des Dreiecks, da λ'1 = 0 ist.





****************************************************************************************
****************************************************************************************




Answer to Question 7
a) Hier sind die Angaben für die Pipeline-Stufen:

Fragment Shader:
- Eingabedaten: Fragmente (Anzahl N)
- Ausgabedaten: Fragmente (Anzahl M = N)

Vertex Shader: 
- Eingabedaten: Vertices (Anzahl N)
- Ausgabedaten: Transformierte Vertices (Anzahl M = N)

Rasterisierung:
- Eingabedaten: Primitive (Anzahl N) 
- Ausgabedaten: Fragmente (Anzahl M > N)

Primitive Assembly:
- Eingabedaten: Vertices (Anzahl N)
- Ausgabedaten: Primitive (Anzahl M < N)

b) Backface-Culling entscheidet anhand der Orientierung der Primitive (Dreiecke), ob diese verworfen werden können. Die Orientierung lässt sich erst nach der Primitive Assembly bestimmen, wenn aus den einzelnen Vertices zusammenhängende Primitive erzeugt wurden. Daher muss die Pipeline bis zu dieser Stufe durchlaufen werden, bevor Backface-Culling angewendet werden kann.

c) Im Geometry Shader kann aus der eingehenden Partikelposition (1 Vertex) durch Erzeugen zusätzlicher Vertices und Ausgabe von Triangle Strips die gewünschte Partikelform mit 2 Dreiecken erzeugt werden. Dazu werden im Geometry Shader 4 Vertices an den Ecken eines Quads positioniert und als Triangle Strip ausgegeben, was effektiv 2 Dreiecke ergibt.

d) Alternativ zum Geometry Shader können die 2 Dreiecke pro Partikel auch direkt im Vertexbuffer gespeichert werden. Dazu werden statt nur der Partikelposition die 4 Eckpunkte der 2 Dreiecke als separate Vertices gespeichert und als Triangle List an die Pipeline übergeben. Der Geometry Shader entfällt dann.

e) Um Teile der Textur transparent darzustellen, kann im Fragment Shader der Alphakanal der Textur ausgewertet werden. Fragmente, deren Texturwert einen Alphawert von 0 hat, werden verworfen (Discard). So werden diese Teile der Textur nicht gezeichnet, ohne Blending zu benötigen.





****************************************************************************************
****************************************************************************************




Answer to Question 8
a) Blending findet in der OpenGL-Pipeline nach dem Fragment Shader und vor dem Schreiben in den Framebuffer statt.

b) i) 1. Fs + 0 · Fd
glBlendFunc(GL_ONE, GL_ZERO);
glBlendEquation(GL_FUNC_ADD);

ii) As · Fs + (1 - As) · Fd
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  
glBlendEquation(GL_FUNC_ADD);

iii) Ad · Fs - As · Fd
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_SUBTRACT);

c) Beim Alpha-Blending von semitransparenten Objekten ist eine Sortierung notwendig, weil der Tiefentest alleine nicht ausreicht. Der Tiefentest verwirft zwar Fragmente, die weiter hinten liegen als bereits gezeichnete Fragmente. Bei semitransparenten Objekten sollen aber auch weiter hinten liegende Fragmente zum endgültigen Farbeindruck beitragen. Daher müssen die Objekte von hinten nach vorne sortiert gezeichnet werden, damit durch das Blending die Transparenz korrekt berücksichtigt wird.





****************************************************************************************
****************************************************************************************




Answer to Question 9
Hier sind meine Antworten zu den Fragen:

(1) gl_Position = ...;
Die gl_Position Variable wird im Vertex-Shader gesetzt, um die transformierte Position des Vertex im Clip Space zu definieren.

(2) Berechnung der Richtung vom Betrachter zu einem Oberflächenpunkt
Dies erfolgt am besten im Fragment-Shader. Für jeden Pixel (Fragment) muss die Richtung vom Betrachter zur Oberfläche an diesem Punkt berechnet werden, um korrekte Beleuchtung und Reflexionen zu erhalten.

(3) textureCube
textureCube wird verwendet, um Werte aus einer Cube-Map Textur zu sampeln. Dies geschieht im Fragment-Shader, um die Umgebungsreflexionen für jeden Pixel zu berechnen.

(4) refract
Die refract Funktion berechnet die Richtung eines gebrochenen Lichtstrahls basierend auf dem Einfallsvektor, der Oberflächennormalen und dem Brechungsindex. Auch dies erfolgt im Fragment-Shader, um die Lichtbrechung für jeden Pixel zu simulieren.

(5) Berechnung des Fresnel-Terms
Der Fresnel-Term beschreibt das Verhältnis von Reflexion zu Brechung in Abhängigkeit vom Einfallswinkel. Die Berechnung erfolgt im Fragment-Shader, da sie von der Richtung des Betrachters zur Oberfläche an jedem Pixel abhängt.

Zu den Unterfragen:

(a) Die Einschränkung auf Lichtbrechung nur am ersten Schnittpunkt ist bei Rasterisierung notwendig, da nur die Oberfläche des Objekts gerendert wird. Mehrfache Brechungen im Inneren des Objekts können nicht verfolgt werden, da keine Tiefeninformationen vorliegen.

(b) Es werden mindestens ein Vertex-Shader und ein Fragment-Shader benötigt. Der Vertex-Shader transformiert die Geometrie, während der Fragment-Shader die Beleuchtung, Reflexion und Brechung für jeden Pixel berechnet.

(c) Siehe die Begründungen zu den einzelnen Funktionsaufrufen oben. Die meisten Berechnungen finden im Fragment-Shader statt, da sie von den individuellen Pixeln abhängen. Lediglich die Transformation der Vertex-Positionen erfolgt im Vertex-Shader.





****************************************************************************************
****************************************************************************************




Answer to Question 10
a) Die Funktion intersectDF führt Sphere-Tracing auf dem Distanzfeld aus, um einen Schnittpunkt zu finden. Dazu werden folgende Schritte in einer Schleife bis zu maxSteps mal durchgeführt:
- Auswerten der Distanzfunktion DF am aktuellen Punkt o auf dem Strahl
- Wenn die Distanz kleiner als eine kleine Toleranz eps ist, wurde ein Schnittpunkt gefunden. Die Funktion gibt true sowie die Schnittpunktkoordinate s und die Distanz entlang des Strahls t zurück.
- Ansonsten wird die Distanz ds zur aktuellen Schrittweite entlang des Strahls addiert und der neue Punkt o berechnet.
- Ist nach maxSteps Schritten kein Schnittpunkt gefunden, wird false zurückgegeben.

b) Eine Korrektur des Schnittpunkts s_R = s + ds ist notwendig, da der Schnittpunkt durch Sphere-Tracing nur bis auf eine Toleranz eps genau bestimmt wird. Ohne Korrektur würde der Refraktionsstrahl R nicht exakt auf der Oberfläche starten.

Die Berechnung der relativen Brechzahl relEta ist nötig, um zu bestimmen, ob der Strahl in das Objekt eintritt (eta/1.0) oder austritt (1.0/eta). Dies ist wichtig für die korrekte Berechnung der Refraktion.

Die Bedingung if(DF(o) < 0) testet, ob der Strahl sich innerhalb des Objekts befindet. Dies ist notwendig, um die korrekte relative Brechzahl zu wählen und zwischen Ein- und Austritt zu unterscheiden.

c) Gloss-Mapping ist eine Technik, bei der die Rauheit bzw. der Glanzgrad der Oberfläche durch eine Textur gesteuert wird. Bei der hier verwendeten Schattierungstechnik mit Environment-Mapping kann dies einfach durch Skalierung der Reflexionsrichtung mit dem Gloss-Wert erreicht werden. Je kleiner der Wert, desto stärker die Streuung der Reflexion und desto rauer erscheint die Oberfläche. Da die Reflexionsberechnung ohnehin durchgeführt wird, ist der zusätzliche Aufwand für Gloss-Mapping sehr gering.

d) Dispersionseffekte können hinzugefügt werden, indem die Brechzahl eta wellenlängenabhängig gewählt wird, z.B. durch separate eta-Werte für die RGB-Kanäle. Dadurch wird der Refraktionsstrahl für jede Farbkomponente in eine leicht andere Richtung gebrochen.

Der Berechnungsaufwand im Shader erhöht sich dadurch, dass die Refraktionsberechnung nun dreimal (für R,G,B) durchgeführt werden muss. Auch das Sphere-Tracing des Refraktionsstrahls muss dann für jeden Farbkanal separat erfolgen, was den Aufwand ungefähr verdreifacht.





****************************************************************************************
****************************************************************************************




Answer to Question 11
a) Eine BVH B', die mit T_K'(x) mit K' ≤ K konstruiert wird, ist eine korrekt funktionierende BVH für die Szene, weil die Hüllkörper der BVH B' die Quader der Szene vollständig umschließen. Da T_K'(x) ≥ T_K(x) für alle x gilt, sind die Hüllkörper in B' größer oder gleich groß wie die tatsächlichen Quader. Somit werden bei der Traversierung der BVH B' alle potentiellen Schnittpunkte gefunden.
Der Nachteil gegenüber einer BVH B, die mit K' < K generiert wurde, ist, dass die Hüllkörper in B' tendenziell größer sind als nötig. Dadurch werden beim Traversieren der BVH B' mehr Schnittpunkttests durchgeführt als bei der BVH B, was zu einer längeren Laufzeit führt.

b) Um die Rauschfunktion n(x) beim Raymarching minimal oft auszuwerten, kann man die bereits berechneten Werte von T_K(x) wiederverwenden:
1. Berechne T_K(r_x(0), r_y(0)) und speichere das Ergebnis.
2. Für jedes i > 0:
   - Wenn r_z(i) ≤ T_K(r_x(i-1), r_y(i-1)), ist der Schnittpunkt gefunden.
   - Sonst berechne T_K(r_x(i), r_y(i)) und speichere das Ergebnis.
So muss n(x) nur einmal pro Marching-Schritt ausgewertet werden und nicht mehrfach für verschiedene k in der Summe.

c) Die Funktion n(x) = sin(x) erfüllt die Eigenschaft der Periodizität, die für manche Anwendungen von Rauschfunktionen gewünscht ist.
Dennoch ist von der Verwendung abzuraten, da sin(x) zu regelmäßig und vorhersehbar ist. Gute Rauschfunktionen sollten zufällig und unregelmäßig erscheinen, was bei sin(x) nicht der Fall ist. Die resultierenden Texturen oder Objekte würden zu künstlich und repetitiv wirken.

d) Die Ableitungsregeln für das L-System zur Erzeugung der Kochschen Schneeflocke sind:

F → F+F--F+F
+ → +
- → -

Das Startwort ist: F--F--F

Interpretation als Turtle-Grafik:
F: Zeichne eine Linie der Länge 1 in aktuelle Richtung
+: Drehe um 60° gegen den Uhrzeigersinn
-: Drehe um 60° im Uhrzeigersinn





****************************************************************************************
****************************************************************************************




Answer to Question 12
a) Um den Punkt F(0.5) zu bestimmen, unterteile ich die Bézierkurve F(u) zeichnerisch für u = 0.5:
- Verbinde b0 mit b1, b1 mit b2 und b2 mit b3 durch gerade Linien. Markiere die Mittelpunkte dieser Linien.
- Verbinde die Mittelpunkte der Linien b0b1 und b1b2 sowie b1b2 und b2b3. Markiere die Mittelpunkte dieser neuen Linien.
- Verbinde die Mittelpunkte der zuletzt gezeichneten Linien. Der Mittelpunkt dieser finalen Linie entspricht F(0.5).
Um F(u) zu skizzieren, nutze ich die Kontrollpolygone der entstandenen Teilkurven und die Eigenschaft, dass Bézierkurven innerhalb der konvexen Hülle ihrer Kontrollpunkte verlaufen.

b) Laut affiner Invarianz kann ich die affine Transformation (Rotation, Skalierung, Verschiebung) auf die Kontrollpunkte b0, b1, b2, b3 anwenden. Die transformierten Kontrollpunkte definieren dann die transformierte Bézierkurve.

c) In der Abbildung sieht man, dass die Kurve G(u) nicht durch alle Kontrollpunkte c0, c1, c2, c3 verläuft. Eine kubische Bézierkurve muss aber immer durch ihren Anfangspunkt c0 und Endpunkt c3 verlaufen. Da dies hier nicht der Fall ist, kann G(u) keine kubische Bézierkurve sein. Die gezeigte Kurve weist mehr als einen Wendepunkt auf, was der Variationsreduzierung von kubischen Bézierkurven widerspricht. Daher entspricht die abgebildete Kurve nicht der kubischen Bézierkurve G(u).





****************************************************************************************
****************************************************************************************




