Hi Mike,
So to clarify, the custom depth/stencil pass is isolated and handled after the base pass (g-buffer pass). It doesn’t share any data so you shouldn’t be seeing draw-order dependent effects. It writes to and tests against a separate depth buffer (Custom-Depth on buffer visualization modes). It is rather limited but can be utilized as needed for isolating objects in later passes and effects. If you are seeing cases where objects not set to render into the custom depth buffer are interacting with those that are flagged, it’s a bug and not intended. If you have a reproduction I’d really appreciate it, please.
As this is a separate pass it means you will be drawing any flagged meshes an additional time, so I wouldn’t recommend drawing all objects. If you need all objects to write a value, then a cleaner solution is likely to extend the g-buffer with an ID channel. Unless you’re explicitly relying on the data being stored in a stencil buffer, you should be able to add an additional buffer and have all objects output your custom IDs during the base pass. Then follow through the code to use that where necessary. For a similar but more complex example, you can try taking a look at how “r.BasePassOutputsVelocity” is used.
If however you only need a small group of specific objects to write IDs, then the cheapest method if probably to re-work the custom depth-stencil pass. Instead of writing to the custom depth buffer, bind the main scene depth buffer (from the base pass) and run a depth-less-equal test against that. The downside here is that you likely couldn’t write to the main stencil buffer as it’s in use during most of the frame, but as above you could create and bind a single-channel render target for ID storage. If you take a look where the existing custom targets are used you can add new buffers alongside that code to get material graph access, or apply them more directly in code.
Thanks,
Chris