Graphics Reference
In-Depth Information
more than SM Dim samples. It is not necessary to store the height map itself,
so all coarser levels can be packed into SM Dim
1 samples (in case the shadow
map dimension is a power of two). We pack data so that level 1 starts at column
x = 0, level 2 starts at column x = SM Dim / 2 and so on. The data for the i th
cascade begins at row y = N Slices ·
i .
The first tree level is obtained by reading the slice origin O UV and direction
D UV from the tex2DSliceUVDirAndOrigin texture, computing the locations of the
two required samples on the shadow map ( O UV +2 i
D UV )
and the min/max depth. To obtain conservative bounds, we use the Gather()
instruction to fetch four depths, which would be used if PCF filtering was per-
formed, for each location. We use the 16-bit unorm texture to save memory and
bandwidth. Since conversion from 32-bit float to 16-bit uint can lose precision,
we have to be careful with proper rounding, as shown in the following snippet:
D UV and O UV +(2 i +1)
·
·
const float R16U_PRECISION =1. f /( float )(1 << 16) ;
fMinDepth = floor ( fMinDepth / R16U_PRECISION ) ￿ R16U_PRECISION ;
fMaxDepth =
ceil ( fMaxDepth / R16U_PRECISION ) ￿ R16U_PRECISION ;
Coarser levels are computed by reading min/max bounds from the two finer
level nodes and taking minimum/maximum of these values. To implement this,
we use two textures, setting them alternately as a source and destination. Since
it is unlikely that very coarse tree levels could be reached, we limit the coarsest
level step by 1 / 16 of the shadow map resolution. Rendering to low-resolution
textures is ine cient on modern GPUs and numerical integration is less accurate
when performing very long steps.
2.8.4 Ray Marching Shader
Ray marching shader implements the algorithm described in Section 2.7.3. tex2D
InitialInsctr texture is set as the render target, while stencil tex2DEpipolar
Stencil is used to execute the shader only for the marked ray marching samples.
The shader full code is too long to be presented here, and Listing 2.2 contains
only the most important lines, mentioning the remaining parts in comments.
We tried three strategies to process cascades. The first strategy renders each
cascade in a single draw call and accumulates in-scattering in tex2DInitialInsctr
texture using alpha blending. The second strategy uses instancing to perform this
in a single draw call. The third strategy (shown in the listing) goes through all
cascades in the shader. The last method works slightly better because common
computations, like intersection with top of the atmosphere, are not duplicated,
but the GPU is still fully utilized.
Search WWH ::




Custom Search