Frustum Culling

Saw the frustum culling demo and have a question.  i know all spartals are either classified inside,interect,or outside.  Do you just completly render inside, and intersect, or do you go per-vertex checking to see if stuff intersecting with frustum can be culled?

There is no per-vertex checking done by jme. I do not know what opengl dose.

If the bounding volume intersects with the frustum, the object is not culled. This is done because per vertex checking is slow. (ok, below is the much better explanation now)



OpenGL itself does not do any culling, other than scissor testing. http://www.mevis.de/opengl/glScissor.html

Here's why we have both an intersects and inside constant:



OUTSIDE - Throw away that node, no longer process it.

INTERSECT - Check the children of that node against the frustum.

INSIDE - Render every child of the node.



By having INSIDE, we can determine that every Geometry within that Node is going to be drawn, so there is no need to process further. However, with Intersect there is.



I think what has you confused and thinking that there is per vertex checks is you are imagining Geometry being checked like this rather than Node.

actually it was just a question, I wanted to know to what primative the culling went to.  Another question I know it's alot faster to check bound spheres than bounding boxes is this true in jme.  How much of a proformance gain does this give a person?

of course bounding spheres should be much faster. i use them more often than the other types, but there is also a drawback:



imagine a very thin and long 3D object like a street light or a skyscraper - the object would be rendered almost all the time.

a bounding box or even a not axis aligned bounding box can propably do the job much better in this situation.



if you want some performance tests - just create a little scene with 10000 nodes that contain only one little cube or something like that.

set their modelbounds to the type you like and watch the fps debug text.



maybe you want to post your results as an image in this forum. :slight_smile:

you do bring up a good point I wonder if you could have a bounding elipse?  Would that still carry the same proformance gain that sphere give somebody.  Also just because the spheres are faster doesn't that also make them less accurate if the object is like you said a skyscrapper.  Ya that test would not be hard to do just add a key manager to change bounding boxes to bounding spheres in frustum culling test. I'll post results tomm.

Ran into a interesting question maybe even a bug.  I added a simple thing of code to the TestFrustumCulling.java.  It is suppose to change the bounding volume of the boxes to a sphere. I get a ton of weird results.  It'll end up having both a bounding box and sphere, it i start with bounding spheres then press Y it'll take the spheres off ever other row and i had a rare occasion where the fpsNode would say there are verts and stuff but nothing is draw no bounding volumes, nothing at all.


input.addAction( new InputAction() {
            public void performAction( InputActionEvent evt ) {
                // change Boundbox to bounding Sphere
               int z = 0;
               for ( int x = 0; x < 10; x++ ) {
                    for ( int y = 0; y < 10; y++ ) {
                        Box box = (Box)rootNode.getChild(z);
                 
                        if(BoundingBox)
                        {
                           box.setModelBound( new BoundingBox() );
                           BoundingBox = false;
                        }
                        else
                        {
                           box.setModelBound( new BoundingSphere() );
                           BoundingBox = true;
                        }
                        box.updateModelBound();
                        z++;
                    }
                }
            }
        }, InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_Y, InputHandler.AXIS_NONE, true );



just had a look at this code.

why do you use 2 loops instead of one?

why do you set the boolean BoundingBox every second step?



Maybe you intended something else than your fingers did code?  :wink:

@patrick: what is that BoundingBox variable? seems like you alternately set the bounding volumes to spheres and boxes. and ogli is right: you don't need 2 loops.


public static deepSetBoundingVolumes(Node node, boolean useBoundingSpheres){
  BoundingVolume bounds;
  if (useBoundingSpheres){
    bounds = new BoundingSphere();
  }
  else {
    bounds = new BoundingBox();
  }
  if (node instanceof Geometry){
    Geometry g = (Geometry)node;
    g.setModelBound(bounds);
    g.updateModelBound();
  }
  else {
    // optional: set the node bounds to the same type of bounding voilume
    node.setWorldbound(bounds);
    for (int i = 0; i < node.getQuantity(); ++i){
      setBoundingVolumes(node.getChild(i), useBoundingSpheres);
    }
    node.updateWorldBound();
  }
}



there could be errors in the code as i typed it in notepad and used the online javadocs (not cvs). could it be possible to add the cvs jme javadocs to the jme documentation page -  at least once per month or so? that way it would be possible to take a quick look at the api whitout checking jme out (from work, or school, or other similar places where you can't always do a quick cvs check out).

Sfera it didn't like you code because you tried to change node to Geometry.  Anyways I got my stuff working just changed the Boolean BoundingBox varible outside the loop.  Proformance wise I only got roughly 10fps more using spheres than boxes looking top down clipping half the boxes.  At extreme angles it's a different story, the fpsNode reports 26 meshes with bounding box(at the angle i was looking at) and when i switched over to bounding Spheres i got 68.  That dropped the fps by 100!  Best to use a bounding volume that best suites the node.  Pretty easy if the x,y,z extent are so close i would say within 10 units use bounding sphere.  Unless in such case like this one where you know it's a box.  Also to make the test more real world you might randomly spawn some other shapes too and randomly place them.  Unless this is just a tech demo then don't bother.



Code I used it is a little tricky to switch between bounding volumes but hey it works

input.addAction( new InputAction() {
            public void performAction( InputActionEvent evt ) {
               if(BoundingBox)
                  BoundingBox = false;
               else
                  BoundingBox = true;
               
               for ( int x = 0; x < rootNode.getQuantity() ; x++ ) {
                   
                       Box box = (Box)rootNode.getChild(x);
                       if(BoundingBox)
                          box.setModelBound(new BoundingBox());
                       else
                          box.setModelBound(new BoundingSphere());
                       box.updateModelBound();
                  }
                       
                }
        }, InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_K, InputHandler.AXIS_NONE, true );

Patrick said:

Sfera it didn't like you code because you tried to change node to Geometry.

only geometry objects have that setModelBound() method. and boxes are geometry :P

it just didn't want to work sorry.

as i said, i wrote it in notepad…  ://

call it on the root node


public static void deepSetBoundingVolumes(Spatial s, boolean useBoundingSpheres){
    BoundingVolume bounds;
    if (useBoundingSpheres){
      bounds = new BoundingSphere();
    }
    else {
      bounds = new BoundingBox();
    }
    if (s instanceof Geometry){
      Geometry g = (Geometry)s;
      g.setModelBound(bounds);
      g.updateModelBound();
    }
    else {
      Node node = (Node)s;
      for (int i = 0; i < node.getQuantity(); ++i){
        deepSetBoundingVolumes(node.getChild(i), useBoundingSpheres);
      }
    }
  }