お米 is ライス

C#やらUnityやらを勉強していて、これはメモっといたほうがええやろ、ということを書くつもりです

【Cg Programming/Unity】透過 ~ 描画順に依存しない透過【順番にやっていく】

今回はこちら。
en.wikibooks.org
前節でやったような一般的なアルファブレンディングの場合、描画する順番で最終的な見え方が異なる。
そのようなアルファブレンディングは描画順がオブジェクト単位で決まってしまう環境ではうまく描画されないことがあるというのは前回言ったとおりだ。

そこで、それならば「描画順に依存しないアルファブレンディングをしてしまえばいいではないか」というのがこの節の内容である。

描画順に依存しないアルファブレンディング

前節では以下のようなブレンディングを行っていた。

Blend SrcAlpha OneMinusSrcAlpha

これだと初めに描画されたものほど次々と上書きされて行ってしまう。
これを避けるため、可換なブレンディングを行う必要がある。
可換なブレンディングというのも色々あると思うが、最も単純なのは加算または乗算によるブレンディングだ。
加算はSrcColor + DstColor = DstColor + SrcColorで可換だし、乗算はSrcColor * DstColor = DstColor * SrcColorでやはり可換だ。
(すごく適当なことを言っている)

というわけでこれらを行うために必要なブレンディングの指定方法は以下である。

加算

1つ目の項がDstColorに依存せず、2つ目の項がSrcColorおよびDstColorに依存しない値であれば加算になると思う。

Blend One One
Blend ScrAlpha One  //アルファを使いたければこう

乗算

1つ目の項はZeroで、2つ目の項はScrColorに依存した値であれば乗算ブレンディングとなる。

Blend Zero SrcColor  //2つ目の項がそのままDstColorとSrcColorをかけたものになる
Blend Zero OneMinusSrcAlpha

コード

というわけで上記のブレンディングを実際に行うとこうなる。

Shader "Custom/OrderIndependentTransparency"
{
    SubShader
    {
        Tags { "Queue" = "Transparent" }
        pass
        {
            ZWrite Off
            Cull Back

            //アルファブレンディングの形式を指定
            Blend One One   //加算
            //Blend Zero SrcColor   //乗算

            CGPROGRAM
            #pragma vertex v
            #pragma fragment f

            struct v2f
            {
                float4 position : SV_POSITION;
                float4 color : TEXCOORD0;
            };

            v2f v(float4 vertexPos : POSITION)
            {
                v2f output;
                output.position = UnityObjectToClipPos(vertexPos);
                output.color = float4(vertexPos.xyz, 0.5) + float4(0, 0, 0, 0);
                return output;
            }

            float4 f(v2f input) : COLOR
            {
                return input.color;
            }
            ENDCG
        }
    }
}

f:id:spi_8823:20200506072231p:plain

Sceneビューで視点をぐりぐり動かしてもらえばわかると思うが、Cube同士が重なっている箇所の色は視点を変えても不自然に変わったりしないようになっている。
(前節のブレンディングで同じように視点を動かすと、オブジェクト同士の前後関係が変わったときにチラッチラッと描画が変わってしまうのだ)

以上。
次はこちら。
spi8823.hatenablog.com