Center the cascaded shadow map

Started by
0 comments, last by Alundra 11 years, 5 months ago
Hi,
I'm testing some techniques of shadowing.Using one shadow map all is working good, but if I do PSSM, the shadow map is not centered anymore.The reconstruction from shadow map is not good since it's outside range [-1,1].
Here the code :

// Get the good up vector.
const float LightUdotL = VectorDot( CVector3( 0.0f, 1.0f, 0.0f ), LightDirection );
const CVector3 LightViewUp = ( MathLib::Abs( LightUdotL ) >= 1.0f ) ? CVector3( 0.0f, 0.0f, 1.0f ) : CVector3( 0.0f, 1.0f, 0.0f );
// Compute light view matrix.
CMatrix4 LightViewMatrix;
LightViewMatrix.LookAt( -LightDirection, CVector3( 0.0f, 0.0f, 0.0f ), LightViewUp );
// Camera values.
const float CameraNear = Camera->GetNear();
const float CameraFar = Camera->GetFar();
// Compute split distances.
const float Range = CameraFar - CameraNear;
const float Ratio = CameraFar / CameraNear;
const float Lambda = 0.75f;
float SplitDepths[ 5 ];
SplitDepths[ 0 ] = CameraNear;
SplitDepths[ 4 ] = CameraFar;
for( UInt32 i = 1; i < 4; ++i )
{
const float p = static_cast< float >( i ) / 4.0f;
const float Log = CameraNear * std::pow( Ratio, p );
const float Uniform = CameraNear + Range * p;
SplitDepths[ i ] = Lambda * ( Log - Uniform ) + Uniform;
}
// Compute each split projection matrix.
CMatrix4 LightProjectionMatrix[ 4 ];
for( UInt32 Split = 0; Split < 4; ++Split )
{
// Get near/far of the current split.
const float NearSplit = SplitDepths[ Split ];
const float FarSplit = SplitDepths[ Split + 1 ];
// Compute frustum corners view space.
const float ScaleXInv = 1.0f / CameraProjectionMatrix( 0, 0 );
const float ScaleYInv = 1.0f / CameraProjectionMatrix( 1, 1 );
CVector3 Corners[ 8 ];
const float NearX = ScaleXInv * NearSplit;
const float NearY = ScaleYInv * NearSplit;
Corners[ 0 ] = CVector3( -NearX, NearY, NearSplit );
Corners[ 1 ] = CVector3( NearX, NearY, NearSplit );
Corners[ 2 ] = CVector3( -NearX, -NearY, NearSplit );
Corners[ 3 ] = CVector3( NearX, -NearY, NearSplit );
const float FarX = ScaleXInv * FarSplit;
const float FarY = ScaleYInv * FarSplit;
Corners[ 4 ] = CVector3( -FarX, FarY, FarSplit );
Corners[ 5 ] = CVector3( FarX, FarY, FarSplit );
Corners[ 6 ] = CVector3( -FarX, -FarY, FarSplit );
Corners[ 7 ] = CVector3( FarX, -FarY, FarSplit );
// Transform frustum corners into light view space.
const CMatrix4 CameraViewToLightProj = CameraViewMatrix.Inverse() * LightViewMatrix;
CVector3 CornersLightView[ 8 ];
for( UInt32 i = 0; i < 8; ++i )
CornersLightView[ i ] = CameraViewToLightProj.Transform( Corners[ i ] );
// Compute AABB of the CornersLightView.
CVector3 Min = CVector3( +MathLib::INFINITY_f, +MathLib::INFINITY_f, +MathLib::INFINITY_f );
CVector3 Max = CVector3( -MathLib::INFINITY_f, -MathLib::INFINITY_f, -MathLib::INFINITY_f );
for( UInt32 i = 0; i < 8; ++i )
{
Min = VectorMinimize( Min, CornersLightView[ i ] );
Max = VectorMaximize( Max, CornersLightView[ i ] );
}
// Compute light projection matrix.
LightProjectionMatrix[ Split ].OrthoOffCenter( Min.x, Max.x, Min.y, Max.y, Min.z - 50.0f, Max.z );
}


Do you have a solution to have correct shadow map ?
Thanks
Advertisement
Does it need to have one view matrix for one projection matrix or a trick exist to have the projection offset good ?

This topic is closed to new replies.

Advertisement