Stencil Shader を利用して、オブジェクトの重なり具合に応じて色を変える実装をしてみます
オブジェクトのShader
Stencil Pass を利用して オブジェクトがある箇所のステンシルバッファの値を加算していきます
こうすることでオブジェクトが重なっている箇所ではステンシルバッファの値が 2 や 3 などにすることができます
また、このオブジェクト自体は 描画する必要が無いため ColorMask 0
を指定して、色の描画をしないようにしています
Shader "Custom/Element" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry+1" } Pass { Stencil { Comp Always Pass IncrSat } ColorMask 0 CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" fixed4 frag (v2f_img i) : SV_Target { return fixed4(0, 0, 0, 1); } ENDCG } } }
オブジェクトの重なりを描画する Shader
こちらの Shader は Stencil ReadMask を利用して、ステンシルバッファの値が奇数のときのみ描画するようにしてあります
奇数は最下位ビットが必ず 1 になるので 1 とビットマスクした結果が 1になれば奇数です
プログラム的に書くと (num & 0x01) == 0x01
となります
※ 偶数の場合は Ref 0
ReadMask 1
Shader "Custom/OddStencil" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Color", Color) = (1, 1, 1, 1) } SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry+1" } Pass { Stencil { Ref 1 ReadMask 1 Comp Equal } CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" float4 _Color; fixed4 frag (v2f_img i) : SV_Target { return _Color; } ENDCG } } }
実際に動かしてみる
オブジェクトの Stencil と 奇数の Stencil を利用して実際に動かしてみます
重なった数が奇数の場合色がついてることが確認できます
問題点
四角い画像ならいいのですが、アルファが入っている画像だといい感じに表示することができませんでした
もしかしたら現在の描画している色を調べる方法があるかもしれないので、気が向いたら対応してみたいと思います