Frustum Culling

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Frustum Culling

Post by BlindSide »

EAC_FRUSTUM_BOX is screwed, EAC_BOX does jack **** either, test case:

Code: Select all

#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;

int main()
{
	IrrlichtDevice* device = createDevice(EDT_DIRECT3D9);
	ISceneManager* smgr = device->getSceneManager();
	IVideoDriver* driver = device->getVideoDriver();

	ISceneNode* node = smgr->addSphereSceneNode(1.0);
	node->setScale(vector3df(300, 300, 300));
	node->setAutomaticCulling(EAC_FRUSTUM_BOX);

	ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();

	cam->setPosition(vector3df(0, 500, -500));
	cam->setTarget(vector3df(0,0,0));

	while(device->run())
	{
		stringw windowCaption = "Primitive Count Drawn: ";
		windowCaption += driver->getPrimitiveCountDrawn();
		windowCaption += " Plane relation: ";
		windowCaption += node->getTransformedBoundingBox().classifyPlaneRelation(cam->getViewFrustum()->planes[SViewFrustum::VF_RIGHT_PLANE]);
		device->setWindowCaption(windowCaption.c_str());

		driver->beginScene(true, true, SColor(0xffaaaaff));
		smgr->drawAll();
		driver->endScene();
	}

	device->drop();
	device = 0;

	return 0;
}
Hold down the Left key and you will notice that when sphere leaves view the primitive count is still 512, culling is not working (Even when plane relation shows it's past the frustum plane!). It might get culled after a while but something is definately wrong.

So anyway, I look at the isCulled function, it's overly complicated and outdated, doing things that have their own helper functions already, so I replace the EAC_FRUSTUM_BOX with this:

Code: Select all

case scene::EAC_FRUSTUM_BOX:
		{
			SViewFrustum frust = *cam->getViewFrustum();

			const core::aabbox3df& nodeBox = node->getTransformedBoundingBox();

			for (s32 i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i)
				if(nodeBox.classifyPlaneRelation(frust.planes[i]) == core::ISREL3D_FRONT)
					return true;
		}
		break;
And it works beautifully.

I also demand you change the default culling mode for scene nodes to EAC_FRUSTUM_BOX, as EAC_BOX does jack ****.

Thank you.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Frustum Culling

Post by hybrid »

BlindSide wrote:I also demand you change the default culling mode for scene nodes to EAC_FRUSTUM_BOX, as EAC_BOX does jack ****.
What kind of mood are you currently in :shock: Anyway, thanks for the report. Just don't expect it to be fixed in the near future, as we all have only very little time currently.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Re: Frustum Culling

Post by vitek »

BlindSide wrote:EAC_FRUSTUM_BOX is screwed, EAC_BOX does jack **** either
I think you're mistaken. The EAC_BOX culling mode culls objects outside the frustum bounding box. The frustum box is as deep as the view frustum (distance from the far to the near plane), and is as wide as the view frustum (the height and width of the view frustum at the far plane). This makes a box that is quite large, but it will cull objects correctly. It isn't always useful, but it is simple, efficient, and works. As an example, it would be useful for a top down game where the far plane is only slightly under the playing field.

The implementation of EAC_FRUSTUM_BOX culling you've provided above transforms the node bounding box to world space which makes the bounding box of objects that aren't aligned with the world coordinate system very large. This causes objects to not be culled when they should be.

Travis
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

BlindSide wrote:Hold down the Left key and you will notice that when sphere leaves view the primitive count is still 512, culling is not working (Even when plane relation shows it's past the frustum plane!). It might get culled after a while but something is definately wrong.
Make the following change to your code, and you'll see what is happening...

Code: Select all

   ISceneNode* node = smgr->addSphereSceneNode(1.0); 
+  node->setDebugDataVisible(scene::EDS_BBOX);
   node->setScale(vector3df(300, 300, 300)); 
   node->setAutomaticCulling(EAC_FRUSTUM_BOX); 
The EAC_FRUSTUM_BOX cull mode tests the node bounding box against the view frustum. As soon as the bounding box moves out of the view, the primitive count drops to zero.

I don't see any real problem until I change the scale and rotation of the node and move the mouse around. Then the object gets culled when it should not be. In my testing, it looks like the transformation of the view frustum into node space is causing the problem.

Travis
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

I think you're mistaken. The EAC_BOX culling mode culls objects outside the frustum bounding box. The frustum box is as deep as the view frustum (distance from the far to the near plane), and is as wide as the view frustum (the height and width of the view frustum at the far plane). This makes a box that is quite large, but it will cull objects correctly. It isn't always useful, but it is simple, efficient, and works. As an example, it would be useful for a top down game where the far plane is only slightly under the playing field.
Yes I know that, that's precisely why it shouldn't be the default mode.
In my testing, it looks like the transformation of the view frustum into node space is causing the problem.
Yeah I figured that was the reason too, that's why I decided to transform the node's bounding box.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

We should probably make the culling method use flags and do multiple tests, this kind of change would need lots of performance tests under all kinds of conditions though. Did you assess the impact of this change on a scene with hundreds of nodes?
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Well yeah, the impact went from everything being drawn to only visible things being drawn. :P

I think the camera angle has big role to play in how useless the EAC_BOX or previous EAC_FRUSTUM_BOX method's culling is. You see, the previous method, as Vitek pointed out, would suffer problems when the camera is rotated, where as this methods weakness is when the particular object is rotated. Now in most cases, the object is way smaller than the entire view frustum, and so transforming that is going to cause us way less trouble most of the time.

The previous frustum culling method was also more inefficient and complicated than the one I'm suggesting, but I suppose EAC_BOX would still be suitable for low end systems when drawing thousands of nodes. And yes thousands not hundreds, even with a low end system culling a few hundred nodes isn't going to effect performance.

I don't see any real problem until I change the scale and rotation of the node and move the mouse around. Then the object gets culled when it should not be. In my testing, it looks like the transformation of the view frustum into node space is causing the problem.
Is this with the old method or the new method? I'm not experiencing this problem with the new method.

On another note this problem might be related to newer revisions only, as I tested on a slightly older revision but the bug was not present :!:

This leads me to think some recent changes in the frustum or transformation utility functions has screwed something up.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Post Reply