美文网首页
三、效果实现:8、水(3)流动起来

三、效果实现:8、水(3)流动起来

作者: GameObjectLgy | 来源:发表于2021-02-26 10:17 被阅读0次

原理:显示泡沫,让泡沫流动起来,看起来水就像流动起来。

Shader "Customer/Water01"
{
    Properties
    {
        _Color("Color水颜色", color) = (0,0,0.8,0.5)
        _WaveNormalMap("Wave Normal Map", 2D) = "bump"{}
        _WaveHeight("Wave Height",Range(0,1)) = 0.1
        _WaveNormalScale("Wave Scale", float) = 10.0
        _WaveNormalSpeed("Wave Speed", float) = 1.0
        _waveNumber("Wave Number",float) = 4
        _BigWaveSpeed("Big Wave Speed",float) = 10
        _BigWaveHeight("Big Wave Height",float) = 0.5
        _BigWaveNumber("Big Wave Number",float) = 10
        _Opacity("不透明度", range(0, 1)) = 0.5

        _FoamTex("Foam Texture", 2D) = "white" {}
        _FoamSpeed("FormSpeed",float) = 0.1
    }
        SubShader
        {
            Tags
            {
                "Queue" = "Transparent"
                "RenderType" = "Transparent"
            }
            GrabPass{
                "_GrabPassTex"
            }
            LOD 100

            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                #include "UnityCG.cginc"
                #include "Lighting.cginc" 
                #pragma multi_compile_fog

                float4 _Color;
                sampler2D _WaveNormalMap;
                float4 _WaveNormalMap_ST;
                fixed _WaveHeight;
                float _WaveNormalScale;
                fixed _WaveNormalSpeed;
                fixed _waveNumber;

                fixed _dividHeight;
                fixed _BigWaveSpeed;
                fixed _BigWaveHeight;
                fixed _BigWaveNumber;

                // 输入参数
                float4 _MainTex_ST;
                uniform half _Opacity;

                sampler2D _GrabPassTex;//用于渲染透明物体
                uniform sampler2D_float _CameraDepthTexture;

                sampler2D _FoamTex;//泡沫噪声
                float _FoamSpeed;//泡沫流动速度
                float4 _FoamTex_ST;//泡沫Tiling

                // 输入结构
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                    float3 normal:NORMAL;//法线通常都是必须的
                    float4 tangent : TANGENT;
                    float3 color:COLOR0;
                };
                // 输出结构
                struct v2f
                {
                    float4 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;   // 由模型顶点信息换算而来的顶点屏幕位置
                    float depth : TEXCOORD2;
                    float3 normal:NORMAL;//法线通常都是必须的
                    float4 lightDir_Tangent:TEXCOORD5;
                    float4 screenuv:TEXCOORD1;
                    float3 viewDir:TEXCOORD3;
                    float4 vertex_Local : TEXCOORD4;
                    float3 color:COLOR0;
                };

                // 输入结构>>>顶点Shader>>>输出结构
                v2f vert(appdata v)
                {
                    //v2f o;
                    v2f o = (v2f)0;
                    UNITY_INITIALIZE_OUTPUT(v2f, o);
                    //获取自身深度值
                    COMPUTE_EYEDEPTH(o.depth);

                    float2 flow = float2(_Time.x * _WaveNormalSpeed, _Time.z * 1.215 * _WaveNormalSpeed);

                    fixed3 n = UnpackNormal(tex2Dlod(_WaveNormalMap, float4(v.uv.xy * _WaveNormalScale + flow, 0, 0))).xyz;
                    //float tempN = tex2Dlod(_WaveNormalMap, float4(v.uv.xy*_WaveNormalScale + flow, 0, 0)).g;这种写法也可以,当然下面的高度也要用下面这句
                    //v.vertex.y = v.vertex.y + tempN * _WaveHeight + height;

                    float height = 0;

                    fixed wavebevel = 5;

                    fixed attenuation = (1.0 - v.uv.y);

                    fixed b = 0.8;
                    fixed x = v.uv.y + b * sin(v.uv.y);
                    if (v.vertex.y > _dividHeight)
                    {
                        height = (cos(x * _BigWaveNumber - _Time.z * _BigWaveSpeed + v.uv.x * wavebevel) + 1) * 0.5 * _BigWaveHeight * attenuation;
                        height += (cos(x * _BigWaveNumber - _Time.z * _BigWaveSpeed + (1.0 - v.uv.x) * wavebevel) + 1) * 0.5 * _BigWaveHeight * attenuation;
                    }
                    v.vertex.y = v.vertex.y + n * _WaveHeight + height;


                    if (v.vertex.y > _dividHeight)
                        v.vertex.z -= height * 0.1;

                    o.vertex = UnityObjectToClipPos(v.vertex);
                    //rotation
                    TANGENT_SPACE_ROTATION;
                    o.lightDir_Tangent.xyz = mul(rotation, ObjSpaceLightDir(v.vertex));
                    o.normal = v.normal;//得到法线,很重要

                    //屏幕UV
                    o.screenuv = ComputeScreenPos(o.vertex);// 背景纹理采样坐标
                    o.viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
                    o.viewDir = mul(rotation, mul(o.viewDir, unity_ObjectToWorld));//得到视方向
                     //本地空間位置
                    o.vertex_Local = v.vertex;
                    o.color = v.color;

                    //UV
                    //o.uv.xy = TRANSFORM_TEX(v.uv, _FoamTex);//白沫噪声纹理采样
                    o.uv.zw = TRANSFORM_TEX(v.uv, _WaveNormalMap);
                    //UNITY_TRANSFER_FOG(o, o.vertex);
                    return o;
                }

                // 输出结构>>>像素
                fixed4 frag(v2f i) : COLOR
                {
                    //屏幕深度Z
                    float ScreenZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenuv)));
                    //float4 finalCol = _Color;
                    fixed mask = dot(i.normal, float3(0, -1, 0)) + 0.5;
                    mask = mask > 0.2 ? 0 : 1;

                    float2 flow = float2(_Time.x * _WaveNormalSpeed, _Time.z * 1.215 * _WaveNormalSpeed);
                    fixed3 tangentNormal = UnpackNormal(tex2D(_WaveNormalMap, i.uv.zw * _WaveNormalScale + flow)).xyz;
                    tangentNormal.xy = tangentNormal.xy * 10;
                    fixed3 normal = normalize(tangentNormal);//法线

                    //越近越白
                    fixed d = clamp(1.0 - (abs(i.depth - ScreenZ) * 0.5), 0, 1);

                    //灯光方向
                    fixed3 world_lightDir = normalize(-_WorldSpaceLightPos0.xyz);
                    fixed3 world_normal = normalize(mul(unity_ObjectToWorld, normal));//
                    fixed3 world_normal_self = normalize(mul((float3x3)unity_ObjectToWorld, i.normal));
                    fixed3 n = mask > 0 ? world_normal : world_normal_self;
                    fixed3 diffuse = dot(world_lightDir, n) * 0.5 + 0.5;
                    //计算灯光反射
                    fixed3 reflectDir = reflect(i.lightDir_Tangent, normal);
                    //高光
                    fixed3 specular = max(pow(max(0, dot(i.viewDir, reflectDir)), 70), 0) * (1.0 - d);
                    float4 finalCol = fixed4(diffuse, 0);
                    //Grab Tex
                    fixed4 grabCol;
                    grabCol = tex2D(_GrabPassTex, i.screenuv.xy / i.screenuv.w);
                    //深色
                    grabCol = lerp(grabCol, lerp(grabCol, _Color, _Color.a), _Opacity);

                    fixed2 waveUV = i.uv.xy;

                    finalCol = grabCol;
                    if (mask > 0)
                        finalCol.rgb += specular * 2;

                    return finalCol * _LightColor0;
                }
            ENDCG
        }
        }
}

相关文章

网友评论

      本文标题:三、效果实现:8、水(3)流动起来

      本文链接:https://www.haomeiwen.com/subject/gnvlfltx.html