Depth and Normals


Introduction

This article will provide some insight into what depth/normal textures are and how they are generated in the context of a 3D rendering pipeline.


Depth Texture

A depth texture is a render texture that gets its value from the camera's . A render texture is a texture that can be created and updated in realtime so each time the camera moves, the depth texture will update as well. The camera in Unity can generate this depth texture and then in a shader you can request and use that texture. The depth texture displays the depth of the scene by using a color gradient between black and white. Generally closer objects get drawn in black and further away objects in white but of course this is just a convention and it might as well be inverted.


A generic square placeholder image with rounded corners in a figure.
A depth-texture view from the commonly used Sponza Palace scene.

The depth texture gradient is non-linear but can of course be linearized. It is also important note that the depth texture is dependent on the far clipping plane of the camera since this determines the 'most far away point that the camera can see'. If this plane is very far away, all the objects will appear black since they are all relatively close when you consider the whole distance that the camera can see.


A generic square placeholder image with rounded corners in a figure.
Non-linear depth buffer dependent on near and far plane of camera.

When displaying the depth texture in shader graph by using _CameraDepthTexture and sampling it, the displayed texture is tinted red because the first channel (R) is used. This can easily be turned into a black-and-white texture of course. Another thing, is that the depth texture depends on the camera that is being used. The scene camera will generate a different result than the game camera.


A generic square placeholder image with rounded corners in a figure.
The Depth Texture in Shader Graph.


Depth + Normals Texture

You can also generate a _CameraDepthNormalsTexture which is the depth texture and the normal texture combined into 1 texture. You can then decode this DepthNormals Texture to extract the Depth and Normals texture individually.


A generic square placeholder image with rounded corners in a figure.
A DepthNormals Texture decoded into its Depth Texture and Normals Texture


Normals Texture

A Normals Texture is, just like the depth texture, a render texture. This time it does not display the depth of the scene, but the view space normals. The _CameraNormalsTexture isn't usually generated but the _CameraDepthNormalsTexture is, and as shown above, we can extract the Normals Texture from this DepthNormals Texture.


A generic square placeholder image with rounded corners in a figure.
A Normals Texture

It is important to note that the normal values are from the view space and so the normals are stored relative to the camera. When you rotate the camera, the colors of this texture will change.

Sources

https://developer.nvidia.com/content/depth-precision-visualized
https://williamchyr.com


Want to support me in creating free Unity tutorials and content?



Questions about this article?

Send me a message