チキン シェーダー: L11 UV アニメーションの移動、回転、スケーリング、混合のアプリケーション

UVアニメーション - 翻訳

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

コード

Shader "shader forge/L19_Translate"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        _Opacity ("Opacity",Range(0,1)) = 0.5
        _TransRange ("Translate Range", Range(0,1)) = 2
        _TransSpeed ("Translate Speed", Range(0,1)) = 2
    }
    SubShader
    {
    
    
        Tags {
    
    
            "Queue"="Transparent" 
            "RenderType" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        Pass
        {
    
    
            Blend One OneMinusSrcAlpha		//AB

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag            
            #pragma multi_compile_fwdbase_fullshadow

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

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

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_ST;
            uniform half _Opacity;
            uniform half _TransRange;
            uniform half _TransSpeed;

            #define TWO_PI 2 * 3.1415926

            void Translate(inout float3 vertex1){
    
    
                vertex1.y += _TransRange * sin(frac(_Time.z * _TransSpeed)* TWO_PI);
            }

            v2f vert (appdata v)
            {
    
    
                v2f o;
                Translate(v.vertex.xyz);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                // sample the texture
                half4 var_MainTex = tex2D(_MainTex, i.uv);
                half3 finalRGB = var_MainTex.rgb;
                half opacity = _Opacity * var_MainTex.a;
                return half4(finalRGB * opacity , opacity);
            }
            ENDCG
        }
    }
}

最終効果

ここに画像の説明を挿入

ここに画像の説明を挿入

UVアニメーション - 回転

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

コード

Shader "shader forge/L19_Rotate"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        _Opacity ("Opacity",Range(0,1)) = 0.5
        _RotateRange ("Rotate Range", Range(0,50)) = 2
        _RotateSpeed ("Rotate Speed", Range(0,1)) = 2
    }
    SubShader
    {
    
    
        Tags {
    
    
            "Queue"="Transparent" 
            "RenderType" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        Pass
        {
    
    
            Blend One OneMinusSrcAlpha		//AB

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag            
            #pragma multi_compile_fwdbase_fullshadow

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

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

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_ST;
            uniform half _Opacity;
            uniform half _RotateRange;
            uniform half _RotateSpeed;

            #define TWO_PI 2 * 3.1415926

            void Rotate(inout float3 vertex1){
    
    
                //算出要增加的角度
                float theta = _RotateRange * sin(frac(_Time.z * _RotateSpeed)* TWO_PI);
                //转化为弧度
                float radY = radians(theta);
                float sinY, cosY;
                //算出该弧度的sin和cos值
                sincos(radY,sinY,cosY);
                //根据旋转角度,推算出新的xz的坐标
                vertex1.xz = float2(vertex1.x * cosY - vertex1.z * sinY,vertex1.x * sinY + vertex1.z * cosY);
            }

            v2f vert (appdata v)
            {
    
    
                v2f o;
                Rotate(v.vertex.xyz);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                // sample the texture
                half4 var_MainTex = tex2D(_MainTex, i.uv);
                half3 finalRGB = var_MainTex.rgb;
                half opacity = _Opacity * var_MainTex.a;
                return half4(finalRGB * opacity , opacity);
            }
            ENDCG
        }
    }
}


最終効果

ここに画像の説明を挿入
ここに画像の説明を挿入

UVアニメーション - スケーリング

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

コード

Shader "shader forge/L19_Scale"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        _Opacity ("Opacity",Range(0,1)) = 0.5
        _ScaleRange ("Scale Range", Range(0,1)) = 2
        _ScaleSpeed ("Scale Speed", Range(0,1)) = 2
    }
    SubShader
    {
    
    
        Tags {
    
    
            "Queue"="Transparent" 
            "RenderType" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        Pass
        {
    
    
            Blend SrcAlpha OneMinusSrcAlpha		//AB

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag            
            #pragma multi_compile_fwdbase_fullshadow

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

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

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_ST;
            uniform half _Opacity;
            uniform half _ScaleRange;
            uniform half _ScaleSpeed;

            #define TWO_PI 2 * 3.1415926

            void Scale(inout float3 vertex1){
    
    
                vertex1.xyz *= 1.0 + _ScaleRange * sin(frac(_Time.z * _ScaleSpeed)* TWO_PI);
            }

            v2f vert (appdata v)
            {
    
    
                v2f o;
                Scale(v.vertex.xyz);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                // sample the texture
                half4 var_MainTex = tex2D(_MainTex, i.uv);
                half3 finalRGB = var_MainTex.rgb;
                half opacity = _Opacity * var_MainTex.a;
                return half4(finalRGB * opacity , opacity);
            }
            ENDCG
        }
    }
}

最終効果

ここに画像の説明を挿入
ここに画像の説明を挿入

移動、回転、スケーリングの混合アプリケーション - Ghostly Floating

