<p>The logarithmic shadow mapping split scheme produces split points that minimize aliasing. There is a short derivation that can be used to show that it produces the split points that reduce aliasing to values near 1. Here is the calculation:</p>
<p><span class="math-container">$C^{log}_i = z_n(\frac{z_f}{z_n})^\frac{i}{m}$</span></p>
<p>where <span class="math-container">$i$</span> is the ith cascade and m is the total number of cascades.</p>
<p>Chose <span class="math-container">$z_n$</span> carefully. Often it is better to use a &quot;virtual&quot; near plane chosen to maximize coverage and reduce wasted shadow map space. (A poorly chosen near plane can cause an entire cascade to produce no meaningful data) Also, keep in mind that shadows closer to the camera then the chosen near plane will still produce shadows but may have higher aliasing. There are algorithms for choosing a virtual near plane I recommend looking them up.</p>
<p>While <span class="math-container">$C^{log}_i$</span> will produce split points that minimize aliasing, it will generally not give the best coverage for distant shadows(where the majority of the geometry is rendered). And a better scheme (published in several places) is to use something called the &quot;practical&quot; or &quot;weighted&quot; algorithm. It combines a uniform distribution with the logarithmic distribution. Here is its calculation: (just a simple lerp)</p>
<p><span class="math-container">$C^{pract}_i = \alpha C^{log}_i + (1-\alpha)C^{uni}_i$</span></p>
<p>where <span class="math-container">$C^{uni}_i$</span> is:</p>
<p><span class="math-container">$C^{uni}_i= n + (f-n)\frac{i}{m}$</span></p>
<p>This makes it easy to adjust between full logarithmic and uniform split.</p>
<p>Most of this info is readily available but the bit about choosing Z near is glossed over in most publications.</p>
<p>Here are my sources:
My used copy of &quot;Real-Time Shadows&quot; and <a href="https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10-parallel-split-shadow-maps-programmable-gpus" rel="nofollow noreferrer">GPU Gems 3 chapter 10</a> (because there was an error in the book!)</p>

CC BY-SA 4.0
2022-10-11T20:59:52.447Z
Perfect! That is, what I was looking for
Thomas
CC BY-SA 4.0
2022-10-12T07:07:26.973Z
Thanks a lot! Also for the hint, that there is an error in the book. This will save me a lot of time (+1)
Thomas
CC BY-SA 4.0
2022-10-12T11:47:31.317Z
if I see it correctly, then the "FoV" is not taken into account. Is that correct?
Thomas
CC BY-SA 4.0
2022-10-12T14:38:53.570Z
Yes, aliasing in shadow mapping is mostly a function of depth and light to geometry/camera angle. But a narrow FOV will zoom distant geometry. Then the parallel projection matrix can end up with a long a narrow strip that gets sampled from when rendering  shadows. Modifying the projection matrix to better fit the situation can help, modifying Z near used in the calculations can help, and modifying the alpha value used in Cpract can help.
pmw1234
CC BY-SA 4.0
2022-10-11T14:58:11.823Z
2022-10-11T14:58:11.823Z
pmw1234
<p>I am trying to implement CSM technique with &quot;Fit to Cascade&quot; projections. My problem is to find good distances to partitioning the cameras view frustum. The FoV of my camera is changing, so the partitioning for the CSM algorithm need to be changed as well with respect to the FoV angle.</p>
<p>My shadowMap texture is a Texture2dArray which will be filled by layered rendering technique. So unlike some CSM tutorials, the shadowMap of each cascade has the same resolution.</p>
<p>What formular can I use to have a mostly 1 to 1 mapping of camera viewSpace pixel to shadowMap pixel?</p>
<p><strong>An example to show what is meant:</strong></p>
<p>For a 90° FoV, the far cascades should always be larger.</p>
<p>For a 10° FoV, the far cascades should be much smaller than the cascades for the 90° Fov to have a better 1 to 1 match</p>

