39
CG (Subject) / Deffered Shading (Lesson)
Advertisement
- Was ist Deffered Shading Deferred Shading (oder auch Deferred Lightning) beschreibt den Vorgang, eine Szene in zwei Durchgängen zu rendern, wobei im ersten Durchgang auf einem FBO gearbeitet wird. Hier werden Informationen in Texturen gespeichert, die im zweiten Durchgang auf ein Screen-Filling-Polygon gerendert werden. Es findet dann z.B. die Beleuchtung erst im zweiten Schritt statt.
- Phong-Shading via DS Möchte man eine große Anzahl von Lichtquellen in der Szene verwenden, ist die Auswertung jeder Lichtquelle pro Pixel eine sehr aufwändige Methode. Im Normalfall werden hier auch Pixel ausgewertet, die später in der Szene gar nicht zu sehen sind. Implementiert man für die Beleuchtung ein Deferred Shading, werden die Objekteigenschaften (Weltkoordinaten, Normalen, Farben...) in MRTs (Multiple Rendering Targets) gerendert. Für jede Lichtquelle wird danach die Beleuchtung via Post-Processing auf die erstellten Texturen angewandt. Dadurch werden nur die tatsächlichen Pixel beleuchtet.
- G-Buffer / MRTs füllen Um die MRTs zu beschreiben wird ein Vertex-Shader verwendet, der Positionskoordinaten (mit Model- und Viewm. verrechnet), UV-Koordinaten, und die Normale (mit transponierter Inversen der ModelViewm. verrechnet)weitergibt. glPosiiton wirdganznormalüberProjektions-,Model-undViewmatrix berechnet. Der Fragment-Shader gibt anstelle eines Farbwerts drei Werte für Position (reiner pass), Normale (normalisierte Eingabe als vec4) und die Farbe (nur von der Textur via UV-Koordinate übernommen) aus. Diese Werte werden in ihrer Renderreihenfolge in Attachments des aktuellen FBOs geschrieben. Die hierfür verwendeten Attachments (MRTs) werden auch G-Buffer genannt.
- Compositing Das Pixelweise auswerten des Beleuchtungsmodells für das Screen-Filling-Polygon wird als Compositing bezeichnet. Für jedes Pixel (vorderstes Element) steht alles zur Verfügung, was man zur Beleuchtung benötigt: - Position in Kamerakoordinaten - Normale in Kamerakoordinaten - Texturfarbe (oder -koordinate) Die entsprechenden Texturen werden als uniform sampler2D an den Fragment-Shader übergeben, welcher diese wie gewohnt über texture(position, passUV) ausliest und das Phong-Modell anwendet.
- Performante Beleuchtung mit Deferred Lighting Um die Performanz weiter zu steigern, können Lichtkegel (alternativ auch Kugeln für Punktlichtquellen) als Geometrie approximiert werden. Das Beleuchtungsmodell der Lichtquelle muss dann nur noch ausgewertet werden, wenn der Lichtkegel den zu rendernden Pixel überdeckt. Hierfür muss Frontface-Culling mit glCullFace() aktiviertsein,damiteineLichtquellenichtzweimal“aktiviert”wird,undderTiefentest ausgeschaltet werden. Es wird eine Szene mit Proxygeometrien (Lichteinflüssen) erstellt. Für den zweiten Renderpass wird dann nur noch die Proxygeometrie gerendert (anstelle eines Sreen-Filling-Quads), jedoch das Beleuchtungsmodell mit den Informationen des FBOs ausgewertet. ! Es wird nur der hintere (statt des vorderen) Teil der Proxygeoemtrien betrachtet, damit das Modell auch ausgewertet wird, wenn die Kamera in dieser Geoemetrie ist.
- Vorteile von DS Viele Lichtquellen bei komplexer Geometrie möglich. Postprocessing-Effekte können einfach angeschlossen werden, da benötigte Informationen bereits vorliegen.
- Nachteile von DS Speicherverbrauch des G-Buffers (heute nicht mehr allzu relevant) Hohe Bandbreitenauslastung Kein AA / Multisampling Transparenzen (es wird nur das vorderste Objekt gespeichert)
- Was ist Ambient Occlusion Ambient Occlusion behandelt die Fragestellung wie viel ein bestimmter Pixel von der Umgebung verdeckt wird und welchen Teil des ambienten Lichts er somit erhält. Dies gibt den Eindruck von Volumen und Tiefe. Der Einfallsanteil von Umgebungslicht wird in einem Wirkungsradius definiert, da sonst z.B. in einem geschlossenen Raum in jede Richtung irgendwann ein verdeckendes Objekt gefunden werden würde. Dieser Wirkungsradius wird von einer Fläche aus als Halbraum berechnet.
- Verfahren von Ambient Occlusion Ray-Tracing: Wird im Objektraum durchgeführt. Man schickt Strahlen in alle Richtungen des Halbraums und errechnet schneidende Objekte. Verfahren wie SSAO werden im Bildraum durchgeführt (also als Post-Processing). Hybride Verfahren
- Was ist SSAO SSAO (Screen Space Ambient Occlusion) Auf Basis von Tiefenwerten, Normalen- und weiteren Buffern wird eine AO-Map erstellt. Es gibt unterschiedliche Verfahren für diesen Vorgang.
- Advertisement
- Verfahren nach Cytrek Für einen zu rendernden Pixel werden zufällige Punkte im Wirkungsradius berechnet. Für diese Punkte werden Tiefenwerte aus Sicht der Kamera berechnet. Für diese Tiefenwerte wird bestimmt, ob sie sichtbar wären (anhand der Tiefentextur des Objektbildes). Das Verhältnis der Sichtbaren zu nicht-Sichtbaren Punkte gibt an, wie viel ambientes Licht den zu rendernden Punkt erreicht.
- Notizen zu Cytrek Dieses Verfahren erzeugt ab ca. 16 Samples annehmbare Bilder. Zusätzlich verwendet man am Ende einen Bilateralfilter um Störungen zu verringern. Die Zufallsvektoren können zu Performanzsteigerung auch einmal übergeben und dann nur noch zufällig rotiert werden.
- Anzahl der Color Buffer im Allgemeinen 3 Stück - Position - Normale - Farbe - (denkbar auch Texturkoordinate) - (denkbar auch andere Attribute)
- Inhalt der Color Buffer - Position Position in Weltkoordinaten? Oder in Bildschirmkoordinaten? - XYZ-Wert als RGB-Wert kodieren - Alpha-Wert der Textur beispielsweise für Tiefe - Mindestens 16bit-float Werte je Channel verwenden, damit negative Werte gespeichert werden
- Inhalt der Color Buffer - Normale In Weltkoordinaten? In Bildschirmkoordinaten? - XYZ-Wert als RGB-Wert kodieren - Entweder 16bit-float Werte je Channel, oder Normale normalisieren und vom Bereich [-1, 1] auf [0, 1] skalieren
- Inhalt der Color Buffer - Farbe - Farbe des Objekts - Farbe aus Textur mittels Texturkoordinaten - Noch nicht beleuchtet oder schattiert (das kommt später)
- Ist ein Depth Buffer notwendig? Kommt auf die zu rendernde Geometrie an - Gibt es in der Szene verschiedene Tiefenwerte auf einem Fragment und es soll nur der vorderste gelten? ⇒ Dann ja
- Wie genau werden diese Texturen des G-Buffers mit Daten gefüllt? Befüllen der Texturen mittels Shader - Festlegen der Outputs mit dem layout() Befehl - Berechnung der Position und der Normale in dem gewünschten Raum (Objektkoordinaten, Weltkoordinaten, Kamerakoordinaten oder Bildschirmkoordinaten?) - Nutzung von Model-, View- und Projectionmatrix im Shader
- Was geschieht bei der Berechnung der Daten genau? Fragment Shader Variablen: //incoming data for the single texturesin vec4 passPosition; in vec3 passNormal; in vec2 passUVCoord; //additional datauniform vec3 diffuseColor; uniform float alpha; uniform int useColorTexture; uniform sampler2D colortexture; //writable textures for deferred screen space calculations layout(location = 0) out vec4 positionOutput; layout(location = 1) out vec4 normalOutput; layout(location = 2) out vec4 colorOutput;
- Was geschieht bei der Berechnung der Daten genau? Fragment Shader Wertzuweisung: layout(location = 0) out vec4 positionOutput;layout(location = 1) out vec4 normalOutput;layout(location = 2) out vec4 colorOutput; void main(){ positionOutput = passPosition; normalOutput = vec4(normalize(passNormal), 0); colorOutput = vec4(diffuseColor, 1); if (useColorTexture != 0){colorOutput = texture(colortexture, passUVCoord);}}
- G-Buffer G-Buffer in erstem Renderpass aufstellen - Rendern der Szene - mit Position - mit Normale - Beleuchtung mit Deferred Lighting nur dort, wo sie gebraucht wird (im Bildraum)
- Renderpass für Beleuchtung - Beleuchtung nur in der Umgebung der Lichtquellen - Umgebung einspannen mit Proxie Geometrie - Rendern der Proxie Geometrie (Beleuchtung nur in diesem Gebiet) - Beleuchtung im Bildraum der zuvor gerenderten Szene
- OpenGL Einstellungen für zweiten Renderpass - Proxie Geometrie hat 2 Seiten (Vorder- und Rückseite), aber es soll nur einmal beleuchtet werden, daher glCullFace() - Culling von Vorderseiten, Rückseiten werden gerendert, auch dann, wenn die Kamera innerhalb der Proxie Geometrie ist - Ausschalten des Tiefenpuffers, da die Rückseiten von der Szene verdeckt sein könnten, aber dennoch in diesem Gebiet beleuchtet werden soll - Beleuchtung aller Lichtquellen zusammenaddieren, daher Nutzung vonglBlendFunc(GL ONE, GL ONE)
- Proxy Geometrie für Lichtquellen Punktlichtquellen leuchten in alle Richtungen, Kugel als Proxie Geometrie - Spotlights leuchten nur in eine Richtung, Kegel als Proxie Geometrie - Prinzipiell ist jede Geometrie als Proxie Geometrie möglich - Dort, wo die Proxie Geometrie dargestellt wird, beleuchtet die Lichtquelle die Szene
- Welche Renderpasses sind notwendig, wenn eine Szene mithilfe von Deferred Shading beleuchtet werden soll? 1. Renderpass für G-Buffer - 2. Renderpass für Beleuchtung (auf G-Buffer)
- Welche Geometrie wird jeweils gerendert? 1. Renderpass rendert Szene - 2. Renderpass rendert Proxie Geometrie - Eine Lichtquelle beleuchtet genau nur dort!
- Welche Geometrie wird jeweils gerendert? 1. Renderpass rendert Szene - 2. Renderpass rendert Proxie Geometrie - Eine Lichtquelle beleuchtet genau nur dort!
- Welche Shader werden verwendet und was bewirken sie? 1. Renderpass nutzt G-Buffer Shader (s.o.) 2. Renderpass nutzt Beleuchtungs Shader Phong Beleuchtung Position, Normale und Farbe aus G-Buffer an der entsprechenden Stelle
- Welche zusätzlichen Einstellungen müssen jeweils festgelegt werden und warum? 1. Renderpass nutzt Tiefentest (wie immer) 2. Renderpass ohne Tiefentest, aber mit Blending und mit Frontface Culling (s.o.)
- Was ist das Ziel von Screen-Space Ambient Occlusion? - Verschattung eines Punktes in Abhängigkeit seiner Umgebung - Vereinfachung der globalen Beleuchtung der Realität - Verfahren basierend auf dem Bildraum
- Advertisement
- Wie physikalisch plausibel ist das Verfahren und dessen Ergebnisse? - Die Idee ist plausibel - Ergebnis aber nur eine Annäherung - Vortäuschen von globaler Beleuchtung...
- Was passiert pro Fragment bei der SSAO Berechnung? Es werden zufällige Strahlen v ausgehend von dem derzeitigen Punkt berechnet - Strahlende von v hat eine berechnete Tiefe vD - Strahlende von v wird auf Bildschirm projiziert BP - BP hat eine gespeicherte Tiefe BPD - Vergleich von vD und BPD - Mehr Verschattung, wenn vD kleiner als BPD
- Problem: Wie erhält man zufällige Vektoren in GLSL? GLSL hat keine rand() Funktion - rand() Funktion muss irgendwie selbst geschrieben werden...
- Wie kann man die Performance und die Qualität des Verfahrens beeinflussen Mehr Vergleichsstrahlen - bessere Qualität - schlechtere Performance
- Zusammenfassung Multi Pass Verf Ein FBO je Pass - Bestimmte Menge an Buffern je FBO - Pro Pass ein eigener Shader - Zwischenspeichern von Ergebnissen, welche anschließend wiederverwendet werden können - Arbeiten auf Texturen (Render-to-Texture)
- Ich will ein Multi-Pass Verfahren erstellen... Was muss ich mir überlegen? Ich muss ein FBO erzeugen - Braucht das FBO einen Tiefenpuffer? - Begrenze ich den Bildbereich (Stencilbuffer)? - Wie viele Informationen will ich speichern (jeweils einen Colorbuffer)? - Gibt mein Shader auch in alle Buffer etwas aus? - Gibt er auch das richtige aus? (Test mit Screen-Filling Quad oder Shader Debugger) - Welche Geometrie? (Szene? Andere Szene? Screen-Filling Quad?)
- Wie könnte man dies in einem Framework wie dem CVK bewerkstelligen? Renderer schreiben - Renderpasses zuweisen (automatisch?) - Texturen und FBOs erzeugen (automatisch?)
- Welche Klassen müssten erstellt werden? Neue Klasse für Renderer- Verwaltung von Szenen und Renderpasses - Renderer.render() rendert die Szenen mit den entsprechenden Renderpasses Neue Klasse für Renderpasses- Verwaltung von FBOs und Shadern - Renderpass.render() bindet FBO und Shader
- Woher könnte man die benötigten Informationen erhalten? Shader weiß über die out Befehle bereits, ob undwenn ja, wie viele Ausgabetexturen ein möglichesFBO haben muss - Shader beim Auslesen auch auf diese Parameter hin parsen - Renderpass bei Laden des Shaders erstellen