(10) Deferred Shading - Uni Koblenz-Landaucg/ss13/cg2/10...KOBLENZ · LANDAU (10) Deferred Shading...
Transcript of (10) Deferred Shading - Uni Koblenz-Landaucg/ss13/cg2/10...KOBLENZ · LANDAU (10) Deferred Shading...
U N I V E R S I T Ä T
KOBLENZ · LANDAU
(10) Deferred Shading
Vorlesung
Computergrafik II
Stefan Müller
Dank an Niklas Henrich, Gerrit Lochmann
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Wdh. 1: Framebufferobjects (FBOs)
Statt in den Framebuffer direkt
zu rendern, kann man Texturen
„attachen“, in die gerendert
werden soll (render to texture)
Ein Framebuffer-Objekt kann
mehrere Rendering-Ziele
beinhalten
- GL_COLOR_ATTACHMENT0
…
- GL_COLOR_ATTACHMENTn
- GL_DEPTH_ATTACHMENT
- GL_STENCIL_ATTACHMENT
- Default Framebuffer wird vom
Windows-Manager eingerichtet
(Color, Depth und Stencil).
S. Müller - 2 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Wdh. 2: Beispiel Depthbuffer
FBO generieren und bindenGLuint framebufferHandle = 0;
glGenFramebuffers(1, &framebufferHandle);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferHandle);
Texturobj anlegen + bindenGLuint depthTextureHandle;
glGenTextures(1, &depthTextureHandle);
glBindTexture(GL_TEXTURE_2D, depthTextureHandle);
Textur anlegen und Parameter setzenglTexImage2D(…); glTexParameteri(…);
Textur an FBO attachenglFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, depthTextureHandle, 0);
Szene rendernglDrawBuffer(GL_NONE); // No color buffer is drawn to.
Später darauf zugreifen glBindTexture(GL_TEXTURE_2D, depthTextureHandle);
S. Müller - 3 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Wdh. 3: Shadow Mapping
Einfache Schattenabfrage pro Fragment/pro Lichtquellevec3 p = pos_LKS.xyz / pos_LKS.w;
float depth = texture( tex, vec2(p.x,p.y)).x;
if (depth < (p.z-0.0005))
//Schatten
Selbstverdeckung (Shadow Acne)GL_POLYGON_OFFSET_FILL
Peter Panning (Schwebende Objekte)glCullFace(GL_FRONT)
Aliasing Effekte Percentage Closer Filter (PCF)
Weiche Schatten Flächige Lichtquellen
Mehrere Samples/Shadowmaps
S. Müller - 4 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading
Stefan Müller - 5 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading
Ein sehr unscharfer Begriff …
Im allgemeinen Fall versteht man darunter
Deferred Shading („verzögertes Schattieren“) oder auch
Deferred Lighting („verzögerte Beleuchtung“)
Szene in verschiedene Texturen rendern
In einem zweiten Schritt auf / mit dem Inhalt der Texturen
arbeiten
Praktisch jede moderne GPU-Anwendung benutzt
irgendeine Form des deferred rendering / shading
Im Folgenden wird das Szenario (Beleuchtung von
Objekten in einer Szene) vorgestellt, für welches der
Begriff am häufigsten verwendet wird
S. Müller - 6 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Objekte in Szene beleuchten
(ohne Deferred Shading)
Eine Möglichkeit
Jedes Objekt muss somit #Lichtquellen #Objekte mal
gezeichnet (und beleuchtet) werden
Manche Objekte werden beleuchtet, obwohl sie
vielleicht in einem späteren Schritt von einem anderen
Objekt verdeckt werden
Für jede Lichtquelle in der Szene
Lichtquelle aktivieren
Für jedes Objekt in der Szene
Objekt zeichnen
S. Müller - 7 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Objekte in Szene beleuchten
(ohne Deferred Shading) Eine andere Möglichkeit
Jedes Objekt muss wieder #Lichtquellen #Objekte
mal gezeichnet und beleuchtet werden
Warum nicht mehrere Lichtquellen gleichzeitig
anwenden?
Funktioniert bei wenigen Lichtquellen
Manche Anwendungen (Spiele) können über hunderte von
Lichtquellen verfügen, die gleichzeitig aktiv sind
Zu viele Argumente an einen Shader
Für jedes Objekt in der Szene
Für jede Lichtquelle in der Szene
Lichtquelle aktivieren und Objekt zeichnen
S. Müller - 8 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading
Vorteile
Jedes Objekt wird genau einmal gezeichnet
Es werden nur die tatsächlich sichtbaren Pixel beleuchtet
Aufwand: #Objekte + #Lichtquellen anstatt
#Lichtquellen #Objekte
Für jedes Objekt in der Szene
Rendere Weltkoordinate, Normale, Farbe etc. in MRTs
Für jede Lichtquelle in der Szene
Beleuchtung als Postprocess auf den erstellten Texturen
S. Müller - 9 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Was leisten folgende Shader?
Vertex-Shader
void main(){
Pass_UVCoord = In_UvCoord;
Pass_Position = u_View * u_Model * In_Position;
gl_Position = u_Projection * u_View * u_Model * In_Position;
Pass_Normal = vec3(transpose(inverse(u_View * u_Model))* In_Normal);}
Fragment-Shader
void main(){
Out_Position= Pass_Position;
Out_Normal= vec4(normalize( Pass_Normal), 0);
Out_Color= texture(tex, Pass_UVCoord);}
S. Müller - 10 -
in vec4 In_Position;
in vec2 In_UvCoord;
in vec4 In_Normal;
uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Projection;
out vec4 Pass_Position;
out vec2 Pass_UVCoord;
out vec3 Pass_Normal;
in vec4 Pass_Position;
in vec2 Pass_UVCoord;
in vec3 Pass_Normal;
uniform sampler2D u_tex; out vec4 Out_Position;
out vec4 Out_Normal;
out vec4 Out_Color;
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Multiple Render Targets
Der Vorteil der FBOs
Multiple Render Targets (MRT)
In einem Schritt in verschiedene Texturen rendern
Ohne MRTs müsste die Szene für jede Information (Position,
Normale, etc.) neu gerendert werden
Niklas Henrich - 11 -
Fragment
Program
Render Target 1 (Textur)
Render Target 2 (Textur)
Render Target 3 (Textur)
Position
U N I V E R S I T Ä T
KOBLENZ · LANDAU
G-Buffer
Trennung der Geometrieverarbeitung von der Lichtberechnung
Im ersten Pass werden für jedes Pixel alle
beleuchtungsrelevanten Daten (z.B. 3D-Position, Normale,
Texturfarbe, Glanzzahl) in unterschiedliche Rendertargets
(oftmals auch G-Buffer genannt) rasterisiert.
Dies geschieht sogar „gleichzeitig“ (also Füllen der Buffer in
einem Schritt)
S. Müller - 12 -
3D-Position; Normale; Farbe
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Compositing
Am Ende geht man Pixel für Pixel durch
Für jedes Pixel (vorderstes Flächenelement) seht alles
zur Verfügung, was man zur Beleuchtung benötigt:
Position in Kamerakoordinaten
Normale in Kamerakoordinaten
Farbe
Hierfür rendert man ein bildschirmfüllendes Rechteck
(screen filling quad)
Dadurch wird für jedes Pixel der Fragment-Shader
aufgegriffen
In diesem Pass findet die Beleuchtung pro Pixel statt
S. Müller - 13 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Screen filling …
Polygon
S. Müller - 14 -
x
y
1 11
1
3
3
Dreieck
x
y
1 11
1
Vertex-Shaderin vec2 In_Position;
out vec2 Pass_UV;
void main() {
gl_Position = vec4(positionAttribute, 0, 1);
passUV = (positionAttribute + 1) / 2;
// Texturkoordinaten zwischen 0 und 1
}
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Final Composition (Fragment-Programm)
void main() {
vec4 position = texture(positionMap, passUV);
vec4 normal = texture(normalMap, passUV);
vec4 color = texture(colorMap, passUV);
//lightPosition from camera system
vec4 lightPos = vec4(0,4,-4,1);
//calculate lighting with given position, normal and lightposition
vec3 nPosToLight = normalize(vec3(lightPos.xyz - position.xyz));
float ambient = 0.3;
float diffuse = max(dot(normal.xyz, nPosToLight), 0);
fragmentColor = color * ambient + color * diffuse;
}
S. Müller - 15 -
in vec2 Pass_UV; uniform sampler2D positionMap;
uniform sampler2D normalMap;
uniform sampler2D colorMap
out vec4 fragmentColor;
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Ergebnis
S. Müller - 16 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading – Kamera-/Weltkoordinate?
Falls genügend Platz vorhanden ist, können die 3 Koordinaten in
einer eigenen Textur gespeichert werden
Ansonsten kann die Position aus dem Tiefenwert sowie der
Position des Pixels im Framebuffer und der Kamera errechnet
werden
Trade-off: Speicherverbrauch vs. Rechenlast
Anmerkung Normalen:
Falls die Normalen normalisiert sind, müssen nur zwei Werte
gespeichert werden
Der dritte kann aus diesen errechnet werden
Das Vorzeichen des dritten Wertes muss bei einem anderen Wert
mit abgespeichert werden
• Z.B. Tiefenwert (ist immer positiv)
S. Müller - 17 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading – performante Beleuchtung
Approximiere Lichtkegel
durch konvexes Polygon
Aktiviere Back-Face Culling
Rendere konvexes Polygon
Für jedes Pixel, das durch
den Lichtkegel überdeckt
wird, wird der „Lichtquellen-
Pixel Shader“ aktiviert
Pixel Shader liest Daten aus
G-Buffer aus (Position,
Normale, Material etc.) und
führt Lichtberechnungen für
aktuelles Pixel durch
Anmerkung: Wenn kein Back-Face Culling
aktiviert ist, wird jedes Pixel doppelt
beleuchtet. Der Pixel Shader würde einmal
für die Vorderseite und einmal für die
Rückseite des Polygons aktiviert.
Stefan Müller - 18 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading
Für die roten Pixel wird der „Beleuchtungs“-Pixel
Shader aktiviert
Stefan Müller - 19 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading
Pixel Shader liest an „seiner Position“ die
Informationen aus dem G-Buffer aus und führt
Beleuchtungsberechnung durch
Position
Normale
Material
liest Daten
Stefan Müller - 20 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading
Vorteile
Viele Lichtquellen bei
komplexer Geometrie
möglich
Postprocessing Effekte
(Compositing) (Bloom,
Tonemapping, Depth of Field,
etc.) können einfach
angeschlossen werden, da
bereits alle benötigten
Informationen aufbereitet
vorliegen.
Nachteile
Speicherverbrauch des G-
Buffers
Hohe Bandbreitenausleistung
(viele Texturzugriffe)
Kein Antialiasing /
Multisampling
Wird nicht auf den Color
Attachments durchgeführt
Transparenzen
Pro Pixel wird nur das
vorderste Objekt gespeichert
Stefan Müller - 21 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Deferred Shading – Demo
http://www.humus.name/index.php?page=3D&ID=74
Stefan Müller - 22 -
Demo
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Filter
S. Müller - 23 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Filter
Mit Hilfe eines screen-filling Polygons lassen sich
Texturen auch sehr gut filtern.
Für jedes Pixel werden die entsprechenden
Nachbarpixel bestimmt , gemäß der Filtermaske
gewichtet und das Resultat als finale Pixelfarbe
weitergegeben.
Allerdings werden hier – je nach Filter-Kernel –
ziemlich viele Texturzugriffe nötig.
Ist der Filter separierbar, so lässt sich dies effizienter
implementieren
S. Müller - 24 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Glow
Finales, gerendertes Bild wird z.B. mit Gauß-Maske
gefiltert und geblendet
Besser: nur helle Flächen rendern/filtern (hier durch
zusätzliche Textur)
S. Müller - 25 -
GPU Gems
DemoDemo
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Environment Maps
S. Müller - 26 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU Niklas Henrich - 27 -
Cube Mapping
Eine Form des Environment Mappings
Umgebung wird durch 6 Texturen beschrieben Kamera sieht nach vorne, hinten, oben, unten, links und
rechts
Texturen aus Media-Ordner der
DirectX SDK March 2008
© Microsoft Corp.
U N I V E R S I T Ä T
KOBLENZ · LANDAU Niklas Henrich - 28 -
Environment Mapping
Simulation von Objekten, die deren Umgebung reflektieren
Gespiegelten oder gebrochenen Strahl als „look-up“ in die Cube Map benutzen
…
envColor = textureCube(envMap,r);
…
…
r = reflect(i, n);
…
n
i
r
Cube Map
Vertex Shader
Fragment Shader
U N I V E R S I T Ä T
KOBLENZ · LANDAU Niklas Henrich - 29 -
Environment Mapping - Ergebnisse
r = reflect(i, n)
ersetzt durch
r = refract(i, n, 1.1)Demo
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Depth Peeling
S. Müller - 30 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Depth Peeling
Im Framebuffer ist immer das vorderste Pixel zur Kamera zu
sehen
Depth Peeling erzeugt n Bilder, in denen jeweils das vorderste,
„zweit-vorderste “, …, „n-vorderste“ Pixel zu sehen ist
Stefan Müller - 31 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Depth Peeling – Ablauf
1. Schritt (Vordersten Pixel)
Szene rendern
Tiefenpuffer abspeichern
2. bis n.Schritt („Zweit-vordersten“ bis „n-vordersten“ Pixel )
Szene rendern
Im Pixel Shader den Tiefenwert des aktuellen
Fragments mit dem Wert aus dem zuvor gespeicherten
Tiefenpuffer vergleichen
• Nur diejenigen Fragments mit einem größeren Tiefenwert
zeichnen
Tiefenpuffer für gezeichnete Pixel speichern
Stefan Müller - 32 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Depth Peeling – BilderEbene 0 Ebene 1
Ebene 2 Ebene 3
Stefan Müller - 33 -
Demo
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Depth Peeling
Komplexität ist linear O(n)
Größter Kritikpunkt
Speicherverbrauch ist linear
Ein Bild pro Schicht
Komplexe Szenen bestehen schnell aus 20+ Schichten
Anwendungen
Transparenzen
Ray-Tracing
Volumen Rendering
Unzählige mehr …
Stefan Müller - 34 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Depth Peeling - Transparenzen
Um Transparenzen korrekt darstellen zu können, müssen die Objekte in
der richtigen Reihenfolge gezeichnet werden
Mit Depth Peeling kann dieses Problem umgangen werden
Ablauf
Szene „depth peelen“ und jede Schicht (RGBA) in Textur speichern
Alpha Blending aktivieren
Schichten von hinten nach vorne überlagern
Mit Depth Peeling (korrekte Transparenz) Ohne Depth Peeling (inkorrekte Transparenz))
Stefan Müller - 35 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Order Independent Transparency - Demo
http://developer.download.nvidia.com/SDK/10.5/opengl/samples.html#dual_depth_peeling
http://developer.download.nvidia.com/SDK/10.5/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf
Demo
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Geometry-Shader
Stefan Müller - 37 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Geometry Shader
Neue programmierbare Einheit der Grafikpipeline
Direkt nach Vertex Shader (vor Clipping etc.)
Dynamisch neue Geometrie erzeugen
Geometrie löschen
Stefan Müller - 38 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Geometry Shader - Eingabe
Arbeitet immer auf „gesamten“ Eingabeprimitiv
Mögliche Eingabeprimitive Punkt
Linie
Dreieck
Shader hat Zugriff auf Alle Punkte des Eingabeprimitives
Alle direkt benachbarten Punkte
p0
p1
p2
q0
q1
q2
Benachbartes DreieckZugriff möglich
Stefan Müller - 39 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Geometry Shader - Ausgabe
Ausgabe (beliebig* viele) Punkte
Linien (line strips)
Dreiecke (triangle strips)
Es ist auch möglich, keine Geometrie auszugeben
Maximale Anzahl der ausgegebenen Primitive pro Shaderaufruf muss zur Compile-Zeit bekannt sein Je größer diese Zahl, umso stärker sinkt die Performance
Ein- und Ausgabetyp können verschieden sein Dreieck als Eingabe
Linienzug als Ausgabe
Wireframe
*beliebig bedeutet „bis zum Hardwarelimit“
Stefan Müller - 40 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Geometry Shader – neue Befehle
EmitVertex() Eckpunkt dem aktuellen Ausgabeprimitiv (z.B. Dreieck)
hinzufügen
EndPrimitive() Aktuelles Ausgabeprimitiv abschließen
Neues Ausgabeprimitiv vom gleichen Typ wird begonnen
Ähnlich wie OpenGL-Befehlsreihenfolge:
gl_Position = vec4(1.0, 0.5, 0.3, 1.0);
EmitVertex();
glEnd();
glBegin(…);
Stefan Müller - 41 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Beispiel – aus Eins mach Drei
Geometry Shader: Aus Geometry Shader: Ein
Stefan Müller - 42 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Beispiel – aus Eins mach Dreivoid main()
{
// 1. Dreieck erzeugen und verschieben
for(int i = 0; i < gl_VerticesIn; i++){
gl_FrontColor = vec4(0,1,0,1);
gl_Position = vec4(gl_PositionIn[i].x * 0.5, (gl_PositionIn[i].y * 0.5) + 0.5, 0, 1);
EmitVertex();
}
EndPrimitive();
// 2. Dreieck erzeugen und verschieben
…
// 3. Dreieck erzeugen und verschieben
….
Anzahl der Eckpunkte des
Eingabeprimitives
Array von Eckpunkten des
Eingabeprimitives
Stefan Müller - 43 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Geometry Shader – Ausgabelimit
Ein Geometry Shader kann momentan maximal ca.
256 Eckpunkte ausgeben
Soll mehr Geometrie erzeugt werden, muss dies in
mehreren Schritten geschehen
Folgende Funktionalität wird dazu benötigt:
Bereits erzeugte Geometrie muss zwischengespeichert
werden können
Erzeugte Geometrie muss wieder abgerufen werden können
Diese Funktionalität wird durch das sogenannte
„Transform Feedback“ bereitgestellt
Stefan Müller - 44 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Transform Feedback
Ermöglicht es, Geometrie in Buffer-Objekte zu rendern
Fragment Shader wird ausgeschaltet
Geometrie kann somit zwischengespeichert werden
Inhalt des Buffers kann zu einem späteren Zeitpunkt
erneut gerendert werden
Stefan Müller - 45 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Transform Feedback
Vertex Shader und Geometry Shader können
Geometrie beliebig verändern
Neue Geometrie hinzufügen (GS)
Vorhandene Geometrie verschieben (VS + GS)
Geometrie löschen (GS)
Nachdem gewünschte Geometrie erzeugt wurde
Fragment Shader einschalten
Geometrie rendern
Stefan Müller - 46 -
U N I V E R S I T Ä T
KOBLENZ · LANDAU
Transform Feedback – Demo
http://developer.download.nvidia.com/SDK/10.5/opengl/samples.html#transform_feedback_fractal
Stefan Müller - 47 -
DemoDemo