Sorting 3D objects by material makes my game slow

Hi!

ok, only about 7 fps of 120, but it is strange… I didn´t expect a great speed up, but not a slow down! i have reduced significantly the number of opengl state changes (texture binding, activation of texture stage, program binding, etc.). The fact is that if I do not order my objects (each one is a display list) i have 127 fps, and sorting them i have 120 fps…
my code for drawing an array of objects is like this:


   int matIdAnt=-1;
   Objeto3d *obj=0;
   int numObj=objetos.size();

   for(int i=0; i<numObj; ++i){
      obj = this->objetos[i];
      if(matIdAnt!=obj->material.id){
         obj->material.setupOGL_on(posCamara);
         matIdAnt=obj->material.id;
      }
      this->objetos[i]->dibujaGeometria(true, true);
   }

   if(obj!=0){
      obj->material.setupOGL_off();
   }

Note that changing this code by a simple loop does not make performance changes. The only code that slows down this line that orders objects by material id:


std::sort(objetos.begin(), objetos.end(), ordenMateriales);

and of course it is only called at objects loading.

Thank you for your help.

and the question is… what can be the reason?

I would put a timer around the std::sort call to see if that’s where your extra time is going.

std::sort is going to do many many copies of objects. Depending on its size this could nuke you.

If so, try sort a list of indicies instead (overload the sort comparison)…

Otherwise, hard to say why its slower…

the sort call is only called at initialization, not when the rendering loop is active as i said, so the sort call is not the problem :wink: … maybe it sorts in a way that when drawing opengl needs to do more operations?

Keep in mind there are several different parts of rendering, and each may be a bottleneck, depending on the situation. Of course, the main bottleneck will hide others.

For this example, one possibility is that changing the drawing order now makes roughly back to front rendering, voiding any high speed rejection by the depth buffer, and forcing evaluation of complex shaders or texturing for fragments that will end up being covered later anyway.

Try reducing the render window size to something tiny like 64*64 pixels (to remove the per fragment bottleneck), and check the rendering differences between sorting and unsorted.

IMPORTANT : measure and compare frame rendering time, and NOT frames per seconds, which is not additive.

nice, very helpful! using gdebugger and turning off raster operations I have 3.1ms/frame sorting, and 4.3 with no sorting, so i clearly see there is a improvement ocluded by the bottleneck that make my fragment shaders… now i know what to tune to gain performance…

thanks a lot!