Harmony Phase 1 Proposal
The purpose of the Harmony project is to improve the Blender Game Engine’s rendering of light and shadows. The first phase of improvements will focus on the rendering and use of shadows. The scope of this phase includes a revised shadow panel, point light shadows, variance shadow maps, shadow cookies, and shadow color.
Shadow Panel Changes
Currently the shadow panel displays many options not available to the game engine, even while the Game Engine renderer is active. In the Harmony project we intend to simplify the shadow panel while the Game Engine renderer is active to avoid confusion about what is, and more importantly is not, supported in the Blender Game Engine. Below is an example of a simplified shadow panel.
Point Light Shadows
While point light shadows are expensive on resources, they are still an often requested feature. For the Harmony project we intend to use cubemaps to create point light shadows as they are one of the simpler solutions. In order to do this we will first need to add cubemap support to the texture creation functions in GPU_extensions. This will include adding a function to create cubemaps, and a function to attach them to framebuffers. After GPU_extension has been updated, GPU_material will need to be updated so that point lights use cubemaps instead of the usual depth maps for their shadow buffers. For the actual rendering of shadows three things need to be addressed: rendering into the cubemap, a point light shader, and reading the cubemap in the material shader. Both the 3D viewport and the Blender Game Engine already have functions for rendering into shadow buffers. A check will need to be added into these functions to check if rendering into a cubemap is required, and then rendering into each face of the cubemap if the check passes. Because depth cubemaps are not well supported, the depth data will need to be written into a color texture, requiring these functions to first setup a shader to allow this to happen. Finally a function similar to test_shadowbuf in gpu_shader_material.glsl will need to be written in order to read from the cube shadowbuffer.
Variance Shadow Maps
Variance Shadow Maps (VSMs) are a more advanced form of shadow mapping. Instead of rendering the scene into a depth buffer for the shadow map, the scene is stored in two color channels (depth and depth^2). With these to values it is possible to compute the variance of the depth and color pixels appropriately. The benefit of VSMs is that the depth information is stored in a linear fashion, which means that soft shadows can easily be done by running a separable Gaussian blur over the shadow map. This is cheaper than using a technique like Percentage-Closer Filtering. For this feature, a lamp’s shadow buffer will need to use RGB32F or RGB16F instead of DEPTH_COMPONENT when using VSMs. Also, a shader will need to be written to handle storing the VSM data and the current shadow map shader will need to be reworked to calculate the variance and use the color components of the shadow buffer texture instead of depth. Also, a shader will need to be written to handle the Gaussian blur for soft shadows.
I do not now the actual name for this feature, but I believe they are referred to as “Light Cookies” in Unity 3D. The idea is to project an image with a lamp. This would be done by reusing the shadow buffer code and using a user-defined texture as opposed to a generated shadow map.
This will simply require a function in gpu_shader_material.glsl that multiplies the shadow color against the diffuse rgb based on the shadow factor, and ensuring the shadow colors are properly passed into the shader.