# Comments on Frustum Culling Method?

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

## Recommended Posts

This code uses an object's bounding sphere and some testing to determine if it is inside the frustum. The bounding sphere is created at load time, then transformed with the scene. The Z near and far are tested by z coordinates, then the distance from each of the four other planes is calculated. comments, suggestions, are appreciated. ty
bool IsInFrustum(OBJECT *object)
{
return false;
return false;

float vlen = sqrt(object->tcenter.x*object->tcenter.x + object->tcenter.y*object->tcenter.y + object->tcenter.z*object->tcenter.z);

object->tcenter.x /= vlen;
object->tcenter.y /= vlen;
object->tcenter.z /= vlen;

for(int pl = 0; pl < 4; pl++)
if(  (D3DXVec3Dot((D3DXVECTOR3*)&object->tcenter, (D3DXVECTOR3*)&frustum[pl]) * vlen) < -object->bound_radius  )
return false;

return true;
}



##### Share on other sites
Quote:
 Original post by CPPNickThe bounding sphere is created at load time, then transformed with the scene.
I take this to mean that the bounding sphere has been transformed into view space?

I am not clear whether that optimisation is worth making. Rather than the 6 planes of the view frustum into world space, you transform N bounding spheres into view space - all to save 2 dot products per intersection test.

##### Share on other sites
Im not sure what you mean. I transform the object's centers to view space, and then test them against 4 of the frustum planes, because two(znear, and zfar) are parallel to the viewing plane.

here is the render loop.
	for(UINT p = 0; p < dxtechdesc.Passes; ++p)	{		for(int ob = 0; ob < ocount; ob++)		{			D3DXVec4Transform(&objects[ob].tcenter, &objects[ob].center, &objects[ob].mtxworld);			D3DXVec4Transform(&objects[ob].tcenter, &objects[ob].tcenter, &mtxview);						if(IsInFrustum(&objects[ob]) == false)				continue;			dxfxdiffusetexture->SetResource(dxrvtexture[ob]);			fxmtxworld->SetMatrix((float*)&objects[ob].mtxworld);			dxfxselfillum->SetBool(objects[ob].SelfIllum);			dxfxtechnique->GetPassByIndex(p)->Apply(0);			objects[ob].mesh->DrawSubset(0);		}	}	dxsc->Present(0, 0);

##### Share on other sites
Quote:
 Original post by CPPNickIm not sure what you mean. I transform the object's centers to view space, and then test them against 4 of the frustum planes, because two(znear, and zfar) are parallel to the viewing plane.

I guess the point is that it makes more sense to transform the planes to world coordinates and do the test there.

##### Share on other sites
Quote:
 Original post by alvaroI guess the point is that it makes more sense to transform the planes to world coordinates and do the test there.

If I understand what you mean, It would mean I had to transform the frustrum by the inverse view matrix. If I did that, then I would not be able to get the distance from the plane properly here:

if(  (D3DXVec3Dot((D3DXVECTOR3*)&object->tcenter, (D3DXVECTOR3*)&frustum[pl]) * vlen) < -object->bound_radius  )

The reason being that the planes of the frustrum would no longer pass through (0,0,0).

does that make sense?

##### Share on other sites
Quote:
Original post by CPPNick
Quote:
 Original post by alvaroI guess the point is that it makes more sense to transform the planes to world coordinates and do the test there.

If I understand what you mean, It would mean I had to transform the frustrum by the inverse view matrix. If I did that, then I would not be able to get the distance from the plane properly here:

*** Source Snippet Removed ***
The reason being that the planes of the frustrum would no longer pass through (0,0,0).

does that make sense?

You'd just have to subtract the camera position from the center, or something trivial like that.

EDIT: Also, if you have your scene in a hierarchy you should consider returning three value for each intersection with a plane: "outside", "inside" and "in between". That way, you can keep a mask indicating what planes of the frustum need to be checked. I don't know if there is a name for this technique, so I can't find you an online reference. I learned about it in one of David Eberly's books. It seems to be described here.

##### Share on other sites
I read that article once through, but didn't catch this the first time:

bool IsInFrustum(OBJECT *object){	if(object->tcenter.z > (Z_FAR + object->bound_radius))		return false;	if(object->tcenter.z < (Z_NEAR - object->bound_radius))		return false;	float vlen = sqrt(object->tcenter.x*object->tcenter.x + object->tcenter.y*object->tcenter.y + object->tcenter.z*object->tcenter.z);		//object->tcenter.x /= vlen;	//object->tcenter.y /= vlen;	//object->tcenter.z /= vlen;	for(int pl = 0; pl < 4; pl++)		//if(  (D3DXVec3Dot((D3DXVECTOR3*)&object->tcenter, (D3DXVECTOR3*)&frustum[pl]) * vlen) < -object->bound_radius  )		if(  D3DXVec3Dot((D3DXVECTOR3*)&object->tcenter, (D3DXVECTOR3*)&frustum[pl]) < -object->bound_radius  )			return false;	return true;

The new code works just the same, but I commented out the redundant math.

thanks for reminding me of that article.. that coulda costed me 3 nasty divs AND a sqrt per object......eww.

##### Share on other sites
also, mine is faster right now because I am skipping the two dot products when I check the near and far plane. I think I understand about the hierarchy now though. If a bounding sphere of a model of a human was to intersect the frustum, I may then have to check the bounding sphere of each of the limbs...right?

##### Share on other sites
Quote:
 Original post by CPPNickalso, mine is faster right now because I am skipping the two dot products when I check the near and far plane.
Sure, it is faster in isolation. However, you have to transform the bounding sphere into view space before testing, which costs a matrix multiply per sphere (considerably more than the cost of two dot products).

I also don't think you can handle non-uniform scale with your approach - although you may not need that anyway.

##### Share on other sites
Maybe you can use SSE instructions to speed up a bit, making only 1 dot with a SoA vectors!

• 10
• 17
• 9
• 13
• 41