Unity Shader - 实现类似UI遮罩流光

运行效果

Unity Shader - 实现类似UI遮罩流光_第1张图片

思路

  • 准备流光图
  • 准备流光遮罩图
  • 主要显示纹理

流光图(我用GIMP随便画的,还是PS好用)
Unity Shader - 实现类似UI遮罩流光_第2张图片

流光遮罩图
Unity Shader - 实现类似UI遮罩流光_第3张图片

主纹理
Unity Shader - 实现类似UI遮罩流光_第4张图片

先是实现流光划过
Unity Shader - 实现类似UI遮罩流光_第5张图片

就是控制流光图的UV偏移

但是这样太丑了,所以我们还是对流光部分应用在需要流光上的像素,需要需要遮罩图。

这遮罩将以亮度(灰度)来过渡,大于0的才会被流光到。

最后,就是一开始时的效果图了

完整Shader

// jave.lin 2019.08.11
Shader "Test/Flash" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
        [NoScaleOffset] _FlashTex ("FlashTex", 2D) = "white" {}
        [NoScaleOffset] _FlashMaxTex ("FlashMaskTex", 2D) = "white"{}
        _Percent("Percent", Range(0, 1)) = 0
    }
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            struct appdata {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct v2f {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _FlashTex;
            sampler2D _FlashMaxTex;
            float _Percent;
            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }
            fixed4 frag (v2f i) : SV_Target {
                float x = _Percent * 2 - 1; // _Percent是0~1的,我们转换为-1~1
                fixed4 flash = tex2D(_FlashTex, i.uv + fixed2(-x, 0));
                fixed flash_mask = tex2D(_FlashMaxTex, i.uv).r;
                flash *= flash.a * flash_mask;
                fixed4 col = tex2D(_MainTex, i.uv) + flash;
                return col;
            }
            ENDCG
        }
    }
}

如果不想手动控制流光,想让流光无限循环播放,可以将 Percent 变量用 _Time.y 来替代,如下:

// jave.lin 2019.08.11
Shader "Test/Flash" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
        [NoScaleOffset] _FlashTex ("FlashTex", 2D) = "white" {}
        [NoScaleOffset] _FlashMaxTex ("FlashMaskTex", 2D) = "white"{}
    }
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            struct appdata {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct v2f {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _FlashTex;
            sampler2D _FlashMaxTex;
            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }
            fixed4 frag (v2f i) : SV_Target {
                fixed4 flash = tex2D(_FlashTex, i.uv + fixed2(-_Time.y, 0));
                fixed flash_mask = tex2D(_FlashMaxTex, i.uv).r;
                flash *= flash.a * flash_mask;
                fixed4 col = tex2D(_MainTex, i.uv) + flash;
                return col;
            }
            ENDCG
        }
    }
}

  • TestingUIFlowLight.unitypackage
  • mob-sakai/ShinyEffectForUGUI

你可能感兴趣的:(unity,unity-shader,Unity,Shader,Unity,Shader,UI流光)