In Unity's Universal Render Pipeline (URP), expressions that smoothly blur the edges of the water surface (Soft Water), expressions that softly blend the areas where smoke and fog intersect with the ground (Soft Particles), and fog effects that cover the entire screen with fog are standard effects that improve the quality of a game's graphics. To achieve this, "depth information" that indicates the distance from the camera to the opaque object is essential. However, when you use the "Scene Depth" node in Shader Graph or refer to "_CameraDepthTexture" from C#, have you ever encountered a bug where the depth value cannot be obtained at all, the screen becomes completely white (or completely black), and the screen freezes with an unnatural, scissor-cut appearance? In this article, we will explain the root cause of depth buffer acquisition failure in a URP environment, using the analogy of a "cameraman and a ruler," and provide detailed configuration steps and troubleshooting to resolve the problem.
1. Understand with an analogy: ``A photographer who went out to take pictures without a surveying ruler.''
In order to intuitively understand the problem of not being able to obtain depth textures, let's consider the relationship between ``a photographer who takes landscape photos and an assistant who measures distances''.
You are the director (developer) of a movie, and you have instructed the cameraman (URP's drawing engine) to shoot a "scene of mist (translucent effect) floating on the water." The director requests, ``I want the boundary line where Moya collides with the ground to blend in with a gradation depending on the distance from the ground.'' In order to process this order, the assistant (depth texture generation path) needs to prepare a recording paper (Depth Texture) that measures the "accurate distance from the camera to the ground."
However, on the day of shooting, the producer (project settings) arbitrarily prohibited the assistant from having a ``distance measuring ruler (Depth Texture generation option)'' in order to ``speed up shooting and reduce equipment costs (performance optimization)''. Since the assistant cannot measure the distance, the recording paper remains blank. Since the photographer had blank recording paper, he couldn't judge the difference in distance, so he had no choice but to overwrite the haze on the ground, resulting in an unnatural finish (sharp intersecting lines) that looked like the edges of the haze were stuck into the ground.
This is the true nature of 'depth texture invalidation bug' in URP. In order to reduce the processing load, Unity URP immediately discards the depth buffer without leaving it in memory unless you explicitly set the depth information to be saved as a separate image (texture).
2. Root cause: Automatic destruction of depth information in URP
In the built-in (legacy) pipeline, when a shader requested depth information, Unity automatically enabled depth texture generation behind the scenes. However, in URP (and SRP as a whole), where performance optimization is paramount, developers have tight control over the behavior of the drawing pipeline.
GPU internally uses a "Z buffer (depth buffer)" to correctly determine the context when drawing opaque objects. Once the opaque object is finished drawing, this Z-buffer is typically obsolete and is cleared from GPU memory to save video memory (VRAM) bandwidth. When the render pass (Transparent Pass) that draws the translucent effect starts moving, the background depth information has already been physically erased and no longer exists, so even if the shader tries to refer to "Scene Depth", it cannot obtain a valid value and returns the default value (1.0 = furthest), resulting in a pure white screen. In order to maintain depth information, it is necessary to explicitly "copy (store)" the contents of the Z buffer to another texture and save it after drawing the opaque object, and settings for this are required in both the URP Asset and the camera.
3. Complete configuration steps to solve the problem
In order to correctly deliver depth information to the shader, it is necessary to change the settings in the following two places.
Step 1: Enabling URP Asset (Universal Render Pipeline Asset)
- From the project window, select the UniversalRenderPipelineAsset currently assigned to your project (if you don't know the path, you can locate the asset by clicking at the top of `Project Settings > Graphics`).
- Open an inspector window and expand the General section.
- Change the Depth Texture checkbox to ON (enabled).
Step 2: Injection settings for the camera (Main Camera)
- Select the game object of the Main Camera (or the sub camera that is drawing) in the scene.
- Expand the Rendering section within the Camera component.
- Check the Depth Texture item and make sure it is set to Use Pipeline Settings. If you want to control them individually, set them to On.
| Setting location | Settings | Recommended value | Effect |
|---|---|---|---|
| URP Pipeline Asset | Depth Texture | ☑ ON | Enable depth texture generation pass project-wide. |
| Camera Component | Rendering -> Depth Texture | Use Pipeline Settings (or On) | Generate a copy of the depth information in this camera's rendering pass. |
4. Troubleshooting and performance considerations
Depth texture generation forces the GPU to perform an additional memory copy pass (copying the contents of the Z buffer to the texture), which can strain pixel fill rate, consume VRAM bandwidth, and cause a slight frame rate drop, especially on low-end mobile devices and VR headsets (such as Meta Quest). As a golden rule for optimization in practice, we recommend the following measures.
- Turn depth texture off for cameras you don't need: If you have multiple cameras in your scene (UI camera, minimap camera, item preview camera, etc.), explicitly set `Depth Texture` to Off in each camera's inspector. Thoroughly eliminate the waste of running depth copy to unnecessary cameras.
- Coordination with post process application order: Depth textures are mainly required when drawing translucent effects and when calculating post processes (depth of field, SSAIO, etc.). For scenes and stages that do not use these, it is also effective to dynamically switch the `depthTextureMode` of the graphics settings (URP assets) from C# and disable it.