Unity Shader中获取像素点深度信息
1.顶点着色器中对深度进行计算
v2f vert(appdata v)
{v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.depth = (o.pos.z / o.pos.w + 1.0) * 0.5; // Normalize depth to [0, 1]return o;
}
但是达不到预期,最后返回的值一直大于1。2.片元着色器中使用深度纹理
sampler2D _CameraDepthTexture;fixed4 frag(v2f i) : SV_Target
{float depth = tex2D(_CameraDepthTexture, i.uv).r;return float4(depth, 0, 0, 1);
}
补充一句:
如果您手动获取深度 (Z) 缓冲区值,您可能需要检查缓冲区方向。下面是一个例子:
float z = tex2D(_CameraDepthTexture, uv);
#if defined(UNITY_REVERSED_Z)z = 1.0f - z;
#endif
之后才符合距离摄像机越远,深度值越大。
关于深度信息的一些补充:
特效:
unity中特效使用的默认着色器,无法通过摄像机绘制到RenderTexture,在网上看到了对应的解释,
[Unity] RenderTexture上不显示粒子_unity 粒子特效显示不全-CSDN博客
尝试新建着色器发现,修改ColorMask RGBA之后:
只有需要使用的是深度RT时,需要将ZWrite打开,才可以正常绘制。
好像ColorMask不会影响到输出RT,如果有了解的大佬可以讲一下。
下面是我本地为粒子特效重写的shader:
Shader "Custom/ParticleShader"
{Properties{_MainTex("Texture", 2D) = "white" {}_Color("Color", Color) = (1,1,1,1)}SubShader{Tags{"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent""PreviewType" = "Plane"}Blend SrcAlpha OneMinusSrcAlpha // 设置混合模式ColorMask RGBACull OffLighting Off//ZWrite OffPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;float4 _Color;struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};v2f vert(appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv) * _Color;//if (col.a <= 0)// discard;return col;}ENDCG}}
}