Faster Deferred Shading
In the last two late evenings I have worked on the elimination of the 3D position from the geometry buffer, making some improvements on shader parameter passing and not surprisingly, hunting bugs down. The results are the following:
First of all, there is no such thing as position buffer in the renderer, I calculate the eye-coordinate position directly from the depth buffer using the inverse of the projection matrix. Although this causes some extra cycles in the fragment shaders, but the thinner Gbuffer significantly reduces the overall memory bandwidth of the process. It caused about a 10-20% performance gain, it definitely worths the effort. 🙂
The geometry buffer has the following layout:
Attachment #1: RGBA8, diffuse color and specular exponent.
Attachment #2: RGBA8, normal vector and BRDF index.
Attachment #3: depth, 24 bit
Second, I have introduced several automatic built-in engine variables to the shaders to support these calculations. (I will write about automatic shader parameters later, I promise).
Furthermore, transformation matrices needed by the shaders are calculated on-demand (modelview, normal, etc.).
Now, the renderer can handle many dynamic omnidirectional lights, specular reflections and 255 different BRDFs for shading.
Lights are rendered with bounding spheres, discarding surface pixels not interacting with the light. There is no stencil optimization, I have “deferred” its implementation to a later coding spree.
The final rendering pass combines light accumulation buffer with the GBuffer and renders directional sunlight, ambient light and sky background.
There is a demo video showing a simple scene with the results: