Culling with Parents?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Culling with Parents?

Post by TheC »

Hi,

I have a grid of terrain "chunks" which are parented to one object (to easily rotate and position).

When I rotate around the yaw to a value between 0 and 90 (43 in this case), the culling on the chunks becomes very strange.

Below is a screenshot, the chunks appear to disappear in a line.
Does anyone know what might be happening, and how to fix it?

Thanks in Advance!

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

Post by vitek »

What version of Irrlicht are you using [svn or 1.2]? It looks as if the nodes are being culled. Possibly the bounding boxes of the nodes are wrong, or the function that does the culling has some sort of bug. Are these custom scene nodes, or are they just terrain scene nodes or mesh scene nodes? Do you have your own custom cull method or are you just using the culling provided by Irrlicht?

Travis
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post by TheC »

I'm using irrlicht 1.1, these are "AnimatedMeshSceneNode"'s but they are static.

The green outlines are the bounding boxes, and they are correct. The problem must be with the default culling code. I cannot find out where it is going wrong though.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Those bounding boxes don't look right to me. They are much taller than they should be. The bounding box should be the smallest object aligned box that all of the vertices can fit into. Are you loading a model from file? I'm assuming you are loading a model from file, and if so, I would guess that the problem is with your model.

I did some testing with Irrlicht 1.2 and I don't see the problem. I tested with both animated mesh nodes and just plain mesh scene nodes. No problem noticed.

Code: Select all

  core::dimension2df tileSize(100.f, 100.f);
  core::dimension2di tileCount(1, 1);
  f32 hillHeight = 0.f;
  core::dimension2df hillCount(0.f, 0.f);
  core::dimension2df textureRepeat;
  textureRepeat.Height = 1.f; // tileCount.Height / tileSize.Height;
  textureRepeat.Width  = 1.f; // tileCount.Width  / tileSize.Width;

  video::ITexture* textures[8];
  textures[0] = driver->getTexture("../../media/portal1.bmp");
  textures[1] = driver->getTexture("../../media/particlered.bmp");
  textures[2] = driver->getTexture("../../media/portal3.bmp");
  textures[3] = driver->getTexture("../../media/particlewhite.bmp");
  textures[4] = driver->getTexture("../../media/portal5.bmp");
  textures[5] = driver->getTexture("../../media/particlered.bmp");
  textures[6] = driver->getTexture("../../media/portal7.bmp");
  textures[7] = driver->getTexture("../../media/particlewhite.bmp");

  scene::IAnimatedMesh* mesh =
    smgr->addHillPlaneMesh("floor", tileSize, tileCount, 0, hillHeight, hillCount, textureRepeat);
  if (mesh)
  {
    u32 x, z;
    for (x = 0; x < 20; ++x)
    {
      for (z = 0; z < 20; ++z)
      {
        const core::vector3df pos(x * 100.f, -10.f, z * 100.f);

        //scene::IAnimatedMeshSceneNode* floor = smgr->addAnimatedMeshSceneNode(mesh, 0, -1, pos);
        scene::IMeshSceneNode* floor = smgr->addMeshSceneNode(mesh->getMesh(0), 0, -1, pos);
        if (floor)
        {
          floor->setMaterialTexture(0, textures[ rand() & 0x7 ]);
          floor->setMaterialFlag(video::EMF_LIGHTING, false);
          floor->setDebugDataVisible(true);
        }
      }
    }
  }
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post by TheC »

This is a custom model.

the reason the boxes are so high is because I added an extra vertex to make them that high, just because it would be difficult to seem them if they are flat.

Even if I removed it, this still happens.
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

I remember seeing this with software drivers or something.


it's the culling in irrlicht.

is your frustum wide? skewed??

I've seen this before somewhere can't place it.

try directx if yer not already.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I think you're talking about the software driver. It doesn't render triangles that are intersected by the frustrum. You can tell by the screenshot that this is not the case. It does not clip the tris on the left or front, only on the right edge of the screen.

Are you doing anything special with the camera? Can you provide a link to your 'model' so that I can try it out first hand?

Travis
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post by TheC »

I'm not messing with the camera, its how it is by default.

The mesh is custom. Its just 5 verts, and scaled, with the parent rotated.

The driver is DX, but the culling code is in the scene manager, so its device independant.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

I remember having a problem with terrain chunks cliping at weird angles and places. I think playing with the zoom/fov fixed it? not sure...

For a hacky fix zoom in with the fov and move the camera back, that way the things that are clipped are not visible on the screen anymore!
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

