Skip to main content
GameDev.net gamedev.net
🔒 Locked

Frustum Culling Dx9

Started by Denzin Jan 17, 2011 at 11:33 PM 3 replies 2k views
Original Post
Denzin
Denzin
I'm having an issue that could require some fresh eyes to look at while attempting frustum culling. Everything ends up outside the frustum regardless of where the camera is positioned.
Here are the steps i'm taking with my camera and cull check.

First I Set the projection matrix..

void CD3DCamera::SetLens(float fov, float aspect, float nearZ, float farZ)
{
D3DXMatrixPerspectiveFovLH(&projMat, //projection matrix
D3DXToRadian(fov), //field of view
aspect,
nearZ,
farZ);
}


The camera updates its position and rebuilds its view matrix as follows..


void CD3DCamera::BuildView()
{
//keep axes orthoganal
D3DXVec3Normalize(&look, &look);

//up
D3DXVec3Cross(&up, &look, &right);
D3DXVec3Normalize(&up, &up);

//right
D3DXVec3Cross(&right, &up, &look);
D3DXVec3Normalize(&right, &right);

//fill view matrix
float x = -D3DXVec3Dot(&position, &right);
float y = -D3DXVec3Dot(&position, &up);
float z = -D3DXVec3Dot(&position, &look);

viewMat(0,0) = right.x;
viewMat(1,0) = right.y;
viewMat(2,0) = right.z;
viewMat(3,0) = x;

viewMat(0,1) = up.x;
viewMat(1,1) = up.y;
viewMat(2,1) = up.z;
viewMat(3,1) = y;

viewMat(0,2) = look.x;
viewMat(1,2) = look.y;
viewMat(2,2) = look.z;
viewMat(3,2) = z;

viewMat(0,3) = 0.0f;
viewMat(1,3) = 0.0f;
viewMat(2,3) = 0.0f;
viewMat(3,3) = 1.0f;
}


Next the frustum planes are extracted with


void CD3DCamera::BuildFrustum()
{
D3DXMatrixMultiply( &viewProj, &viewMat, &projMat );
//D3DXMatrixMultiply( &viewProjection, &m_mView, &m_mProjection );
// Left plane
frustum[0].a = viewProj._14 + viewProj._11;
frustum[0].b = viewProj._24 + viewProj._21;
frustum[0].c = viewProj._34 + viewProj._31;
frustum[0].d = viewProj._44 + viewProj._41;

// Right plane
frustum[1].a = viewProj._14 - viewProj._11;
frustum[1].b = viewProj._24 - viewProj._21;
frustum[1].c = viewProj._34 - viewProj._31;
frustum[1].d = viewProj._44 - viewProj._41;

// Top plane
frustum[2].a = viewProj._14 - viewProj._12;
frustum[2].b = viewProj._24 - viewProj._22;
frustum[2].c = viewProj._34 - viewProj._32;
frustum[2].d = viewProj._44 - viewProj._42;

// Bottom plane
frustum[3].a = viewProj._14 + viewProj._12;
frustum[3].b = viewProj._24 + viewProj._22;
frustum[3].c = viewProj._34 + viewProj._32;
frustum[3].d = viewProj._44 + viewProj._42;

// Near plane
frustum[4].a = viewProj._13;
frustum[4].b = viewProj._23;
frustum[4].c = viewProj._33;
frustum[4].d = viewProj._43;

// Far plane
frustum[5].a = viewProj._14 - viewProj._13;
frustum[5].b = viewProj._24 - viewProj._23;
frustum[5].c = viewProj._34 - viewProj._33;
frustum[5].d = viewProj._44 - viewProj._43;

// Normalize planes
for ( int i = 0; i < 6; i++ )
{
D3DXPlaneNormalize( &frustum, &frustum );
}
}


last, bounding coordinates are checked with


bool FrustumCheck(D3DXVECTOR3 max, D3DXVECTOR3 min, const D3DXPLANE* frustum)
{
D3DXVECTOR3 P;
D3DXVECTOR3 Q;
bool ret = false;

for(int i = 0; i < 6; ++i)
{
for(int j = 0; j < 3; ++j)
{
if( frustum[j] > 0.0f )
{
P[j] = min[j];
Q[j] = max[j];
}
else
{
P[j] = max[j];
Q[j] = min[j];
}
}

if(D3DXPlaneDotCoord(&frustum, &Q) < 0.0f ) // outside
ret = false;
}
return ret;
}


Note, all the aabbs to be checked are technically 2D as y is constant. If anyone notices something that is wrong with this calculation please reply.
Zakwayda
Zakwayda
Could you fix the tags in your post?
Denzin
Denzin

Could you fix the tags in your post?


whats the new tags if it is no longer [source]
-edit guessed it right. fixed now.
DrunkMonkey25
DrunkMonkey25
In the beginning of function FrustumCheck, you set ret to false and it never has an opportunity to change. You might want to add an

else
ret = true;

in that last if statement.

I think anyway. I'm no expert.

kspansel
kspansel
You need to initialize "ret" to true. Additionally:

1. Get out of the loop as soon as the plane test returns false (no point in checking the other planes if we're already out!)
2. No need to calculate P if you're not going to use it

--
Kory
"The pioneers of a warless world are the youth who refuse military service" - Albert Einstein

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.