Sign in to follow this  
Corillian

Some troubles with calculating the View Frustrum bounding box

Recommended Posts

Hello I am trying to get the points for the viewing frustrum in world space so that I can render it. So far I am able to render something that resembles a viewing frustrum except the far plane appears to be about half the dimensions it's supposed to be. I have poured over all of the threads I could find on these boards and other sources on the internet but nothing i've tried has fixed the problem just yet. Here is my code (d3d): The function to pull the planes from the matrix mat which is (view * proj):
m_vLeft.a = mat._14 + mat._11;
m_vLeft.b = mat._24 + mat._21;
m_vLeft.c = mat._34 + mat._31;
m_vLeft.d = mat._44 + mat._41;
D3DXPlaneNormalize(&m_vLeft, &m_vLeft);

m_vRight.a = mat._14 - mat._11;
m_vRight.b = mat._24 - mat._21;
m_vRight.c = mat._34 - mat._31;
m_vRight.d = mat._44 - mat._41;
D3DXPlaneNormalize(&m_vRight, &m_vRight);

m_vBottom.a = mat._14 + mat._12;
m_vBottom.b = mat._24 + mat._22;
m_vBottom.c = mat._34 + mat._32;
m_vBottom.d = mat._44 + mat._42;
D3DXPlaneNormalize(&m_vBottom, &m_vBottom);

m_vTop.a = mat._14 - mat._12;
m_vTop.b = mat._24 - mat._22;
m_vTop.c = mat._34 - mat._32;
m_vTop.d = mat._44 - mat._42;
D3DXPlaneNormalize(&m_vTop, &m_vTop);

m_vNear.a = mat._13;
m_vNear.b = mat._23;
m_vNear.c = mat._33;
m_vNear.d = mat._43;
D3DXPlaneNormalize(&m_vNear, &m_vNear);

m_vFar.a = mat._14 - mat._13;
m_vFar.b = mat._24 - mat._23;
m_vFar.c = mat._34 - mat._33;
m_vFar.d = mat._44 - mat._43;
D3DXPlaneNormalize(&m_vFar, &m_vFar);
After that I make a call to get each point of the frustrum:
//far bottom left
GetIntersectionWithPlanes(m_vFar, m_vBottom, m_vLeft, pOut);
The intersection code is the following:
void GetIntersectionWithPlanes(D3DXPLANE &plane1, D3DXPLANE &plane2, D3DXPLANE &plane3, D3DXVECTOR3 &outPoint)
{
	//D3DXVECTOR3 linePoint, lineVect;

	D3DXMATRIX mat;
	D3DXVECTOR4 *vec;

	vec = (D3DXVECTOR4*)&mat.m[0];
	*vec = *((D3DXVECTOR4*)&plane1);
	vec->w = 1.0f;

	vec = (D3DXVECTOR4*)&mat.m[1];
	*vec = *((D3DXVECTOR4*)&plane2);
	vec->w = 1.0f;

	vec = (D3DXVECTOR4*)&mat.m[2];
	*vec = *((D3DXVECTOR4*)&plane3);
	vec->w = 1.0f;

	vec = (D3DXVECTOR4*)&mat.m[3];
	*vec = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);

	FLOAT d = D3DXMatrixDeterminant(&mat);
	D3DXMatrixInverse(&mat, &d, &mat);
	vec = (D3DXVECTOR4*)&mat.m[0];
	outPoint.x = -vec->w;

	vec = (D3DXVECTOR4*)&mat.m[1];
	outPoint.y = -vec->w;

	vec = (D3DXVECTOR4*)&mat.m[2];
	outPoint.z = -vec->w;
}
I've tried transforming the point returned by the intersection function by the inverse of the view * proj matrix thinking I needed to go from clip space to world space but it did nothing:
GetIntersectionWithPlanes(m_vFar, m_vBottom, m_vRight, pOut);
D3DXVec3Transform(&pRes, &pOut, &matInv);
If anyone could provide some insight on the matter that would be fantastic.

Share this post


Link to post
Share on other sites
The planes returned by the algorithm should be in world space, so no transformation of the frustum corners should be necessary.

Depending on where you got your plane intersection function, a good place to start might be testing it independently of the frustum code by intersecting three planes whose intersection point is known and seeing if the results are correct. You might also proof the frustum extraction code (assuming you had to type it yourself at some point) to make sure all the matrix indices are correct.

Beyond that, I'm not sure. Perhaps you could clarify what you mean by the far plane being half the dimensions it's supposed to be. Do you mean twice as close as it should be? Does the rest of the frustum look correct?

Also, when you say 'view frustum bounding box' I gather you just mean the frustum itself, rather than an AABB or OBB enclosing the frustum (which is what a 'bounding box' would actually be).

Share this post


Link to post
Share on other sites
There's another way that's conceptually easier to understand (at least for me) and would seem to be a bit faster - not that it really matters, as its probably only used a few times per frame.
Firstly, compute the View*Projection matrix - this transforms from World->View->Projection(Homogeneous). Now invert it to get a transform Projection->View->World matrix. Then transform the 8 homogeneous-space frustum corners (x=-1,1 y=-1,1 z=0,1) by this matrix to get equivalent world-space points. Then it should be a matter of min/max'ing to get an axis aligned box.

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