• Advertisement
Sign in to follow this  

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.

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

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]);
}

bool CD3dcam::SphereInFrustum(D3DXVECTOR3 *pPosition, float pRadius)
{
	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

bool CD3dmesh::CalcRadiusAndWorldPos()
{
	mAttrWorldPos		= new D3DXVECTOR3[mAttrSize];
	mAttrBoundingRadius = new float[mAttrSize];
	mAttrBoundingBox	= new BOUNDINGBOX[mAttrSize];

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

	mVtxBuffer->Lock(0, 0, (void**)&verticesPointer, 0); //D3DLOCK_READONLY);
	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]); 
		mAttrBoundingRadius[obj] += 0.1f;

		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)
	{
		D3DXVec3Add(&mAttrWorldPos[obj], &mAttrWorldPos[obj], &mWorldPos); 
		for(int vc=0;vc<8;++vc) 
			D3DXVec3Add(&mAttrBoundingBox[obj].boxArray[vc], &mAttrBoundingBox[obj].boxArray[vc], &mWorldPos);
	}
	UpdateWorldMatrix(); 
	return true;
}

 

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

 

Share this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


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

  • Advertisement