Jump to content

  • Log In with Google      Sign In   
  • Create Account

Center the cascaded shadow map


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 Alundra   Members   -  Reputation: 868

Like
0Likes
Like

Posted 24 November 2012 - 09:26 AM

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

Edited by Alundra, 24 November 2012 - 09:30 AM.


Sponsor:

#2 Alundra   Members   -  Reputation: 868

Like
0Likes
Like

Posted 24 November 2012 - 04:44 PM

Does it need to have one view matrix for one projection matrix or a trick exist to have the projection offset good ?




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS