OpenGL 3 Deferred Shading with point in polyhedron test
-
Upload
alejandrocosinayerbe -
Category
Technology
-
view
606 -
download
1
description
Transcript of OpenGL 3 Deferred Shading with point in polyhedron test
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
OpenGL 3 Deferred Shading with point in polyhedrontest
Alejandro Cosin
July 2014
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Introduction
Topics covered:
Forward shading and Deferred shading.
What is needed to do deferred shading at hardware level.
The Geometry Buffer or G-Buffer.
Populating the G-Buffer.
Light pass: tagging fragments in the G-Buffer to be lighten
Light pass: rendering tagged fragments
Directional light pass
Point inside a light volume
Displaying the result
Getting the source
Bibliography
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Forward and Deferred shading
Forward and Deferred shading
Current standard rendering methodology is called ”forward shading”, andoffers two options:
Include all light sources when rendering each object in a single pass.
For each light, render all lit objects and add the results in the framebuffer.
Forward shading works fine in scenes with small number of lights, wellpartitioned environment geometry and outdoor scenes, but has its limitations:
Single pass lighting: which lights affect each mesh to be rendered needsto be determined, it is common to shade partially or fully occludedfragments.
Multi-pass lighting: render the illuminated part of a mesh for each light,and for each mesh in the scene. Pixel overdraw is again unavoidable dueto objects falling in several bounding volumes.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Forward shading and Deferred shading
Deferred shading, on the other hand, manages very well scenes with complexlighting situations. Uses two passes:
First to populate what will be called as the G-Buffer.
Second to add the lighting working in image-space.
It lowers the cost of rendering many light: if there are A objects in the scene,and B lights, then the deferred shading theoretical algorithmic complexity isO(A + B), whereas the forward shading is O(A * B).
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Deferred shading HW requirements
Deferred shading HW requirements
DS demands many hardware features which have not been fully available untilsome years ago:
Floating point textures: the positions of the vertex (world spacecoordinates) and its normals, and the diffuse information needs to bestored, so a texture with great precision is needed.
Offscreen framebuffers: after the first pass, position, normal and diffuseinformation is stored in offscreen buffers, and must be used in the secondpass for lighting.
Render to texture: render directly into a texture map.
MRTs or multiple render targets: to save time in the first pass, andpopulate the position, normal and diffuse textures at once for eachfragment, MRTs is needed.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
G - Buffer
G - Buffer
The G-Buffer contains all the information that will be needed in the lightingpass, and it is nothing but a collection of framebuffers with the outputinformation from the first pass: one with position (in world spacecoordinates), another with normals, and another with diffuse color.
Additional info such as gloss map, material emissive ando other per fragmentrelevant info can be stored.
To minimize the size in memory of the G-Buffer, I recommend following thesteps shown in the OpenGL SuperBible (6th Edition), where 32-bitcomponents are used to store the information with lower precissionrequirements such as normals and diffuse.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
G - Buffer
The following is an example of the code needed to build up a G-Buffer inOpenGL v3 (at the end of the presentation, you can find an email address toget the full code of this demo):
// Crea te the FBO ( ask OpenGL f o r a l o c a t i o n , s t o r e d i n the uns i gned i n t m fbo )g l G e n F r a m e b u f f e r s ( 1 , &m fbo ) ;g l B i n d F r a m e b u f f e r (GL DRAW FRAMEBUFFER, m fbo ) ;
// Crea te the g b u f f e r t e x t u r e s : p o s i t i o n , normal and d i f f u s e .// Depth + s t e n c i l and f i n a l a r e r e q u i r e d too .f o r ( auto i t = m vTextures . b e g i n ( ) ; i t != m vTextures . end ( ) ; ++i t )
g l G e n T e x t u r e s ( 1 , &(* i t ) ) ;
g l G e n T e x t u r e s ( 1 , &m depthTexture ) ;g l G e n T e x t u r e s ( 1 , &m u F i n a l T e x t u r e ) ;
// Con f i g the gene r a t ed g b u f f e r t e x t u r e s : i t s d imens i on s a r e WindowWidth and// WindowHeight// Pxe l fo rmat i s GL RGB32F , so a s i n g l e p i x e l can s t o r e t h r e e 32 b i t f l o a t sf o r ( uns igned i n t i = 0 ; i < m vTextures . s i z e ( ) ; i ++) {
g l B i n d T e x t u r e (GL TEXTURE 2D , m vTextures . a t ( i ) ) ;glTexImage2D (GL TEXTURE 2D , 0 , GL RGB32F , WindowWidth , WindowHeight , 0 ,
GL RGB , GL FLOAT , NULL) ;g l T e x P a r a m e t e r f (GL TEXTURE 2D , GL TEXTURE MIN FILTER , GL NEAREST) ;g l T e x P a r a m e t e r f (GL TEXTURE 2D , GL TEXTURE MAG FILTER , GL NEAREST) ;g l F r a m e b u f f e r T e x t u r e 2 D (GL DRAW FRAMEBUFFER, GL COLOR ATTACHMENT0 + i ,
GL TEXTURE 2D , m vTextures . a t ( i ) , 0) ;}
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
G - Buffer
// depth : a l s o c o n t a i n s e i g h t b i t s f o r the s t e n c i l b u f f e r , due to the f l a g// GL DEPTH32F STENCIL8 , and aga in has d imens i on s WindowWidth and WindowHeight
g l B i n d T e x t u r e (GL TEXTURE 2D , m depthTexture ) ;glTexImage2D (GL TEXTURE 2D , 0 , GL DEPTH32F STENCIL8 , WindowWidth , WindowHeight ,
0 , GL DEPTH COMPONENT, GL FLOAT , NULL) ;g l F r a m e b u f f e r T e x t u r e 2 D (GL DRAW FRAMEBUFFER, GL DEPTH STENCIL ATTACHMENT ,
GL TEXTURE 2D , m depthTexture , 0) ;
// F i n a l : h e r e the r e s u l t i n g r e nd e r r e s u l t to be d i s p l a y e d w i l l be s t o r e dg l B i n d T e x t u r e (GL TEXTURE 2D , m u F i n a l T e x t u r e ) ;glTexImage2D (GL TEXTURE 2D , 0 , GL RGBA , WindowWidth , WindowHeight , 0 , GL RGB ,
GL FLOAT , NULL) ;g l F r a m e b u f f e r T e x t u r e 2 D (GL DRAW FRAMEBUFFER, GL COLOR ATTACHMENT3, GL TEXTURE 2D
, m u F i n a l T e x t u r e , 0) ;
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Populating the G-Buffer
Populating G-Buffer
The steps to populate the G-Buffer when rendering are the following:
Clear and bind the G-Buffer for writting: the position, normal and diffuseframebuffers are ready to be written from the shaders when rendering
Render each model in the scene, and enable depth test to populate thedepth buffer too.
The shaders used to render a model accomplish the tasks:
Vertex shader: transform each vertex (to obtain its world spacecoordinates) by the model matrix, and each normal and tangent by thetypical 3x3 normal matrix.
Fragment shader: build the TBN matrix to transform the normal, samplethe diffuse texture and output this data to the position, normal anddiffuse bound framebuffers using gl_FragData[0], gl_FragData[1] andgl_FragData[2] (no gl_FragColor is written in this case, as the goal isto fill the G-Buffers with data).
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Populating the G-Buffer
Position buffer (left) and normal buffer (right). The position of each vertex isobtained in the vertex shader and interpolated in the fragment shader, wherethe position framebuffer is filled. The frambebuffer containing the normaldata is filled using the TBN matrix to apply correct rotation.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Populating the G-Buffer
Vertex shader:
#v e r s i o n 130u n i f o r m mat4 MMatrix ;u n i f o r m mat4 MVPMatrix ;u n i f o r m mat3 NormalMatr ix ;
i n vec3 V e r t e x ;i n vec2 tTexCoord0 ; // Texture datai n vec3 Normal ;i n vec3 tTexCoord1 ; //Tangent data
v a r y i n g vec3 p o s i t i o n 3 ;v a r y i n g vec2 tCoord0 ;v a r y i n g vec3 normal3 ;v a r y i n g vec3 t a n g e n t 3 ;
v o i d main ( v o i d ){
g l P o s i t i o n = MVPMatrix * vec4 ( Vertex , 1 . 0 ) ;tCoord0 = tTexCoord0 ;// We have to mu l t i p l y by the model mat r i xvec4 p o s i t i o n = MMatrix * vec4 ( Vertex , 1 . 0 ) ;p o s i t i o n 3 = ( vec3 ( p o s i t i o n ) ) / p o s i t i o n . w ;//Uncompress v e r t e x normal and r o t a t e a c c o r d i n g to the normal r o t a t i o nnormal3 = NormalMatr ix * ( vec3 ( 2 . 0 ) * Normal − vec3 ( 1 . 0 ) ) ;//Uncompress v e r t e x tangen t and r o t a t e a c co r d i n g to the normal r o t a t i o nt a n g e n t 3 = NormalMatr ix * ( vec3 ( 2 . 0 ) * tTexCoord1 . xyz − vec3 ( 1 . 0 ) ) ;
}
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Populating the G-Buffer
Fragment shader:
#v e r s i o n 130u n i f o r m sampler2D d i f f u s e T e x ;u n i f o r m sampler2D normalMap ;v a r y i n g vec3 p o s i t i o n 3 ;v a r y i n g vec2 tCoord0 ;v a r y i n g vec3 normal3 ;v a r y i n g vec3 t a n g e n t 3 ;
v o i d main ( v o i d ){
vec3 norm3PS = normal3 ;norm3PS = n o r m a l i z e ( norm3PS ) ;vec3 tang3PS = t a n g e n t 3 ;tang3PS = n o r m a l i z e ( tang3PS ) ;vec3 b i n o r m a l 3 = c r o s s ( norm3PS , tang3PS ) ;b i n o r m a l 3 = n o r m a l i z e ( b i n o r m a l 3 ) ;// Cons t ru c t the t e x t u r e−space mat r i x and r o t a t e the normal i n t o the eye
spacemat3 rotMat = mat3 ( tang3PS , b inormal3 , norm3PS ) ;vec3 vnormal = t e x t u r e 2 D ( normalMap , tCoord0 . s t ) . xyz ;vnormal = vec3 ( 2 . 0 ) * vnormal − vec3 ( 1 . 0 ) ;vec3 snorma l = rotMat * vnormal ;snorma l = n o r m a l i z e ( snorma l ) ;g l F r a g D a t a [ 0 ] = vec4 ( p o s i t i o n 3 , 1 . 0 ) ;g l F r a g D a t a [ 1 ] = vec4 ( t e x t u r e 2 D ( d i f f u s e T e x , tCoord0 . s t ) . rgb , 1 . 0 ) ;g l F r a g D a t a [ 2 ] = vec4 ( snormal , 1 . 0 ) ;
}
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: tagging fragments
Light pass: tagging fragments
With the G-Buffer populated, the second pass can now be done:
For each light, a volume representing the 3D shape being lighted by thatlight must be rendered.
The drawn pixels for each light are compared with those in the sameposition in image space in the G-Buffer.
Those pixels are lighten using the information in the G-Buffer.
Basically, for the typical point and spot light, spheres and cones can be used,and a full screen quad can be used to add directional light such as the sun.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: tagging fragments
One important thing when rendering a light volume is finding the pixels thatare really lighten by that light, i.e. the pixels, taking into account the positioninformation for each one of them from the G-Buffer, that are inside the lightvolume.
To solve this problem and tag the pixels that must be lighten when a lightvolume is rendered, the stencil buffer can be used together with the depth test:
// Enab le depth t e s tg l E n a b l e (GL DEPTH TEST) ;// D i s a b l e f a c e c u l l i n gg l D i s a b l e ( GL CULL FACE ) ;// C l e a r the s t e n c i l b u f f e rg l C l e a r ( GL STENCIL BUFFER BIT ) ;
//The s t e n c i l t e s t w i l l a lways suceed , so the f l a g i s GL ALWAYSg l S t e n c i l F u n c (GL ALWAYS , 0 , 0) ;
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: tagging fragments
And then, use the two following instructions before rendering the light volume,wich define the behaviour of the stencil buffer when rendering:
g l S t e n c i l O p S e p a r a t e (GL BACK , GL KEEP , GL INCR WRAP , GL KEEP) ;g l S t e n c i l O p S e p a r a t e (GL FRONT , GL KEEP , GL DECR WRAP , GL KEEP) ;
Let’s take a look at these two statements: the function declaration isglStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
GLenum ppass), and the meaning of the parameters are:
GLenum face type of face render
GLenum sfail what to do if the stencil test fails
GLenum dpfail what to do if the stencil test passes, but the depth testfails
GLenum ppass what to do if the stencil and depth test pass
The important parameters in this case are first and third.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: tagging fragments
With glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR_WRAP,
GL_KEEP), if a back face being rendered passes the stencil test (always willpass, because the stencil func is GL_ALWAYS) and fails the depth test (thedepth of the corresponding fragment in the depth bufferis lower), then increment the value in the stencil test for the corresponding pixel.
This could happen when rendering a triangle of the light volume and thedepth of the pixels of that triangle is greater than the depth of thecorresponding pixels present in the G-Buffer (so this pixels are ”tagged” in thestencil buffer, as they are inside the light volume).
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: tagging fragments
With glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR_WRAP,
GL_KEEP), if a front face being rendered passes the stencil test (always willpass, because the stencil func is GL_ALWAYS) and fails the depth test (thedepth of the corresponding fragment in the depth bufferis lower), then decrement the value of the stencil test for the corresponding pixel.
This could happen for example when rendering a triangle of the light volumewhich has a greater depth than thedepth of the corresponding pixels present inthe G-Buffer (so this pixels, if they were considered inside the light volume,are ”untagged”).
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Sphere light volume render in wireframe mode (left), stencil buffer contentafter rendering the sphere light volume with the vertex shader (center), andfinal result after lighting pass.
The stencil buffer shows how only pixels inside the light volume are tagged forlighting. Notice in the stencil buffer the box (on the right) between thecamera and the light volume, which has untagged the pixels behind it andinside the light volume from being lighten.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: rendering tagged fragments
Light pass: rendering tagged fragments
Light volumes are rendered with a simple vertex shader and no fragmentshader, as the target of the render is the stencil and no the color buffer. Theshader is the following:
#v e r s i o n 130
u n i f o r m mat4 MVPMatrix ;
i n vec3 V e r t e x ;
v o i d main ( v o i d ){
g l P o s i t i o n = MVPMatrix * vec4 ( Vertex , 1 . 0 ) ;}
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: rendering tagged fragments
The advantage of using the stencil buffer is that the number of fragmentsprocessed for each light can be limited by establishing that only the fragmentswith a non zero stencil value must be taken into account, which can be donewith glStencilFunc(GL_NOTEQUAL, 0, 0xFF). This will speed up theproccess of rendering each light.
As there can be more than one light volume affecting a fragment, thecontribution of each light can be added using alpha blending when doing thelighting pass:
g l E n a b l e (GL BLEND) ;g l B l e n d E q u a t i o n (GL FUNC ADD) ;g lB le n dF u nc (GL ONE , GL ONE) ;
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: rendering tagged fragments
When doing the lighting pass, the face culling changes depending on if thecamera is inside or outside the light volume. If it is inside, thenglCullFace(GL_FRONT) culling must be used, and glCullFace(GL_BACK)
otherwise.
If not used, then if the camera enters a light volume, the light will be ”turnedoff” and won’t add lighting to the scene.
Now, the relevant points for doing pe pixel lighting are:
The light volume is rendered
As with any other type of rendered primitive, each triangle is transformedin the vertex shader, and interpolated in the fragment shader.
For each interpolated fragment of the ligth volume, the G-Buffer (boundto the fragment shader) information is accessed as a texture (eachframebuffer is bound as a texture to the light shader).
The relevant information for each fragment is given by those textures.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: rendering tagged fragments
For each type of light volume, a fragment shader is needed, for example, thevertex and fragment shaders for a sphere light volume are:
#v e r s i o n 130
u n i f o r m mat4 MVPMatrix ;
i n vec3 V e r t e x ;
u n i f o r m vec3 vEyePos ;u n i f o r m vec3 v L i g h t P o s ;u n i f o r m f l o a t f L i g h t R a d i u s ; // Rad ius o f the sphe r e l i g h t volume
v o i d main ( v o i d ){
g l P o s i t i o n = MVPMatrix * vec4 ( Vertex , 1 . 0 ) ;}
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: rendering tagged fragments
#v e r s i o n 130
// G−b u f f e r componentsu n i f o r m sampler2D p o s i t i o n T e x ;u n i f o r m sampler2D d i f f u s e T e x ;u n i f o r m sampler2D normalTex ;
u n i f o r m vec3 vEyePos ;u n i f o r m vec3 v L i g h t P o s ;u n i f o r m f l o a t f L i g h t R a d i u s ; // Rad ius o f the sphe r e l i g h t volume
v o i d main ( v o i d ){
vec4 ambient = vec4 ( 0 . 0 ) ;vec4 d i f f u s e = vec4 ( 0 . 0 ) ;vec4 s p e c u l a r = vec4 ( 0 . 0 ) ;vec2 t e x c o o r d = g l F r a g C o o r d . xy / vec2 ( 1 0 2 4 . 0 , 7 6 8 . 0 ) ;vec4 p o s i t i o n 4 = t e x t u r e ( p o s i t i o n T e x , t e x c o o r d ) ;vec4 normal4 = t e x t u r e ( normalTex , t e x c o o r d ) ;vec4 d i f f u s e 4 = t e x t u r e ( d i f f u s e T e x , t e x c o o r d ) ;vec3 p o s i t i o n 3 = p o s i t i o n 4 . xyz ;vec3 normal3 = n o r m a l i z e ( normal4 . xyz ) ;vec3 d i f f u s e 3 = d i f f u s e 4 . xyz ;
// c on t i n u e s i n the nex t s l i d e
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Light pass: rendering tagged fragments
// Perform l i g h t i n g c a l c u l a t i o n svec3 l i g h t D i r = vec3 ( v L i g h t P o s − p o s i t i o n 3 ) ;f l o a t d = l e n g t h ( l i g h t D i r ) ;l i g h t D i r = n o r m a l i z e ( l i g h t D i r ) ;
f l o a t f A t t = d / f L i g h t R a d i u s ;f l o a t a t t = 1 . 0 − ( f A t t * f A t t ) ;
vec3 e y e D i r = n o r m a l i z e ( vEyePos − p o s i t i o n 3 ) ;vec3 h a l f A n g l e = n o r m a l i z e ( l i g h t D i r + e y e D i r ) ;
f l o a t nDotLD = max ( 0 . 0 , dot ( normal3 , l i g h t D i r ) ) ;f l o a t nDotHA = max ( 0 . 0 , dot ( normal3 , h a l f A n g l e ) ) ;
s p e c p o w e r = ( nDotLD == 0 . 0 ) ? 0 . 0 : pow ( nDotHA , 1 0 0 . 0 ) ;d i f f u s e = clamp ( vec4 ( nDotLD * a t t * d i f f u s e 3 , 1 . 0 ) , 0 . 0 , 1 . 0 ) ;s p e c u l a r = vec4 ( s p e c p o w e r * a t t ) ;
g l F r a g C o l o r = d i f f u s e + s p e c u l a r ;}
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Directional light pass
Directional light pass
After each light volume has been rendered, a directional light pass can bedone. The geometry rendered, as the deferred shading techique is animage-space one, is a simple screen quad which goes from (-1,-1) to (1,1).
The G-Buffer data is again supplied for the fragment shader, and once again,the vertex shader is the same.
Scene without directional light (left) and with directional light (right):
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Directional light pass
The following is the code of the fragment shader for the directional light pass:
#v e r s i o n 130
u n i f o r m vec3 v L i g h t P o s ;
// G−b u f f e r componentsu n i f o r m sampler2D p o s i t i o n T e x ;u n i f o r m sampler2D d i f f u s e T e x ;u n i f o r m sampler2D normalTex ;
v o i d main ( v o i d ){
vec2 t e x c o o r d = g l F r a g C o o r d . xy / vec2 ( 1 0 2 4 . 0 , 7 6 8 . 0 ) ;vec3 p o s i t i o n = t e x t u r e ( p o s i t i o n T e x , t e x c o o r d ) . xyz ;vec3 normal = t e x t u r e ( normalTex , t e x c o o r d ) . xyz ;vec3 d i f f u s e = t e x t u r e ( d i f f u s e T e x , t e x c o o r d ) . xyz ;// Perform l i g h t i n g c a l c u l a t i o n svec3 l i g h t D i r = vec3 ( v L i g h t P o s − p o s i t i o n ) ;l i g h t D i r = n o r m a l i z e ( l i g h t D i r ) ;f l o a t nDotLD = max ( 0 . 0 , dot ( normal , l i g h t D i r ) ) ;d i f f u s e = clamp ( vec3 ( nDotLD * d i f f u s e ) , 0 . 0 , 1 . 0 ) ;g l F r a g C o l o r = vec4 ( d i f f u s e , 0 . 2 5 ) ; // Add 1/4 o f the d i f f c o l o r to the
r e s u l t}
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Point inside a light volume
Point inside a light volume
Determining whether the camera is inside a light volume can be an easy taskif the light volumes are simple.
For instance, if the light volume is a sphere, then a simple formula can bedetermining if the distance from the camera to the center of the sphere is lessthan the radius of the sphere.
However, as the sphere is not a perfectly round polygonal mesh due to thegeometry limitation, problems can arise if the camera is near and outside thesphere mesh, but at a distance less than the radius from its center.
A solution to this problem is computational geometry. Although sometimesexpensive for high LOD meshes, it gives a much more reliable results than asimple estimation, and can be used with complex light volumes.
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Point inside a light volume
In the demo source code there is a class called PInPolyhedron whichperforms this task (at the end of the presentation there is an email address ifyou want the source code of the demo), and gives no unwanted light ”turningoffs” when moving the camera and / or the light volumes.
This class implements the chapter seven (section five) of the (stronglyrecommended) book Computational Geometry, Second Edition, JosephO’Rourke (Cambridge University Press), which analyzes the ”point inpolyhedron” problem.
g l E n a b l e ( GL CULL FACE ) ;i f ( CMathUti l : : P o i n t I n P o l y h e d r o n ( m tCamera . G e t P o s i t i o n ( ) , pModel ) )
g l C u l l F a c e (GL FRONT) ;e l s e
g l C u l l F a c e (GL BACK) ;
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Displaying the result
Displaying the result
When all the light passes have been done, the screen buffer is set for drawing,and the framebuffer for reading, so the information can be copied to thescreen buffer and displayed:
// b ind s c r e e n f r amebu f f e r f o r drawing ( number 0 co r r e s pond s to the s c r e e nf r amebu f f e r )
g l B i n d F r a m e b u f f e r (GL DRAW FRAMEBUFFER, 0) ;
// b ind d e f e r r e d shad ing F i n a l f r amebu f f e r f o r r e a d i n gg l B i n d F r a m e b u f f e r (GL READ FRAMEBUFFER , m fbo ) ;
// s e t a c o l o r b u f f e r as the s ou r c e to copy from , GL COLOR ATTACHMENT3 i s the// f i n a l f r amebu f f e r which c o n t a i n s a l l the r e n d e r i n g r e s u l t s , and i s o f type
GL RGBAg l R e a d B u f f e r (GL COLOR ATTACHMENT3) ;
// d i r e c t l y from OpenGL doc ” copy a b l o ck o f p i x e l s from the read f r amebu f f e rto
// the draw f r amebu f f e r ” , so copy from GL COLOR ATTACHMENT3 to s c r e e n// f r amebu f f e r , i . e . the number 0g l B l i t F r a m e b u f f e r ( 0 , 0 , WINDOW WIDTH, WINDOW HEIGHT, 0 , 0 , WINDOW WIDTH,
WINDOW HEIGHT, GL COLOR BUFFER BIT , GL LINEAR ) ;
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Getting the source
Getting the source
Want the source? email me at [email protected] and you’ll have itin the twinkling of an eye (VS project)
OpenGL 3DeferredShading
with pointin
polyhedrontest
Introduction
Forward andDeferredshading
Deferredshading HWrequire-ments
G - Buffer
PopulatingG-Buffer
Light pass:taggingfragments
Renderingtaggedfragments
Directionallight pass
Point insidea lightvolume
Displayingthe result
Getting thesource
Bibliography
Dave Astle.
More OpenGL game programming.
Thomson Course Technology, second edition, 2005.
Etay Meiri.
http://ogldev.atspace.co.uk/.
Joseph O’Rourke.
Computational Geometry in C.
Cambridge University Press, second edition, 1998.
Graham Sellers, Richard S. Wright Jr., and Nicholas Haemel.
OpenGL SuperBible: Comprehensive Tutorial and Reference.
Addison-Wesley, sixth edition, 2002.
http://www.opengl-tutorial.org/.