OpenGL 3 Deferred Shading with point in polyhedron test

41
OpenGL 3 Deferred Shading with point in polyhedron test Introduction Forward and Deferred shading Deferred shading HW require- ments G - Buffer Populating G-Buffer Light pass: tagging fragments Rendering tagged fragments Directional light pass Point inside a light volume Displaying OpenGL 3 Deferred Shading with point in polyhedron test Alejandro Cosin July 2014

description

Deferred shading demo written in OpenGL v3 with point in polyhedron test for light volumes. Email me to get the source

Transcript of OpenGL 3 Deferred Shading with point in polyhedron test

Page 1: 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

Page 2: 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

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

Page 3: 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

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

Page 4: 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

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

Page 5: 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

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

Page 6: 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

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

Page 7: 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

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

Page 8: 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

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

Page 9: 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

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

Page 10: 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

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

Page 11: 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

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

Page 12: 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

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

Page 13: 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

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.

Page 14: 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

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).

Page 15: 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

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.

Page 16: 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

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.

Page 17: 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

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) ;}

Page 18: 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

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) ;

Page 19: 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

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).

Page 20: 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

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.

Page 21: 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

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 ) ) ;

}

Page 22: 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

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 ) ;

}

Page 23: 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

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.

Page 24: 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

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) ;

Page 25: 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

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.

Page 26: 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

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).

Page 27: 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

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”).

Page 28: 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

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.

Page 29: 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

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 ) ;}

Page 30: 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

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) ;

Page 31: 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

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.

Page 32: 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

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 ) ;}

Page 33: 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

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

Page 34: 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

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 ;}

Page 35: 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

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):

Page 36: 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

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}

Page 37: 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

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.

Page 38: 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

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) ;

Page 39: 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

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 ) ;

Page 40: 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

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)

Page 41: 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

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/.