# Transforming a split frustum from NDC to world space

This topic is 1127 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I'm trying to implement cascaded shadow maps in my Direct3D project and I've been struggling with this issue for a few days now. What I'm trying to do is calculate the current view frustum splits in world space by manually constructing frustum splits in NDC space and transforming them with the current inverse viewprojection matrix. I've managed to create the frustums in NDC space, using these values for the first frustum;

/// NDC Frustum points (xyzw)
LTN:-1.000000  1.000000  0.100000  1.000000
RTN: 1.000000  1.000000  0.100000  1.000000
LBN:-1.000000 -1.000000  0.100000  1.000000
RBN: 1.000000 -1.000000  0.100000  1.000000
LTF:-1.000000  1.000000  0.215443  1.000000
RTF: 1.000000  1.000000  0.215443  1.000000
LBF:-1.000000 -1.000000  0.215443  1.000000
RBF: 1.000000 -1.000000  0.215443  1.000000

LTN means LeftTopNear, LBF means LeftBottomFar and so on. The data for the second and third frustum are similar, but with the different z-values for the far planes (0.464159 for the second frustum and 1.0 for the last one)

Here's the code that is supposed to transform and normalize the frustum points:

/// m_viewProjection verified to be correct
XMMATRIX invViewProjection = XMMatrixInverse(nullptr, m_viewProjection);

{
for (int j = 0; j < 8; j++)
{
m_frustumsWorld[i].point[j] = XMVector4Transform(m_frustumsNDC[i].point[j], invViewProjection);
m_frustumsWorld[i].point[j] /= m_frustumsWorld[i].point[j].m128_f32[3];
}
}


The problem seems to occur when I do the transform. The last frustum (with NDC z-far distance of 1.0) seems to get transformed right with a world z-value corresponding to 100% of the max view distance, but the other two doesn't. Their transformed values puts them extremly close to the camera, not ~21% and ~46% of the max view distance which is what I'm looking for. I've spent days trying to figure out whats wrong appreciate any help I can get!

##### Share on other sites

Here the code to compute the 8 corners of the camera frustum in world-space :

void CCameraComponent::ComputeFrustumCornerPoints( CVector3* Points ) const
{
// Get property values.
const float NearClipPlane = GetNearClipPlane();
const float FarClipPlane = GetFarClipPlane();

// Compute the projection inverse scale factor.
const float ScaleXInv = 1.0f / m_ProjectionMatrix( 0, 0 );
const float ScaleYInv = 1.0f / m_ProjectionMatrix( 1, 1 );

// Compute corners in view space.
CVector3 CornersVS[ 8 ];
const float NearX = ScaleXInv * NearClipPlane;
const float NearY = ScaleYInv * NearClipPlane;
CornersVS[ 0 ] = CVector3( -NearX, +NearY, NearClipPlane );
CornersVS[ 1 ] = CVector3( +NearX, +NearY, NearClipPlane );
CornersVS[ 2 ] = CVector3( +NearX, -NearY, NearClipPlane );
CornersVS[ 3 ] = CVector3( -NearX, -NearY, NearClipPlane );
const float FarX = ScaleXInv * FarClipPlane;
const float FarY = ScaleYInv * FarClipPlane;
CornersVS[ 4 ] = CVector3( -FarX, +FarY, FarClipPlane );
CornersVS[ 5 ] = CVector3( +FarX, +FarY, FarClipPlane );
CornersVS[ 6 ] = CVector3( +FarX, -FarY, FarClipPlane );
CornersVS[ 7 ] = CVector3( -FarX, -FarY, FarClipPlane );

// Compute the inverse of the view matrix.
const CMatrix4 InverseViewMatrix = m_ViewMatrix.Inversed();

// Compute the world space corners.
for( UInt32 i = 0; i < 8; ++i )
Points[ i ] = InverseViewMatrix.TransformPoint( CornersVS[ i ] );
}
Edited by Alundra

##### Share on other sites

Thanks so much Alundra, your solution with constructing the corners in view space works much better. Still curious as to why the original solution didn't work though!

##### Share on other sites

Thanks so much Alundra, your solution with constructing the corners in view space works much better. Still curious as to why the original solution didn't work though!

The reason why is would be this (To quote Eric Lengyel)
Z is nonlinear because perspective-correct rasterization requires linear interpolation of 1/z -- linear interpolation of z itself does not produce the correct results.

http://www.gamedev.net/topic/539378-why-non-linear-depth-buffer/#entry4483438

1. 1
2. 2
3. 3
Rutin
23
4. 4
5. 5
khawk
14

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633653
• Total Posts
3013166
×