# strange frustum culling behaviour

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

## Recommended Posts

Hi,

I've noticed that my frustum culling is behaving strange when doing a boundingsphere check on entities of meshes. It looks like entities are being culled just before there out of the frustum/ screen.

Before I dig into my code calculation the radius of my entities, I'd like to know if someone sees any strange things my frustum calculation and check boundingsphere functions. Any help is really appreciated:

void CD3dcam::CalculateFrustum()
{
D3DXMatrixMultiply(&mFrustumMatrix, &mMatView, &mMatProjection);

// left plane
mFrustumPlane[0].a = mFrustumMatrix._14 + mFrustumMatrix._11;
mFrustumPlane[0].b = mFrustumMatrix._24 + mFrustumMatrix._21;
mFrustumPlane[0].c = mFrustumMatrix._34 + mFrustumMatrix._31;
mFrustumPlane[0].d = mFrustumMatrix._44 + mFrustumMatrix._41;
D3DXPlaneNormalize(&mFrustumPlane[0], &mFrustumPlane[0]);

// right plane
mFrustumPlane[1].a = mFrustumMatrix._14 - mFrustumMatrix._11;
mFrustumPlane[1].b = mFrustumMatrix._24 - mFrustumMatrix._21;
mFrustumPlane[1].c = mFrustumMatrix._34 - mFrustumMatrix._31;
mFrustumPlane[1].d = mFrustumMatrix._44 - mFrustumMatrix._41;
D3DXPlaneNormalize(&mFrustumPlane[1], &mFrustumPlane[1]);

// top plane
mFrustumPlane[2].a = mFrustumMatrix._14 - mFrustumMatrix._12;
mFrustumPlane[2].b = mFrustumMatrix._24 - mFrustumMatrix._22;
mFrustumPlane[2].c = mFrustumMatrix._34 - mFrustumMatrix._32;
mFrustumPlane[2].d = mFrustumMatrix._44 - mFrustumMatrix._42;
D3DXPlaneNormalize(&mFrustumPlane[2], &mFrustumPlane[2]);

// bottom plane
mFrustumPlane[3].a = mFrustumMatrix._14 + mFrustumMatrix._12;
mFrustumPlane[3].b = mFrustumMatrix._24 + mFrustumMatrix._22;
mFrustumPlane[3].c = mFrustumMatrix._34 + mFrustumMatrix._32;
mFrustumPlane[3].d = mFrustumMatrix._44 + mFrustumMatrix._42;
D3DXPlaneNormalize(&mFrustumPlane[3], &mFrustumPlane[3]);

// near plane
mFrustumPlane[4].a = mFrustumMatrix._13;
mFrustumPlane[4].b = mFrustumMatrix._23;
mFrustumPlane[4].c = mFrustumMatrix._33;
mFrustumPlane[4].d = mFrustumMatrix._43;
D3DXPlaneNormalize(&mFrustumPlane[4], &mFrustumPlane[4]);

// far plane
mFrustumPlane[5].a = mFrustumMatrix._14 - mFrustumMatrix._13;
mFrustumPlane[5].b = mFrustumMatrix._24 - mFrustumMatrix._23;
mFrustumPlane[5].c = mFrustumMatrix._34 - mFrustumMatrix._33;
mFrustumPlane[5].d = mFrustumMatrix._44 - mFrustumMatrix._43;
D3DXPlaneNormalize(&mFrustumPlane[5], &mFrustumPlane[5]);
}

{
float fDistance;
for(int i=0;i<6;++i)
{
fDistance = D3DXPlaneDotCoord(&mFrustumPlane[i], pPosition) + pRadius;

if(fDistance < -pRadius) return false; // outside the frustum
if((float)fabs(fDistance) < pRadius) return true; // intersects
}
return true; // inside the frustum completely or intersecting; see XLS
}

// calculating the entities/ meshes radius

{
mAttrWorldPos		= new D3DXVECTOR3[mAttrSize];
mAttrBoundingBox	= new BOUNDINGBOX[mAttrSize];

TVERTEX *verticesPointer;
TVERTEX *vertices = new TVERTEX[mMesh->GetNumVertices()];

memcpy(vertices, verticesPointer, mMesh->GetNumVertices()*D3DXGetDeclVertexSize(dec, 0));
mVtxBuffer->Unlock();

// scale the vertices, before determining bounding radius, mesh (world)pos etc.

for(DWORD vc=0;vc<mMesh->GetNumVertices();++vc)
D3DXVec3Scale(&vertices[vc].position, &vertices[vc].position, mScale);

// calculatie bounding radius, using always absolute, 0.0.0 mMeshCenter
D3DXComputeBoundingSphere(&vertices[0].position, mMesh->GetNumVertices(), D3DXGetDeclVertexSize(dec, 0), &mMeshCenter, &mBoundingRadius);

// do the same for all subobjects in the attr table, mAttrWorldPos is DETERMINED based on subobject vertices

for(DWORD obj=0;obj<mAttrSize;++obj)
{
D3DXComputeBoundingSphere(&vertices[mAttrTable[obj].VertexStart].position, (DWORD)mAttrTable[obj].VertexCount, D3DXGetDeclVertexSize(dec, 0), &mAttrWorldPos[obj], &mAttrBoundingRadius[obj]);

CalcBoundingBox(vertices, mAttrTable[obj].VertexStart, mAttrTable[obj].VertexCount, &mAttrBoundingBox[obj]);
}
SafeDelete(vertices);

// add WorldPos of object to all sub objects

for(DWORD obj=0;obj<mAttrSize;++obj)
{
for(int vc=0;vc<8;++vc)
}
UpdateWorldMatrix();
return true;
}


It doesn't seem to occur on full meshes though (first boundingsphere check in rendering a frame).

##### Share on other sites

addition; I also tried to switch true and false in the boundingsphere check function, to see if nothing's culled, but strangely a lot of entities are still not culled (depending on the frustum at that moment)..

##### Share on other sites

Found the cause already, when I don't rotate my meshes (and thus entities), everything works fine.

I scale all vertices before calculating the boundingradius, but I don't do any rotation... probably have to do that to first

##### Share on other sites
Found the cause already, when I don't rotate my meshes (and thus entities), everything works fine.

I scale all vertices before calculating the boundingradius, but I don't do any rotation... probably have to do that to first

You mean you werent rotating your bounding sphere to be in the same place as your rendering mesh?

Did you try rendering out the bounding sphere on top of the mesh to make sure they look correct?

It doesnt sound like you're sure what the problem is.  You should know what the problem is before moving on, not just put in a fix and hope that it's the right fix for the real problem.

##### Share on other sites
Hi.
What i do after loading the beshes, during initialization, is calculation the bounding radius of the meshes and entities. So i can use them for boundinghere checks in culling.

What i did was:
- lock vertexbuffer in local space (not scaled or rotated)
- scale the vertices
- then calculate the boundingradius (using d3dxcreateboundingsphere)
- then do the same for all entities

I was nearly there but forgot to rotate where i scale the vertices.
Found that out by setting rotation xyz for all meshes to 0 and then the problem wasn't there.