I use a deferred rendering. During g-buffer stage my rendering loop for a sponza model (obj format) looks like this:

int i = 0;
int sum  = 0;
map<string, mtlItem *>::const_iterator itrEnd = mtl.getIteratorEnd();
for(map<string, mtlItem *>::const_iterator itr = mtl.getIteratorBegin(); itr != itrEnd; ++itr)
   glActiveTexture(GL_TEXTURE0 + 0);
   glBindTexture(GL_TEXTURE_2D, itr->second->map_KdId);
   glDrawElements(GL_TRIANGLES, indicesCount[i], GL_UNSIGNED_INT, (GLvoid*)(sum * 4));
   sum += indicesCount[i];
   glBindTexture(GL_TEXTURE_2D, 0);

I sorted faces based on materials. I switch only a diffuse texture but I can place there more material properties. Is it a good approach ? I also wonder how to handle a different kind of materials, for example: some material use a normal map, other doesn't use. Should I have a different shaders for them ?


1 Answer 1


Optimising render state changes is definitely good.

  • You should sort the materials by render state, preferably rating more expensive states (texture change, shader change) higher.
  • You should render big and visible geometry first, to increase z culling efficiency. Eg level geometry.
  • When there are no expensive render states to change between a group of objects or when the fragment shader is very expansive, sorting them front to back can be faster.
  • You should keep track of the render states yourself as opengl doesn't do it and redundant state change are not free at all.
  • Sorting by vertex declaration can give considerable performance gains on some platforms.
  • Profile

As to writing a seperate shader for features like normal mapping: Normal mapping using tangent space normals requires a different or an additional vertex stream, an additional texture and some decent computations which outweight the fragment shader change in nearly all cases. When sorting the object rendering order you can even remove most of the shader changes. The benefit depends on how costly the feature is and how many objects you render with the feature. Eg if you have 100 objects using normal maps and one object not using them and the object is small it might be faster to render it with an identity normal map. Some simple features, like applying a constant ambient, should just get applied to all objects even if some get black ambient.

I think these are the most important aspects to consider, most importantly test and compare. This msdn article has very details informations on how to accurately measure state changes inn directx which should apply to opengl, linux, macos and mobile platforms too.

Deferred Shading shouldn't change anything it normally leads to less materials due to less freedom when shading and not requiring the many light related state changes which makes sorting more efficiently.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .