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 shader with Z-Buffer

Discussion in 'Shaders' started by danielesuppo, Jan 13, 2018.

  1. danielesuppo

    danielesuppo

    Joined:
    Oct 20, 2015
    Posts:
    331
    Hello all!
    I really have no experience on shaders, but I'm trying to solve a problem:
    I'm using a volumetic fog plugin (Fog Volume 3) that to correctly work need the objects inside the fog to have a shader that write into the Z-Buffer of the scene.
    Well, I'd need to put into the fog some (many) transparent objects (texture with alpha channel), not cutout, and I know that standard tranparent shaders do not write into the Z-Buffer.
    So, I've seen in the Unity manual that this could be achieved with this code
    Code (CSharp):
    1. Shader "Transparent/Diffuse ZWrite" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5. }
    6. SubShader {
    7.     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    8.     LOD 200
    9.  
    10.     // extra pass that renders to depth buffer only
    11.     Pass {
    12.         ZWrite On
    13.         ColorMask 0
    14.     }
    15.  
    16.     // paste in forward rendering passes from Transparent/Diffuse
    17.     UsePass "Transparent/Diffuse/FORWARD"
    18. }
    19. Fallback "Transparent/VertexLit"
    20. }
    As Unity manual say (https://docs.unity3d.com/Manual/SL-CullAndDepth.html) this shader should write into the Z-Buffer.
    But, unfortunately, this seem not to work: with the "Fog Volume 3" plugin come a Scene Depth Viewer, that do not show the objects with this shader (but correctly show the objects with non transparent shader).
    Maybe I'm missing something somewhere else in Unity? Or, maybe, I'm using the wrong code?
    Many thanks for your help!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    This is incorrect. Objects do not need to write to the Z-Buffer, but rather the camera depth texture. Only objects that are in the opaque queues (0~2499) and have a shadowcaster pass write to the camera depth texture, but you can make a transparent shader with a queue of 2499 and a Fallback "VertexLit" (not "Transparent/VertexLit") and it'll show up in the camera depth texture. However this has serious implications elsewhere, such as transparency sorting and the directional shadow receiving. The sorting issue can be solved with some additional coding on your end (injecting your transparent objects into the depth texture manually), but the other two aren't as easily solved with out changes to the Fog Volume 3 asset.

    There are other volumetric assets that do support transparencies better, like Volumetric Fog & Mist and Hx Volumentric Lighting, but neither offer quite the features of Fog Volume 3. The real solution is getting @DavidMiranda to take a pass at supporting this in some way.
     
    terrycheung and bitinn like this.
  3. danielesuppo

    danielesuppo

    Joined:
    Oct 20, 2015
    Posts:
    331
    Thank's a lot bgolus for your deep explanation!
    Reading your suggestion (but without knowing anything about shader coding) I've tried to modify the shader in this way:
    Code (CSharp):
    1. Shader "Transparent/Diffuse TestDepthCamera" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5. }
    6. SubShader {
    7.     Tags {"Queue"="Geometry+2499" "IgnoreProjector"="True" "RenderType"="Transparent"}
    8.     LOD 200
    9.     // extra pass that renders to depth buffer only
    10.     Pass {
    11.         Name "ShadowCaster"
    12.         Tags{ "LightMode" = "ShadowCaster" }
    13.         ZWrite On
    14.         ColorMask 0
    15.     }
    16.     // paste in forward rendering passes from Transparent/Diffuse
    17.     UsePass "Transparent/Diffuse/FORWARD"
    18. }
    19. Fallback "VertexLit"
    20. }
    but I think I did a mess... and it doesn't show in the camera depth texture...
    maybe can you give one more tip on what I'm doing wrong?
    Again many thanks!
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    “Queue” = “Geometry+2499”
    That’s a queue of 4499 since Geometry is 2000 already.
    https://docs.unity3d.com/Manual/SL-SubShaderTags.html

    You also don’t need the extra shadowcaster pass there. The Fallback shader already has one, so the shader will use that. The one you have there isn’t properly defined anyway. See this page if you’re curious what it should look like:
    https://docs.unity3d.com/Manual/SL-VertexFragmentShaderExamples.html

    That page also uses UsePass to include only the shadow caster pass from the VertexLit shader, which is probably more correct, but all of Unity’s built in shaders just use FallBack.
     
  5. sewy

    sewy

    Joined:
    Oct 11, 2015
    Posts:
    150
    How one can inject into _CameraDepthTexture?
    (Forward Rendering + VR)
     
    Last edited: Aug 8, 2019