This topic is 3160 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I recently implemented a 2-system CSM. 1 map local, 1 covers the whole scene. My shader uses the basic idea given by an Nvidia whitepaper to use the z-depth to choose what Shadow Map to use. Shader code is something like: if(EYE_Z < 10) use local shadow map else Linear blend from Local to Global from Z = 10, to Z = 20 I.E. z = 10 means 1.0*Local z = 15 means .5*Local +.5*Global z >= 20 means 1.0*global If I put in a total of say 3 or 4 CSM's, I would have to have a bunch of if statements. Is this how everyone is doing it? Should I also put my CSM's into a 3D-texture to make it easier?

##### Share on other sites
Er...
I'm not sure about shader implementation, but couldn't you use something like this:

z_for_comparison = magic_formula(EYE_Z);

The simplest case (but haven't thought about it) is
get_unit: floor(EYE_Z)
magic_formula: EYE_Z-floor(EYE_Z)

I guess you have directional light, so "magic_formula" will be a simple linear interpolation, if you have the starting and end values.

If you have arbitrary values (cascades), then I guess if-else is the simplest/fastest, but if you can express the relation between the cascades with a function (thus the start-end values), you could get the shadow_map_unit and the z_for_comparison directly, using this function (more precisely its inverse)

It's just an idea, maybe you can do something with it (if it makes sense at all)

##### Share on other sites
Quote:
 Should I also put my CSM's into a 3D-texture to make it easier?
I think that would be actually worse, only relatively small amount of fragments will need to fetch both shadow maps.

We use different approach, it takes into acount not only distance but the area covered by shadow maps as well.

float4 fragmentSMPos = mul(float4(fragmentWorldPos.xyz, 1), SM1Matrix);

2) Then you convert fragments coordinates to shadow map texture space and check them:
bool s = all(abs(shadowCoord - 0.5f) < 0.5f); //shadowCoord is the fragmentSMPos, converted to 0..1 texture range

3) If all values of s are true then fragment is definately belongs to first split and you fetch shadow map to calculate shadow term:

if(s){
}

4) If one or more s components is false, you get back to step 1 and project fragment into next split shadow map and repeat all steps:

else{
fragmentSMPos = mul(float4(fragmentWorldPos.xyz, 1), SM2Matrix);
.....
}

Dynamic branching won't be an issue as mostly it will occur only on edges of splits\cascades. And if you already found to which cascade fragment belongs branching practically avoids other calculation. In worst case you will check all splits, but this will be true only for most distance fragments.

1) Fetch not one but two shadow maps at the same time for a splits which you want to blend, so that would be one of the steps 3.
2) Use projected fragment posititon (-1..1) or texture coordinates (0..1) used to fetch shadow map, to blend from one shadow term to another.

1. 1
2. 2
3. 3
Rutin
20
4. 4
khawk
14
5. 5

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633655
• Total Posts
3013187
×