Jump to content

  • Log In with Google      Sign In   
  • Create Account

#Actuallipsryme

Posted 29 March 2013 - 11:29 AM

Doing frustum culling on 10.000 objects it takes about 0.85ms...is that slow/fast ?

 

I'm using AABBs to frustum cull my objects.

See code here:

 

bool RendererD3D11::FrustumCull(SceneEntityDescription* entity,
								XMFLOAT4* frustumPlanes)
{
	// If there even was a rejection last time
	if(entity->lastRejectedFrustumPlane != 999999)
	{
		// Check last rejected planeId first
		XMVECTOR planeNormal = XMVectorSet(frustumPlanes[entity->lastRejectedFrustumPlane].x, frustumPlanes[entity->lastRejectedFrustumPlane].y,
			frustumPlanes[entity->lastRejectedFrustumPlane].z, 0.0f);

		float planeConstant = frustumPlanes[entity->lastRejectedFrustumPlane].w;

		// Check each axis (x, y, z) to get the AABB vertex furthest away from the direction
		// the plane is facing (plane normal)
		XMFLOAT3 axisVert;
		XMFLOAT3 aabb_min = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Min();
		XMFLOAT3 aabb_max = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Max();
		XMFLOAT3 objPos = entity->worldPosition;

		// x-axis
		if(frustumPlanes[entity->lastRejectedFrustumPlane].x < 0.0f)
		{
			axisVert.x = aabb_min.x + objPos.x; // min x + obj position's x
		}
		else
		{
			axisVert.x = aabb_max.x + objPos.x; // max x + obj position's x
		}

		// y-axis
		if(frustumPlanes[entity->lastRejectedFrustumPlane].y < 0.0f)
		{
			axisVert.y = aabb_min.y + objPos.y; // min y + obj position's y
		}
		else
		{
			axisVert.y = aabb_max.y + objPos.y; // max y + obj position's y
		}

		// z-axis
		if(frustumPlanes[entity->lastRejectedFrustumPlane].z < 0.0f)
		{
			axisVert.z = aabb_min.z + objPos.z; // min z + obj position's z
		}
		else
		{
			axisVert.z = aabb_max.z + objPos.z; // min z + obj position's z
		}

		// Now we get the signed distance from the AABB's vertex that's furthest down the frustum planes normal,
		// and if the signed distance is negative, then the entire bounding box is behind the frustum plane, which means
		// that it should be culled
		if(XMVectorGetX(XMVector3Dot(planeNormal, XMLoadFloat3(&axisVert))) + planeConstant < 0.0f)
		{
			return true;
		}
	}
	

	// Loop through each frustum plane
	for(int planeID = 0; planeID < 6; ++planeID)
	{
		if(entity->lastRejectedFrustumPlane != 999999)
		{
			if(planeID == entity->lastRejectedFrustumPlane)
			{
				// skip last rejected frustum plane since we've checked it before this loop
				continue;
			}
		}


		XMVECTOR planeNormal = XMVectorSet(frustumPlanes[planeID].x, frustumPlanes[planeID].y,
										   frustumPlanes[planeID].z, 0.0f);

		float planeConstant = frustumPlanes[planeID].w;

		// Check each axis (x, y, z) to get the AABB vertex furthest away from the direction
		// the plane is facing (plane normal)
		XMFLOAT3 axisVert;
		XMFLOAT3 aabb_min = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Min();
		XMFLOAT3 aabb_max = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Max();
		XMFLOAT3 objPos = entity->worldPosition;

		// x-axis
		if(frustumPlanes[planeID].x < 0.0f)
		{
			axisVert.x = aabb_min.x + objPos.x; // min x + obj position's x
		}
		else
		{
			axisVert.x = aabb_max.x + objPos.x; // max x + obj position's x
		}

		// y-axis
		if(frustumPlanes[planeID].y < 0.0f)
		{
			axisVert.y = aabb_min.y + objPos.y; // min y + obj position's y
		}
		else
		{
			axisVert.y = aabb_max.y + objPos.y; // max y + obj position's y
		}

		// z-axis
		if(frustumPlanes[planeID].z < 0.0f)
		{
			axisVert.z = aabb_min.z + objPos.z; // min z + obj position's z
		}
		else
		{
			axisVert.z = aabb_max.z + objPos.z; // min z + obj position's z
		}

		// Now we get the signed distance from the AABB's vertex that's furthest down the frustum planes normal,
		// and if the signed distance is negative, then the entire bounding box is behind the frustum plane, which means
		// that it should be culled
		if(XMVectorGetX(XMVector3Dot(planeNormal, XMLoadFloat3(&axisVert))) + planeConstant < 0.0f)
		{
			entity->lastRejectedFrustumPlane = planeID; // store rejected frustum plane ID for the next frames
			return true;
		}
	}

	return false;
}

 

 

Keep in mind these 10.000 objects are all inside the view frustum so they'll all go through all 6 planes and pass (worst case scenario I know).

I've commented out the draw call itself so the rendering itself has no influence on these numbers.


#4lipsryme

Posted 29 March 2013 - 11:22 AM

Doing frustum culling on 10.000 objects it takes about 0.85ms...is that slow/fast ?

 

I'm using AABBs to frustum cull my objects.

See code here:

 

bool RendererD3D11::FrustumCull(SceneEntityDescription* entity,
								XMFLOAT4* frustumPlanes)
{
	// If there even was a rejection last time
	if(entity->lastRejectedFrustumPlane != 999999)
	{
		// Check last rejected planeId first
		XMVECTOR planeNormal = XMVectorSet(frustumPlanes[entity->lastRejectedFrustumPlane].x, frustumPlanes[entity->lastRejectedFrustumPlane].y,
			frustumPlanes[entity->lastRejectedFrustumPlane].z, 0.0f);

		float planeConstant = frustumPlanes[entity->lastRejectedFrustumPlane].w;

		// Check each axis (x, y, z) to get the AABB vertex furthest away from the direction
		// the plane is facing (plane normal)
		XMFLOAT3 axisVert;
		XMFLOAT3 aabb_min = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Min();
		XMFLOAT3 aabb_max = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Max();
		XMFLOAT3 objPos = entity->worldPosition;

		// x-axis
		if(frustumPlanes[entity->lastRejectedFrustumPlane].x < 0.0f)
		{
			axisVert.x = aabb_min.x + objPos.x; // min x + obj position's x
		}
		else
		{
			axisVert.x = aabb_max.x + objPos.x; // max x + obj position's x
		}

		// y-axis
		if(frustumPlanes[entity->lastRejectedFrustumPlane].y < 0.0f)
		{
			axisVert.y = aabb_min.y + objPos.y; // min y + obj position's y
		}
		else
		{
			axisVert.y = aabb_max.y + objPos.y; // max y + obj position's y
		}

		// z-axis
		if(frustumPlanes[entity->lastRejectedFrustumPlane].z < 0.0f)
		{
			axisVert.z = aabb_min.z + objPos.z; // min z + obj position's z
		}
		else
		{
			axisVert.z = aabb_max.z + objPos.z; // min z + obj position's z
		}

		// Now we get the signed distance from the AABB's vertex that's furthest down the frustum planes normal,
		// and if the signed distance is negative, then the entire bounding box is behind the frustum plane, which means
		// that it should be culled
		if(XMVectorGetX(XMVector3Dot(planeNormal, XMLoadFloat3(&axisVert))) + planeConstant < 0.0f)
		{
			return true;
		}
	}
	

	// Loop through each frustum plane
	for(int planeID = 0; planeID < 6; ++planeID)
	{
		if(entity->lastRejectedFrustumPlane != 999999)
		{
			if(planeID == entity->lastRejectedFrustumPlane)
			{
				// skip last rejected frustum plane since we've checked it before this loop
				continue;
			}
		}


		XMVECTOR planeNormal = XMVectorSet(frustumPlanes[planeID].x, frustumPlanes[planeID].y,
										   frustumPlanes[planeID].z, 0.0f);

		float planeConstant = frustumPlanes[planeID].w;

		// Check each axis (x, y, z) to get the AABB vertex furthest away from the direction
		// the plane is facing (plane normal)
		XMFLOAT3 axisVert;
		XMFLOAT3 aabb_min = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Min();
		XMFLOAT3 aabb_max = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Max();
		XMFLOAT3 objPos = entity->worldPosition;

		// x-axis
		if(frustumPlanes[planeID].x < 0.0f)
		{
			axisVert.x = aabb_min.x + objPos.x; // min x + obj position's x
		}
		else
		{
			axisVert.x = aabb_max.x + objPos.x; // max x + obj position's x
		}

		// y-axis
		if(frustumPlanes[planeID].y < 0.0f)
		{
			axisVert.y = aabb_min.y + objPos.y; // min y + obj position's y
		}
		else
		{
			axisVert.y = aabb_max.y + objPos.y; // max y + obj position's y
		}

		// z-axis
		if(frustumPlanes[planeID].z < 0.0f)
		{
			axisVert.z = aabb_min.z + objPos.z; // min z + obj position's z
		}
		else
		{
			axisVert.z = aabb_max.z + objPos.z; // min z + obj position's z
		}

		// Now we get the signed distance from the AABB's vertex that's furthest down the frustum planes normal,
		// and if the signed distance is negative, then the entire bounding box is behind the frustum plane, which means
		// that it should be culled
		if(XMVectorGetX(XMVector3Dot(planeNormal, XMLoadFloat3(&axisVert))) + planeConstant < 0.0f)
		{
			entity->lastRejectedFrustumPlane = planeID; // store rejected frustum plane ID for the next frames
			return true;
		}
	}

	return false;
}

 

 

Keep in mind these 10.000 objects are all inside the view frustum so they'll all go through all 6 planes and pass (worst case scenario I know).


#3lipsryme

Posted 29 March 2013 - 11:08 AM

Doing frustum culling on 10.000 objects it takes about 0.85ms...is that slow/fast ?

 

I'm using AABBs to frustum cull my objects.

See code here:

 

bool RendererD3D11::FrustumCull(SceneEntityDescription* entity,
								XMFLOAT4* frustumPlanes)
{
	// Loop through each frustum plane
	for(int planeID = 0; planeID < 6; ++planeID)
	{
		XMVECTOR planeNormal = XMVectorSet(frustumPlanes[planeID].x, frustumPlanes[planeID].y,
			frustumPlanes[planeID].z, 0.0f);

		float planeConstant = frustumPlanes[planeID].w;

		// Check each axis (x, y, z) to get the AABB vertex furthest away from the direction
		// the plane is facing (plane normal)
		XMFLOAT3 axisVert;
		XMFLOAT3 aabb_min = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Min();
		XMFLOAT3 aabb_max = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Max();
		XMFLOAT3 objPos = entity->worldPosition;

		// x-axis
		if(frustumPlanes[planeID].x < 0.0f)
		{
			axisVert.x = aabb_min.x + objPos.x; // min x + obj position's x
		}
		else
		{
			axisVert.x = aabb_max.x + objPos.x; // max x + obj position's x
		}

		// y-axis
		if(frustumPlanes[planeID].y < 0.0f)
		{
			axisVert.y = aabb_min.y + objPos.y; // min y + obj position's y
		}
		else
		{
			axisVert.y = aabb_max.y + objPos.y; // max y + obj position's y
		}

		// z-axis
		if(frustumPlanes[planeID].z < 0.0f)
		{
			axisVert.z = aabb_min.z + objPos.z; // min z + obj position's z
		}
		else
		{
			axisVert.z = aabb_max.z + objPos.z; // min z + obj position's z
		}

		// Now we get the signed distance from the AABB's vertex that's furthest down the frustum planes normal,
		// and if the signed distance is negative, then the entire bounding box is behind the frustum plane, which means
		// that it should be culled
		if(XMVectorGetX(XMVector3Dot(planeNormal, XMLoadFloat3(&axisVert))) + planeConstant < 0.0f)
		{
			return true;
		}
	}

	return false;
}

 

I've read about caching the the plane that was rejected in the previous frame, gonna try that now but still would like some feedback.


#2lipsryme

Posted 29 March 2013 - 11:08 AM

Doing frustum culling on 10.000 objects it takes about 0.85ms...is that slow/fast ?

 

I'm using AABBs to frustum cull my objects.

See code here:

 

bool RendererD3D11::FrustumCull(SceneEntityDescription* entity,
								XMFLOAT4* frustumPlanes)
{
	// Loop through each frustum plane
	for(int planeID = 0; planeID < 6; ++planeID)
	{
		XMVECTOR planeNormal = XMVectorSet(frustumPlanes[planeID].x, frustumPlanes[planeID].y,
			frustumPlanes[planeID].z, 0.0f);

		float planeConstant = frustumPlanes[planeID].w;

		// Check each axis (x, y, z) to get the AABB vertex furthest away from the direction
		// the plane is facing (plane normal)
		XMFLOAT3 axisVert;
		XMFLOAT3 aabb_min = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Min();
		XMFLOAT3 aabb_max = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Max();
		XMFLOAT3 objPos = entity->worldPosition;

		// x-axis
		if(frustumPlanes[planeID].x < 0.0f)
		{
			axisVert.x = aabb_min.x + objPos.x; // min x + obj position's x
		}
		else
		{
			axisVert.x = aabb_max.x + objPos.x; // max x + obj position's x
		}

		// y-axis
		if(frustumPlanes[planeID].y < 0.0f)
		{
			axisVert.y = aabb_min.y + objPos.y; // min y + obj position's y
		}
		else
		{
			axisVert.y = aabb_max.y + objPos.y; // max y + obj position's y
		}

		// z-axis
		if(frustumPlanes[planeID].z < 0.0f)
		{
			axisVert.z = aabb_min.z + objPos.z; // min z + obj position's z
		}
		else
		{
			axisVert.z = aabb_max.z + objPos.z; // min z + obj position's z
		}

		// Now we get the signed distance from the AABB's vertex that's furthest down the frustum planes normal,
		// and if the signed distance is negative, then the entire bounding box is behind the frustum plane, which means
		// that it should be culled
		if(XMVectorGetX(XMVector3Dot(planeNormal, XMLoadFloat3(&axisVert))) + planeConstant < 0.0f)
		{
			return true;
		}
	}

	return false;
}

 

I've read about caching the the plane that was rejected in the previous frame, gonna try that now but the question still stands :)


#1lipsryme

Posted 29 March 2013 - 11:02 AM

Doing frustum culling on 10.000 objects it takes about 0.85ms...is that slow/fast ?

 

I'm using AABBs to frustum cull my objects.

See code here:

 

bool RendererD3D11::FrustumCull(SceneEntityDescription* entity,
								XMFLOAT4* frustumPlanes)
{
	// Loop through each frustum plane
	for(int planeID = 0; planeID < 6; ++planeID)
	{
		XMVECTOR planeNormal = XMVectorSet(frustumPlanes[planeID].x, frustumPlanes[planeID].y,
			frustumPlanes[planeID].z, 0.0f);

		float planeConstant = frustumPlanes[planeID].w;

		// Check each axis (x, y, z) to get the AABB vertex furthest away from the direction
		// the plane is facing (plane normal)
		XMFLOAT3 axisVert;
		XMFLOAT3 aabb_min = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Min();
		XMFLOAT3 aabb_max = this->contentManager->GetPrimitiveFromPool(entity->ID)->GetBoundingVolume()->Max();
		XMFLOAT3 objPos = entity->worldPosition;

		// x-axis
		if(frustumPlanes[planeID].x < 0.0f)
		{
			axisVert.x = aabb_min.x + objPos.x; // min x + obj position's x
		}
		else
		{
			axisVert.x = aabb_max.x + objPos.x; // max x + obj position's x
		}

		// y-axis
		if(frustumPlanes[planeID].y < 0.0f)
		{
			axisVert.y = aabb_min.y + objPos.y; // min y + obj position's y
		}
		else
		{
			axisVert.y = aabb_max.y + objPos.y; // max y + obj position's y
		}

		// z-axis
		if(frustumPlanes[planeID].z < 0.0f)
		{
			axisVert.z = aabb_min.z + objPos.z; // min z + obj position's z
		}
		else
		{
			axisVert.z = aabb_max.z + objPos.z; // min z + obj position's z
		}

		// Now we get the signed distance from the AABB's vertex that's furthest down the frustum planes normal,
		// and if the signed distance is negative, then the entire bounding box is behind the frustum plane, which means
		// that it should be culled
		if(XMVectorGetX(XMVector3Dot(planeNormal, XMLoadFloat3(&axisVert))) + planeConstant < 0.0f)
		{
			return true;
		}
	}

	return false;
}

 

 


PARTNERS