ダイアログウィンドウなんかのサイズが可変するウィンドウでよく見かけるUI表示で、制作環境によって呼び名が変わるようです。9スライスとか、9-patch とかいうやつ。
UE4でももちろん標準実装されているのでとても手軽に使えます。
詳しくはこちらの記事。
普通に使えるのに、わざわざマテリアルで試そうと思ったのは、カラーを乗せたかったから。
で、できたのがこれ。
UMGで マテリアルを使った 9Slice を作ってみた。なんとか完成できたけど、偶然できたカラーアニメーションのインパクトに驚いている #UE4 #ue4UMG pic.twitter.com/Qm0s3N8dEE
— みつまめ杏仁 (@MMAn_nin) 2021年4月2日
AlphaチャンネルとRGBカラーを分離すれば実現できるはず。ということでマテリアルと格闘することになったのでした。
UE4の Mergin指定はデザインに対して柔軟に合わせられるつくりなので、真似してみたかったけど、まずはシンプルなところから理解していこうということにしました。
今回は作り方というより考え方の記録みたいな内容です。
下図は、UMGでの指定方法。
考えやすいように、Marginは 0.5 固定で進めます。
Marginはテクスチャの分割位置を上下左右の端から割合で指定するので、全部 0.5 ということは中央になります。
用意したテクスチャ ↓
実際に描画する際は、この4分割のパーツを9か所に配置することになります。
縦と横の中央部が延ばされます。
マテリアルでこのようなUVを作れればOKなわけです。
まずは U方向(水平)について考えてみます。
変化量を縦軸にしてグラフにすると下図のようなイメージになります。
何も手を加えなければ、0 ~ 1.0 へのまっすぐな直線です。これを指定したSize固定部分で分断して引き延ばす感じ。
ノードで組んでみるとこうなりました。
Scalarパラメータノードが Size固定部分の値になります。
そこを if ノードで判定して、ナナメ(0→0.5 と 0.5→1.0 )にするか、0.5 にするかを仕分けています。
もっと頭のいい計算方法があると思う。
パッと見ややこしいし、U方向だけでこのボリューム感。ついでにSize固定幅の指定をピクセルで指定したいので、TexCoord[3] を活用。
これについてはこちらのツイートが参考になりました。
#UE4Study
— 恒吉星光 (@seiko_dev) 2020年7月30日
UI用Materialで描画領域のpixel sizeが欲しい場合、TexCoord[3]で取れるとの事。https://t.co/3Su6Q1Wo1E
スゴイ裏技みを感ずるが、確かに「Imageの縦横幅や画面解像度に依存せず見た目のPixel幅が一定の枠」みたいな事ができた。 pic.twitter.com/4CEDlp3rLN
コピペとはいえ V方向のぶんも必要なので最終的にこうなりました。
コンパクトにしたいので、HLSLのコードを書ける Customノードを試してみました。
1 | float temp = 0.5 / Width;
2 | float result;
3 | if ( Value < Width ){
4 | result = temp * Value;
5 | }else {
6 | if ( (1 - Width) < Value ) {
7 | result = (Value -(1 - Width)) * temp + 0.5;
8 | }else {
9 | result = 0.5;
10| }
11| }
12| return result;
すっきり。
今回 ノードで組むより、コードで書いたほうが Instructions(命令)数は少なくなった。
使ったテクスチャはこれ。
できたマテリアルは、いつも通り Image に貼り付けて完成。
これで途中で伸びることなくカラーテクスチャが自由にオーバーレイできるようになった。
UVの計算方法については、結果オーライでまったく自信ないので、どなたか頭のいい人ご指摘いただけるとありがたいです。
テクスチャの品質で圧縮による劣化を少しでもマシにしたくて、RGB と Alphaを別々の解像度で作って合体させるというのを実践しているのですが、今回のネタもそこからのつながりです。
まだまだ、応用できそうですが今回はこのへんで
ではでは
すてきな9スライス ライフを!