Depth Test = false results in Stencil like-behaviour if Material doesn't use Blending

Test case with the rim aqua color material i’m using as a base for my unit counter.

Let’s consider default case depthTest = true and depthWrite = true

If using pc.BLENDING_NONE, it seems setting depthTest = false, does not make it appear in front always. Instead, a stencil like-behaviour occurs where the fragments only appear if behind another object entity (apparently if behind another object entity within the same graph parent space). Is this expected behaviour or some sort of bug?

However, the problem is fix if i set the blending to something like pc.BLENDING_NORMAL.

So, yea, is this expected that everything must at least use a blending: Alpha setting always or something to always make it appear in front (ie. get depthTest = false to work…) and cannot use BLENDING_NONE? BLENDING_NONE seems to use a stencil like behaviour (inverse zculling) which causes fragments to only appear if behind something else…(at the time of writing this…) Isn’t this a bug or is it supposed to be as such?

Is it possible to create a small project to repro this please?

Setting depth test to false giving stencil like behaviour does seem odd.

What is the end result you are trying to achieve?

I’m assuming all your models are in the World Layer.

What’s happening is this:

When you set pc.BLEND_NONE the model is classed as opaque. We sort all World Layer opaque draw calls by the material and mesh instance so that all models with the same material are drawn one after the other (this speeds up rendering). But importantly, the order things are rendered is not from furthest to nearest and the order is somewhat arbitrary (because they are all opaque it doesn’t matter what order they are rendered in).

When you set depthTest = false you are disabling the hardware depth test so when a model is rendered it doesn’t test if there are going to be pixels in front of it before rendering. This does not change the order that the models are rendered. In your second image all the models are opaque so I would guess something like this is happening:

  • grey targets are rendered
  • blue unit counters are rendered (with no depth test)
  • green background is rendered (with no depth test maybe?)

The green background is overwriting the the blue unit counter either because it has no depth test or blue counter has no depth write?

The problem is fixed when you enable blending because now the model is treated as transparent and rendered in back to front order, after all the opaque meshes are rendered.

Anyway key takeaway here, depthWrite/depthTest don’t change the order that things are rendered in and opaque meshes are not necessarily rendered in the order you expect.

SpectorJS is a great tool for stepping through each drawcall and you can debug why you’re not seeing what you expect.

1 Like