めーぷるのおもちゃばこ

- アイドルになりたいエンジニア女子の制作日記 -

【Unity】Unlit Shaderで透過をする

UnityのUnlitシェーダーで透過をさせる方法です!

f:id:maplesyrup-cs6:20200617133243p:plain
Unlit Shaderでの透過


Unlitで透過をする

🐼まずコード🐼

プロジェクトウィンドウでCreate>Shader>Unlit ShaderでShaderをつくって以下のプログラムを記入します!

Shader "Custom/UnlitTransparent"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Color", Color) = (1, 1, 1, 1)
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha 
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

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

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;

            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 col = tex2D(_MainTex, i.uv) * _Color;
                col.a = _Color.a;
                return col;
            }
            ENDCG
        }
    }
}

   

🐼解説🐼

Unlitで透過をする場合、以下の記述にします。
まず、RenderTypeQueueTransparentにします。

Tags { "RenderType"="Transparent"  "Queue" = "Transparent"}

   
そして、BlendingType

Blend SrcAlpha OneMinusSrcAlpha 

を指定します。
  
このBlending TypeはUnityドキュメントによると以下の通りです。

Blend SrcAlpha OneMinusSrcAlpha // 昔ながらの透明
Blend One OneMinusSrcAlpha // プリマルチプライドの透明
Blend One One // 追加
Blend OneMinusDstColor One // ソフトな追加
Blend DstColor Zero // 乗算
Blend DstColor SrcColor // 2x 乗算
引用元:ShaderLab: Blending - Unity マニュアル

 
基本的な透過だと今回のようにBlend SrcAlpha OneMinusSrcAlphaがよいです。
ほかのもまた試してみて記事にしますね🐼


そしてプロパティからのアルファの指定をcolorに設定すれば、完了です。

col.a = _Color.a;

  

マテリアルを作成し、先ほどのシェーダーを当てたらモデルにセットします。
テクスチャをはめて、ColorのところからAlphaを設定しましょう。

f:id:maplesyrup-cs6:20200623030515p:plain
ColorからAlpha値を設定しましょう
  
  
透過が反映されましたね。
しかし、この状態だと、モデルの裏側まで透けてしまいます。
後ろ側のかわいいしっぽが見えてしまっていますね。
これを透けないように直しましょう。
f:id:maplesyrup-cs6:20200623011409p:plain
透けてしまっている


   

裏側を描画しないようにする

🐼裏側を描画しない方法🐼

  
裏側が描画されてしまう理由は、普通に描画をするとデプスバッファ(Zバッファ)への書き込みを行わないため、裏側があとから描画され上書きされてしまうからです。
なのでシェーダーを2パスにし、1パス目で描画を行わずにデプス値だけを取ります。
そして2パス目でそのデプス値を参照しながら描画を行います。

  
1パス目では以下のように記述します。ColorMaskを0にすることで描画を行わず、Zwriteでデプス値を読み込みます。

Pass
{
     ZWrite ON
     ColorMask 0
}

  
ZWriteについては以下の通りです。

オブジェクトのピクセルをデプスバッファに書き込むかどうかを制御します (デフォルトは On)。実線でオブジェクトを描画する場合は、これを On にします。半透明の効果を描画する場合は ZWrite Off にします。
引用元:ShaderLab :Culling と Depth Testing - Unity マニュアル

  
1パス目でデプスをバッファに書き込んだので、2パス目ではZWriteOFFにし、ZtestLequalにします。

ZWrite OFF
Ztest LEqual

   
Ztestはデプステストの実行方法です。

デプステストの実行方法。デフォルトは LEqual (すでに描画されているオブジェクトと距離が等しいか、より近い場合に描画します。それより遠い場合はオブジェクトで隠します)
引用元:ShaderLab :Culling と Depth Testing - Unity マニュアル

    

🐼全コード🐼

これらを追加して最終的なコードは以下の通りです。

Shader "Custom/UnlitTransparent"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha 
        LOD 100

        Pass
        {
            ZWrite ON
            ColorMask 0
        }

        Pass
        {
            ZWrite OFF
            Ztest LEqual

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

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

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;

            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 col = tex2D(_MainTex, i.uv) * _Color;
                col.a = _Color.a;
                return col;
            }
            ENDCG
        }
    }
}

  

これで良い感じに描画できました。

f:id:maplesyrup-cs6:20200617133243p:plain
透けずに描画できた!

  

だがしかし

これで完成したかと思わせておきつつ、実は上記のコードだとテクスチャをつけなかったときにもはやシルエット状態になってしまいます。

f:id:maplesyrup-cs6:20200623021608p:plain
テクスチャつけないともはやシルエット

   
テクスチャ無しで透過で凹凸ってたぶんこういう表現をしたいときになると思います。
こういう表現にしたい場合はリムライティングの表現になってきます!

f:id:maplesyrup-cs6:20200623033647p:plain
テクスチャ無しで透過で良い感じのやつ

  
ということで透過リムライティングの記事は以下をご覧ください↓↓↓
[記事をかいたらここに貼ります]