   PSSM/CSM with directional light question
  I have PSSM/CSM implemented with spot lights which uses perspective projections. Can someone maybe elaborate how this can be done with orthographic projections as well. I get how the zooming in would work; however, how do you check for which split to use in the shader?   
  I'm surprised you bothered with spotlights tbh. I've found they just aren't needed unless you're doing 170 degrees because you don't have PSSM on directional lights yet! :)   (Been there meself)It's pretty similar actually. Set an orthographic matrix for your lights using similar code for the spots - obviously a different matrix is used and you'll need a new parameter - the ortho scale or whatever you call it. The value that defines how many pixels you see in the viewport.Work that number out by getting a radius around your splits in the same way as you must be doing for a spot.Here's some random bits of code for you to look at. It won't even nearly compile, but hopefully the variable names etc will give you some clues.tVOIDRZPSSM::InitFromScene (RZView* SceneView,const RZMatrix34& OrgLightMatrix){RZMatrix34SceneCamMat=SceneView->GetCamera()->GetMatrix();tF32Aspect=SceneView->GetAspectRatio();tF32FOV=SceneView->GetCamera()->GetFOV();tF32SplitSchemeLambda=SceneView->GetLambdaPSSM();// Blend between log and practical. Range= 0-1tF32Distances[5];tF32OrgNear=SceneView->GetNearClip();tF32OrgFar=RZMath::Min(300.0F,SceneView->GetFarClip());// Pointless going out beyond 300 units as you can't see it anyway. Better to concentrate on the closer detailfor (tINT x=0;x<4;x++){tF32fIDM=x/4.0F;tF32fLog=OrgNear*RZMath::Pow((OrgFar/OrgNear),fIDM);tF32fUniform=OrgNear+(OrgFar-OrgNear)*fIDM;Distances[x]=fLog*SplitSchemeLambda+fUniform*(1-SplitSchemeLambda);}Distances[4]=OrgFar;for (tINT x=0;x<4;x++){// Adjust clip planes for each split. Do a better method than this once it works - we should focus more on the closer frustiitF32Near=Distances[x];tF32Far=Distances[x+1];// Calculate the mini-frustum and store data for later usetFDIMENSIONDim=RZView::GetFrustumDimensionAtDepth(Far,FOV,Aspect);RZVector3FarCorner(Dim.Width*0.5F,Dim.Height*0.5F,Far);Splits[x].Centroid.Set(0,0,Near+((Far-Near)*0.5F));tF32Rad=(Splits[x].Centroid-FarCorner).GetLength();//RZDebug::Printf("N,F,R: %3.3f, %3.3f, %3.3f",Near,Far,Rad);Splits[x].OrthoScale=Rad*2.01F;Splits[x].MainViewNearClip=Near;Splits[x].MainViewFarClip=Far;tF32PullBackDist=RZMath::Min(300.0F,SceneView->GetFarClip());Splits[x].ShadowNearClip=0;Splits[x].ShadowFarClip=PullBackDist+Rad*2.1F;Splits[x].Centroid*=SceneCamMat;Splits[x].Centroid-=OrgLightMatrix.ROW3*(PullBackDist+Rad*1.01F);Splits[x].LightMatrix=OrgLightMatrix;Splits[x].LightMatrix.ROW4=Splits[x].Centroid;}}tVOIDRZPSSM::SetSplitWrite (tINT Split,RZView* SceneView,RZView* ShadowView,RZMatrix34& LightMatrix){// Build an orthogonal camera view that looks at our scene (ie the current view frustum)RZCamera*Cam=ShadowView->GetCamera();Cam->SetOrthoScale(Splits[Split].OrthoScale);Cam->SetMatrix(Splits[Split].LightMatrix);LightMatrix=Splits[Split].LightMatrix;ShadowView->NearClip=Splits[Split].ShadowNearClip;ShadowView->FarClip=Splits[Split].ShadowFarClip;ShadowView->MinZ=0;ShadowView->MaxZ=1;tINTXc=0;tINTYc=0;if (Split&1)Xc=RZShadowTextureSize/2;if (Split>=2)Yc=RZShadowTextureSize/2;ShadowView->DisplayArea.Xc=Xc;ShadowView->DisplayArea.Yc=Yc;ShadowView->DisplayArea.Width=RZShadowTextureSize/2;ShadowView->DisplayArea.Height=RZShadowTextureSize/2;}tVOIDRZView_Base::FillOrthoMatrix (RZMatrix44& Matrix,tF32 Near,tF32 Far,tF32 OrthoFactor,tF32 Aspect){ClearStruct(Matrix);Matrix.ROW1.VX= 2.0F/OrthoFactor/Aspect;Matrix.ROW2.VY= 2.0F/OrthoFactor;Matrix.ROW3.VZ= 1.0F/(Far-Near);Matrix.ROW4.VZ= Near/(Near-Far);Matrix.ROW4.VW= 1;}RZMatrix44RZView_Base::BuildProjection_Dir (tF32 Near,tF32 Far,tF32 OrthoFactor,tF32 Aspect){RZMatrix44Matrix;FillOrthoMatrix(Matrix,Near,Far,OrthoFactor,Aspect);return Matrix;tVOIDRZRenderMgr::SetLightProjection_Dir (tVOID){// For PSSM we need to set all four matrices and let the PS decide which one to use per pixelfor (tINT s=0;s<4;s++){// Local to cameraRZMatrix44Munge=PSSM_Mgr->Splits.LightMatrix.GetInverse();<br>RZMatrix44BigMat=RZView::BuildProjection_Dir (PSSM_Mgr-&gt;Splits.ShadowNearClip,PSSM_Mgr-&gt;Splits.ShadowFarClip,PSSM_Mgr-&gt;Splits.OrthoScale,<span class="cpp-number">1</span>);<br>Munge*=BigMat;<br><br><span class="cpp-comment">// Dick with it so that the position comes out 0 to 1 instead of -1 to +1 and then flip the Yc value and add on half a pixel. This is so we can read the 'screen' coordinates</span><br><span class="cpp-comment">// out as texture coordinates without having to frig them in the PS</span><br>tF32OffsetX=<span class="cpp-number">0</span>.5F+(<span class="cpp-number">1</span>.0F/RZShadowTextureSize);<br>tF32OffsetY=<span class="cpp-number">0</span>.5F+(<span class="cpp-number">1</span>.0F/RZShadowTextureSize);<br>BigMat.Set(<span class="cpp-number">0</span>.5F,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,-<span class="cpp-number">0</span>.5F,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,<span class="cpp-number">1</span>,<span class="cpp-number">0</span>,OffsetX,OffsetY,<span class="cpp-number">0</span>,<span class="cpp-number">1</span>);<br>Munge*=BigMat;<br><br>RZCore::Core-&gt;PShaderMgr-&gt;SetConstant(ePixelShaderConstant(PSC_PSSM_LIGHTMATRIX1_R0+(s&lt;&lt;<span class="cpp-number">2</span>)),Munge);<br>}<br><br>RZVector4SplitDist;<br>SplitDist.VX=PSSM_Mgr-&gt;Splits[<span class="cpp-number">0</span>].MainViewFarClip;<br>SplitDist.VY=PSSM_Mgr-&gt;Splits[<span class="cpp-number">1</span>].MainViewFarClip;<br>SplitDist.VZ=PSSM_Mgr-&gt;Splits[<span class="cpp-number">2</span>].MainViewFarClip;<br>SplitDist.VW=PSSM_Mgr-&gt;Splits[<span class="cpp-number">3</span>].MainViewFarClip;<br>RZCore::Core-&gt;PShaderMgr-&gt;SetConstant(PSC_PSSM_SPLIDIST,SplitDist);<br>}<br><br><br>}<br><br><br><br><br></pre></div><!–ENDSCRIPT–> 