夜風のMixedReality

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

ゼロから始めるUnityShader開発 第五章 アルファクリップなシェーダーを書く

本日はシェーダーチュートリアル枠です。

今回は透明度を持ったシェーダーを記述していきます。

透明度を持ったシェーダーの場合描画順などが難しくなりますが、今回行うαクリッピングの手法は描画順を意識しなくてよいためとてもとっかかりやすいです。

〇アルファクリッピングとは?

アルファとはShaderの出力する4次元情報の中でRGBに続く第四成分です。

これは透明度を表しています。

 アルファクリップとは、透明度をもとに描画するか、描画しないかを切り替えるシェーダーです。

 植物などの描画や画像の切り抜きなどの場面で多く使用されています。

 描画するか描画しないかという2パターンであり半透明を考慮しないため透明度を持ったシェーダーの中では一番理解しやすいシェーダーになります。

〇AlphaToMask

アルファクリップな表現を行うためにはShaderLabでAlphaToMaskを使用します。

docs.unity3d.com

 SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        AlphaToMask On//追加

        Pass
        {
     ・・・
  }

これによってGPU上でAlpha to coverageの有効無効が設定できます。

これを有効化することでフラグメントシェーダーで0もしくは1の透明度を出力します。

つまりRGBAのAの値に応じて描画するかされないかが選択されるようになります。

この状態で出力のα値に0を記述するような形で使用します。

            float4 frag (v2f i) : SV_Target
            {
                float4 col = _MainColor;
                //Light.hlslで提供されるUnityのライトを取得する関数
                Light lt = GetMainLight(i.shadowCoord);

                //ライトの向きを計算
                float strength = dot(lt.direction, i.normalWS);
                float4 lightColor = float4(lt.color, 1)*(lt.distanceAttenuation * lt.shadowAttenuation);
                col = col* lightColor*strength;
                col.a = 0;//追加
                return col;
            }

デフォルトの値では0.5以上かそれ以下かで1か0が出力されるようになっています。

ではこの閾値を制御できるようにしていきます。

Propertiesブロックにfloat型の変数を追記します。

    Properties
    {
     //   _MainTex ("Texture", 2D) = "white" {}
        _MainColor("Color" ,color) = (1,1,1,1)
        _AplhaThreshold("AlphaThreshold",float)=0.5
    }

 次にフラグメントシェーダーでAlphaがAlphaThresholdより小さい場合0、大きい場合1が出力されるようになります。

            float4 frag (v2f i) : SV_Target
            {
                float4 col = _MainColor;
                //Light.hlslで提供されるUnityのライトを取得する関数
                Light lt = GetMainLight(i.shadowCoord);

                //ライトの向きを計算
                float strength = dot(lt.direction, i.normalWS);
                float4 lightColor = float4(lt.color, 1)*(lt.distanceAttenuation * lt.shadowAttenuation);
                col = col* lightColor*strength;
                col.a = (_AlphaThreshold<_Alpha)? 1:0;//追加
                return col;
            }

以上でアルファクリッピングの基礎的なシェーダーができました。

アルファクリッピングはテクスチャと合わせて使用することで真価が発揮される表現のため次回以降でテクスチャと合わせて表現を行います。