マテリアルでUV座標上に図形を描く
に更新
趣旨
UV 座標空間に長方形とかの図形を描くマテリアルを遊びで作ったのでメモとして記事にしておきます。以下のようなことになります。
環境
- Engine Version: 5.0.0 Early Access 2
長方形
UV 座標から長方形マスクを作成する
まず、以下のような Material Function を作成しました。Custom ノード内部の内部で各ピクセルの UV 座標に基づいて長方形の内外を判定し、マスクを作成しています。
float range = abs(UVs.x - 0.5 + Offset.x);
float half_w = Width / 2;
float ubGrad = (0.5 - abs(UVs.y - 0.5 + Offset.y)) * 2;
float mask = int((ubGrad - CutOut*2) + 0.999999);
float lineBase = 1-int(range - half_w + 0.999999);
return mask * lineBase;
シェーダーにおいては、if などによる分岐命令パイプライン上で分岐が発生する機能を使用すると大きな性能低下が見られるため、if を用いない形で記述しています。
そのため少しわかりにくくなっていますが、やっていることはWidth
の幅を持ち、上下をCutOut
の大きさだけカットされ、Offset
分描画位置をオフセットされた長方形を想定し、該当ピクセルに対応する UV 座標がその内側か外側かを判定しているだけです。これだけで、長方形のマスクを作成することができます。
(ノードを見ると CustomRotator による入力 UV の回転を行い、長方形を回転させる機能が入っていますが、汎用性のために入れただけで今回は使っていません)
しかし、このパラメータだとすこし使いにくいので、より長方形マスクを作成することに特化したマテリアル関数でラップします。
こちらは極めて単純です。先程のマテリアル関数の入力パラメータをUVs
Width
Height
Left
Top
という扱いやすいものにするための前処理を加えただけです。
色付き長方形を作成する
せっかくですので、長方形マスクだけでなく、透明度と色を持った長方形を描画するマテリアル関数も作ってみましょう。
このネットワークでは、先ほど作成した長方形マスク関数を元に、長方形の色と背景の色を透明度付きで指定できるようにしています。 これで位置・サイズ・色が指定可能な長方形が作れたので、これを素材に何かを生成するなり、テクスチャに合成するなりして自由に使うことができます。
使ってみる
今回はテストですので、テクスチャに対して異なる色・透明度を持つ複数の正方形をアルファブレンドするサンプル(冒頭に示していたもの)を作成しました。
こちらがサンプルのネットワークです。(動きをつけている部分は今回の本質ではないので入れていません)
すると、冒頭に示したこちらの動画のように、テクスチャが配置された UV 座標に基づいて長方形の描画ができます。
円
今度は円を描画してみます。
円の数学的な表示
円はベクトルとして表すと、以下のようになります。 ここで、は円周上の任意の点、は円の中心、は半径です。
これはとの距離が r と等しくなるような点の集合が円であるということなので、結果として線状の円周を示します。今回指定したいのは円の内側の面領域なので、不等式にすればよいです。
円のマスクを描画する
この考えに従うと、円のマスクを描画するのは次のコード 1 行で完結します。
return int(saturate(Radius - distance(Center, UVs)) + 0.999999);
また分岐を使っていないので可読性が下がっていますが、やっていることは円の中心Center
と現在のUV座標であるUVs
の距離を出し(ノルムに対応)、半径からその距離を減算し、0以下になったかそうでないかで、最終的に0と1のどちらかに値がなるように調整しています。
こちらを以下のようにCustomノードに記入して、配線するだけです。これで位置と半径を指定した円を描くことができます。
色付き円を作成する
これについては、色付き長方形を作成した際の長方形マスクマテリアル関数を、そのまま円のマスクマテリアル関数の置き換えるだけで作成可能なので、割愛します。
まとめ
UV 座標を元に図形を描くのは簡単にできることがわかったと思います。次はレイマーチングしたい。