LoginSignup
4

More than 3 years have passed since last update.

【Unity】点が集まった素材をランダムに点滅させる

Posted at

はじめに

以下のような細かい点が集まったテクスチャがあります。

red_light.png

このテクスチャを以下のように点滅させる方法を解説します。
result.gif

アプローチ

  1. 時間とsinを使って点を明滅させる
  2. 時間を点ごとにランダムにずらす

ランダムな色を持つテクスチャの作成

点の時間をランダムにズラすためには点ごとに0~1のランダムな色が格納されたテクスチャが必要になります。
今回はSubstanceDesignerを利用してこれを作成します。

以下のようなノードを組みます。
image.png

結果として以下のテクスチャを得ます。 点ごとに0~1のランダムな値が格納されたテクスチャです。
RandomBlink_output.png

点滅シェーダー(uGUIシェーダー)

以下のようなシェーダーを利用してテクスチャを点滅させます。
先ほど作成したランダムテクスチャを以下のシェーダーの_BlinkRandomTexに割り当てることにより、点がランダムに点滅するようになります。

BlinkTexture.shader
// テクスチャを点滅させる
Shader "UI/BlinkTexture"
{
    Properties
    {
        [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
        _Color("Tint", Color) = (1,1,1,1) // 色
        [Space]
        _BlinkRandomTex("Blink Texture", 2D) = "white" {} // 点滅のバラつきを設定するためのテクスチャ(r:点滅の間隔, g:点滅の速さ)
        _BlinkIntervalMin("Blink Interval Min", Float) = 3.0 // 点滅間隔の最小値
        _BlinkIntervalMax("Blink Interval Max", Float) = 6.0 // 点滅間隔の最大値
        _BlinkSmoothstepEdge1("Blink Smoothstep Edge 1", Range(0,1)) = 0.1 // 点滅の緩急を調整するパラメータ
        _BlinkSmoothstepEdge2("Blink Smoothstep Edge 2", Range(0,1)) = 0.9 // 点滅の緩急を調整するパラメータ

        _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 __ 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
    };

    // 円周率PIの2倍
    #define PI2 6.28318530718

    fixed4 _Color;
    half _BlinkIntervalMin;
    half _BlinkIntervalMax;
    fixed _BlinkSmoothstepEdge1;
    fixed _BlinkSmoothstepEdge2;
    float4 _ClipRect;
    sampler2D _MainTex;
    sampler2D _BlinkRandomTex;

    v2f vert(appdata_t IN)
    {
        v2f OUT;
        UNITY_SETUP_INSTANCE_ID(IN);
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
        OUT.worldPosition = IN.vertex;
        OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

        OUT.texcoord = IN.texcoord;

        OUT.color = IN.color * _Color;
        return OUT;
    }


    fixed4 frag(v2f IN) : SV_Target
    {
        fixed4 color = tex2D(_MainTex, IN.texcoord); // カラー
        fixed4 blinkRandom = tex2D(_BlinkRandomTex, IN.texcoord); // 点滅のバラツキ

#define BLINK_INTERVAL lerp(_BlinkIntervalMin, _BlinkIntervalMax, blinkRandom.r)
#define BLINK_ALPHA_SINE (0.5 + 0.5 * sin(PI2 * (_Time.y / BLINK_INTERVAL - BLINK_SHIFT)))
#define BLINK_ALPHA smoothstep(_BlinkSmoothstepEdge1, _BlinkSmoothstepEdge2, BLINK_ALPHA_SINE)
#define BLINK_SHIFT (blinkRandom.g)

        color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect) 
                * BLINK_ALPHA; // 点滅

#ifdef UNITY_UI_ALPHACLIP
        clip(color.a - 0.001);
#endif

        return color;
    }
        ENDCG
    }
    }
}

点滅の実装箇所(フラグメントシェーダー)

フラグメントシェーダー内にて点滅を実装しています。

点滅
        fixed4 frag(v2f IN) : SV_Target
        {
            fixed4 color = tex2D(_MainTex, IN.texcoord); // カラー
            fixed4 blinkRandom = tex2D(_BlinkRandomTex, IN.texcoord); // 点滅のバラツキ

    #define BLINK_INTERVAL lerp(_BlinkIntervalMin, _BlinkIntervalMax, blinkRandom.r)
    #define BLINK_ALPHA_SINE (0.5 + 0.5 * sin(PI2 * (_Time.y / BLINK_INTERVAL - BLINK_SHIFT)))
    #define BLINK_ALPHA smoothstep(_BlinkSmoothstepEdge1, _BlinkSmoothstepEdge2, BLINK_ALPHA_SINE)
    #define BLINK_SHIFT (blinkRandom.g)

            color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect)
                    * BLINK_ALPHA; // 点滅

    #ifdef UNITY_UI_ALPHACLIP
            clip(color.a - 0.001);
    #endif

            return color;
        }

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4