Search Unity

Using GrabPass to grab depth and GBuffer contents

Discussion in 'Shaders' started by Zergling103, Sep 9, 2018.

  1. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    I'd like to know how to use GrabPass to grab the contents of the depth buffer and GBuffers. The documentation specifies that it "grabs the current screen contents into a texture", however this doesn't clarify what it does when there are multiple buffers worth of screen contents, as it would require multiple textures to write into.

    A simpler problem possibly to solve would be using a grab pass to copy the depth buffer so that opaque shaders can achieve depth-based effects.

    Otherwise, if GrabPass cannot be used this way, is there a way to invoke a script (perhaps a command buffer) at a particular point in the Render Queue (such as "AlphaTest+48") that copies the various g/depth buffers into global shader textures? This would achieve a similar effect.
     
    Last edited: Sep 9, 2018
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    In deferred shading, Unity writes the g-buffer to the bound "_CameraGBufferTexture" textures, according to the documentation:
    https://docs.unity3d.com/Manual/RenderTech-DeferredShading.html

    Code (CSharp):
    1.  
    2. half4 gbuffer0 = tex2D (_CameraGBufferTexture0, uv); // Diffuse RGB, Occlusion A
    3. half4 gbuffer1 = tex2D (_CameraGBufferTexture1, uv); // Specular RGB, Smoothness A
    4. half4 gbuffer2 = tex2D (_CameraGBufferTexture2, uv); // Normal RGB
    https://forum.unity.com/threads/accessing-deferred-renderer-g-buffers.315223/#post-2052380


    Depth is stored in "_CameraDepthTexture" or "_CameraDepthNormalTexture", depending on the depthTextureMode.
     
  3. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    This is correct. However, if you try accessing the depth texture while within an Opaque shader, you'll find that its contents are invalid. They may be the previous frame's depth buffer, or if you have multiple cameras, it may contain the depth contents of the last camera that rendered and thus produces and unpredictable result.

    Unfortunately you cannot both read from and write to the same depth texture at the same time, even if it's just the single depth value that you're currently overwriting. It is a similar way with the color buffer; you need a grab pass to copy the contents so that you may read from the copy while writing to the original.

    A grab pass for depth and G Buffers would allow one to more efficiently render deferred decals for example. Otherwise, you are required to use inefficient script callbacks and continuously write command buffers which is an inferior approach compared to just letting Unity's Renderer component render the things for you.
     
  4. Pangamini

    Pangamini

    Joined:
    Aug 8, 2012
    Posts:
    54
    Hello zergling. Is there a chance you have figured this out?