Übungen: Rendering-Pipeline & Interpolation
Übungsaufgaben zu Kapitel 8: Koordinatenräume (coordinate spaces) und Viewport-Transformation (viewport transformation), lineare und baryzentrische Farbinterpolation (linear / barycentric color interpolation) im Dreieck, Tiefentest (depth test) mit z-Buffer sowie der Painter's Algorithm. Rechne jede Aufgabe erst selbst, bevor du die Lösung aufklappst. Alle Farbwerte sind in normierten RGB-Kanälen angegeben.
Beginner
Aufgabe 1 (Beginner) - Koordinatenräume ordnen
Bringe die folgenden Koordinatenräume (coordinate spaces) in die korrekte Reihenfolge, die ein Vertex von den Rohdaten bis zur normierten Darstellung durchläuft, und benenne jeweils die Matrix bzw. den Schritt, der den Übergang bewirkt:
Camera Space, NDC, World Space, Clipping Space, Local Space.
Lösung anzeigen
Korrekte Kette:
| Von -> Nach | Übergang per |
|---|---|
| Local Space -> World Space | ModelMatrix (model matrix) |
| World Space -> Camera Space | ViewMatrix (view matrix) |
| Camera Space -> Clipping Space | ProjectionMatrix (projection matrix) |
| Clipping Space -> NDC | Homogenisierung (perspective divide) |
Merke:
- Bis zum NDC () ist alles auflösungsunabhängig (resolution-independent). Erst die anschließende Viewport-Transformation macht die Ausgabe geräteabhängig.
- Local -> Clipping Space werden selbst im Vertex Shader berechnet; ab der Homogenisierung/NDC läuft es automatisch auf der GPU (die Homogenisierung kann aber auch manuell im Vertex Shader erfolgen).
Typischer Fehler: Die Kamerablickrichtung falsch angeben. Im Camera Space (view space) sitzt die Kamera im Ursprung und blickt entlang der negativen z-Achse.
Aufgabe 2 (Beginner) - Lineare Farbinterpolation bei
Entlang einer Dreieckskante wird die Farbe linear interpoliert (linear interpolation). Am Startpunkt gilt (rot), am Endpunkt (blau). Berechne die Farbe .
Lösung anzeigen
Formel der linearen Farbinterpolation:
Einsetzen von , also :
Ergebnis: , eine überwiegend rötliche Mischfarbe mit leichtem Blauanteil. Kontrolle: Bei käme heraus, bei käme heraus.
Typischer Fehler: Interpolationsvorzeichen vertauschen. Der Gewichtungsfaktor von ist , nicht . Wer rechnet, erhält fälschlich .
Aufgabe 3 (Beginner) - Fragment oder Pixel?
Beantworte kurz: Was ist der Unterschied zwischen einem Fragment (fragment) und einem Pixel (pixel)? Warum wird nicht jedes Fragment zu einem Pixel?
Lösung anzeigen
- Ein Pixel ist ein Bildschirmelement (das finale Bildpunkt-Ergebnis).
- Ein Fragment ist die Vorstufe eines Pixels, erzeugt von der Rasterisierung (rasterization).
Beziehung:
- Mehrere Fragmente können zu einem Pixel beitragen (z.B. bei Transparenz).
- Nicht jedes Fragment wird zu einem Pixel: Der Tiefentest (z-Buffer) verwirft verdeckte Fragmente, bevor sie das Bild beeinflussen.
Tipp: Diese Unterscheidung ist prüfungsrelevant. Der Fragment Shader (fragment shader) berechnet die Farbe pro Fragment, nicht direkt pro Pixel.
Fortgeschritten
Aufgabe 4 (Fortgeschritten) - Viewport-Transformation
Ein Punkt liegt im Normalized Device Space (NDC) bei . Die Bildschirmauflösung beträgt (Breite) und (Höhe). Berechne den zugehörigen Bildpunkt im Screen Space.
Lösung anzeigen
Formeln der Viewport-Transformation (viewport transformation):
Einsetzen:
Ergebnis: .
Tipp: Der Tiefenwert wird von auf abgebildet und bleibt auflösungsunabhängig; nur und hängen von und ab. Genau deshalb ist erst die Viewport-Transformation geräteabhängig.
Hinweis: Die Folie nennt zusätzlich Pixelmittelpunkte wie unten links und oben rechts. Die reine Skalierungsformel oben liefert an den NDC-Rändern exakt bzw. (nicht bzw. ). Für Klausuren genügt in der Regel die Grundformel; die Mittelpunkt-Angaben beschreiben die diskreten Rasterzentren.
Aufgabe 5 (Fortgeschritten) - Baryzentrische Farbinterpolation im Dreieck
Ein Dreieck hat die folgenden Vertices mit zugeordneten Vertex-Farben:
| Vertex | Position | Farbe (RGB) |
|---|---|---|
| rot | ||
| grün | ||
| blau |
Bestimme die interpolierte Farbe im inneren Punkt . Berechne dazu zuerst die baryzentrischen Gewichte (barycentric weights) und prüfe, dass sie sich zu summieren.
Lösung anzeigen
Schritt 1: Baryzentrische Gewichte. Da im Ursprung liegt und auf den Achsen bei liegen, gilt . Aus :
Kontrolle der Summe: . Alle Gewichte liegen in , also liegt tatsächlich im Dreieck.
Schritt 2: Farbe interpolieren. Die Farbe ist die gewichtete Summe der Vertex-Farben:
Ergebnis: , ein blaustichiges Violett (blau dominiert, weil näher an liegt).
Tipp: Weil hier jede Vertex-Farbe genau ein reiner RGB-Kanal ist, entsprechen die Farbkanäle direkt den Gewichten. Das ist ein guter Selbstcheck: Die drei Kanäle müssen sich ebenfalls zu summieren.
Typischer Fehler: Gewichte verwenden, die sich nicht zu summieren. Immer setzen und gegenprüfen.
Aufgabe 6 (Fortgeschritten) - z-Buffer mit GL_LESS
Der Tiefentest ist mit glEnable(GL_DEPTH_TEST) aktiviert und glDepthFunc(GL_LESS) gesetzt. Der z-Buffer ist an einer bestimmten Pixelzelle bereits mit dem Tiefenwert belegt. Nacheinander treffen an dieser Zelle Fragmente mit den Tiefenwerten , dann , dann ein. Welchen Wert enthält der z-Buffer am Ende, und welche Farbe ist sichtbar?
Lösung anzeigen
Regel bei GL_LESS: Ein Fragment wird nur übernommen (Buffer aktualisiert, Farbe geschrieben), wenn sein neuer Tiefenwert kleiner ist als der gespeicherte (näher an der Kamera).
Startwert im Buffer: .
- Fragment : ? Nein -> verworfen. Buffer bleibt .
- Fragment : ? Ja -> übernommen. Buffer wird , dessen Farbe ist jetzt sichtbar.
- Fragment : ? Nein -> verworfen. Buffer bleibt .
Endstand: z-Buffer ; sichtbar ist die Farbe des Fragments mit (das kameranächste).
Typischer Fehler: z-Vergleich falsch herum. Standardmäßig (GL_LESS) gewinnt der kleinere, nähere z-Wert. Der z-Buffer löst die Sichtbarkeit korrekt und ohne globales Sortieren, unabhängig von der Ankunftsreihenfolge der Fragmente.
Anspruchsvoll
Aufgabe 7 (Anspruchsvoll) - Baryzentrische Interpolation mit gegebenen Gewichten
Für einen Fragmentpunkt im Dreieck sind die baryzentrischen Gewichte , , bereits bekannt. Die Vertex-Farben sind:
| Vertex | Farbe (RGB) |
|---|---|
Berechne die interpolierte RGB-Farbe am Fragmentpunkt.
Lösung anzeigen
Zuerst prüfen: . Gültig.
Die Interpolation erfolgt kanalweise: .
Rot:
Grün:
Blau:
Ergebnis: .
Tipp: Jeder interpolierte Kanal muss zwischen dem kleinsten und größten Vertex-Wert dieses Kanals liegen (Konvexkombination). Beispiel Blau: Alle Ergebniskanäle bleiben im Intervall , hier liegt zwischen und . So lassen sich Rechenfehler schnell entdecken.
Typischer Fehler: Die interpolierte Farbe am Ende zusätzlich durch die Summe der Gewichte teilen. Das ist nur nötig, wenn die Gewichte nicht auf normiert sind; hier summieren sie bereits zu .
Aufgabe 8 (Anspruchsvoll) - Grenze des Painter's Algorithm
Beim Painter's Algorithm (painter's algorithm / Maleralgorithmus) werden die Polygone in einer bestimmten Reihenfolge gezeichnet, spätere überdecken frühere. Nenne zwei konkrete Situationen, in denen dieses Verfahren ein falsches Bild liefert, und erkläre, warum der z-Buffer sie korrekt löst.
Lösung anzeigen
Situation 1: Ungünstige Renderreihenfolge. Wird ein weit entferntes Polygon zufällig nach einem nahen gezeichnet, überdeckt es dieses fälschlich. Die Darstellung hängt allein von der Reihenfolge der Renderbefehle ab, nicht vom tatsächlichen Abstand zur Kamera.
Situation 2: Sich schneidende Polygone. Zwei Flächen, die sich gegenseitig durchdringen, lassen sich mit einer einzigen Zeichenreihenfolge grundsätzlich nicht korrekt darstellen, weil kein Polygon durchgehend vor dem anderen liegt.
Warum der z-Buffer korrekt löst: Der z-Buffer arbeitet pro Fragment. Für jede Pixelzelle wird der Tiefenwert gespeichert, und ein Fragment gewinnt nur, wenn sein z-Wert kleiner (näher) ist. Dadurch entscheidet der Abstand jedes einzelnen Pixels zur Kamera, nicht die Reihenfolge der Objekte. So entsteht die korrekte Durchdringung auch bei sich schneidenden Polygonen, ganz ohne globales Sortieren.
Tipp: Der Painter's Algorithm greift immer dann, wenn der Tiefentest nicht aktiviert ist (glEnable(GL_DEPTH_TEST) vergessen). Ziel des z-Buffers ist gerade, eine explizite globale Sortierung der Fragmente zu vermeiden.
Klausur-Niveau
Aufgabe 9 (Klausur-Niveau) - Multiple Choice, gemischt
Genau eine Antwort pro Teilfrage ist korrekt.
(a) Welche Shaderstufen sind Pflicht?
- Vertex Shader und Geometry Shader
- Vertex Shader und Fragment Shader
- Tesselation Shader und Fragment Shader
- Alle vier Stufen
(b) Bis zu welchem Raum ist die Darstellung auflösungsunabhängig?
- Bis World Space
- Bis Camera Space
- Bis NDC (Einheitswürfel)
- Bis Screen Space
(c) Was bewirkt glDepthFunc(GL_LESS)?
- Das Fragment mit dem größeren z-Wert gewinnt.
- Das Fragment mit dem kleineren (näheren) z-Wert gewinnt.
- Der Tiefentest wird deaktiviert.
- Alle Fragmente werden immer gezeichnet.
(d) Was ist die Homogenisierung (perspective divide)?
- Die Multiplikation mit der ModelMatrix.
- Die Division durch die homogene Koordinate , die auf abbildet.
- Die Abbildung des NDC auf den Screen Space.
- Die Interpolation der Vertex-Attribute.
Lösung anzeigen
- (a) -> 2. Pflicht sind Vertex Shader und Fragment Shader. Tesselation und Geometry Shader sind optional (Tradeoff Speicherplatz versus Performance).
- (b) -> 3. Bis zum NDC () ist alles auflösungsunabhängig; erst die Viewport-Transformation macht die Ausgabe geräteabhängig.
- (c) -> 2.
GL_LESS(Standard): Der kleinere, nähere z-Wert gewinnt; das Pixel wird nur bei geringerem Tiefenwert aktualisiert. - (d) -> 2. Die Homogenisierung ist die Division durch und bildet den Würfel auf den Würfel ab. Sie kann automatisch auf der GPU oder manuell im Vertex Shader erfolgen.
Typischer Fehler: Auflösungsunabhängigkeit falsch zuordnen (Antwort b) oder den z-Vergleich umdrehen (Antwort c).
Aufgabe 10 (Klausur-Niveau) - Kante interpolieren und Tiefentest kombinieren
Ein Dreieck hat unter anderem die Kantenendpunkte:
| Vertex | Farbe (RGB) | Tiefenwert |
|---|---|---|
| gelb | ||
| cyan |
(a) Berechne die entlang der Kante linear interpolierte Farbe am Parameter (also am Mittelpunkt der normierten Strecke).
(b) Ein zweites Objekt liefert an genau dieser Fragmentzelle den Tiefenwert . Der Tiefentest läuft mit GL_LESS, der Buffer ist an der Zelle noch auf (unendlich). Beide Objekte, das Kantenfragment aus (a) und das zweite Objekt, treffen ein. Welche Farbe ist am Ende sichtbar?
Hinweis zu (b): Der Tiefenwert des Kantenfragments bei wird auf gleiche Weise linear interpoliert.
Lösung anzeigen
(a) Lineare Farbinterpolation. Mit und :
Ergebnis: , ein helles Grün.
(b) Tiefentest. Der interpolierte Tiefenwert des Kantenfragments bei :
Ablauf mit GL_LESS, Buffer startet bei :
- Kantenfragment : ? Ja -> übernommen. Buffer wird , sichtbare Farbe ist das helle Grün .
- Zweites Objekt : ? Nein -> verworfen.
(Bei umgekehrter Ankunftsreihenfolge ergäbe sich dasselbe Endbild: Zuerst -> Buffer ; dann -> Buffer . Der z-Buffer ist reihenfolgeunabhängig.)
Endergebnis: Sichtbar ist die interpolierte Kantenfarbe mit Tiefenwert .
Tipp: Farbe, Tiefe und alle weiteren Vertex-Attribute werden mit demselben Interpolationsverfahren behandelt. Der z-Wert entscheidet über Sichtbarkeit, die interpolierte Farbe über das Aussehen des Gewinner-Fragments.