Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Transparent Layers in Standard Shader (Z-Write?)

Discussion in 'Shaders' started by NoBullIntentions_P, Feb 26, 2017.

  1. NoBullIntentions_P

    NoBullIntentions_P

    Joined:
    Jul 2, 2012
    Posts:
    311
    I have a skinned mesh which has layers of overlapping (but not intersecting) polygons, which need to be rendered with transparency (cutout will not suffice). I saw a thread last night (which I sadly can't find now) which said there was an option to have transparent surfaces ordered within a mesh which had been added in 5.5. They weren't specific about what the solution was or what it was called, but I assumed that they meant there was an option to enable Z-Write as I think this would be suitable for a situation where the layers overlap but do not intersect. They might also have been referring to triangle sorting, I guess.

    What is this option added to 5.5 which allows a different kind of transparency sorting? Is it suitable for my needs here?

    If not, what would I need to do? Would modifying the standard shader to use Z-Write do the job? Or do I need something more than this?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    I know of nothing specific to Unity 5.5 that was added for this, using a z write pre-pass has been possible since Unity 2.0, and people have been doing experiments with OIT since Unity 4.0, though it's more common with 5.0 since render textures are available with the free version. There's also depth peeling and, as you mentioned, triangle sorting, both of which probably have worked for the last few versions of Unity as well.

    But, you probably want the pre-pass ZWrite option. For that you'll need to write a custom surface shader with this snippet of shader code near the top:
    Code (CSharp):
    1. Pass { ColorMask 0 }
    That's it.
     
  3. NoBullIntentions_P

    NoBullIntentions_P

    Joined:
    Jul 2, 2012
    Posts:
    311
    Thanks for the suggestion. I need to use the Standard shader so I tried modifying it by adding the pass as you demonstrated but it isn't sufficient to solve the problem. I've attached a couple of screens which show how it should look (with alpha cutoff used) and how it looks with the z-write pre-pass.

    I'm really not sure which transparency solution is the answer to a problem like this, with layers of transparency on top of one another (but not intersecting). I'm using deferred rendering too, which probably complicates things. I tested your solution with both forward and deferred though.

    MaskedHair.png TransparentHair.png
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Deferred rendering is only for opaque, anything that's transparent will be rendered using the forward rendering path. Also by "need to use the Standard shader" I suspect you really mean you need to use the standard shading model so it works with deferred. But as I just mentioned, transparencies aren't rendered deferred so that doesn't have to be a hard limit. That being said surface shaders exist in part so you can easily use the standard shading model easily while also doing more complex things than what the standard shader is capable of by default.

    So for your specific case of hair, try this:

    https://forum.unity3d.com/threads/s...y-shiny-on-the-underside.393068/#post-2574717
     
  5. NoBullIntentions_P

    NoBullIntentions_P

    Joined:
    Jul 2, 2012
    Posts:
    311
    Yes, that's much closer to what I was aiming for. Thanks very much for the assistance.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    As a minor note, that shader should really be updated to use UnityObjectToClipPos(v.vertex) instead of mul(UNITY_MATRIX_MVP, v.vertex) for the depth pass. In some cases you might get z fighting in 5.4+