Unity water shader with depth and distortion

PHOTO EMBED

Thu Mar 10 2022 17:49:35 GMT+0000 (Coordinated Universal Time)

Saved by @BryanJ22

Shader "Water/SimpleWater"
{
    Properties
    {
        [Header(Appearance)] [Space]
        _MainTex ("Water Texture", 2D) = "white" {}
        [Space]
        _Color("Tint", Color) = (1,1,1,1)
        _Emission("Emissive Color", Color) = (0.1886792,0.1486294,0.1486294,1)
        _Opacity("Opacity", Range(0,1)) = .85

        [Header(Wave Distortion)] [Space]
        _NoiseTex("Noise Texture", 2D) = "white" {}
        [Space]
        _NoiseSize("Noise Fineness", Range(0.01, 1)) = 0.126
        _Frequency("Frequency", Range(2, 0.2)) = 0.5
        _Intensity("Intensity", Range(0.0002, .0035)) = 0.002
        _Containment("Containment", Range(0.22, 2.5)) = 0.73

        [Header(Movement)][Space]
        _HorizontalSpeed("Horizontal Speed", Range(0, 20)) = 12
        _VerticalSpeed("Vertical Speed", Range(0, 20)) = 2
        [Space]

        //Create a dropdown of Enum values and their numeric equivalents
        [Enum(Left,0,Right,2)] _HorizontalDirection("Horizontal Direction", Float) = 0
        [Enum(Down,0,Up,2)] _VerticalDirection("Vertical Direction", Float) = 0

        [Header(Wave Behavior)][Space]
        _WaveFrequency("Frequency", Range(0, 1.6)) = 0.4
        _WaveSpeed("Speed", Range(0,10)) = 5
        _WaveHeight("Height", Range(0,1)) = .16

        [Header(Underwater Fog)][Space]
        _WaterFogDensity("Fog Density", Range(0.3,4)) = 1.3

        [Header(Underwater Distortion)][Space]
        _RefractionStrength("Distrortion Strength", Range(0,1)) = 0.5
    }
    SubShader
    {
        Tags {"Queue" = "Transparent" "RenderType"="Transparent" }
        LOD 200

        //Use Grabpass to get background color
        //Reduce GrabPass to single draw call giving grabbed texture explicit name, which is set in WaterMaths.cginc
        GrabPass{"_WaterBackground"}

        CGPROGRAM
  
        //include our cginc file
        #include "WaterMaths.cginc"

        //Physically based Standard lighting model, and enable shadows on all light types
        //use ResetAlpha function of finalcolor type to reset alpha value
        #pragma surface surf StandardSpecular alpha fullforwardshadows vertex:CreateWaves finalcolor:ResetAlpha

        //Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        fixed4 _Color, _Emission;
        sampler2D _MainTex, _NoiseTex;
        half _HorizontalSpeed, _VerticalSpeed;
        half _Opacity;
        float _HorizontalDirection;
        float _VerticalDirection;

        half _NoiseSize, _Frequency, _Intensity, _Containment;
        half _WaveFrequency, _WaveSpeed, _WaveHeight;

        //time var set in our buoyancy c# script so floating objects and waves are in sync
        float _time;

        struct Input
        {
            float2 uv_MainTex;

            //for grabbing screen uv
            half4 screenPos;
        };

        void CreateWaves(inout appdata_full v)
        {
            //if in editor mode, set _time var to built in _Time variable since it can't be set in script
            if (!_time)
                _time = _Time.y;

            //Create Waves math
            //multiply time var with wave speed var to get speed
            half speed = _time * _WaveSpeed;
            half4 wpos = mul(unity_ObjectToWorld, v.vertex);
            float waveValueA = sin(speed + wpos.x * _WaveFrequency) * _WaveHeight;
            wpos.y += waveValueA;
            v.vertex = mul(unity_WorldToObject, wpos);
            v.normal.x += waveValueA * .03f;
            //
        }

        void surf (Input IN, inout SurfaceOutputStandardSpecular o)
        {
            //offset the _HorizontalDirection/_VerticalDirection variables to give -1 or 1,
            //since Enum values can not be negative and we need negative values to change texture scroll direction
            int Xfloat = _HorizontalDirection - 1;
            int Zfloat = _VerticalDirection - 1;
            //

            //Scrolling texture
            fixed2 ScrolledUV = IN.uv_MainTex;
            fixed MoveX = _HorizontalSpeed * Xfloat *  _Time;
            fixed MoveZ = _VerticalSpeed * Zfloat * _Time;
            ScrolledUV += fixed2(MoveX, MoveZ);
            //

            //Grab updated water text that has been moved using ScrolledUV
            //and grab noise texture but use the water texture UV's
            fixed4 waterTex = tex2D(_MainTex, ScrolledUV);
            fixed4 noise = tex2D(_NoiseTex, ScrolledUV * _NoiseSize);

            half waterDistortion = 
                DistortWater
                (
                    half(_Time[1]) + (noise.xy) * _Containment, 
                    half(-_Intensity), 
                    half(_Intensity), 
                    half(_Frequency));


            fixed4 finalColor = tex2D(_MainTex, (ScrolledUV * .18) + waterDistortion * 5) * _Color;

            // Albedo comes from a texture tinted by color
            o.Albedo = finalColor.rgb;
            o.Alpha = _Opacity;
            o.Emission = _Emission * ColorBelowWater(IN.screenPos, o.Albedo);
        }

        void ResetAlpha(Input IN, SurfaceOutputStandardSpecular o, inout fixed4 color)
        {
            color.a = 1;
        }

        ENDCG
    }
}
content_copyCOPY

Water shader for Unity that includes depth based alpha, moving vertices to create waves and image distortion.