Reducing texture switches

If I’m rendering geometry with only one texture pass, does it make sense to bind textures to all the 4 (or 8 or whatever) texture units to avoid texture switching? Because I’m using a very small number of textures with a large number of switches, this could be very helpful for me.

And the followup question is what is the best way to do this? Should I disable the texture units that I’m not using at the time? (Is disabling a texture unit as bad as changing textures?) Or should I write a pixel shader that has as a parameter a vector of weights for each texture unit that can be varied to in effect turn on and off individual textures? Or is there some other way to do this?

My understanding is that on the GeForce3, for example, if you have one pass, you get a second pass for free. But on other cards (like ATIs), is it true that extra active texture units will take proportially more performance? I’m trying to reconcile this fact with a lecture given by ATI/Nvidia recommending that people should assign textures (as above) to reduce the number of batches submitted by the CPU.

Thanks all

Edit - Okay, I found a post below on texture units, texture coordinates, and texture image units, its helping to clear some of my confusion up that I mentioned in the last paragraph.

[This message has been edited by Stephen_H (edited 08-11-2003).]

Was that lecture based on Direct3D? If so, that information does not hold in terms of OpenGL.

That doesn’t mean you won’t get a performance boost from using multiple textures over a multi-textured object. However, the main performance penalty, under OpenGL, comes from changing state. You will still have to frequently change state, as you will need to upload new shaders/texenv settings for each separately textured subset of the object. So, if all the textures are already loaded into video memory, you probably won’t get much out of this.

Korval - Yes, it was the D3D lecture. They had a single slide showing that OpenGL didn’t exactly follow the performance characteristics of D3D in regards to batching. I’ve also read your previous post regarding lots of small VBOs versus less larger VBOs where Cass mentioned that D3D had to switch to kernal mode to submit a batch while OpenGL did not and thus large batches don’t make as much sense with OpenGL.

I’m not concerned with reducing the number of batches, but I would like to reduce the number of texture switches if at all possible. The problem is that I have about 4 transparent textures that I switch between pretty often and 2 or 3 of them are tiled so I can’t pack them. What the presentation seemed to be implying is that I could bind the non-repeating textures to units 0 & 1 and the repeated ones to 2 & 3 and somehow(?) batch them and at the same time it seems to me that they are also avoiding the texture switching penalty. Perhaps I am misunderstanding the presentation slides?

I don’t understand how this would work in OpenGL.

Its page 44 of this presentation:
http://www.ati.com/developer/gdc/D3DTutorial3_Pipeline_Performance.pdf

On of the best method known to man to minimize texture switching or state switching is to implement a scene graph in your engine…

There are some free (with the caveat that are design to satisfy all scenarios).
You shoul check openscengraph.org, even the nebula device engine (which is free and open to anyone http://www.radonlabs.de and find out the sourceforce CVS repository)

Have fun

Transforms are generally the primary criteria in a scenegraph. So that will reduce the number of matrix uploads, not texture switches. Unless you store multiple scenegraphs, one with material priority, one with transform priority etc.

I forgot where i read that, but what about putting all your important scene textures into a 3D texture, and just using a 3rd texture coordinate ? Then you no longer need to switch any texture at all.

I’m sceptikal about performance gains though… a scene graph, well implemented, should not slow down much because of texture switches.

Y.

Originally posted by Ysaneya:
I forgot where i read that, but what about putting all your important scene textures into a 3D texture, and just using a 3rd texture coordinate ? Then you no longer need to switch any texture at all.

That wouldn’t work with mipmapping, because the smallest mipmap would be a single texel which is a blend of all the colors in all your textures. You really need separate mipmaps for every texture, and you can’t have them with this approach.

– Tom

Originally posted by knackered:
Transforms are generally the primary criteria in a scenegraph. So that will reduce the number of matrix uploads, not texture switches. Unless you store multiple scenegraphs, one with material priority, one with transform priority etc.

You can organize your scene graph to suit your needs… i was talking about the concept of scenegraph…

n3rvu5

That wouldn’t work with mipmapping

Yeah, you’re obviously right.

Thanks for the replies!

Regarding scene graphs and sorting objects by texture - yes I have already done this as far as possible. The reason I cannot sort by texture fully is because the objects I’m rendering mostly will have alpha channels so they need to be sorted by distance to be displayed properly. I have already packed the stretched and 1-1 textures into a larger texture, but I cannot pack the tiled textures because they need to be GL_REPEAT.

Regarding using 3D textures… I have thought about this. I actually don’t need mipmapping but I do need linear filtering. If I do arrange the textures in a 3D texture, when a texture gets applied non-one-to-one won’t it also attempt to interpolate across 2D slices and give unintended results? Additionally, all the textures would have to be the same size which doesn’t work well in my situation without lots of wasted texture memory. This would be a great technique though for a series of textures that get applied over time, like an explosion or something, and you have lots of them in the scene.

Maybe I misunderstood the ATI/Nvidia presentation, but it seems to me that they are implying that you can batch up a series of vertex arrays each with a different texture by using the unused texture units. I couldn’t see how to do this and I thought that perhaps I was missing something incredibly simple or perhaps being stupid, but I guess not.

Thanks everyone again for all the replies.

edit - grammar

[This message has been edited by Stephen_H (edited 08-13-2003).]