Realtime Cubemap Placement

When using screen space global illumination, alpha blended surface become a problem because you can’t defer the ray evaluation. Doing the SS casts in a forward pass isn’t an option because of the high performance need and inability of temporal smoothing.

Therefore, we implemented a system that collects stochastic queries of all currently rendered objects. The queries are triggered at a random point inside the bounding volume of the object. We then merge those “points of interest”, to get a linearly decreasing density if you are far away from the viewer.

The cubemaps are then updated once the viewer does not move anymore. We do not update cubemaps outside the frustum and prefer the nearest ones.

Alpha Rendering

We pick the nearest two cubemaps per alpha blended object and calculate the influence in the vertex shader as follows:

C++

1

2

3

floatDistNear=length(PositionWS-nearest_pos);

floatDistSecond=length(PositionWS-second_pos);

blendVal=DistNear/(DistNear+DistSecond+epsilon);

Deferred rendering

For opaque objects, we render the cubemaps in a deferred pass into a RGB16F specular and a RGBA16F diffuse texture. We use blending to simple add the intensity values.

The cubemap radius is dependant of the mentioned density to get an average overlap of 1.5 cubemaps. We use a weighting of 1 from the center to half of the radius and smoothstep to zero from the half of the radius to the sphere’s boundary. The diffuse alpha channel stores the cubemap intensity. In the compositing process we do the following to normalize the overlapping cubemaps and add the skybox where we miss information: