# Get the current depth buffer from GPU memory in URP

> Use a depth input attachment to read the current pixel depth from GPU memory instead of sampling a depth texture.

To read the depth value at the current pixel from on-chip memory in a custom Universal Render Pipeline (URP) shader, use the `FetchSceneDepth` method with a depth input attachment.

A render pass can read the depth buffer that a previous render pass wrote to on-chip memory, instead of writing it to a separate texture and sampling it back. In some graphics APIs, this is called an input attachment. For more information, refer to [Get the current framebuffer from GPU memory in URP](/engine/6000.7/manual/analysis/graphics-performance-profiling/in-urp/framebuffer-fetch/render-graph-framebuffer-fetch.md).

Reading depth using an input attachment reduces memory bandwidth in your project, especially on mobile devices that use tile-based deferred rendering (TBDR). This is useful to optimize effects like custom on-tile depth-based fog and depth-based smoke.

> **Note:**
>
> If you use Shader Graph, use the [Fetch Scene Depth node](https://docs.unity3d.com/Packages/com.unity.shadergraph@latest/index.html?subfolder=/manual/Fetch-Scene-Depth-Node.html) instead of writing HLSL.

## Requirements

Depth input attachments are supported only in URP, and only on DirectX 12 and Vulkan. You can check whether your target platform supports this at runtime by using `SystemInfo.supportsDepthAttachmentAsInputAttachment`.

## Read the current pixel depth

To read depth from on-chip memory in your shader, do the following:

1. In your URP Renderer, add a [Render Objects Renderer Feature](/engine/6000.7/manual/render-pipelines/universal-render-pipeline/customizing-urp/urp-renderer-feature/renderer-feature-render-objects.md).

2. In the Render Objects Renderer Feature, enable **Depth** and **Set As Input Attachment**.

3. In the Render Objects Renderer Feature, set **Event** to **After Rendering Opaques** or later. This is necessary because depth data is available only after the opaque pass.

4. In the `HLSLPROGRAM` in your shader file, add an `#include` directive for the `DeclareDepthTexture.hlsl` file.

   For example:

   ```lang-hlsl
   #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
   ```

5. Add a `multi_compile` pragma for the input attachment keywords, so Unity can enable the correct keyword for the pass. URP sets these keywords automatically at runtime when a render pass uses depth as an input attachment.

   For example:

   ```lang-hlsl
   // URP sets these keywords automatically at runtime; you don't set them manually.
   #pragma multi_compile _ _DEPTH_AS_INPUT_ATTACHMENT _DEPTH_AS_INPUT_ATTACHMENT_MSAA
   ```

6. In your fragment shader, call `FetchSceneDepth` to read the depth value at the current pixel. For more information about the overloads, refer to [FetchSceneDepth overloads](#overloads).

   For example:

   ```lang-hlsl
   #if defined(_DEPTH_AS_INPUT_ATTACHMENT)
       // Reads depth directly from on-chip memory instead of sampling a depth texture.
       float depth = FetchSceneDepth(input.positionCS.xy);
   #elif defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA)
       float depth = FetchSceneDepth(input.positionCS.xy, 0);
   #endif
   ```

7. Create a material from your shader, and assign it to objects that your Render Objects Renderer Feature affects.

The material now reads current depth values from on-chip memory instead of a separate depth texture sample.

### FetchSceneDepth overloads

`FetchSceneDepth` has the following overloads.

| **Syntax**                                                 | **Description**                                                                                                                                          |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `float FetchSceneDepth(float2 fragCoord)`                  | Returns the depth at the current pixel. Use this overload when the `_DEPTH_AS_INPUT_ATTACHMENT` keyword is defined.                                      |
| `float FetchSceneDepth(float2 fragCoord, int sampleIndex)` | Returns the depth at the current pixel for the given MSAA sample index. Use this overload when the `_DEPTH_AS_INPUT_ATTACHMENT_MSAA` keyword is defined. |

## Full code example

The following example shader code reads the current pixel depth and writes it to the red channel of the output color.

```lang-hlsl
Shader "CustomFetchDepth"
{
    SubShader
    {
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
        }

        Pass
        {
            Name "CustomFetchDepth"

            ZWrite On
            ZTest LEqual
            Cull Off

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment FragDepthVisualization
            #pragma target 4.5
            // URP sets these keywords automatically at runtime; you don't set them manually.
            #pragma multi_compile _ _DEPTH_AS_INPUT_ATTACHMENT _DEPTH_AS_INPUT_ATTACHMENT_MSAA

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            Varyings Vert(Attributes input)
            {
                Varyings output;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

                output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
                return output;
            }

            #if defined(_DEPTH_AS_INPUT_ATTACHMENT)
            float4 FragDepthVisualization(Varyings input) : SV_Target0
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                // Reads depth directly from on-chip memory instead of sampling a depth texture.
                float depth = FetchSceneDepth(input.positionCS.xy);
                return float4(depth, 0.0f, 0.0f, 1.0);
            }
            #elif defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA)
            float4 FragDepthVisualization(Varyings input) : SV_Target0
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                // Reads depth directly from on-chip memory for the given MSAA sample, instead of sampling a depth texture.
                float depth = FetchSceneDepth(input.positionCS.xy, 0);
                return float4(depth, 0.0f, 0.0f, 1.0);
            }
            #else
            float4 FragDepthVisualization(Varyings input) : SV_Target0
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                // Unity doesn't provide an automatic fallback to depth texture sampling here.
                float depth = 0;
                return float4(depth, 0.0f, 0.0f, 1.0);
            }
            #endif
            ENDHLSL
        }
    }
}
```

## Additional resources

* [Render Objects Renderer Feature reference](/engine/6000.7/manual/render-pipelines/universal-render-pipeline/customizing-urp/urp-renderer-feature/renderer-feature-render-objects.md)
* [Get the current framebuffer from GPU memory in URP](/engine/6000.7/manual/analysis/graphics-performance-profiling/in-urp/framebuffer-fetch/render-graph-framebuffer-fetch.md)
* [Shader keywords and macros reference in URP](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom-shaders-urp/shader-keywords-macros.md)
* [Writing custom shaders](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom-shaders-urp.md)
* [Optimize for untethered XR devices in URP](/engine/6000.7/manual/xr/graphics/untethered-device-optimization.md)
