夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Hex表現を使用した出現シェーダーを作る その③発光演出

本日は昨日に引き続きシェーダー枠です。

先日はHex表現を使用した出現シェーダーとして透明度を持たせて出現する仕組みを作成しました。

redhologerbera.hatenablog.com

今回はさらに発光エフェクトを追加してエフェクトとしてディティールアップしていきます。

〇発光演出の追加

Shaderにおいて発光表現は一般的に出力されるテクスチャに発光色を加算します。

   (出力色 float4(0~1)) = (計算結果) + (発光色)

例えば先日の出現シェーダーの状態にプロパティブロックに変数を加えることで発行を再現できます。

Shader "Unlit/HexShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Scale("Scale" ,float) = 0
        _Power("Power",float) = 0
        [HDR]_EmissionColor("Emission" ,color) = (1,1,1,1)//追加
    }
    SubShader
    {
  ・・・
        Pass
        {
   ・・・
            float4 _EmissionColor;//宣言
            ・・・

            fixed4 frag(v2f i) : SV_Target
            {
              ・・・
                col.a *= saturate(1 - float4(1, 1, 1, 1) * step(Hex, smoothstep(i.uv.y + _Power, 0.8, 0)).x);
                col.rgb += _EmissionColor.rgb;//加算
                return col;
            }

今回は上記画像のように一律に発光するのではなく、出現に合わせてHexに沿って光らせていきます。

〇発光演出の実装

今回はHexメソッドの帰り値であるHexを使用します。

     Hexagon(i.uv, _Scale, HexIndex, HexPos, HexUV, Hex);
     ・・・
                emission *= 1-Hex.x;

このように1-hexを行うことで次のような中心が黒く外に向かって白くなるテクスチャを出力できます。

この出力に冒頭で述べた_EmissionColorの色を掛け合わせます。

            fixed4 frag(v2f i) : SV_Target
            {
                float2 Hex;
                float2 HexUV;
                float HexPos;
                float2 HexIndex;
                Hexagon(i.uv, _Scale, HexIndex, HexPos, HexUV, Hex);

                fixed4 col = tex2D(_MainTex, i.uv);
                float StepHex = step(Hex, smoothstep(i.uv.y + _Power, 0.8, 0));
                col.a *= saturate(1 - float4(1, 1, 1, 1) * StepHex.x);
                float3 emission = _EmissionColor.rgb;
                emission *= 1-Hex.x;
                col.rgb += emission;
                return col;
            }

これによって次のようなHexの縁に合わせて発行するようになります。

出現中のHexのみ発光を起こしたいため発光色にグラデーションを掛け合わせます。このsmoothstepは先日紹介したように次のようなUVに対してのグラデーションを起すことができます

            fixed4 frag(v2f i) : SV_Target
            {
                float2 Hex;
                float2 HexUV;
                float HexPos;
                float2 HexIndex;
                Hexagon(i.uv, _Scale, HexIndex, HexPos, HexUV, Hex);

                fixed4 col = tex2D(_MainTex, i.uv);
                float StepHex = step(Hex, smoothstep(i.uv.y + _Power, 0.8, 0));
                col.a *= saturate(1 - float4(1, 1, 1, 1) * StepHex.x);
                float3 emission = _EmissionColor.rgb*smoothstep(i.uv.y + _Power, 0.8, 0);//変更
                emission *= 1-Hex.x;
                col.rgb += emission;
                return col;
            }

これによって次のように出現時のみ発光するようなエフェクトが再現できます。

〇コード全文

Shader "Unlit/HexShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Scale("Scale" ,float) = 0
        _Power("Power",float) = 0
        [HDR]_EmissionColor("Emission" ,color) = (1,1,1,1)
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 100
        AlphaToMask On
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"
            #include  "Hex.hlsl"

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

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

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _Scale;
            float _Power;
            float4 _EmissionColor;
            
            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
            {
                float2 Hex;
                float2 HexUV;
                float HexPos;
                float2 HexIndex;
                Hexagon(i.uv, _Scale, HexIndex, HexPos, HexUV, Hex);

                fixed4 col = tex2D(_MainTex, i.uv);
                float StepHex = step(Hex, smoothstep(i.uv.y + _Power, 0.8, 0));
                col.a *= saturate(1 - float4(1, 1, 1, 1) * StepHex.x);
                float3 emission = _EmissionColor.rgb*smoothstep(i.uv.y + _Power, 0.8, 0);
                emission *= 1-Hex.x;
                col.rgb += emission;
                return col;
            }
            ENDCG
        }
    }
}