Optimization issue

Well, I’m maybe just a beginner, but I’m just trying to make some order in my code.
If we let models have more than one material/texture, then we should sort it’s faces so we don’t have to do wastefull switching.
But when it comes to BSP trees, you just think about where is certain face or is it splitted with plane etc. Then we can forget our material optimization, because it is highly expected that parts of the same object will be in several tree nodes, and only node you draw consecutively. This will happen even if models dont have >1 materilas, but it is more complicated if they do.
How can one resolve this?

Why are you using a BSP tree for rendering?

Because it is very usefull. Rendering optimization with frustum culling, collision detection… You can find it all over the net.

I am using BSP-trees, too, and they are VERY useful.
However usually BSP-trees make it impossible to sort by material or texture, or so. But you have to make a decision: either using BSP-trees for sorting, or sorting by material etc.

Anyway, if you use a leafy BSP-tree, than you have a group of polys at every leaf, which can be drawn order-independent (but only with back-face culling). So you can still sort your polys in every leaf to minimize mode/texture switches.

Hope that helps you.
Jan.

Yes Jan, thanks. That’s what I wanted to hear. Can you be more specific about leafy tree. Or some link? Thanks in advance.

You can certainly sort by texture/material even in BSP trees.

The key is to have a list of everything you want to draw with a single material, hanging off that material. As you traverse the tree (or whatever scene graph you’re using), you tack on more stuff to draw onto this list. If you’re using meshes, then you tack on whole vertex buffers with triangle lists, and end up calling DrawRangeElements on each of them in the end. If you’re using single polygons, then you keep a buffer of vertices, fill it in, and end up calling DrawArrays in the end. You can combine the two, if necessary.

Once everything’s traversed, and you know what to draw, you can sort by whatever you want, and draw it. For example, transparent materials can know to draw last, and know to draw deep-to-shallow rather than sort by material.

jwatte, it’s a very good idea. I guess that sorting shouldn’t take much time.
Also, you suggested that sorting close to far is better than by mats. Does that mean that you can draw without depth testing? I saw some posts about this, but is it so good, that can swallow all mats and texs switching?

Whether switching materials is slower, or rasterizing unnecessary fragments is slower, depends on your hardware, and the degree of shading you do per fragment.

If you’re running a 70 instruction fragment shader with three levels of dependent reads and using 9 different texture targets, every single fragment you can prevent from drawing is significant.

If you’re doing vertex lighting or light mapping, plus a single diffuse color texture, then different cards have different characteristics.

The way I’d do it is render only to depth buffer, first, sorting near-to-far. This doesn’t touch color at all, and should be reasonably quick. Then, I’d go over the scene again, sorting by material, and rendering in depth EQUAL mode (or possibly LEQUAL, because there are some hints from ATI that that may be faster). Hierarchical Z cull will help a lot in this case – each fragment will only be shaded once!

Last sort far-to-near for transparent items.