Unity/수업 내용

[Unity 2020.3] Water Shader

JSH1 2021. 11. 26. 17:50

 

Shader "Custom/Water"
{
    Properties
    {
        _BumpTex ("Normal Map", 2D) = "bump" {}
        _Cube ("Cube Map", Cube) = "" {}
        _Alpha ("Alpha", Range(0, 1)) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }

        GrabPass{}

        CGPROGRAM

        #pragma surface surf _WaterSpecular alpha:fade vertex:vert

        sampler2D _BumpTex;

        sampler2D _GrabTexture;
        samplerCUBE _Cube;

        struct Input
        {
            float4 color:COLOR;
            float2 uv_BumpTex;
            float3 worldRefl; INTERNAL_DATA
            float viewDir;
            float4 screenPos;
        };

        float _Alpha;

        void vert(inout appdata_full v)
        {
            float movement;
            float waveLength = 20;
            float waveTiming = 1;
            float waveHeight = 0.25;
            movement = sin (abs (v.texcoord.x * 2 - 1) * waveLength  + _Time.y * waveTiming) * waveHeight;
            movement += sin (abs (v.texcoord.y * 2 - 1) * waveLength  + _Time.y * waveTiming) * waveHeight;
            v.vertex.y += movement / 2;
		}

        void surf (Input IN, inout SurfaceOutput o)
        {
            float3 n1 = UnpackNormal(tex2D(_BumpTex, IN.uv_BumpTex + _Time.x * 0.1));
            float3 n2 = UnpackNormal(tex2D(_BumpTex, IN.uv_BumpTex - _Time.x * 0.1));
            float3 n = (n1 + n2) / 2;
            o.Normal = n;

            float3 reflectionColor = texCUBE(_Cube, WorldReflectionVector(IN, o.Normal));

            float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
            float4 refraction = tex2D(_GrabTexture, screenUV + o.Normal.xy * 0.1);

            //프레넬공식 rim = dot(N, V)
            //반전 1 - rim 
            //알파에다가 적용한다 
            //바라보는 곳일수록 투명해진다 
            float rim = max( 0, dot(o.Normal, IN.viewDir));
            rim = pow(1 - rim, 2);

            //reflectionColor * rim : 시선에 가까울수록 반사가 줄어들게 만듬 
            o.Emission = (reflectionColor * rim + refraction) * 0.5;// * 2;
            o.Alpha = _Alpha;//rim + 0.5;
        }

        float4 Lighting_WaterSpecular(SurfaceOutput o, float3 lightDir, float3 viewDir, float atten)
        {
            float h = normalize (lightDir + viewDir);
            float spec = max (0, dot (o.Normal, h));
            spec = pow (spec, 30);

            float4 finalColor;
            finalColor.rgb = spec * float4 (1, 1, 1, 1) * 2;
            finalColor.a = o.Alpha;// + spec;

            return finalColor;
		}

        ENDCG
    }
    FallBack "Diffuse"
}