Sign in to follow this  
Alundra

Center the cascaded shadow map

Recommended Posts

Alundra    2316
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 :
[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 );
}
[/CODE]

Do you have a solution to have correct shadow map ?
Thanks Edited by Alundra

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this