35
CG (Subject) / Frame Buffer Objects (Lesson)
Advertisement
- Was sind FBOs Wie dem Vertexbuffer können auch dem Framebuffer Objekte zugeordnet werden. Statt direkt zu rendern, kann man Texturen “attachen”, in welche gerendert werden soll. Der default-Framebuffer wird vom Windowmanager eingerichtet (Color, Depth und Stencil).
- Was ist ein Screen Filling Quad Zum Anzeigen der Textur wird ein Polygon mit dieser Textur auf der Größe des Viewports gerendert. Schleife über alle Pixel erzwungen Fragment-Shader die Farbe des Texels übergeben. Alternativ kann auch ein Screen Filling Triangle gerendert werden, welches über die Dimension des Viewports hinausgeht.
- Ablauf eines Screen Filling Quads Erstellen des FBOs (inkl. Textur) Binden des FBOs Wechsel auf herkömmliche ShaderRendern der Szene Entbinden des FBOsWechsel auf Post-Processing ShaderRendern des Screen Filling Quads
- Mittelwertfilter Im Fragment-Shader wird der Mittelwert der umliegenden Pixel über out vec4 fragmentColor; void main() {fragmentColor = texture(colorTexture, passUVCoord)} fragmentColor +=texture(colortexture, passUVCoord + vec2(offsetX, offsetY)) berechnet.
- Wozu gl_FragCoord und texelFetch Um die Übergabe von Fenstergröße, UV-Koordinaten und die Normalisierung der Texturkoordinaten zu umgehen, kann man im Fragment-Shader auch folgenden Zugriff machen: fragmentColor += texelFetch(colortexture, ivec2(gl_FragCoord) + ivec2(i-1, j-1)) Die Behandlung der Randkoordinaten erfolgt mit eingeschaltetem Clamping automatisch. Die Mittelung erfolgt nachdem alle Texel so aufaddiert wurden.
- Was ist der StencilBuffer Der Stencil-Buffer (im Fragment-Shader) bietet weitere Möglichkeiten die Pixel zu beschreiben. Dieser nutzt eine Stencil-Textur um diese über das gerenderte Bild zu legen (häufigste Anwendung: Masken).
- Spezifikation von Colorbuffer Diese Funktion legt beim rendern eines Pixels fest, ob der Stencilbuffer gefüllt werden soll. Dabei wird mit ref fest. x kann hierbei sein: NEVER, LESS, LEQUAL, GREATER, GEQUAL, EQUAL, NOTEQUAL, ALWAYS. Bsp: glStencilFunc(GL_GRAEATER, 3, 0xFF); Falls der Stencilwert > 3 wird der Colorbuffer gefüllt.
- Welche Funktion legt fest, wie in den Stencil Buffer geschrieben wird? // legt fest wie in den Stencilbuffer geschrieben wird glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
- Welche Parameter gibt es im Stencil Buffer sfail: Aktion bei fehlgeschlagenem Stencil-Testdpfail: Aktion bei erfolgreichem Stencil- aber fehlgeschlagenem Tiefentestdppass: Aktion bei erfolgreichem Stencil- und Tiefentest
- Mögliche Operationen im Stencil Buffer GL_KEEP: das Pixel unverändert lassen GL_ZERO: Stencil löschen GL_REPLACE: Referenzwert schreiben GL_INCR / GL_DECR: gespeicherten Wert erhöhen/verringern GL_INVERT: gespeicherten Wert invertieren
- Advertisement
- Spiegelungen Im Stencil Buffer Wie werden sie gerendert - Stencilbuffer löschen- Szene zeichnen- Beim rendern eines Spiegels wird der Stencilbuffer gefüllt, indem vorher die Funktionen gesetzt werden: glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE) glStencilFunc(GL_ALWAYS, 1, 1) - Szene vom gespiegelten Viewpoint erneut zeichnen, aber nur in den Spiegel, indem vorher die Funktionen gesetzt werden: glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) glStencilFunc(GL_EQUAL, 0, 0xFF - Colorbuffer abhängig von den Werten im Stencilbuffer verändern
- Code von Spiegelung glEnable(GL_STENCIL_TEST); // Setze den Löschwert glClearStencil(1); // Normale Szene in Color- und Stencilbuffer glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS, 0, 0xFF); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); sceneStencil->render(); // Spiegelung der Szene nur in Colorbuffer, wenn Stencilwert 0 glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); glStencilFunc(GL_EQUAL, 0, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); scene->render();
- Code von Screen Filling Quad in vec2 passUvCoord; uniform sampler2D colortexture; out vec4 fragmentColor; void main() {fragmentColor = texture(colorTexture, passUVCoord)}
- Code vom FBO // FBO generieren und bindenglGenFramebuffers(...) glBindFramebuffer(...) // Texturen anlegen und bindenglGenTextures(...) glBindtexture(...) // Textur anlegen und Parameter setzenglTexImage2D(...) glTexParameteri(...) // Textur an FBO attachenglFramebufferTexture2D(parameter) // Parameter legen fest was attached wird:GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENTn GL_DEPTH_ATTACHMENT GL_STENCIL_ATTACHMENT
- Frame Buffer Objects - Entspricht dem Bildschirm - Enthält Buffer - Buffer als nutzbare Texturen - Alle Buffer haben die gleiche Auflösung / Größe
- Colorbuffer - Buffer in Form einer Textur - Speichert Farben in bestimmten Format - Verschiedene Channels (bsp. RGBA) - Channels mit beliebiger Genauigkeit - Speichert Bildschirminhalte (Farben, Normalen, Positionen...)
- Depthbuffer Textur mit nur einem Channel - Auflösung beliebig - Speichert automatisch die Tiefeninformationen der Szene - Nutzer hat keine eigene Entscheidungsgewalt, was in den Depthbuffer geht - Wird genutzt für Tiefentest
- Stencilbuffer - Meist in kombinierter Textur mit Depthbuffer - Nutzer entscheidet, wann und womit er beschrieben wird (in dem Hauptprogramm) - Stencilbuffer entscheidet, wann in einen Color- oder Depthbuffer geschrieben wird.
- Render-to-Texture - Rendern der Szene in Textur - Können auch mehrere Texturen sein - Textur für Positionen, Normalen und Farben - G-Buffer
- Screen-Filling-Quad - Darstellen von einer Textur auf dem Bildschirm - Rendern eines Quads auf dem Bildschirm - Textur auf Quad - Wenn keine Model- oder Viewmatrix angewendet wird, dann hat das Quad Ausmaße im Bereich [0,1]
- Anlegen des FBOs glGenFramebuffers(1, &fboHandle); glBindFramebuffer(GL_FRAMEBUFFER, fboHandle); glDeleteFramebuffers(1, &fboHandle);
- Anlegen der Texturen glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); glDeleteTextures(1, &textureID);
- Zuordnen der Texturen zu FBOs glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+id, GL_TEXTURE_2D, colorTexHandle, 0); glDrawBuffers(numColorTextures, drawBuffers); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexHandle, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexHandle, 0);
- Programmierung FBO Rendern von Szene in FBO - Rendern von Textur auf Bildschirm - von FBO - von Hauptprogramm
- Silhouettenkanten - Bilden den Unterschied zwischen Schatten und Licht - Sie entscheiden, wo ein Objekt endet - Allein diese Kanten sind ausreichend für die Schattenberechnung
- Silhouettenkanten und deren Detektion Eine Kante verbindet zwei Flächen - Flächen haben Normalen - Weist eine Normale zur Kamera und eine von ihr weg, ist es eine Silhouettenkante - Berechnung auf der CPU
- Generierung der Planes aus Silhouettenkanten - Erzeugung eines Quads - 4 Punkte notwendig - 2 von Kante, zwei als unendliche Projektion
- Read-only z-Buffer - Szene einmal rendern um die Grundgeometrie darzustellen - Diese ist dann im Tiefenbuffer (z-Buffer) - Schattenvolumen wird dann nur dort aufgenommen, wo es auch eigentlich sein würde
- Stencil Buffer - Im Stencil Buffer wird die Information behalten, ob schattiert wird oder nicht - Rendern der Schattenvolumen so, dass der finale Eintrag in dem Buffer angibt, ob Schatten vorhanden ist
- Front- und Backface-Culling Zweimaliges Rendern der Schattenvolumen - Einmal nur die Vorderseiten (Backface-Culling), +1 im Stencil Buffer - Einmal nur die Rückseiten (Frontface-Culling), -1 im Stencil Buffer - Bei einer 0 im Stencil Buffer kein Schatten, alles was addiert wurde wieder subtrahiert wurde - Bei einem Wert größer als 0 Schatten
- Advertisement
- Anzahl der Renderpasses 3 Passes - Szene rendern für den Tiefentest - Szene rendern für den Stencilbuffer (Tiefentest verhindert Einträge, wo sie nicht sein müssen) - Szene rendern für die finale Beleuchtung - aber nicht zwangsläufig eigene FBOs
- Mehrere Render Passes Wie viele? Einen für Lichtquelle, einen für Kamera Welche Geometrie? Jeweils die gesamte Szene
- FBOs Wie viele? Welche Buffer? Wie viele?- Eines für Lichtquelle - (Für Kamera nicht zwangsläufig notwendig) - Welche Buffer?Nur ein Depth Buffer Kein Color Buffer
- Ein und Ausgabe von der Lichtquelle Eingabe: Position des Vertex Ausgabe: Transformation mit MVP (View von Lichtquelle!)
- Kamera Shader wie Phong Zusätzliche Eingabe: Depth Buffer, View Projection Bias der LichtquelleAusgabe: Vertex Shader: Transformation von Vertex in Kamera und Lichtquellensystem Fragment Shader: Berechnen der Farbe, Vergleich der Tiefenwerte