この部分の原理は上記 3 つを組み合わせたものですが、頂点カラーに基づいて異なる部分の UV アニメーションを処理するという非常に重要なポイントもあります。
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

コード

Shader "shader forge/L19_BlendTRS"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "gray" {
    
    }
        _Opacity ("Opacity",Range(0,1)) = 0.5
        //天使圈缩放。Z是高度校正,因为缩放是基于模型中心进行缩放,这就导致如果不对天使圈进行高度校正,天使圈就会变高或者变低
        _ScaleParams ("Circle Scale  X:Intensity   Y:Speed   Z:jiaozheng", vector) = (0.2, 1.0, 4.5, 0.0)
        //左右扭动。
        _SwingXParams ("X_niudong  X:Intensity   Y:Speed   Z:WaveLength", vector) = (1.0, 3.0, 1.0, 0.0)
        //前后扭动
        _SwingZParams ("Z_niudong  X:Intensity   Y:Speed   Z:WaveLength", vector) = (1.0, 3.0, 1.0, 0.0)
        //上下起伏
        _SwingYParams ("Y_qifu  X:Intensity   Y:Speed   Z:Delay", vector) = (1.0, 3.0, 1.0, 0.0)
        //摇头
        _ShakeYParams ("Y_yaotou  X:Intensity   Y:Speed   Z:Delay", vector) = (20.0, 3.0, 0.3, 0.0)
    }
    SubShader
    {
    
    
        Tags {
    
    
            "Queue"="Transparent" 
            "RenderType" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        Pass
        {
    
    
            Blend One OneMinusSrcAlpha		//AB

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag            
            #pragma multi_compile_fwdbase_fullshadow

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float4 color1 : COLOR;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                float4 color1 : COLOR;
                float4 vertex : SV_POSITION;
            };

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_ST;
            uniform half _Opacity;
            uniform half3 _ScaleParams;
            uniform half3 _SwingXParams;
            uniform half3 _SwingZParams;
            uniform half3 _SwingYParams;
            uniform half3 _ShakeYParams;

            #define TWO_PI 2 * 3.1415926
            //顶点动画方法
            void AnimGhost(inout float3 vertex1, inout float3 color){
    
    
                //天使圈缩放,天使圈能缩放的范围只有顶点色为绿色的部分,所以要乘颜色的g通道
                float scale = _ScaleParams.x * color.g * sin(frac(_Time.z * _ScaleParams.y) * TWO_PI);
                //天使圈的xyz都发生缩放,加一是为了不让缩放发生颠倒
                vertex1.xyz *= 1.0 + scale;
                //对天使圈的高度进行校正,使它不会上下移动,并且是在原点以上的区域内进行缩放
                vertex1.y += _ScaleParams.z * -scale;

                //幽灵身体摆动,身体也就是顶点色为红色的部分
                //跟每个顶点的高度有关,每个顶点的高度是不一样的,所以波动的大小也是不一样的
                float swingX = _SwingXParams.x * sin(frac(_Time.z * _SwingXParams.y + vertex1.y * _SwingXParams.z) * TWO_PI);       
                //同上
                float swingZ = _SwingZParams.x * sin(frac(_Time.z * _SwingZParams.y + vertex1.y * _SwingZParams.z) * TWO_PI);
                vertex1.xz += float2(swingX, swingZ) * color.r;

                //幽灵摇头,天使圈的摇动滞后
                float radY = radians(_ShakeYParams.x) * (1.0 - color.r) * sin(frac(_Time.z * _ShakeYParams.y - color.g * _ShakeYParams.z) * TWO_PI);
                float sinY, cosY = 0;
                sincos(radY,sinY,cosY);
                vertex1.xz = float2(vertex1.x * cosY - vertex1.z * sinY,vertex1.x * sinY + vertex1.z * cosY);

                //整体起伏动画,同样,天使圈的起伏滞后
                float swingY = _SwingYParams.x * sin(frac(_Time.z * _SwingYParams.y - color.g * _SwingYParams) * TWO_PI);
                vertex1.y += swingY;

                //处理顶点色,主要是为了增加天使圈的动画效果,让它变亮且闪烁(scale的值有时为-1,那lightness就为0,就闪烁),其他区域则保持不变
                float lightness = 1.0 + color.g * 1.0 + scale * 2.0;
                color = float3(lightness, lightness,lightness);
            }

            v2f vert (appdata v)
            {
    
    
                v2f o;
                AnimGhost(v.vertex.xyz, v.color1.rgb);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.color1 = v.color1;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                // sample the texture
                half4 var_MainTex = tex2D(_MainTex, i.uv);
                half3 finalRGB = var_MainTex.rgb * i.color1.rgb;
                half opacity = _Opacity * var_MainTex.a;
                return half4(finalRGB * opacity , opacity);
            }
            ENDCG
        }
    }
}

最終効果

ここに画像の説明を挿入

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43789369/article/details/131832542