😋

【宣伝】Unity向けのベクターUIライブラリを作成しています!【Unity-SDF-UI-Toolkit】

に公開

⚠️注意⚠️ 宣伝的な内容です!後々情報の更新もするかもしれない…

https://x.com/TLab22913171/status/1875610359194857823?t=PYNYfemYFwKDRH6hASMtcA&s=19

Unity向けのベクターUIライブラリUnity-SDF-UI-Toolkitを作成しています.結構前から作り続けているものなのですが,宣伝がてら記事を書いてみました.

https://github.com/TLabAltoh/Unity-SDF-UI-Toolkit

どんなライブラリなの?

ベクターUIを描画するライブラリです.近いものでは,Unity-UI-Rounded-Cornersがあります.このライブラリもUnity-UI-Rounded-Cornersから着想を得ていますが,より多機能で汎用的なライブラリを目指して開発しています.

より多くの図形のサポート


沢山の図形に対応していることが1つの特徴です.本家にも備わっているQuadとその四隅それぞれの独立した丸角(IndependentCorners)に加えて,CircleTriangle, Arcなどの基本形状,またSDFテクスチャSpline, Squircleなどの少し複雑なシェイプにも対応しました.




このライブラリは,シェーダー内部で距離関数を使用しています.ピクセル単位で図形との内外判定を行うことで解像度に依存しない(ベクター)UIの描画を行っています.各図形を描画するためには,その図形の距離関数を実装する必要があるのですが,この距離関数の実装でこちらの記事が大変参考になりました.

アウトラインとシャドウの対応

UIのアウトラインシャドウに対応しています.本家では対応している図形がQuadのみのため,大きさの違うUIを2つ重ねてしまえばアウトラインが実装できると思いますが,対応する図形を増やそうとすると,その他の図形ではそれが出来ない場合があります.そのため,距離関数の実装を先程も紹介したこちらで置き換えて,どの位置をサンプリングしても物体との距離が正しく取得できるような(標準的な?)距離関数を使用することで,本来の図形の輪郭から一定の距離を含めた内外判定を行い,アウトラインとシャドウに対応しました.



この図形本体・アウトライン・シャドウは,シェーダーで1つのパスでまとめて描画を行っています.当初,シャドウの対応には2パス(影を描画するパスと図形本体・アウトラインを描画するパス)のシェーダーが必要だと思っていたのですが,コントリビュータの方の助言と協力で1パスにまとめることができました(この方はこの機能だけでなく,最適化や新機能の追加など,開発の中で結構いろんなところで活躍してくれています).

バッチレンダリング対応

UIのバッチレンダリングに対応しています.同じプロパティ値シェーダーを持つUIはマテリアルを共有することで可能な限りドローコールなどを減らす実装をしています.もう一人のコントリビュータの方に実装してもらった機能です.

https://github.com/TLabAltoh/Unity-SDF-UI-Toolkit/pull/14

すごく個人的な話ですが,汎用的なシェーダーを作ろうとすると,機能を増やすたびに負荷への影響が心配になってしまうので,こうやって抜本的な最適化をしてもらえたのが,かなり助かっています.

SDFテクスチャエディター

必要ないかもしれませんがSDFテクスチャを作成するための簡単なEditor GUIも実装しました.ベジエカーブを用いた図形の作成方式を採用ています.テクスチャの作成にビットマップ形式のペイントではなくベジエカーブを用いる利点は,ベジエカーブだけで多角形を任意のセグメント数で表現できる→それを距離関数を使って綺麗な(ガコガコ・歪みのない)SDFテクスチャとして簡単に焼き付けが出来るというところにあります.

ちなみに,SDFテクスチャエディターでは4点制御のベジエカーブを図形の作成に使用していますが,この4点制御のベジエカーブは数式的に距離を測ることが(自分には)難しく,こちらを参考に4点制御のベジエカーブから数式的に距離を算出可能な3点制御のベジエカーブへの変換をしたりしています…!

UI エフェクト

UIに対して単純なエフェクトを付与する機能を実装しました(今のところはShinyPatternの2つみ.).Patternでは,SDFテクスチャを使用して図形を描画する方式を採用しています.模様の描画にSDFテクスチャを使用することで,模様の形状の複雑さを問わず一定の描画負荷を保てる利点があります.



ただ,このアップデートでシェーダーバリアントが増えたりしてしまっているので使い勝手が悪いと感じたら削除するかもしれないです ...

グラデーション

図形本体(Graphic),アウトライン,シャドウそれぞれにグラデーションを付与する機能を実装しました.グラデーションの種類は (Linear, Radial, Conical)の3種類を実装しています.

各種類のグラデーションに対応した虹色エフェクトは,もう1人コントリビュータの方に実装してもらった機能です(3色以上を使用したグラデーションをどうやって実装しようか悩んでいたタイミングで,このナイスなプルリクエストをもらえました).

https://github.com/TLabAltoh/Unity-SDF-UI-Toolkit/pull/28

この処理の描画負荷については,モバイルへの影響などは未調査ですが,それぞれそこまで重い処理ではないはずなので,フラグを使用して3種類をそれぞれ計算した後に特定の計算結果だけを残す方式を採用しています.ここをシェーダーキーワードで最適化しようとするとシェーダーバリアントが(None, Linear, Radial, Conical)と(Graphic, Outline, Shadow)の組み合わせて4 x 4 x 4 = 64倍に増えてしまうので各グラデーションの処理そのものを最低限のものにして処理を軽くする方針にしました.あんまり自信がないので意見などぜひ聞かせてほしいです.

将来性は?

正直よくわかりません.今だとUnity公式の提供するUI Toolkitが強く推されていますよね.ただ,丸角かつシンプルなベクターUIの実装の需要に対してuGUIとして動作するUnity-UI-Rounded-Cornersが比較的人気なことを考えると,uGUIベースなベクターUIライブラリもあってもいいのではないかなと考えています(ベクター図形をMeshとして描画するライブラリは存在するけどUIとして描画するライブラリはオープンになっているものはあんまりまだない?).

ともかく,誰かしらに使ってみてもらえると嬉しいです….フィードバックやリクエストなどが開発の1番のモチベーションになります!👇️気になった方は以下からぜひ...!!👇️

https://github.com/TLabAltoh/Unity-SDF-UI-Toolkit


最後に
ところでこういう記事ってツールの紹介にあたるのでカテゴリは本来あっち(Idea)なんでしょうか?近い趣旨の記事を書いてる人はTechにしている印象がある…

Discussion