深度纹理与法线纹理
参考:
Unity3D Shader系列之深度纹理_unity depth texture_WangShade的博客-CSDN博客
UnityShader基础(八)——深度纹理与法线纹理_unity shader 获得法线_implosion98的博客-CSDN博客
笔记十五——获取深度和法线纹理 - 知乎 (zhihu.com)
使用深度纹理的几个简单应用 - 简书 (jianshu.com)
Unity获取使用深度,法线纹理的方式:
c#代码(挂到相机上)
// 深度纹理着色器所用的材质 public Material depthMaterial; private Camera _camera; void Start() { _camera = GetComponent<Camera>(); // 单独开启深度纹理 _camera.depthTextureMode |= DepthTextureMode.Depth; // 或开启深度、法线纹理 _camera.depthTextureMode |= DepthTextureMode.DepthNormals; } void OnRenderImage(RenderTexture source, RenderTexture destination) { // 使用深度纹理着色器对屏幕进行后期处理 Graphics.Blit(source, destination, depthMaterial); }
相机后处理Shader代码
Shader "Custom/DepthTextureShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; // 声明深度纹理 sampler2D _CameraDepthTexture; // 或声明深度法线纹理 sampler2D _CameraDepthNormalsTexture; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag(v2f i) : SV_Target { float depthValue; float3 normalValue; float4 depthNormal; // 解析深度法线纹理分别得到深度值跟法线值 depthNormal = tex2D(_CameraDepthNormalsTexture, i.uv); DecodeDepthNormal(depthNormal, depthValue, normalValue); // 或单独解析深度纹理得到深度值 depthValue = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv)); // 把深度画出来 //return fixed4(depthValue, depthValue, depthValue, 1.0); // 把法线画出来 //return fixed4(normalValue, 1.0); // 一起画出来 return depthNormal; } ENDCG } } }
几个应用:
1.类似绝地求生里的毒圈一样的场景扫描线
2.边缘检测描边
3.高度雾(与场景雾不同)
4.环境光遮蔽(AO)SSAO算法 屏幕空间环境光遮蔽 - 知乎 (zhihu.com)