Scenario: several objects (o1, o2,.., on) have to be rendered with the z test disable, but the z values must be written to the depth buffer. In another pass, some other objects (t1, t2,..., tm) need to be rendered considering with the z test enabled, and considering the prior values from the previous pass.

Is it possible to achieve this with Unity's material script? The goal is to support a custom order for the rendering of transparent objects (the o1,..,on in the scenario description) alongside with matte objects (t1,..., tm). I tried using the features mentioned here, but the results were incorrect, i.e. as if the z values were completely discarded inbetween passes. Can anyone, perhaps, share a code stub for this scenario?

  • 1
    \$\begingroup\$ Speaking on behalf of the lower-level rendering APIs such as D3D and OpenGL, depth values are not written unless the depth test is enabled. You can always set the test function to always to make it pass for everything, but the test has to be enabled. \$\endgroup\$ – Andon M. Coleman Feb 11 '15 at 3:55

Yes you can do this.

Check out this other question which I asked and then answered myself. Specifically the 2nd half that talks about the depth buffer.

Unity3D sprites vs Mesh Quads - Depth, Blending, Shadows

The trick is going to be to use a custom shader and set in the shader the render que (to determine draw order) and the depth buffer settings.

Your earlier objects need to be rendered with ZWrite On, but with ZTest to either Always or to some other setting that will make it draw according to your needs. Possibly LEqual.

Then your later objects will need to be rendered with ZTest also appropriate. Possibly also LEqual. I don't know where your objects are in 3d space. But you can use the ZTest to control culling here.

The trick though is to make sure you are using "Queue" = to force the drawing in a specific order. Check this page: http://docs.unity3d.com/Manual/SL-SubshaderTags.html for info on how the queue works. Essentially the Queue is set to a constant that equates to a number. And you can add +1 (or +100) to that constant to make it higher. Or set it to any number manually. And then rendering is done sorted in this queue order.

To be clear: you can write and test, not write and test, write and draw always.. any combination of writing to the depth buffer and using it to cull.

  • \$\begingroup\$ thanks for the tips and tricks, I hope someone else will find this also helpful! \$\endgroup\$ – teodron Feb 11 '15 at 15:06
  • \$\begingroup\$ I was in your shoes 2 weeks ago trying to figure it out so yeah me too. \$\endgroup\$ – badweasel Feb 11 '15 at 19:32

As far as has been determined currently, writing to the depth buffer does not work. Unity allows the use of depth textures for many screen effects, though it seems that your issue is most likely a problem with using the depth flags correctly. Do you have any code you post or more information about your use case?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.