抓手
可能大家知道build-in管线的深度图如何获取了,但是URP管线下因为api不同了,所以需要移植一下。
下面给出bulid-in和urp管线的获取深度图的对比,
然后提供两个实例来说明获取深度图后怎么使用,
最后提供源码demo下载。
两种管线获取深度图的对比
build-in获取深度图的值的方法:
1、先在代码中调用
GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
启用camera获取深度图。
2、接着,在shader里声明一下深度图:
sampler2D _CameraDepthTexture;
紧接着,vert方法里,获取屏幕坐标:
o.scrPos = ComputeScreenPos(o.vertex);
3、再接着在frag方法里
float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)));
float depthValue = Linear01Depth(depth);
即可获得深度图的值。
urp管线获取深度图的方法:
1、先在assert pipeline或Camera里启用Depth Texture。
与build-in 不同的地方:无需再在代码里设置camera的depthTextureMode 啦!
2、接着在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);
注意:
1、build-in管线和urp管线中,哪些物体会写入深度图:
build-in管线是shader中,必须有ShadowCaster这个pass,而且该物体用的必须是renderQueue小于2500的材质球。
urp管线是只需renderQueue小于2500的材质球的物体都会写入深度图,shader无需添加ShadowCaster这个pass。
2、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下载
链接:https://pan.baidu.com/s/1iQw5vVy2DcB3Xr4yWpoYhg
提取码:1553