Jump to content
  • Advertisement
Baemz

Help with frustum-culling.

This topic is 392 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

Hello,

I've been working on some culling-techniques for a project. We've built our own engine so pretty much everything is built from scratch. I've set up a frustum with the following code, assuming that the FOV is 90 degrees.

float angle = CU::ToRadians(45.f);

Plane<float> nearPlane(Vector3<float>(0, 0, aNear), Vector3<float>(0, 0, -1));
Plane<float> farPlane(Vector3<float>(0, 0, aFar), Vector3<float>(0, 0, 1));

Plane<float> right(Vector3<float>(0, 0, 0), Vector3<float>(angle, 0, -angle));
Plane<float> left(Vector3<float>(0, 0, 0), Vector3<float>(-angle, 0, -angle));
Plane<float> up(Vector3<float>(0, 0, 0), Vector3<float>(0, angle, -angle));
Plane<float> down(Vector3<float>(0, 0, 0), Vector3<float>(0, -angle, -angle));

myVolume.AddPlane(nearPlane);
myVolume.AddPlane(farPlane);
myVolume.AddPlane(right);
myVolume.AddPlane(left);
myVolume.AddPlane(up);
myVolume.AddPlane(down);

When checking the intersections I am using a BoundingSphere of my models, which is calculated by taking the average position of all vertices and then choosing the furthest distance to a vertex for radius. The actual intersection test looks like this, where the "myFrustum90" is the actual frustum described above.
The orientationInverse is the viewMatrix in this case.

bool CFrustum::Intersects(const SFrustumCollider& aCollider)
{
		CU::Vector4<float> position = CU::Vector4<float>(aCollider.myCenter.x, aCollider.myCenter.y, aCollider.myCenter.z, 1.f) * myOrientationInverse;
		return myFrustum90.Inside({ position.x, position.y, position.z }, aCollider.myRadius);
}

The Inside() function looks like this.

template <typename T>
bool PlaneVolume<T>::Inside(Vector3<T> aPosition, T aRadius) const
{
	for (unsigned short i = 0; i < myPlaneList.size(); ++i)
	{
		if (myPlaneList.ClassifySpherePlane(aPosition, aRadius) > 0)
		{
			return false;
		}
	}
	return true;
}

And this is the ClassifySpherePlane() function. (The plane is defined as a Vector4 called myABCD, where ABC is the normal)

template <typename T>
inline int Plane<T>::ClassifySpherePlane(Vector3<T> aSpherePosition, float aSphereRadius) const
{
	float distance = (aSpherePosition.Dot(myNormal)) - myABCD.w;
		// completely on the front side
	if (distance >= aSphereRadius)
	{
		return 1;
	}
		// completely on the backside (aka "inside")
	if (distance <= -aSphereRadius)
	{
		return -1;
	}
		//sphere intersects the plane
	return 0;
}

 

Please bare in mind that this code is not optimized nor well-written by any means. I am just looking to get it working.
The result of this culling is that the models seem to be culled a bit "too early", so that the culling is visible and the models pops away.
How do I get the culling to work properly?
I have tried different techniques but haven't gotten any of them to work.
If you need more code or explanations feel free to ask for it.

Thanks.

 

Edited by Baemz
The full post didn't come through at creation. Here comes the rest.

Share this post


Link to post
Share on other sites
Advertisement

  • 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!