Programming lesson
GPU-Raytracing in GLSL: Normalen, Phong-Beleuchtung und Schatten für die Cs33400 Aufgabe #2
Lerne, wie du in GLSL Fragment-Shadern Oberflächennormalen berechnest, das Phong-Beleuchtungsmodell implementierst und Reflexionen sowie harte Schatten per Raytracing renderst – genau wie in der Cs33400/Ece30834 Aufgabe #2.
GPU-Raytracing in GLSL: Normalen, Phong-Beleuchtung und Schatten für die Cs33400 Aufgabe #2
Die Cs33400/Ece30834 Aufgabe #2 fordert dich heraus, grundlegende Raytracing-Effekte direkt auf der GPU zu implementieren. Statt wie in früheren Aufgaben CPU-seitig zu arbeiten, liegt der Fokus auf Fragment-Shadern (f.glsl). Der besondere Trick: ein Hot-Update-Mechanismus, der es erlaubt, Shader-Code zur Laufzeit neu zu laden – perfekt für schnelles Iterieren. In diesem Tutorial lernst du Schritt für Schritt, wie du Normalen für Kugel und Ebene berechnest, das Phong-Beleuchtungsmodell anwendest, Reflexionen renderst und optional harte Schatten via Raytracing hinzufügst. Die Konzepte sind nicht nur für Uni-Aufgaben relevant, sondern auch für moderne 3D-Apps, Spiele und sogar KI-generierte Szenen.
1. Warm-up: Hot-Update der GPU-Shader
Bevor es ans Eingemachte geht, implementierst du den Hot-Update-Mechanismus. Dazu fügst du in main.cpp (Zeile 123) eine Zeile ein, die das Neuladen des Shaders bei Tastendruck 'r' ermöglicht. Teste es: Setze nach outCol = shading(ro, rd, intersect); die Zeile outCol = vec3(1.0, 0.0, 0.0); ein. Drücke 'r' – der Bildschirm wird rot. Entferne die Zeile und lade neu – die ursprüngliche Ansicht erscheint. Dieser Workflow ist Gold wert, denn du vermeidest ständiges Neukompilieren. Das ist besonders nützlich, wenn du wie in aktuellen KI-Rendering-Pipelines oder Echtzeit-Apps schnell Shader anpassen musst.
2. Normalenberechnung für die Kugel
Die Grundlage jeder Beleuchtung sind korrekte Oberflächennormalen. In TODO 2 erhältst du den Schnittpunkt pos auf der Kugel. Die Kugel ist durch den Vektor sphere definiert: sphere.xyz ist der Mittelpunkt, sphere.w der Radius. Die Normale ist einfach der normalisierte Vektor vom Mittelpunkt zum Schnittpunkt:
vec3 normal = normalize(pos - sphere.xyz);Dieser Schritt ist essenziell für das Phong-Modell. Stelle dir vor, du modellierst die Oberfläche einer E-Sport-Trophäe – ohne korrekte Normalen würden Lichtreflexe unrealistisch wirken. Teste deine Implementierung: Die Kugel sollte gleichmäßig ausgeleuchtet erscheinen.
3. Phong-Beleuchtungsmodell (Ambient, Diffus, Spekular)
Das Phong-Modell kombiniert drei Lichtkomponenten: Ambient, Diffus und Spekular. Jede wird durch Materialeigenschaften (ka, kd, ks, n) und die Lichtfarbe beeinflusst.
- Ambient: Ein konstanter Grundanteil, der indirekte Beleuchtung simuliert. Unabhängig von Licht- oder Blickrichtung.
- Diffus: Abhängig vom Winkel zwischen Normale und Lichtrichtung. Je kleiner der Winkel, desto heller. Berechnung:
diff = max(dot(N, L), 0.0). - Spekular: Glanzlichter, die entstehen, wenn Licht direkt ins Auge reflektiert wird. Dazu berechnest du den reflektierten Lichtvektor
R(ohne die GLSL-Funktionreflect) und den Winkel zur BlickrichtungV:spec = pow(max(dot(R, V), 0.0), n).
Die Reflexionsformel lautet: R = I - 2 * dot(I, N) * N, wobei I der einfallende Lichtvektor (von der Oberfläche zur Lichtquelle) ist. Implementiere dies in TODO 3 und 3.5. Das Ergebnis ist eine Kugel mit plastischem Glanz – ähnlich wie bei aktuellen 3D-Game-Engines oder VR-Anwendungen.
4. Materialeigenschaften einstellen
Jedes Objekt bekommt eigene Materialwerte. Für die Kugel verwendest du z.B. ka = (1.0, 0.5, 0.31), kd = (1.0, 0.5, 0.31), ks = (0.5, 0.5, 0.5), n = 32. Experimentiere mit Werten, um „Gold“ oder „Zinn“-Effekte zu erzielen. Ein Gold-Material (ka=(1.0,0.8,0.2), kd=(1.0,0.8,0.2), ks=(0.8,0.6,0.2), n=64) lässt die Kugel wie eine glänzende Medaille bei den Olympischen Spielen aussehen. Diese Anpassungen sind typisch für Produktvisualisierungen oder Architektur-Renderings.
5. Spiegelreflexion (Specular Reflection)
Ein erster Schritt zum echten Raytracing: die Spiegelreflexion. Du berechnest den reflektierten Strahl von der Oberfläche aus und sampelst die Hintergrundfarbe. Das erfordert einen weiteren Raytracing-Schritt im Shader. Die Implementierung ähnelt der Berechnung des reflektierten Vektors, aber diesmal wird der Strahl in die Szene verfolgt. In der Praxis siehst du dann die Umgebung auf der Kugel gespiegelt – wie bei einem glänzenden Billardball oder einer Chromkugel in einem Rennspiel.
6. Harte Schatten (Bonus)
Schatten entstehen, wenn ein Objekt die Lichtstrahlen blockiert. Du sendest einen Schattenstrahl vom Schnittpunkt zur Lichtquelle. Trifft er ein Objekt, liegt der Punkt im Schatten. Dies ist eine zweite Ordnung des Raytracings. Die Implementierung ist eine for-Schleife über die Szenenobjekte. Harte Schatten sind der einfachste Schattentyp, aber sie verleihen der Szene sofort Tiefe – wichtig für realistische 3D-Szenen in Filmen oder Spielen.
Fazit
Mit diesen Schritten hast du die Kernanforderungen der Cs33400 Aufgabe #2 umgesetzt. Du beherrschst jetzt Normalenberechnung, Phong-Beleuchtung, Reflexion und grundlegendes Raytracing – Fähigkeiten, die in der modernen Computergrafik unverzichtbar sind. Ob du nun an KI-generierten 3D-Welten, Echtzeit-Rendering in Spielen oder wissenschaftlichen Visualisierungen arbeitest, dieses Wissen ist die Basis. Probiere verschiedene Materialien aus und erweitere die Szene um weitere Objekte – der Kreativität sind keine Grenzen gesetzt.