Jump to content
  • Advertisement
Sign in to follow this  
cozzie

Strange frustum problem...

This topic is 2853 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 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 CHECKING

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


Link to post
Share on other sites
Advertisement
fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pMinPosition);
if(fDistance >= 0) return true;

maybe...

Share this post


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


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


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


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


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


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


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


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

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!