CC BY-SA 4.0
2022-10-11T20:54:05.853Z
It's worth noting that if you change the FoV continuously in real time and change the CSM partitioning smoothly as well, it will cause the shadows to shimmer as the size and position of texels changes.
Nathan Reed
CC BY-SA 4.0
2022-10-11T21:02:00.883Z
I'll not change the FoV continuously... It will be defined by starting the program... But the user can choose between 10° and 120°
Thomas
<shadow-mapping>
Cascaded Shadow Mapping (CSM), Partitioning the Frustum to a nearly 1 by 1 mapping
Thomas
# Cascaded Shadow Mapping (CSM), Partitioning the Frustum to a nearly 1 by 1 mapping

(Asked by: username_0 on 2022-10-10)

I am trying to implement CSM technique with "Fit to Cascade" projections. My problem is to find good distances to partitioning the cameras view frustum. The FoV of my camera is changing, so the partitioning for the CSM algorithm need to be changed as well with respect to the FoV angle.

My shadowMap texture is a Texture2dArray which will be filled by layered rendering technique. So unlike some CSM tutorials, the shadowMap of each cascade has the same resolution.

What formular can I use to have a mostly 1 to 1 mapping of camera viewSpace pixel to shadowMap pixel?

**An example to show what is meant:**

For a 90° FoV, the far cascades should always be larger.

For a 10° FoV, the far cascades should be much smaller than the cascades for the 90° Fov to have a better 1 to 1 match

**Tags:** shadow-mapping

> **Comments:**
> **username_1**: It's worth noting that if you change the FoV continuously in real time and change the CSM partitioning smoothly as well, it will cause the shadows to shimmer as the size and position of texels changes.  
> **username_0**: I'll not change the FoV continuously... It will be defined by starting the program... But the user can choose between 10° and 120°  

---

## 1 answers

### Answer by username_2 on 2022-10-11. Score: 1 | Accepted answer

The logarithmic shadow mapping split scheme produces split points that minimize aliasing. There is a short derivation that can be used to show that it produces the split points that reduce aliasing to values near 1. Here is the calculation:

$C^{log}\_i = z\_n(\frac{z\_f}{z\_n})^\frac{i}{m}$

where $i$ is the ith cascade and m is the total number of cascades.

Chose $z\_n$ carefully. Often it is better to use a "virtual" near plane chosen to maximize coverage and reduce wasted shadow map space. (A poorly chosen near plane can cause an entire cascade to produce no meaningful data) Also, keep in mind that shadows closer to the camera then the chosen near plane will still produce shadows but may have higher aliasing. There are algorithms for choosing a virtual near plane I recommend looking them up.

While $C^{log}\_i$ will produce split points that minimize aliasing, it will generally not give the best coverage for distant shadows(where the majority of the geometry is rendered). And a better scheme (published in several places) is to use something called the "practical" or "weighted" algorithm. It combines a uniform distribution with the logarithmic distribution. Here is its calculation: (just a simple lerp)

$C^{pract}\_i = \alpha C^{log}\_i + (1-\alpha)C^{uni}\_i$

where $C^{uni}\_i$ is:

$C^{uni}\_i= n + (f-n)\frac{i}{m}$

This makes it easy to adjust between full logarithmic and uniform split.

Most of this info is readily available but the bit about choosing Z near is glossed over in most publications.

Here are my sources:
My used copy of "Real-Time Shadows" and [GPU Gems 3 chapter 10](https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10-parallel-split-shadow-maps-programmable-gpus) (because there was an error in the book!)

> **Comments:**
> **username_0**: Perfect! That is, what I was looking for  
> **username_0**: Thanks a lot! Also for the hint, that there is an error in the book. This will save me a lot of time (+1)  
> **username_0**: if I see it correctly, then the "FoV" is not taken into account. Is that correct?  
> **username_2**: Yes, aliasing in shadow mapping is mostly a function of depth and light to geometry/camera angle. But a narrow FOV will zoom distant geometry. Then the parallel projection matrix can end up with a long a narrow strip that gets sampled from when rendering  shadows. Modifying the projection matrix to better fit the situation can help, modifying Z near used in the calculations can help, and modifying the alpha value used in Cpract can help.  

---

