Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualAlundra

Posted 24 November 2012 - 09:30 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

#2Alundra

Posted 24 November 2012 - 09:29 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

#1Alundra

Posted 24 November 2012 - 09:26 AM

Hi,
I'm testing some techniques of shadowing, working 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

PARTNERS