[DirectX 10] View Projection frustum planes

Started by
2 comments, last by Zakwayda 12 years, 12 months ago
Hi, I'm trying to calculate the view frustum planes equations in world space like this:


////// UPDATE CORNERS POSITION
float Hnear = 2 * tan(fov / 2) * zNear;
float Wnear = Hnear * ratio;

D3DXVECTOR3 nearCenter = mLook * zNear;

D3DXVECTOR3 nearTopLeft = nearCenter + (mUp * Hnear/2) - (mRight * Wnear/2);
D3DXVECTOR3 nearTopRight = nearCenter + (mUp * Hnear/2) + (mRight * Wnear/2);
D3DXVECTOR3 nearDownLeft = nearCenter - (mUp * Hnear/2) - (mRight * Wnear/2);
D3DXVECTOR3 nearDownRight = nearCenter - (mUp * Hnear/2) + (mRight * Wnear/2);

float Hfar = 2 * tan(fov / 2) * zFar;
float Wfar = Hfar * ratio;

D3DXVECTOR3 farCenter = mLook * zFar;

D3DXVECTOR3 farTopLeft = farCenter + (mUp * Hfar/2) - (mRight * Wfar/2);
D3DXVECTOR3 farTopRight = farCenter + (mUp * Hfar/2) + (mRight * Wfar/2);
D3DXVECTOR3 farDownLeft = farCenter - (mUp * Hfar/2) - (mRight * Wfar/2);
D3DXVECTOR3 farDownRight = farCenter - (mUp * Hfar/2) + (mRight * Wfar/2);

corners[0] = D3DXVECTOR4(nearTopLeft, 1.0f);
corners[1] = D3DXVECTOR4(nearTopRight, 1.0f);
corners[2] = D3DXVECTOR4(nearDownLeft, 1.0f);
corners[3] = D3DXVECTOR4(nearDownRight, 1.0f);
corners[4] = D3DXVECTOR4(farTopLeft, 1.0f);
corners[5] = D3DXVECTOR4(farTopRight, 1.0f);
corners[6] = D3DXVECTOR4(farDownLeft, 1.0f);
corners[7] = D3DXVECTOR4(farDownRight, 1.0f);

////// UPDATE PLANES

D3DXPlaneFromPoints(&planes[0], &nearTopLeft, &nearTopRight, &nearDownRight); //Near
D3DXPlaneFromPoints(&planes[1], &farTopRight, &farTopLeft, &farDownLeft); //Far
D3DXPlaneFromPoints(&planes[2], &nearTopLeft, &nearDownLeft, &farDownLeft); //Left
D3DXPlaneFromPoints(&planes[3], &nearDownRight, &nearTopRight, &farDownRight); //Right
D3DXPlaneFromPoints(&planes[4], &nearTopRight, &nearTopLeft, &farTopLeft); //Top
D3DXPlaneFromPoints(&planes[5], &nearDownLeft, &nearDownRight, &farDownRight); //Down


Im almost sure that the corners position math is correct, I just dont know if I'm creating the planes in a way that the planes normal face inward...The objects in my scene are being incorrectly culled so something is wrong..,
Advertisement
Culled incorrectly is a vague term ^^

I can help you by giving you my code for computing only the points of the far plane, though it's the same for the near plane, just use the near plane distance imo.


// This is how half frustum width/ height is computed

float halfFrustumHeight=(2*tan(m_fieldOfView/2.0f)*m_farPlane)/2.0f;
float halfFustumWidth=((halfFrustumHeight*2)*m_aspectRatio)/2.0f;

// Update (call after new camera matrices have been computed)
// The farPlane,fieldOfView,halfFrustumWidth/height are actually scalars (but the same value is just copied to every component of the vector)
void Update(FXMVECTOR cameraPosition,FXMVECTOR cameraDirectionNormalized,
FXMVECTOR farPlane,CXMVECTOR fieldOfView,
CXMVECTOR halfFrustumWidth,CXMVECTOR halfFrustumHeight,CXMVECTOR cameraUp)
{

// Frustum center
XMVECTOR frustumCenter=XMVectorMultiply(cameraDirectionNormalized,farPlane);
//frustumCenter=XMVectorAdd(frustumCenter,cameraPosition);

XMVECTOR crossNormalized=XMVector3Cross(cameraDirectionNormalized,cameraUp);

// Corners
XMVECTOR cornerTopLeft=frustumCenter;
cornerTopLeft=XMVectorAdd(cornerTopLeft,XMVectorMultiply(cameraUp,halfFrustumHeight));
cornerTopLeft=XMVectorAdd(cornerTopLeft,XMVectorMultiply(crossNormalized,halfFrustumWidth));

XMVECTOR cornerTopRight=frustumCenter;
cornerTopRight=XMVectorAdd(cornerTopRight,XMVectorMultiply(cameraUp,halfFrustumHeight));
cornerTopRight=XMVectorSubtract(cornerTopRight,XMVectorMultiply(crossNormalized,halfFrustumWidth));

XMVECTOR cornerBottomLeft=frustumCenter;
cornerBottomLeft=XMVectorSubtract(cornerBottomLeft,XMVectorMultiply(cameraUp,halfFrustumHeight));
cornerBottomLeft=XMVectorAdd(cornerBottomLeft,XMVectorMultiply(crossNormalized,halfFrustumWidth));

XMVECTOR cornerBottomRight=frustumCenter;
cornerBottomRight=XMVectorSubtract(cornerBottomRight,XMVectorMultiply(cameraUp,halfFrustumHeight));
cornerBottomRight=XMVectorSubtract(cornerBottomRight,XMVectorMultiply(crossNormalized,halfFrustumWidth));

// Store to XMFLOAT4s
XMStoreFloat4(&m_cornerTopLeft,cornerTopLeft);
XMStoreFloat4(&m_cornerTopRight,cornerTopRight);
XMStoreFloat4(&m_cornerBottomLeft,cornerBottomLeft);
XMStoreFloat4(&m_cornerBottomRight,cornerBottomRight);
}
Hello

Why do you compute the viewing frustrum in world space ?
I think it would be better to compute it in view space : you 'd have to rebuild it only when projection matrix is changed (quite rarely commonly) instead of at each camera change.

Cheers

Why do you compute the viewing frustrum in world space ?

It's often convenient to perform frustum culling in world space. Building the frustum is cheap and doing it once per frame should cause no problems with performance.

Conversely, if you build the frustum in view space, you may end up having to transform bounding volumes or other geometry into the local space of the camera for culling purposes. As such, building the frustum in view space could actually end up being more costly than building it in world space, not less.

This topic is closed to new replies.

Advertisement