今回は、線をフラグメントシェーダで描画します。「スキャンライン」というらしい。
線を描く
fixed4 frag(v2f i) : SV_Target { return step(0.3, i.uv.y) * step(i.uv.y, 0.4); }
step
step(閾値, x)
xが閾値以上なら1, 閾値未満なら0 を返す。
上記の例は、UV座標のY座標が0.3~0.4 の位置にあるときに1を返すので、1=白が表示されている。
sin波を使って複数線を描く
fixed4 frag(v2f i) : SV_Target { return sin(i.uv.y * 50); }
複数線を書くために 0→1→0→1→0・・・ となる値が必要なので、今回はsin波を使います。
sin でウェーブさせた値をそのまま色として出力すると、上記のようになり、0(黒)→1(白)→0(黒)→1(白)→0(黒)・・・ を繰り返していることがわかる。
sinでだした値はゆるやかに0から1をいききした値になっている 0→0.1→0.2→…→0.9→0.8…→1
のでぼやけた線みたいな表示になっている。
ここでstep
を使い、閾値を元に0か1だけの値にしてはっきりした直線にする。
fixed4 frag(v2f i) : SV_Target { return step(0.3, sin(i.uv.y * 50)); }
線を動かす
fixed4 frag(v2f i) : SV_Target { return step(0.3, sin((i.uv.y - _Time.y * 0.2) * 50)); }
_Time
を使ってUV座標のyを下に時間経過で移動させて線が動いているようにみせる。
画像と組み合わせたり…
白と黒の線が引けたところで、画像の表示と組み合わせてみるとちょっとゲームで使えそうになってきました。
fixed4 frag(v2f i) : SV_Target { fixed4 color = tex2D(_MainTex, i.uv); if (color.a <= 0) { discard; } return (1 - step(0.8, sin((i.uv.y - _Time.y * 0.2) * 50))) * color; }
画像の色と乗算しているため、 黒(0)は黒いまま、白(1)はx1となるので画像の色がそのまま表示されます。
fixed4 frag(v2f i) : SV_Target { fixed4 color = tex2D(_MainTex, i.uv); color *= (1 - step(0.8, sin((i.uv.y - _Time.y * 0.2) * 50))); if (color.a <= 0) { discard; } return color; }
黒い線の部分は破棄 discard
しちゃうのもよさげだ…