Unityシェーダー - 四角形を描く

 

四角形を描きます。

 

前回のstep関数を応用すればできそう。 

 float4 frag_test (v2f_img i) : SV_Target
{
        float d = step(i.uv.x, 0.2) + step (0.8, i.uv.x) 

                   + step(i.uv.y, 0.2) + step (0.8, i.uv.y);
        return d;
}

 

四角形の周囲の領域 (x <= 0.2 || x >= 0.8|| y <= 0.2 || y >= 8) が 1以上(白)になるように足してみました。一応うまくいってるっぽい。

f:id:ninagreen:20180920193857p:plain

 

あ、いやよく見ると、隅の部分がなんかはみ出してて汚い。clamp しないとダメですかね。

float4 frag_test (v2f_img i) : SV_Target
{
    float d = clamp(step(i.uv.x, 0.2) + step (0.8, i.uv.x)

                          + step(i.uv.y, 0.2) + step (0.8, i.uv.y), 0, 1);
    return d;
}

綺麗になった!

f:id:ninagreen:20180920195227p:plain

 

もう少し簡潔に書けそうです。

 step関数にはfloatNのvector型を渡すこともできて、それぞれのpropertyごとに計算してくれるっぽいです。

            float4 frag_test (v2f_img i) : SV_Target
            {
                float2 d = step(i.uv, float2(0.2, 0.2)) + step (float2(0.8, 0.8), i.uv);
                return clamp(d.x + d.y, 0, 1);
            } 

 というか、xもyも同じ値であればこうするほうがもっと簡潔かも。

            float4 frag_test (v2f_img i) : SV_Target
            {
                float2 d = step(i.uv, 0.2) + step (0.8, i.uv);
                return clamp(d.x + d.y, 0, 1);
            }

 

黒い四角じゃなくて青い四角もできますね

            float4 frag_test (v2f_img i) : SV_Target
            {
                float2 d = step(i.uv, 0.2) + step (0.8, i.uv);
                return d.x + d.y >= 1 ? 1 : float4(0, 0, 1, 1);
            }

f:id:ninagreen:20180921184223p:plain

 

 調べてたら、四角形を書いているコードを他にも発見

nn-hokuson.hatenablog.com

 

まったく別のアプローチですね。まず、こういう画像を作って、

            float4 frag_test (v2f_img i) : SV_Target
            {

                // 中心の四角形のサイズ(横、縦の長さ)を定義
                fixed2 size = fixed2(0.3,0.1);

 

                // 四角形の左下の座標を取得

                //(中心座標からサイズの半分をマイナスした箇所)
                fixed2 leftbottom = fixed2(0.5,0.5) - size * 0.5;

 

                // leftbottom <= i.uv ならば1

                //(四角形の左下座標より右上にいる場合は白にする)
                fixed2 uv = step(leftbottom, i.uv); 

 

                return uv.x*uv.y; // x=1&&y=1の場合のみ塗りつぶす
            }

f:id:ninagreen:20180921185437p:plain

 

こういうコードで上下左右した画像ができるから、

           float4 frag_test (v2f_img i) : SV_Target
            {
                fixed2 size = fixed2(0.3,0.1);
                fixed2 leftbottom = fixed2(0.5,0.5) - size * 0.5;

                // 1 - i.uv にすると上下左右反転できる
                fixed2 uv = step(leftbottom, 1 - i.uv);
                return uv.x*uv.y;
            } 

f:id:ninagreen:20180921185626p:plain

 

それを掛け算で掛け合わせると四角ができますってことだと思う

            float4 frag_test (v2f_img i) : SV_Target
            {
                fixed2 size = fixed2(0.3,0.1);
                fixed2 leftbottom = fixed2(0.5,0.5) - size * 0.5;
                fixed2 uv = step(leftbottom, i.uv);
                uv *= step(leftbottom, 1 - i.uv);
                return uv.x*uv.y;
            }

f:id:ninagreen:20180921185834p:plain

 

最後反転すれば白い背景の黒い四角になりますね

            float4 frag_test (v2f_img i) : SV_Target
            {
                fixed2 size = fixed2(0.3,0.1);
                fixed2 leftbottom = fixed2(0.5,0.5) - size * 0.5;
                fixed2 uv = step(leftbottom, i.uv);
                uv *= step(leftbottom, 1 - i.uv);
                return 1 - uv.x*uv.y;
            }

f:id:ninagreen:20180921190017p:plain