Help with frustum-culling.

Started by
1 comment, last by CrazyCdn 6 years, 6 months ago

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.

 

Advertisement

What exactly do you need help with?  What have you done so far?

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

This topic is closed to new replies.

Advertisement