Home>

We become indebted to.
Currently, we are in the process of creating a UI screen, but we are thinking of a visual effect for displaying the button that is pressed by the user with more emphasis.

Thing I want to do

It is a production performed with the button of the following Gif video

・ The button expands and contracts periodically
・ The image shining on the button flows from left to right

Of the above two points, the former could be achieved by scaling the scale using Dotween.
However, I am bothered by the way the glowing image on the button scrolls.
I didn't know what to call this expression, and I couldn't find the information I was looking for, so if anyone knows about this expression technique, I would appreciate any hints about the approach.

What i tried

-Place a white diagonal image on top and scroll left or right
Rather than shining inside the button, it looks unnatural as if the texture is crossing from the outside of the button

・ Try a test to display another image based on the built-in shader
The button image is sliced, or the display is strange.

Texture used
  

If i try adding the above image to AddTexture of Material with Shader applied

The image to put on top collapses

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Custom/Twinkle GUI"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _AddTex ("Add Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255
        _ColorMask ("Color Mask", Float) = 15
        [Toggle (UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    }
        SubShader
        {
            Tags
            {"Queue" = "Transparent"
                "IgnoreProjector" = "True"
                "RenderType" = "Transparent"
                "PreviewType" = "Plane"
                "CanUseSpriteAtlas" = "True"
            }
            Stencil
            {
                Ref [_Stencil]
                Comp [_StencilComp]
                Pass [_StencilOp]
                ReadMask [_StencilReadMask]
                WriteMask [_StencilWriteMask]
            }
            Cull Off
            Lighting Off
            ZWrite Off
            ZTest [unity_GUIZTestMode]
            Blend SrcAlpha OneMinusSrcAlpha
            ColorMask [_ColorMask]
            Pass
            {
                Name "Default"
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma target 2.0
                #include "UnityCG.cginc"
                #include "UnityUI.cginc"
                #pragma multi_compile_local _ UNITY_UI_CLIP_RECT
                #pragma multi_compile_local _ UNITY_UI_ALPHACLIP
                struct appdata_t
                {
                    float4 vertex: POSITION;
                    float4 color: COLOR;
                    float2 texcoord: TEXCOORD0;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                };
                struct v2f
                {float4 vertex: SV_POSITION;
                    fixed4 color: COLOR;
                    float2 texcoord: TEXCOORD0;
                    float4 worldPosition: TEXCOORD1;
                    UNITY_VERTEX_OUTPUT_STEREO
                };
                sampler2D _MainTex;
                sampler2D _AddTex;
                fixed4 _Color;
                fixed4 _TextureSampleAdd;
                float4 _ClipRect;
                float4 _MainTex_ST;
                v2f vert (appdata_t v)
                {
                    v2f OUT;
                    UNITY_SETUP_INSTANCE_ID (v);
                    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO (OUT);
                    OUT.worldPosition = v.vertex;
                    OUT.vertex = UnityObjectToClipPos (OUT.worldPosition);
                    OUT.texcoord = TRANSFORM_TEX (v.texcoord, _MainTex);
                    OUT.color = v.color * _Color;
                    return OUT;
                }
                fixed4 frag (v2f IN): SV_Target
                {
                    half4 color = (tex2D (_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
                    half4 color2 = (tex2D (_AddTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
                    #ifdef UNITY_UI_CLIP_RECT
                    color.a * = UnityGet2DClipping (IN.worldPosition.xy, _ClipRect);
                    #endif
                    #ifdef UNITY_UI_ALPHACLIP
                    clip (color.a-0.001);
                    #endif
                    return color2;// Display only the textures that will be posted for testing
                }
            ENDCG
            }
        }
}

If i have any wisdom, thank you.

  • Answer # 1

    I wonder what this glossy expression is ... I'm sorry, but I don't understand the general term.
    As you say,texcoordI think that if I sample the texture using, it will look bad due to Slice.
    As described below,_AddTexAs the sampling position ofworldPositionWhy not try using?

    // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    Shader "Custom/Twinkle GUI"
    {
        Properties
        {
            [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
            _AddTex ("Add Texture", 2D) = "white" {}
            _Color ("Tint", Color) = (1,1,1,1)
            _StencilComp ("Stencil Comparison", Float) = 8
            _Stencil ("Stencil ID", Float) = 0
            _StencilOp ("Stencil Operation", Float) = 0
            _StencilWriteMask ("Stencil Write Mask", Float) = 255
            _StencilReadMask ("Stencil Read Mask", Float) = 255
            _ColorMask ("Color Mask", Float) = 15
            [Toggle (UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
        }
        SubShader
        {
            Tags
            {
                "Queue" = "Transparent"
                "IgnoreProjector" = "True"
                "RenderType" = "Transparent"
                "PreviewType" = "Plane"
                "CanUseSpriteAtlas" = "True"
            }
            Stencil
            {
                Ref [_Stencil]
                Comp [_StencilComp]
                Pass [_StencilOp]
                ReadMask [_StencilReadMask]
                WriteMask [_StencilWriteMask]
            }
            Cull Off
            Lighting Off
            ZWrite OffZTest [unity_GUIZTestMode]
            Blend SrcAlpha OneMinusSrcAlpha
            ColorMask [_ColorMask]
            Pass
            {
                Name "Default"
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma target 2.0
                #include "UnityCG.cginc"
                #include "UnityUI.cginc"
                #pragma multi_compile_local _ UNITY_UI_CLIP_RECT
                #pragma multi_compile_local _ UNITY_UI_ALPHACLIP
                struct appdata_t
                {
                    float4 vertex: POSITION;
                    float4 color: COLOR;
                    float2 texcoord: TEXCOORD0;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                };
                struct v2f
                {
                    float4 vertex: SV_POSITION;
                    fixed4 color: COLOR;
                    float2 texcoord: TEXCOORD0;
                    float4 worldPosition: TEXCOORD1;
                    UNITY_VERTEX_OUTPUT_STEREO
                };
                sampler2D _MainTex;
                sampler2D _AddTex;
                fixed4 _Color;
                fixed4 _TextureSampleAdd;
                float4 _ClipRect;
                float4 _MainTex_ST;
                float4 _AddTex_ST;// receive tiling offset of _AddTex
                v2f vert (appdata_t v)
                {
                    v2f OUT;
                    UNITY_SETUP_INSTANCE_ID (v);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO (OUT);
                    OUT.worldPosition = v.vertex;
                    OUT.vertex = UnityObjectToClipPos (OUT.worldPosition);
                    OUT.texcoord = TRANSFORM_TEX (v.texcoord, _MainTex);
                    OUT.color = v.color * _Color;
                    return OUT;
                }
                fixed4 frag (v2f IN): SV_Target
                {
                    half4 color = (tex2D (_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
                    // Try sampling using x and y of worldPosition
                    // If you do it through TRANSFORM_TEX, "Tiling" and "Offset" in the material inspector will be effective
                    // If applied to the UI, Tiling is the reciprocal of the Pixels Per Unit of the UI texture ... If it is 100, 0.01 is probably reasonable?
                    // It's a good idea to adjust Offset as well so that the joints between textures do not look unnatural
                    // If you operate Offset from a script, I think that gloss animation can be done
                    half4 color2 = (tex2D (_AddTex, TRANSFORM_TEX (IN.worldPosition.xy, _AddTex)) + _TextureSampleAdd) * IN.color;
                    #ifdef UNITY_UI_CLIP_RECT
                    color.a * = UnityGet2DClipping (IN.worldPosition.xy, _ClipRect);
                    #endif
                    #ifdef UNITY_UI_ALPHACLIP
                    clip (color.a-0.001);
                    #endif
                    // return color2;// Display only the texture to be put in for the test once
                    // try to add color2 to the base color
                    color.rgb + = color2.rgb * color2.a;
                    return color;
                }
            ENDCG
            }
        }
    }

    The appearance of the offset operation is shown below. The Wrap Mode of glossy texture is set to Clamp.

      

    worldPositionOne of the harmful effects of using is that the way the gloss is applied changes depending on the position of the button on the screen. You may need to make some adjustments such as adjusting the Offset according to the coordinates of the button on the script side.
    If you have a small number of buttons, you may want to create a material object for each button and control the Offset individually, but if you have a large number of buttons, it is more efficient to give the shift amount in MaterialPropertyBlock. It may be.

    Alternatively, I think it is a good idea to allow gloss position to change depending on the button position, and use a gloss texture that will not break even if Wrap Mode is Repeat.
    For example, if you use a glossy texture as shown below (it may look white on StackOverflow, I'm sorry) ...

      

    It will look as if the gloss passes through the entire world space as shown below.

  • Answer # 2

    Animated GIF should be fine.