I was reading about multithreading in games and it turns out clipping is a problem since sometimes diffrent parameters are updated ansychronosly(i cant spell :oops: ) they advised to do what blindside did and compensate by making the clipping frutsum larger (he did this using the fov) so no artiffacts occur, till he next chance of proper synch is available.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post by TheC »

I don't want to mess with the FoV, but, could I scale the frustum within irrlicht? I could scale the bounding box for the frustum.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

This is not a multithreading problem. The frustum culling code is taking an easy-out and checking against the node bounding box that is incorrectly transformed into world space. When the parent node, or any node for that matter, has a rotation applied, the bounding boxes are wrong.

Here is a simple example that shows the problem using the default camera FOV and a single rotated quad. When the program starts, you won't see the textured quad, but you will see the bounding boxes. If you pan right the quad will appear and if you pan back left it will disappear.

Code: Select all

int main()
{
  // ask user for driver

  video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D8;

  // create device and exit if creation failed

  IrrlichtDevice* device =
    createDevice(driverType, core::dimension2d<s32>(1024, 768));

  if (device == 0)
    return 1; // could not create selected driver.

  video::IVideoDriver* driver = device->getVideoDriver();
  scene::ISceneManager* smgr = device->getSceneManager();

  // load the scene

  const core::vector3df scl(10.f, 10.f, 10.f);
  const core::vector3df rot(0.f, 35.f, 0.f);
  const core::vector3df pos(0, -10.f, 0);

  scene::IAnimatedMesh* mesh =
    smgr->addHillPlaneMesh("floor", core::dimension2df(10.f, 10.f), core::dimension2di(1, 1));

  scene::IMeshSceneNode* floor = smgr->addMeshSceneNode(mesh->getMesh(0), 0, -1, pos, rot, scl);
  floor->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));
  floor->setMaterialFlag(video::EMF_LIGHTING, false);

  // setup the camera

  scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
  camera->setPosition(core::vector3df(-90.f, 18.f, 24.f));
  camera->setRotation(core::vector3df(13.f, 37.f, 0.f));

  // create one time materials and matrices

  core::matrix4 identity;
  
  video::SMaterial material;
  material.Lighting = false;

  video::SColor red(255, 255, 0, 0);
  video::SColor grn(255, 0, 255, 0);
  video::SColor blu(255, 0, 0, 255);

  // run the simulation

  while (device->run())
  {
    if (device->isWindowActive())
    {
      if (driver->beginScene(true, true, video::SColor(255,20,20,20)))
      {
        smgr->drawAll();

        // draw boxes

        driver->setTransform(video::ETS_WORLD, identity);
        driver->setMaterial(material);

        core::aabbox3df box;

        //
        // draw the fudged world aligned bounding box. notice it does
        // not enclose all of the vertices of the mesh. this makes it
        // possible for the cull test to cull nodes that are actually
        // in view.
        //

        box = floor->getBoundingBox();
        floor->getAbsoluteTransformation().transformBox(box);
        box.MaxEdge.Y += 10.f; // give the box some height
        driver->draw3DBox(box, red);

        //
        // draw the world aligned bounding box. notice it does include
        // all of the vertices, but in some situations there is a lot
        // of waste, which can cause the frustum culling to not cull
        // something that it should.
        //
        box = floor->getBoundingBox();
        floor->getAbsoluteTransformation().transformBoxEx(box);
        box.MaxEdge.Y += 5.f; // give the box some height
        driver->draw3DBox(box, blu);

        //
        // draw the object space bounding box. notice that this is the
        // smallest enclosing box that is oriented with the object
        // coordinate system. this is the box that should be tested
        // against
        //
        driver->setTransform(video::ETS_WORLD, floor->getAbsoluteTransformation());

        box = floor->getBoundingBox();
        // no box transform needed, the verts will be transformed later
        box.MaxEdge.Y += 5.f; // give the box some height
        driver->draw3DBox(box, grn);

        driver->endScene();
      }   
    }
  }

  device->drop();

  return 0;
}
The solution is to fix CSceneManager::isCulled(). The easy way would be to change transformBox() to transformBoxEx(). Unfortunately that will result in obects not getting culled that should be. This is particularly a problem with slender objects, and is not so much a problem with cube shaped objects.

This is the same exact problem as the one that I ran into here.

Travis
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post by TheC »

TransformBoxEx works great, thanks! :D

I'd rather have "under culling" than "over culling", that way, problems aren't visible :)

Once again, thank you!
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

The SVN version of irrlicht supports culling against the frustum planes which is more accurate. You might give that a try.

Travis
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post by TheC »

I will do, thanks
Post Reply