Jump to content
  • Advertisement
Sign in to follow this  
Graham

View Frustrum Planes

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am working on doing some view frustum culling and I wanted to be able to visualize the view frustum first. So in my terrain engine I have 2 cameras that I can switch between and I want to draw the view frustum for Camera1, then switch to camera2 so I can see how it clips the terrain. I beleive I have extracted the planes correctly, and found all 8 intersection points. The problem is that when I draw the view frustum is it always mirrored around the origin. Once I have the 8 intersection points do I need to use the view matrix to get them into world coordinates? Here is some code Im using to get the planes:
void CTerrain::ExtractPlanes(void)
{
	D3DXMATRIX res;
	D3DXMATRIX view = Camera.GetViewMatrix();
	D3DXMATRIX proj = Graphics.GetFOV();
	D3DXMatrixMultiply(&res, &view, &proj);

	// left
	m_planes[0].a = res._14 + res._11;
	m_planes[0].b = res._24 + res._21;
	m_planes[0].c = res._34 + res._31;
	m_planes[0].d = res._44 + res._41;

	// right
	m_planes[1].a = res._14 - res._11;
	m_planes[1].b = res._24 - res._21;
	m_planes[1].c = res._34 - res._31;
	m_planes[1].d = res._44 - res._41;

	// top
	m_planes[2].a = res._14 - res._12;
	m_planes[2].b = res._24 - res._22;
	m_planes[2].c = res._34 - res._32;
	m_planes[2].d = res._44 - res._42;

	// bottom
	m_planes[3].a = res._14 + res._12;
	m_planes[3].b = res._24 + res._22;
	m_planes[3].c = res._34 + res._32;
	m_planes[3].d = res._44 + res._42;

	// near
	m_planes[4].a = res._13;
	m_planes[4].b = res._23;
	m_planes[4].c = res._33;
	m_planes[4].d = res._43;

	// far
	m_planes[5].a = res._14 - res._13;
	m_planes[5].b = res._24 - res._23;
	m_planes[5].c = res._34 - res._33;
	m_planes[5].d = res._44 - res._43;

	for(int i=0; i < 6; i++)
	{
		D3DXPlaneNormalize(&m_planes, &m_planes);
	}

	return;
}


And getting the 8 intersection points
D3DXVECTOR3 topLeftN, topRightN, botLeftN, botRightN,
				topLeftF, topRightF, botLeftF, botRightF;
	// Ends is N is on near plane, end in F is far plane.

	topLeftN  = Intersect3Planes(m_planes[0], m_planes[2], m_planes[4]);
	topRightN = Intersect3Planes(m_planes[1], m_planes[2], m_planes[4]);
	botLeftN  = Intersect3Planes(m_planes[0], m_planes[3], m_planes[4]);
	botRightN = Intersect3Planes(m_planes[1], m_planes[3], m_planes[4]);

	topLeftF  = Intersect3Planes(m_planes[0], m_planes[2], m_planes[5]);
	topRightF = Intersect3Planes(m_planes[1], m_planes[2], m_planes[5]);
	botLeftF  = Intersect3Planes(m_planes[0], m_planes[3], m_planes[5]);
	botRightF = Intersect3Planes(m_planes[1], m_planes[3], m_planes[5]);


Thanks for any help on this. edit. Then for example the left plane would be drawn like this.
Graphics.m_pd3dDevice->SetFVF(D3DFVF_VertexColor);
	VertexColor g_Vertices[] =
	{
		// left
		{ topLeftN.x, topLeftN.y, topLeftN.z, 0xFFFF0000},
		{ botLeftN.x, botLeftN.y, botLeftN.z, 0xFFFF0000},
		{ topLeftF.x, topLeftF.y, topLeftF.z, 0xFFFF0000},
		{ botLeftF.x, botLeftF.y, botLeftF.z, 0xFFFF0000}
}
Graphics.m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Vertices, sizeof(VertexColor));

Share this post


Link to post
Share on other sites
Advertisement
Hi there Graham, how are you doing?

[The problem]
Your view frustum is mirrored.

I cannot really see anything wrong with your code.
But let's look at the theory

[The Theory]

Article 1 - Frustum Culling by Dion Picco (01 April 2003)
Article 2 - View frustum culling by Ruud van Gaal.

Now from the theory discussed. The points extracted should be in screen space. This means that they will have to be transformed into world space if you want to draw them.

[Why do they need to be transformed]
Let's look at what the transformations do.

World Transform:
A world transform changes coordinates from model space, where vertices are defined relative to a model's local origin, to world space, where vertices are defined relative to an origin common to all the objects in a scene.

View Transform:
The view transform locates the viewer in world space, transforming vertices into camera space. In camera space, the camera, or viewer, is at the origin, looking in the positive z-direction.

Projection Transform:
The projection matrix is typically a scale and perspective projection. The projection transformation converts the viewing frustum into a cuboid shape.


[The solution]
These points you extracted are in Clip space, You need to convert them back into World space so that you can render them. This is done using a Inverse ViewProjection Matrix.

Object Space (Where vertices are defined)
World Space (We go here from Object space with a World Transformation Matrix)
View Space (Camera Space, we go here with a View Transformation Matrix from World Space)
Projection Space (Clip space, we go here with a Projection Transformation Matrix from View Space)

I hope this helps a bit.
Keep cool

Share this post


Link to post
Share on other sites
Thanks for the reply Armadon. I have computed the inverse of the ViewProjection matrix. I am wondering how would I multiply my D3DXVECTOR3 variable by D3DXMATRIX.


D3DXVECTOR3 topLeftN;
topLeftN = Intersect3Planes(m_planes[0], m_planes[2], m_planes[4]);

D3DXMATRIX res;
D3DXMATRIX view = Camera.GetViewMatrix();
D3DXMATRIX proj = Graphics.GetFOV();
D3DXMatrixMultiply(&res, &view, &proj);
D3DXMatrixInverse(&res, NULL, &res);

// need to do this multiplication.
//topLeftN = res * topLeftN ;

Share this post


Link to post
Share on other sites
Hey Graham,
How are you doing?

[The problem]
Transforming a Vector by a given matrix.

[The solution]
Guess what?
Direct3D and Direct3DX comes to the rescue by giving us this function/method:

D3DXVec3Transform Function
Transforms vector (x, y, z, 1) by a given matrix.
Syntax:
D3DXVECTOR4 *WINAPI D3DXVec3Transform( D3DXVECTOR4 *pOut,
CONST D3DXVECTOR3 *pV,
CONST D3DXMATRIX *pM
);

I hope this helps a bit.
Keep cool.

Share this post


Link to post
Share on other sites
Using the inverse viewProj matrix did not help. I now have it working though, I since it was mirrored on all 3 axis, I just multipled the all the vectors by -1 and it works great. Thanks for the help.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!