• 9
• 16
• 15
• 12
• 9

# Strange frustum problem...

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

## Recommended Posts

Hi all,

When I check a sphere against my frustum (d3d dx9 engine, c++), it's all good.
Now I made a function to check a bounding box against the frustum, but it now does this:

every object is only rendered when it's inside the frustum AND somehow intersects with the frustum planes.

I've double checked the min and max positions of the bounding boxes, they're all ok.

Can someone help me out?

Here's the code:

bool CD3dcam::SphereInFrustum(D3DXVECTOR3* pPosition, float pRadius){	float fDistance;	for(int i=0;i<6;++i)    {		fDistance = D3DXPlaneDotCoord(&mFrustumPlane, 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}// NO PROBLEMS WITH SHERE CHECKINGbool CD3dcam::BoxInFrustum(D3DXVECTOR3* pMinPosition, D3DXVECTOR3* pMaxPosition){	float fDistance;	for(int i=0;i<6;++i)    {		fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pMinPosition);		if(fDistance <= 0) return true;		fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pMaxPosition);		if(fDistance <= 0) return true;    }	return false;}

##### Share on other sites
fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pMinPosition);
if(fDistance >= 0) return true;

maybe...

##### Share on other sites
Just a quick look (didn't go into it in depth):

Should:

if(fDistance <= 0) return true;

be?:

if(fDistance >= 0) return true;

EDIT: ninja'd

##### Share on other sites
hi szecs,
that would sound logical indeed, because inside the frustum the value should allways be 0 or higher.
I tried it out, but now all objects are rendered at all time, even when there not in the frustum (I keep a counter).

##### Share on other sites
Just think about it a bit, and you should see what's the problem.

For example if the first condition is not true the second one will surely be: the two conditions should be in AND relation, now they are in OR (think about it)

##### Share on other sites
Reviewed your code. Any coordinate in the world will be on the positive side of one of the frustum planes.

Try checking for both min/max < 0 for each plane. That will, at least, cull boxes entirely on the outside of one of the planes.

EDIT:
fdist1 = D3DXPlane..(plane,min);
fdist2 = D3DXPlane..(plane,max);
if( fdist1 < 0 && fdist2 < 0 ) return false;

If false is not returned for any frustum plane, return true.

EDIT: ninja #2 [smile]

##### Share on other sites
Both thanks for the hints, I understand that I should check both (and not or), the reason why I used or is that I also want to render boxen that intersect the frustum.

I changed the code now to this:

bool CD3dcam::BoxInFrustum(D3DXVECTOR3* pMinPosition, D3DXVECTOR3* pMaxPosition){	float fDistanceMin, fDistanceMax;	for(int i=0;i<6;i++)    {		fDistanceMin = D3DXPlaneDotCoord(&mFrustumPlane, pMinPosition);		fDistanceMax = D3DXPlaneDotCoord(&mFrustumPlane, pMaxPosition);		if(fDistanceMin < 0 && fDistanceMax < 0) return false;     }	return true;}

This works almost, only now objects that are not fully in the frustum are not rendered I think. When I change it to '<= 0' instead of "<0" still objects that are partially in the frustum are not returned as 'true' and therefor not rendered.

##### Share on other sites
Because you're using AABB, it's possible that min and max could be outside the frustum, but one of the corners (not min or max) could be inside the frustum.

I think you'll have to test all 8 corners of the AABB.

##### Share on other sites
Ok, I can make that work and code that.
But will checking all 8 points still be be quicker then just checking all objects (included boxes) with a radius as a bounding sphere?

##### Share on other sites
Quote:
 But will checking all 8 points still be be quicker then just checking all objects (included boxes) with a radius as a bounding sphere?

Unfortunately, no. However, depending on how many objects and what their shapes are, you can cull bounding spheres that are outside the frustum. Then do the full 8 point AABB check only for those objects whose bounding spheres are not outside the frustum.

EDIT: I don't know how you determine the bounding radius, but you can precalculate the radius (and sphere center position) for each object if you don't already. That would speed things up a bit as you wouldn't have to calculate the radius for each "in-frustum" call.