Unity学习之Shader Water

Shader "URP/Water"
{
    Properties
    {
        _ShallowWater ("shallowColor", Color) = (1.0, 1.0, 1.0, 1.0)
        _DeepWater ("DeepColor", Color) = (1.0, 1.0, 1.0, 1.0)
        _WaterAlpha("WaterAlpha",Range(0,1)) = 0.5
        
        _SurfaceNoise("Surface Noise", 2D) = "white" {}
        _MoveSpeed("MoveSpeed",Range(0,1)) = 0.5
        
        _FoamDistance("Foam Distance",Range(0,10)) = 0.4
        _FoamColor("FoamColor", Color) = (1.0, 1.0, 1.0, 1.0)
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Transparent"
            "Queue"="Transparent"
        }
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
            
            float4 _ShallowWater;
            float4 _DeepWater;
            float _WaterAlpha;

            sampler2D _SurfaceNoise;
            float4 _SurfaceNoise_ST;
            float _MoveSpeed;
            
            float _FoamDistance;
            float4 _FoamColor;

            // 顶点着色器的输入
            struct a2v
            {
                float3 positionOS : POSITION;
                float4 uv : TEXCOORD0;
            };

            // 顶点着色器的输出
            struct v2f
            {
                float4 positionCS : SV_POSITION;
                float4 screenPosition : TEXCOORD0;
                float2 noiseUV : TEXCOORD1;
                float2 distortUV : TEXCOORD2;
            };
            
            v2f vert(a2v v)
            {
                v2f o;
                VertexPositionInputs positionInputs = GetVertexPositionInputs(v.positionOS);
                o.positionCS = positionInputs.positionCS;
                o.noiseUV = TRANSFORM_TEX(v.uv, _SurfaceNoise);
                o.screenPosition = ComputeScreenPos(positionInputs.positionCS);
                return o;
            }
            
            half4 frag(v2f i) : SV_Target
            {
                // 通过深度纹理的采样 计算屏幕深度
                float sceneRawDepth = SampleSceneDepth(i.screenPosition.xy / i.screenPosition.w);
                // 深度纹理的采样结果转换到视图空间下的深度值
                float sceneEyeDepth = LinearEyeDepth(sceneRawDepth, _ZBufferParams);
                // 因为关心的是这个深度值相对于我们的水面有多深,所以需要把视图深度,减去模型顶点的深度
                // 最终得到水的深度
                float waterDepth = sceneEyeDepth - i.screenPosition.w; 
                // 拿到水的颜色
                float3 waterColor = lerp(_ShallowWater, _DeepWater, waterDepth);
                
                float surfaceNoiseSample = tex2D(_SurfaceNoise, i.noiseUV + _Time.y * _MoveSpeed * 0.1).r;
                
                // 浮沫
                float foam = saturate(waterDepth / _FoamDistance);
                float surfaceNoise = smoothstep(0, foam, surfaceNoiseSample) ;
                // 混合水面透明度
                float4 col = float4(waterColor + surfaceNoise * _FoamColor, _WaterAlpha) ;
                return col;
            }
            ENDHLSL
        }
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值