Archive for July, 2011

Deep Opacity Maps in Crystal Space

Deep Opacity Maps (DOM) represent a nice way of removing artifacts caused by the linear splitting in Opacity Shadow Maps (OSM).

The novelty of DOM is that they align the opacity maps (layers) with the hair geometry by first computing a depth map and use this information as an offset to the linear splitting that happens at a later rendering pass. In the following picture taken from [DOM] you can see exactly the difference between splitting in OSM (a) and DOM (b).

The advantage of using DOM is that visual artifacts do not occur even when using just a few layers, because by being aligned with the geometry the splitting follows the light distribution. Next is a comparison between the rendering obtained with OSM with 60 layers (a) and DOM with 16 layers (b) in Crystal Space:

However, one major disadvantage of DOM is that even though they explicitly specify a starting splitting position for each point (via the depth map), no information about the stopping splitting position is given whatsoever. This can create a lot of difficulties when trying to make the implementation work with different objects of different sizes and shapes. Using either a constant or the length of the object measured at a particular point in order to obtain the distance between two consecutive splits are too restrictive and thus fail.

This is why for the remaining time of the project I plan to extend DOM to compute and use information from a depth map containing the depth of the farthest points (the stopping splitting positions) as well. I also want to experiment with different splitting schemes, apart from the linear one, and add support for opaque objects, possibly by using the information provided by the depth map.

Opacity Shadow Maps artifacts

Opacity shadow maps can suffer from sever artifacts if not “enough” maps are generated. The artifacts are caused by the fact that new points, without shadow information, are introduced by each opacity map. Below you can see the grass from CS rendered using only 15 opacity maps (the diagonal lines perpendicular to the light’s direction are the artifacts, in case they weren’t obvious enough 🙂 ):

The limit is 15 because, at the moment, the textures are passed as an array of sampler2D and only 16 (15 opacity + 1 material) textures can be used in one shader on my video card, NVIDIA GeForce 9500M GS. However, 4 times more maps can be generated if every channel of every texture is used, yielding 60 maps (but only 14 textures):

As can be seen from the above picture the artifacts are now slightly less visible (more but smaller), so increasing the number of maps is one way of trying to remove these artifacts. Another (smarter) way is by aligning the opacity maps with the geometry, using information from a depth map, as described in deep opacity maps (DOM). This is what I plan to implement for the second part of GSoC. Here is how DOM should improve the rendering: