Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


#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