   Cascaded Shadow Maps (choosing level)
  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 mapelseLinear blend from Local to Global from Z = 10, to Z = 20I.E. z = 10 means 1.0*Localz = 15 means .5*Local +.5*Globalz >= 20 means 1.0*globalIf 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?   
  Er...I'm not sure about shader implementation, but couldn't you use something like this:shadow_map_unit = get_unit(EYE_Z);z_for_comparison = magic_formula(EYE_Z);The simplest case (but haven't thought about it) isget_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)   ;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.1) First, you project fragment position into first split\cascade shadow map.    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 range3) 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){float sm_depth = tex2D(sm1_sampler, shadowCoord);....calculate shadow term.... }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.Adapting this for your case wiil require following: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.   