DecalEffect

Hello all,

I have been working on my terrain and have encountered some problems in that I have a subgraph of the terrain of several nodes and a subgraph of various decals to apply to the terrain (also of several nodes and levels), both of which are created procedurally, but have run into the problem of having the decaleffect requiring the children of a node to be the actual decals. At first I thought that I could parent both the terrain and the decals to a single node with the effect enabled, which indeed gets the right results, but then the terrain renders without regard to camera angle (sometimes front to back). Then I thought I would just go into the source and create my own “decal effect” only to find that the decaleffect.cxx and decaleffect.h (as the rendereffect.cxx/h) don’t actually “do” anything other than account for bam loading/saving. Could someone point me in the right direction??

(oh, and setdepthoffset did not seem to work…)

Thanks!

The DecalEffect has such strange operating parameters because of the nature of the rendering tricks it enables. Specifically, it requires (a) the decals are a child of a single Geom that can be drawn in one pass (hence the strange parent-child requirement), and that (b) the base geometry is not self-occluding anywhere, and that © the decal geometry is also not self-occluding and is perfectly coplanar with its base geometry, and that © the decal geometry does not extend anywhere beyond the base geometry.

Specifically, the DecalEffect causes the base geometry to be drawn once, with color-write enabled and depth-write disabled, then the decal geometry is drawn once in normal mode, and then the base geometry is drawn once more with color-write disabled and depth-write enabled (to fill in the depth buffer).

This is the most reliable way to draw coplanar decals, especially on older hardware. It works best when hanging posters and things on flat walls.

But for putting things coincident with a bumpy terrain–especially a terrain geometry that is very large and visible everywhere–it probably won’t work that well. You might need a different technique. There are several other approaches you can use, all of which have different tradeoffs.

For instance, one easy thing to do is to apply a DepthOffsetAttrib to your decal geometry. This will offset the depth values just slightly, usually enough to clear the geometry it is coplanar with. It generally works well, and is simple to use, and requires less overdraw than the DecalEffect. The only downside is that it doesn’t always work on very old hardware, and that from very oblique angles or from very far away it can tend to shimmer a bit.

David

Oh, hmm, you say setDepthOffset doesn’t work. That surprises me. Can you give me more information on this?

David

Thanks, Drwr.

Well, you can always write a pixel shader, of course.

Other tricks involve using a BillboardEffect to play games with the offset. And you can explicitly play games with depth write and/or depth test, especially in conjunction with binning, to achieve all sorts of overlay effects.

David

Upon further testing I found the “bug” again, and it only happens with the depth offset attrib. It does not blend the transparency correctly on multiple levels of offset at the same position, blending each layer with the original terrain instead of each other… not sure how to work around this one. I had originally turned off the depth write, which worked, but then the layers would be rendered in a random order…

I’m going to try to use the billboard, but if that doesn’t work I guess it might finally be time for me to learn how to use a shader…

Transparency? Sounds like you might need to ensure the proper sort order with binning. Or, just make sure you are using transparency mode MBinary, which doesn’t require sorting.

David

How would I go about binning the order of the terrain…is this possible while still leaving everything else on top of the terrain alone??

Sure. Try:

terrain.setBin('background', 0)
decal1.setBin('background', 10)
decal2.setBin('background', 20)

If you have other things actually parented to the terrain, and you don’t want them to inherit the background bin setting, you can do:

object.setBin('', 0)

David

Thanks, that solved it!!!
(and I had to turn off depthtest on all the things that I changed the bin for…)