Kapitel 7: Kameras
Wie eine Kamera (camera) in der Computergrafik realisiert wird, obwohl die GPU nur Geometrie im festen Normalized Device Space rendert: extrinsische Parameter (View-Matrix via lookAt), intrinsische Parameter (orthografische vs. perspektivische Projektion), Strahlensatz, View-Frustum und die komplette Vertex-Transformationskette.
Überblick
Die GPU rendert letztlich nur Geometrie innerhalb eines festen Wertebereichs, des Normalized Device Space (NDC). Bisher wurde Geometrie oft direkt in diesem Bereich definiert. Das Ziel dieses Kapitels ist es, die dargestellte Geometrie von einer frei platzierbaren Kamera abhängig zu machen.
Zentraler Gedanke: Statt die Kamera zu bewegen, wird die gesamte Szene so transformiert, dass die Kamera im Ursprung liegt und entlang der negativen Z-Achse blickt.
Die Kamera zerfällt in zwei Parametergruppen:
- Äußere (extrinsische) Parameter (extrinsic parameters): Position und Ausrichtung der Kamera, umgesetzt durch die View-Matrix V (mittels
lookAt). - Innere (intrinsische) Parameter (intrinsic parameters): welcher Bereich der Szene gerendert wird (Öffnungswinkel, Brennweite), umgesetzt durch die Projektionsmatrix M_proj (orthografisch oder perspektivisch).
Roter Faden:
- Der NDC ist der Zielraum, ein Würfel .
- Die View-Matrix bringt die Szene in den View Space (Camera Space).
- Die Projektion bildet das Sichtvolumen auf den NDC-Würfel ab.
- Die perspektivische Projektion folgt aus dem Lochkamera-Modell und dem Strahlensatz.
- Die gesamte Kette wird in einer Vertex-Shader-Zeile ausgeführt.
Normalized Device Space (NDC)
Der Normalized Device Space (normalized device space) ist der normierte Wertebereich , ein Würfel von bis . Nur Vertices innerhalb dieses Würfels werden letztlich gerendert. Die Koordinaten in diesem Raum heißen Normalized Device Coordinates (NDC).
Motivation: Das Blendenproblem
Das Blendenproblem (aperture problem) ist ein Motivationsbeispiel: Man sitzt im Zug und schaut aus dem Fenster; ein anderer Zug bewegt sich. Mit einem begrenzten Blick (Ausschnitt) ist unmöglich zu entscheiden, ob der eigene oder der andere Zug fährt.
Kernaussage: Bewegung ist relativ. Eine relative Bewegung erzeugt dasselbe visuelle Ergebnis. Das motiviert die Grundidee, statt der Kamera die Szene zu bewegen.
Kameraausrichtung: Szene statt Kamera bewegen
Grundprinzip: Anstatt die Kamera zu bewegen oder zu drehen, bewegt bzw. dreht man die gesamte Szene. Das liefert dasselbe Ergebnis, ist effizienter in der Umsetzung, und die benötigten Transformationen (Translation, Rotation) sind bereits bekannt.
Ziel: Die Kamera liegt im Ursprung und schaut entlang der negativen Z-Achse.
Äußere (extrinsische) Kameraparameter
Die extrinsischen Kameraparameter (extrinsic camera parameters) beschreiben Position und Ausrichtung der Kamera im Weltkoordinatensystem. Sie sind über drei Größen definiert:
- Kamerazentrum c (camera center): Position der Kamera.
- Betrachtungspunkt a (look-at point / target): das Blickziel.
- up-Vektor u (up vector): legt die Oben-Richtung bzw. die Rotation um die Blickachse (Roll) fest.
Diese drei Größen werden durch die View-Matrix integriert und lassen sich automatisch per lookAt in eine Matrix umrechnen.
lookAt
Die Funktion lookAt erzeugt die View-Matrix aus 9 Skalaren: Kamerazentrum, Betrachtungspunkt und up-Vektor.
lookAt( cx, cy, cz, // Kamerazentrum c
ax, ay, az, // Betrachtungspunkt a
ux, uy, uz ); // up-Vektor u
View Transformation und View-Matrix
Die View Transformation (view transformation) ist die Transformation der gesamten Szene, ausgedrückt als Matrixmultiplikation , so dass die Kamera im Ursprung liegt und entlang der negativen Z-Achse schaut. Zugrunde liegt ein rechtshändiges Koordinatensystem. Das resultierende Koordinatensystem heißt View Space bzw. Camera Space.
Die View-Matrix ist das Produkt aus einer Rotationsmatrix (die Kamera-Achsen als Zeilen, ausgedrückt in Weltkoordinaten) und einer Translationsmatrix (Verschiebung um , das negative Kamerazentrum):
Die Zeilen der linken (Rotations-)Matrix sind die Kamera-Achsen, jeweils in Weltkoordinaten (Index ):
- rot = x-Achse
- grün = y-Achse
- blau/türkis = z-Achse
Vertex-Transformationen bis jetzt (Model + View)
Die Model Transformation (model transformation) ist die akkumulierte Kette aus Translation , Skalierung und Rotation , die Objekte in der Welt platziert. Zusammen mit der View-Matrix:
Die logische Reihenfolge der Ausführung geht von rechts nach links: zuerst wirkt (der Vertex wird in der Welt platziert), dann (die Welt wird in den Camera Space gebracht).
Innere (intrinsische) Kameraparameter
Die intrinsischen Kameraparameter (intrinsic camera parameters) legen fest, welcher Bereich der Szene gerendert wird. Bei einer echten Kamera entsprächen sie dem Öffnungswinkel und der Brennweite. Sie werden durch die Projektionsmatrix umgesetzt. Es gibt zwei Projektionsmöglichkeiten:
- Orthografische / Parallelprojektion (orthographic / parallel projection)
- Perspektivische Projektion (perspective projection)
Orthografische (Parallel-) Projektion
Bei der orthografischen Projektion verlaufen die Projektionsstrahlen parallel; es gibt keine perspektivische Verkleinerung mit der Entfernung. Definiert wird ein quaderförmiges Rendervolumen zwischen und , das in das kanonische Volumen (NDC) transformiert wird.
Das Rendervolumen ist über seine Grenzen festgelegt:
Unterschiedliche Seitenverhältnisse werden simuliert, indem die gesamte Szene transformiert wird. Das Seitenverhältnis (aspect ratio) von Kamera und Fenster sollte gleich sein, sonst entstehen Verzerrungen (die Fensterauflösung muss ggf. angepasst werden).
glOrtho( GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble near, GLdouble far );
Perspektivische Wahrnehmung
Die perspektivische Projektion ist die "natürliche Darstellung" und die am meisten verwendete Projektionsart. Die Sehstrahlen treffen sich in einem Fluchtpunkt (vanishing point). Je weiter hinten ein Objekt liegt, desto kleiner erscheint es (perspektivische Verkleinerung). Das Rendervolumen ist ein Pyramidenstumpf (Frustum).
Zentrale Begriffe der Zentralperspektive (central perspective): der Fluchtpunkt am Horizont, in dem sich parallele Fluchtlinien (die Sehstrahlen) scheinbar treffen, sowie der Betrachter-Standort. Wird die Regel "je weiter hinten, desto kleiner" gebrochen, entsteht eine fehlerhafte Größeninformation (optische Täuschung).
Perspektivische Projektion: Lochkamera und Strahlensatz
Das physikalische Modell hinter der perspektivischen Projektion ist die Lochkamera (pinhole camera): eine Schachtel mit einem Loch. Für ein "punktgroßes" Loch entsteht ein perfektes, scharfes Bild. Die Lichtstrahlen des Objekts kreuzen sich im Loch und erzeugen ein umgekehrtes (auf dem Kopf stehendes, seitenverkehrtes) Bild auf der gegenüberliegenden Innenwand (der Bildebene).
Im mathematischen Modell wird die Bildebene (image plane) vor die Kamera gelegt (Abstand = near), so dass das projizierte Bild nicht umgedreht ist.
Herleitung über den Strahlensatz
Grundlage der perspektivischen Projektion ist der Strahlensatz (intercept theorem / similar triangles). Aus ähnlichen Dreiecken folgt die Beziehung zwischen der projizierten Koordinate (auf der Bildebene im Abstand ) und der tatsächlichen y-Koordinate in Tiefe :
Dabei ist der Abstand der Bildebene (near) zur Kamera, die y-Koordinate des Punktes, die Tiefe (z-Abstand) und die projizierte y-Koordinate. Analog gilt für : .
Die Division durch erzeugt die perspektivische Verkleinerung: Bei fester Höhe wird die Projektion umso kleiner, je größer die Tiefe ist.
View-Frustum und Clipping-Ebenen
Das View-Frustum (view frustum) ist der pyramidenstumpfförmige Sichtbereich zwischen der near-plane (Nah-Clipping-Ebene) und der far-plane (Fern-Clipping-Ebene). Nur Geometrie innerhalb des Frustums wird gerendert. Erst die Clipping-Ebenen ermöglichen es, die Projektion als Matrixmultiplikation zu realisieren.
nearundfarsind Abstände in Bezug auf die Kamera.- Der Öffnungswinkel ergibt sich aus dem Abstand der near-Plane zur Kamera.
top,bottom,left,rightsind die Abstände zum Mittelpunkt auf der nahen Ebene.
Frustum-Definition
Zwei Wege, ein Frustum zu definieren:
// Auch asymmetrisches Frustum moeglich
glm::frustum(float left, float right, float top, float bottom,
float near, float far);
// Nur symmetrisches Frustum
glm::perspective(float theta, float aspect, float near, float far);
glm::frustumdefiniert ein (auch asymmetrisches) Frustum über left, right, top, bottom, near, far.glm::perspectiveist die Alternative übertheta(vertikaler Öffnungswinkel / field of view),aspect(Seitenverhältnis Höhe : Breite), near, far. Einschränkung: nur symmetrisches Frustum.
Perspektivische Projektionsmatrix
Nicht klausurrelevant! Die folgende perspektivische Projektionsmatrix ist in den Folien ausdrücklich (oben rechts) als "Nicht klausurrelevant!" markiert. Sie ist hier nur zur Vollständigkeit dokumentiert. Konzeptionell relevant ist hingegen die Wirkung der Projektion (nichtlineare z-Skalierung, x/y perspektivisch skaliert, mehr Präzision für nahe Objekte).
Die Matrix, angewendet auf einen homogenen Punkt:
Ergebnis vor der perspektivischen Division:
Nach der perspektivischen Division (durch ):
Man beachte: und ergeben die aus dem Strahlensatz bekannte Form ; die -Komponente ist nichtlinear in (mehr Präzision für nahe Objekte).
Perspektivische Division und Tiefenpräzision
Die perspektivische Division / Homogenisierung (perspective division) teilt die homogenen Koordinaten durch die -Komponente (hier ). Erst dadurch entsteht die eigentliche perspektivische Verkleinerung. Der Vertex-Shader gibt die Position vor dieser Division aus.
Nichtlineare Tiefenskalierung (nonlinear depth scaling): Punkte auf der Nahbereichsebene bleiben unverändert; werden perspektivisch skaliert; wird nichtlinear skaliert. Folge: mehr Tiefenpräzision für nahe Objekte. Eine sehr ferne far-Ebene bei sehr naher near-Ebene führt zu Präzisionsverlust in der Ferne (Motivation für z-fighting bzw. eine sinnvolle near/far-Wahl).
Negation der z-Koordinate (Rechts- zu Linkshänder)
Der NDC ist linkshändig (positive z-Werte als Entfernung), während im Camera Space die Kamera entlang schaut (rechtshändig). Die Matrix multipliziert die z-Werte mit , um zwischen den Systemen zu wechseln. Diese Invertierung ist in den gl-Methoden bereits integriert.
Die komplette Transformationskette
Die Projection Transformation (projection transformation) bildet das Kamera-Frustum auf den Würfel ab; sie ist entweder oder . Die vollständige Vertex-Transformationskette (inklusive z-Negation):
Als Zwischenstufe (ohne explizites ) wird sie oft kompakt geschrieben:
Die drei Raumstufen der Pipeline: Camera View (finales gerendertes Bild), Camera Space (Objekte im Frustum) und Normalized Device Space (Objekte im NDC-Würfel, durch die Projektion "gestreckt").
Umsetzung im Vertex-Shader
Die gesamte Kette wird in nur einer Zeile GLSL umgesetzt:
#version 330
layout(location = 0) in vec3 vertex;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(vertex, 1.0);
}
Der Output ist die Vertex-Position in homogenen Koordinaten, vor der perspektivischen Division (Homogenisierung, die nach dem Vertex-Shader erfolgt). Reihenfolge: projection wird zuerst angeschrieben, wirkt aber zuletzt (Matrizen wirken von rechts nach links auf den Vertex).
Worked Examples
Beispiel 1: Perspektivische Projektion eines Punktes (Strahlensatz)
Gegeben ein Punkt mit Höhe in Tiefe und eine Bildebene im Abstand vor der Kamera. Gesucht: die projizierte Höhe .
Über ähnliche Dreiecke (Strahlensatz):
Interpretation: Bei fester Höhe wird die Projektion umso kleiner, je größer die Tiefe ist (perspektivische Verkleinerung). Analog für .
Beispiel 2: Perspektivische Projektionsmatrix angewendet (nicht klausurrelevant)
Die Anwendung der 4x4-Matrix auf liefert vor der Division . Nach der perspektivischen Division durch erhält man . Die -Komponenten reproduzieren den Strahlensatz; die -Komponente ist nichtlinear in (mehr Präzision nahe der Kamera).
Beispiel 3: Vertex-Shader (GLSL)
Nur 4 wesentliche Zeilen: die drei Uniforms model, view, projection plus die eine Zuweisung gl_Position = projection * view * model * vec4(vertex, 1.0). Output ist die Vertex-Position in homogenen Koordinaten, vor der perspektivischen Division. Reihenfolge: projection steht links (wirkt zuletzt), model steht rechts (wirkt zuerst).
Prüfungsrelevanz
- Grundidee: "Szene bewegen statt Kamera" - relative Bewegung, gleiches Ergebnis, effizienter.
- Die drei extrinsischen lookAt-Parameter: Kamerazentrum , Betrachtungspunkt , up-Vektor . Die Zuordnung der 9
lookAt-Skalare kennen. - Aufbau der View-Matrix als Rotation (Kamera-Achsen als Zeilen, in Weltkoordinaten) Translation.
- Strahlensatz-Herleitung: (aus ähnlichen Dreiecken).
- Unterschied orthografisch vs. perspektivisch (parallele Strahlen / Quader vs. Fluchtpunkt / Frustum).
- View-Frustum mit near/far/left/right/top/bottom;
glm::frustumvs.glm::perspective. - Die komplette Transformationskette und die eine Shader-Zeile.
- Konzeptionell relevant (auch ohne die Matrix selbst): die Wirkung der perspektivischen Projektion (nichtlineare z-Skalierung, x/y perspektivisch skaliert, mehr Präzision für nahe Objekte).
Ausdrücklich NICHT klausurrelevant: die perspektivische Projektionsmatrix (Seite 30, in den Folien oben rechts markiert). Nur die Matrix selbst ist ausgenommen, nicht ihre konzeptionelle Wirkung.
Typische Fehler
- Matrix-Reihenfolge: wirkt von rechts nach links. Im Shader
projection * view * model * vertex:modelwirkt zuerst,projectionzuletzt. Reihenfolge nicht vertauschen. - Blickrichtung: Im Camera/View Space blickt die Kamera entlang der NEGATIVEN Z-Achse (rechtshändig). Der NDC ist linkshändig (positive z = Entfernung). Deshalb die Negation (), in den
gl-Methoden bereits integriert. - Seitenverhältnis: Kamera-Aspect und Fenster-Aspect müssen gleich sein, sonst Verzerrung. Bei
glOrthoauch die Fensterauflösung anpassen. - up-Vektor: legt die Rotation um die Blickachse fest; ohne korrekten up-Vektor ist die Ausrichtung unterbestimmt.
- glm::perspective-Einschränkung: erzeugt nur symmetrische Frusta; asymmetrische Frusta erfordern
glm::frustum. - Parameter-Reihenfolge
glm::frustum: left, right, TOP, BOTTOM, near, far (top vor bottom - abweichend vonglOrtho, das bottom vor top hat). - Tiefenpräzision: sehr nahe near-Ebene bei sehr ferner far-Ebene führt zu Präzisionsverlust hinten (z-fighting).
- Perspektivische Division nicht vergessen: Shader-Output ist homogen (vor Division durch ); die eigentliche Verkleinerung entsteht erst durch die Homogenisierung nach dem Vertex-Shader.
Glossar
| Deutsch | English |
|---|---|
| Normalisierter Geräteraum (NDC) | normalized device space |
| Normalisierte Gerätekoordinaten | normalized device coordinates |
| Blendenproblem | aperture problem |
| äußere / extrinsische Kameraparameter | extrinsic camera parameters |
| innere / intrinsische Kameraparameter | intrinsic camera parameters |
| Kamerazentrum (c) | camera center |
| Betrachtungspunkt (a) | look-at point / target |
| up-Vektor (u) | up vector |
| Sichttransformation / View-Matrix (V) | view transformation / view matrix |
| lookAt-Funktion | lookAt function |
| Sichtraum / Kameraraum | view space / camera space |
| Modelltransformation (M_Model) | model transformation |
| Projektionstransformation (M_proj) | projection transformation |
| orthografische / Parallelprojektion | orthographic / parallel projection |
| perspektivische Projektion | perspective projection |
| Fluchtpunkt | vanishing point |
| Zentralperspektive | central perspective |
| Fluchtlinien | vanishing lines |
| Horizont | horizon |
| Lochkamera | pinhole camera |
| Bildebene | image plane |
| Strahlensatz | intercept theorem / similar triangles |
| Sichtpyramidenstumpf / Sichtvolumen | view frustum |
| Nah- / Fern-Clipping-Ebene | near / far clipping plane |
| Öffnungswinkel (theta) | opening angle / field of view |
| Seitenverhältnis | aspect ratio |
| perspektivische Division / Homogenisierung | perspective division / homogenization |
| nichtlineare z-Skalierung | nonlinear depth scaling |
| Negation der z-Koordinate (M_R->L) | z-negation, right- to left-handed conversion |
| homogene Koordinaten | homogeneous coordinates |
| Vertex-Shader | vertex shader |