Unity 2022.2.19 URP下如何渲染DepthNormals深度图?
在Unity 2022.2.19中渲染并应用DepthNormals深度图(Shader/Shader Graph实现)
一、手写Shader实现DepthNormals渲染
创建一个Unlit Shader,替换为以下代码,该Shader会将场景的深度与法线信息编码输出到纹理中:
Shader "Custom/DepthNormals" { SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; float3 worldNormal : TEXCOORD0; float depth : TEXCOORD1; }; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); // 将深度转换为[0,1]范围 o.depth = -UnityObjectToViewPos(v.vertex).z * _ProjectionParams.w; return o; } fixed4 frag (v2f i) : SV_Target { // 归一化法线并编码到[0,1]区间 float3 normal = normalize(i.worldNormal); float2 encNormal = EncodeNormal(normal); // 深度值饱和处理 float depth = saturate(i.depth); // RG通道存编码后的法线,BA通道存深度(可按需调整通道分配) return fixed4(encNormal, depth, 1.0); } ENDCG } } FallBack "VertexLit" }
二、Shader Graph可视化实现
- 创建Unlit Shader Graph,按以下步骤连接节点:
- 拖入
Position节点,选择World Space,连接到Normal Vector节点的Position输入(Normal Vector节点选择World Space),得到世界空间法线。 - 添加
Encode Normal节点,输入上述法线,将法线编码至[0,1]范围。 - 添加
Scene Depth节点,选择Eye Depth,再连接到Linear 0 to 1节点,将深度值转换为[0,1]区间。 - 将编码后的法线R、G通道连到Master节点的R、G输入;转换后的深度值连到B或A通道。
- 保存Shader Graph,命名为
DepthNormalsGraph。
- 拖入
三、应用到整个相机/场景
通过相机后处理让效果覆盖整个场景:
- 创建C#脚本
DepthNormalsCapture,代码如下:
using UnityEngine; [RequireComponent(typeof(Camera))] public class DepthNormalsCapture : MonoBehaviour { public Shader depthNormalsShader; private Material _depthNormalsMat; void Awake() { _depthNormalsMat = new Material(depthNormalsShader); // 确保相机能获取深度法线纹理 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals; } void OnRenderImage(RenderTexture src, RenderTexture dest) { Graphics.Blit(src, dest, _depthNormalsMat); } }
- 将脚本挂载到主相机,把你创建的DepthNormals Shader(手写或Shader Graph生成的)拖入脚本的
depthNormalsShader字段。 - 运行游戏,相机将直接输出整个场景的DepthNormals图。
补充提示
如果只是为了Moebius风格的轮廓检测,无需单独渲染可视化的DepthNormals图——只需开启相机的DepthTextureMode.DepthNormals,在后续的轮廓后处理Shader中直接采样内置纹理_CameraDepthNormalsTexture即可。Moebius风格的描边核心是对比相邻像素的深度与法线差值,超过阈值时绘制边缘。
内容的提问来源于stack exchange,提问作者bob0815
相关产品推荐
相关产品推荐

