Category Archives: GLSL

Shadow Maps on Omnidirectional Lights

Theoretically, using six shadow mapped spot lights to piece up a shadow casting point light is not a big deal. Especially if the light geometry calculation for deferred lighting is correct. Well, in my engine, it was not the case. 🙂

There was a hidden calculation error that resulted in a frustum with incorrect corner points that made it bigger than desired. This error caused no problem so far because projected mask texture on spotlights and “discard” codes in fragment shader prevented the extra pixels from being seen. But once I have used spot lights with no mask to render point light, the result was erroneous. It looked so strange and mysterious that it took few hours to find the root of the problem.

Finally, the shadows on point light are working now, and I proudly present some screenshots here.

Shadow map on omnilight. Shadow map on omnilight. Shadow map on omnilight. Shadow map on omnilight.

Real-Time Volumetric Light Shafts

Lately, I have replaced the recently added screen-space light shaft algorithm with a new one because I was not satisfied with the results. The new method uses ray marching with interleaved sampling of the shadow map to simulate single scattering in participating media in real-time, thus, it produces more realistic results with relatively low cost.

The implementation calculates sample values in a separate pass to a new framebuffer, and then it collects the samples at the light combiner pass. The interleaved sampling is performed using a hand-crafted 8×8 pixel grayscale image containing random pixels with uniform value distribution.

There are some images with the results.

Crepuscular Rays in Screen Space

I have added a new post-processing effect that approximates light scattering on the sunlight according to this GPU Gems 3 article. It required a minor coding on the engine, I have introduced two new built-in shader parameters: sun screen-space position to use in the calculation, and a term that gradually scales down the ray effect when the camera is not turned towards the sun. The process itself has been implemented in the postprocessing shader of the deferred chain, that made implementing it easy because all required data is available at this point of the rendering.

Here are some pictures about the result.

Dynamic Daylight

I have made dynamic sunlight and shadow support wired to the UI, so the sun position can be controlled interactively. The engine calculates the sun position by using azimuth and elevation as parameters. Sun and fog color is adjusted according to the elevation by using a color gradient generated with GIMP. The result can be seen here:

Normal Mapping with Partial Derivatives

I have added normal mapping support recently. It is not perfect, but works well with some new models I have obtained from ShareCG (thank you, Nobiax). The model loader still lacks of tangent and binormal processing support (still relying on lowly OBJ files), so I am using partial derivatives to reconstruct T and B from GBuffer and shader parameters.

I have extended the deferred light combiner shader to handle multiple BRDFs with many parameters (diffuse, specular, environment reflection, etc.). The BRDF parameters are organized in a table that is indexed by a field in the GBuffer. Different objects can have different BRDFs, the particular index is an effect parameter. Deferred light combiner shader handles backside lighting (e.g. the sunlight shines through the leaves), controlled by a diffuse parameter in the BRDF table.

Here are some images produced by the current state of the renderer.

This slideshow requires JavaScript.

Flicker Free Soft Edged Cascaded Shadows

Just finished the cascaded shadow map support. It uses the technique described in NVidia’s CSM paper. The original method gives somewhat flickering shadow edges so I have added some reduction technique described in a talk about Frostbite. To make it more smooth, I have added 3×3 PCF filtering. There is a short video with the results: 

Through the Valley of Cascaded Shadows and Depth

After some struggling with frustum and light projection matrix calculation, CSM is finally working in the engine. There are four splits, parallel light projection and dynamic bounding frustum calculation. The technique is basically the same as described in the NVidia’s article.

There is still some annoying bug with frustum culling in the shadow map render code, thus, the shadows are leaking sometimes. But performs quite good after all.

Here are some pictures of the results.

This slideshow requires JavaScript.

Some Advancements in the Shaders

I have played with the shaders in the renderer. Now it supports glow maps and specular maps. The specular map is used in two ways. On the one part, it is used as a specular term in the light equation in the lighting pass. On the other part, it is used to add some environment reflections on objects in the final pass.

The terrain shader blends between multiple textures depending on the terrain slope and height. The shading is done in runtime so the changes in the terrain geometry caused by the erosion simulation are properly appearing in the rendering.

Here are some images about the results.

To emphasize the effects of environment reflections (and to make calculations simpler), I have replaced the procedural skybox to a static HDR environment cube map.

Update 10/01/12: I have found a bug in the shaders. I have fixed it, and I have done some modelling to see the results. I have obtained some (cars and dumpster) from TurboSquid too, and I have put some new images to the slideshow to show the results.

This slideshow requires JavaScript.