原文链接
————————————————
版权声明:本文为CSDN博主「黄琅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
正文
抓手
可能大家知道 Build-in 管线的深度图如何获取了,但是 URP 管线下因为 api 不同了,所以需要移植一下。
下面给出 Bulid-in 和 URP 管线的获取深度图的对比,
然后提供两个实例来说明获取深度图后怎么使用,
最后提供源码 demo 下载。
两种管线获取深度图的对比
Build-in 获取深度图的值的方法:
- 先在代码中调用
GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
启用 camera 获取深度图。
- 接着,在 shader 里声明一下深度图:
sampler2D CameraDepthTexture;
紧接着,vert
方法里,获取屏幕坐标:
o.scrPos = ComputeScreenPos(o.vertex);
- 再接着在
frag
方法里
float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)));
float depthValue = Linear01Depth(depth);
即可获得深度图的值。
URP 管线获取深度图的方法:
- 先在 Asset Pipeline 或 Camera 里启用
Depth Texture
。
与 Build-in 不同的地方:无需 再在代码里设置 camera 的 depthTextureMode
啦!
- 接着在 shader 中,
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
声明深度图,这里和 Build-in 的 不一样。
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
获取屏幕坐标,这个和 Build-in 管线的一致。
o.scrPos = ComputeScreenPos(vertexInput.positionCS);
采样深度图,这里的 api 和 Build-in 的 不同。
float2 screenPos= v.scrPos .xy / v.scrPos .w;
float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, screenPos).r;
float depthValue = Linear01Depth(depth, _ZBufferParams);
注意:
Build-in 管线和 URP 管线中,哪些物体会写入深度图:
- Build-in 管线是 shader 中,必须 有
ShadowCaster
这个 pass,而且该物体用的 必须 是renderQueue
小于 2500 的材质球。
URP 管线是 只需
renderQueue
小于 2500 的材质球的物体都会写入深度图,shader 无需 添加ShadowCaster
这个pass。
- URP 管线中,不透明材质球渲染完后才会写入深度图,所以
renderQueue
小于 2500 的材质球 无法使用 深度图。
实例
1、使用深度的值,可以打印景深图。
例如,创建一个和摄像机垂直的 plane 或者 quad,充满整个屏幕。将深度图的 Linear01Depth
值作为颜色输出出来。
return float4(depthValue,depthValue,depthValue,1);
效果如下:
2、扫光效果
float4 screenColor106 = tex2D(_CameraOpaqueTexture, screenPos.xy);
float curVal = frac(_Time.y*_Speed);
float showCol = saturate(abs(curVal - depthValue) / _DepthWidth/2);
float3 finalColor = lerp(_Color.rgb, screenColor106.rgb, showCol);
return float4(finalColor, 1);
源码 Demo 下载
提取码:1553