Unityシェーダー - 黒い円を描く

シェーダーで下記のような黒い円を描きます。

f:id:ninagreen:20180919192749p:plain

 

前回、下記のような画像を作成したので、それを応用して距離が一定の閾値内は黒、それ以上は白にすればできそう。

f:id:ninagreen:20180919193001p:plain

 

 

最初に思いつたコードはこれでしたが、エラーになりました。数字のfloatを表すfはいらないらしい。

            float4 frag_test (v2f_img i) : SV_Target
            {
                float d = distance(float2(0.5, 0.5), i.uv);
                return d > 0.5 ? 1f : 0f;
            }

 

修正後はこんな感じ。

            float4 frag_test (v2f_img i) : SV_Target
            {
                float d = distance(float2(0.5, 0.5), i.uv);
                return d > 0.5 ? 1 : 0;
            }

結果はこうなりました。簡単。シェーダーも三項演算子使えるんですね。

f:id:ninagreen:20180919193527p:plain

 

if文で書き直そうかと思ったけど、どうもシェーダーだとif分は遅いらしい。C#の世界では想像もつかない・・・

light11.hatenadiary.com

qiita.com

 

if文の代わりにstep関数を使うほうがいいらしい。

step (DirectX HLSL)

 

step(edge, value)

value が edge 以上の場合は1、それ以外は0

 

なので、先ほどのを書き換えるとこうですかね。

            float4 frag_test (v2f_img i) : SV_Target
            {
                float value = distance(float2(0.5, 0.5), i.uv);
                return 1 - step(value, 0.5);
            }

 

わかりにくい・・・

x < edge が step (x,edge) であるほうが個人的にはわかりやすいですが、逆なんですよね・・この対応表がわかりやすいですが、覚えられる自信がなく・・何回も調べてしまいそうです・・

 

x >= edge x <= edge x > edge x < edge
step(edge,x) step(x,edge) 1.0 - step(edge,x) 1.0 - step(x,edge)