Shader笔记——5.Shader动画

Shader动画

在Unity Shader中引入时间变量_Time,_SinTime,_CosTime,unity_DeltaTime等内置变量来获取在Shader中获取运行时间,就可以来实现各种动画效果

纹理动画

我们可以使用纹理动画来代替复杂的粒子系统等来模拟各种动画效果。

序列帧动画

最常见的纹理动画之一就是序列帧动画


Shader "Custom/SequenceAnime" {
    Properties{
        _Color ("Color Tint" , Color) = (1,1,1,1)
        _MainTex ("Sequence Image" , 2D) = "white" {}
        _HorizontalAmount ("Horizontal Amount" , Float) = 4
        _VerticalAmount ("Vertical Amount" ,Float) = 4
        _Speed ("Anime Speed" ,Range(1,100)) = 30
    }
    SubShader{
        Tags{
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
        }
        Pass{
            Tags{"LightMode" = "ForwardBase"}
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            float4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _HorizontalAmount;
            float _VerticalAmount;
            float _Speed;

            struct a2v {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (a2v v){
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_TARGET{
                float time = floor(_Time.y * _Speed);
                float row = floor(time / _HorizontalAmount);//当前时间所处行数
                float column = time - row * _HorizontalAmount;//当前时间所处列数

                half2 uv = float2(i.uv.x / _HorizontalAmount , i.uv.y / _VerticalAmount);
                uv.x += column / _HorizontalAmount;//确定当前时间所需要在_MainTex上采样的纹理坐标uv.x
                uv.y -= row / _VerticalAmount;//确定当前时间所需要在_MainTex上采样的纹理坐标uv.y
                
                fixed4 c = tex2D (_MainTex ,uv);
                c.rgb *= _Color;
                return c;
            }
            ENDCG
        }
    }
    Fallback "Transparent/VertexLit"
}

背景循环动画


// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/InfiniteScroll" {
    Properties{
        _MainTex ("Main Tex", 2D) = "white"{}
        _DetailTex ("Detail Tex" ,2D) = "white"{}
        _ScrollX ("Mian Tex Speed" , Float) = 1.0
        _Scroll2X ("Detail Tex Speed" , Float ) = 1.0
        _Multiplier ("Layer Multiplier" , Float) = 1.0
    }
    SubShader{
        Tags{"Queue" = "Geometry" "RenderType" = "Opaque"}
        
        Pass{
            Tags{"LightMode" = "ForwardBase"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _DetailTex;
            float4 _DetailTex_ST;
            float _ScrollX;
            float _Scroll2X;
            float _Multiplier;

            struct a2v{
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f{
                float4 pos : SV_POSITION;
                float4 uv : TEXCOORD0;
            };

            v2f vert (a2v v){
                v2f o;
                o.pos = UnityObjectToClipPos( v.vertex);
        //通过TRANSFORM_TEX对顶点坐标变换得到纹理坐标之后,在其x方向上再进行偏移,并且偏移量随时间变量_Time.y而变化
                o.uv.xy = TRANSFORM_TEX(v.texcoord , _MainTex) + float2(frac(_ScrollX * _Time.y),0);
                o.uv.zw = TRANSFORM_TEX(v.texcoord,_DetailTex) + float2(frac(_Scroll2X * _Time.y) ,0);
                return o;
            }

            fixed4 frag (v2f i) : SV_TARGET{
                fixed4 mainLayer = tex2D(_MainTex , i.uv.xy);
                fixed4 detailLayer = tex2D(_DetailTex , i.uv.zw);

                fixed4 c = lerp(mainLayer,detailLayer,detailLayer.a);
                c.rgb *= _Multiplier;
                return c;

            }
            ENDCG
        }
    }
    Fallback "VertexLit"
}

顶点动画

河流流动动画


// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/WaterWave"{
    Properties{
        _MainTex ("Main Tex" ,2D) = "white"{}
        _Color ("Color Tint" , Color) = (1,1,1,1)
        _Magnitude ("Distortion Magnitude" , Float) = 1
        _Frequency ("Distortion Frequency" ,Float) = 1
        _InvWaveLength ("Distortion Inverse Wave Length" ,Float) = 1
        _Speed ("Speed" ,Float ) = 1
    }
    SubShader{
        Tags{
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
            "DisableBatching" = "True"
        }
        Pass{
            Tags{"LightMode" = "ForwardBase"}
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            Cull Off

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Color;
            float _Magnitude;
            float _Frequency;
            float _InvWaveLength;
            float _Speed;

            struct a2v{
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD;
            };

            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert(a2v v){
                v2f o;

                float4 offset;
                offset.yzw = float3(0,0,0);
                offset.x = sin(_Frequency * _Time.y + v.vertex * _InvWaveLength + v.vertex.y * _InvWaveLength + v.vertex.z * _InvWaveLength ) * _Magnitude;
                
                o.pos = UnityObjectToClipPos(v.vertex + offset);
                
                o.uv = TRANSFORM_TEX(v.texcoord , _MainTex);
                o.uv += float2(0,_Time.y * _Speed);
                return o;
            }

            fixed4 frag(v2f i) :SV_TARGET{
                fixed4 c = tex2D(_MainTex ,i.uv);
                c.rgb *= _Color.rgb;
                return c;
            }
            ENDCG
        }
    }
    Fallback "Transparent/VertexLit"
}

BillBoard广告牌

REF

文档:

https://docs.unity3d.com/Manual/class-RenderTexture.html

书籍:

OpenGL宝典、Unity Shader入门

猜你喜欢

转载自www.cnblogs.com/sylvan/p/11223007.html