# 【水深】
- 设置为半透明材质
- 关闭深度写入
- 设置材质灯光属性CastShadows和ReceiveShadows为Off
- 设置摄像机写入深度贴图
Camera.main.depthTextureMode = DepthTextureMode.Depth;
Shader "WaterShader2"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Transparent" }
ZWrite Off
Pass
{
Name "Unlit"
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 posWS : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
};
UNITY_DECLARE_DEPTH_TEXTURE( _CameraDepthTexture );
v2f vert ( appdata v )
{
v2f o;
float4 clipPos = UnityObjectToClipPos(v.vertex);
float4 screenPos = ComputeScreenPos(clipPos);
o.texcoord1 = screenPos;
o.vertex = clipPos;
o.posWS = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
float waterDepth(float4 screenPos,float3 posWS)
{
float4 screenPosNorm = screenPos / screenPos.w;
float clampDepth = SAMPLE_DEPTH_TEXTURE( _CameraDepthTexture, screenPosNorm.xy );
#ifdef UNITY_REVERSED_Z
float staticSwitch = 1.0 - clampDepth;
#else
float staticSwitch = clampDepth;
#endif
float3 screenUV = float3(screenPosNorm.x , screenPosNorm.y , staticSwitch);
float4 temp1 = mul( unity_CameraInvProjection, float4((screenUV*2.0 + -1.0) , 1.0) );
float3 temp2 = ( temp1.xyz / (temp1).w ) * float3(1,1,-1);
float waterDepth = posWS.y - (mul( unity_CameraToWorld, float4(temp2 , 1.0) )).y;
return waterDepth;
}
fixed4 frag (v2f i ) : SV_Target
{
float4 screenPos = i.texcoord1;
float wd = waterDepth(screenPos,i.posWS);
fixed4 finalColor;
finalColor = (wd).xxxx;
return finalColor;
}
ENDCG
}
}
}
TIP
// 深度转世界坐标
float3 depthToWorldPosition(float4 screenPos)
{
float depth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture.screenPos)));
float4 ndcPos = screenPos / screenPos.w;
ndcPos = ndcPos * 2.0 - 1.0; // map [0,1] => [-1,1]
float3 clipPos = float3(ndcPos.x, ndcPos.y, 1.0) * _ProjectionParams.z; // z = far plane = mvp result w
float3 viewPos = mul(unity_CameraInvProjection, clipPos.xyzz).xyz * depth;
float3 worldPos = mul(UNITY_MATRIX_I_V, float4(viewPos,1.0)).xyz;
return worldPos;
}