CPU Side:

for i = 1 to m
    Ci= CalculateSplitPositions(i,n, f ,m)
    Vi= SplitViewFrustum(V,Ci-1,Ci)
    Mi = CalculateTextureMatrix(Vi )
    SetViewProjMatrix(Mi)
    RenderToTexture(Vi, Ti)
    Ci= ConvertToClipSpace(Ci)
    SetShaderParams(Mi,Ti,Ci )
end for
SetViewProjMatrix(MeyeView, MeyeProj)
RenderShadowedScene(V )
 

GPU side:

texture PSSM1;
texture PSSM2;
texture PSSM3;
sampler PSSM Sampler[3] = {
    sampler_state {
         Texture = <PSSM1>;
        // filtering and addressing modes for all samplers are the same.
        MinFilter = Linear;
        MagFilter = Linear;
        MipFilter = None;
        AddressU = Clamp;
        AddressV = Clamp;
    },
    sampler_state {
        Texture = <PSSM2>;
        ...// filtering and addressing modes.
    },
    sampler_state {
        Texture = <PSSM3>;
        ...// filtering and addressing modes.
    },
};


struct PS_INPUT {
    float4 tex[3] : TEXCOORD
    float4 pos : TEXCOORD4
    float4 color : COLOR0 // diffuse color
    ...// other input data
};


float4 PixelShader_Program(PS_INPUT IN) : COLOR
{
    ...// other statements
    float bias = 0.004;
    bool stop = false;
    float shadow_value = 0;
    for (int i=0; i<3 && !stop; i++){
        if (pos.z/pos.w <= splitPositions[i]) {
            float depth = IN.tex[i].z / IN.tex[i].w;
            float depth_SM = tex2Dproj (PSSM_Sampler[i], IN.tex[i]);
            shadow_value = (depth < depth_SM + bias);
            stop = true;
        }
    }
    return shadow_value * color;
}

 
Disclaimer: This is a user-contributed webpage hosted in Department of Computer Science and Engineering, The Chinese University of Hong Kong.
The department is not responsible for the contents nor any loss or damage due to it.