# 【水深】

  1. 设置为半透明材质
  2. 关闭深度写入
  3. 设置材质灯光属性CastShadows和ReceiveShadows为Off
  4. 设置摄像机写入深度贴图Camera.main.depthTextureMode = DepthTextureMode.Depth;

Markdown 图片

Markdown 图片

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;
}