はじめに
こんばんは、代表の堂前です!
本日はUnityのUI、主にuGUIで使われるシェーダですが、ステンシルバッファがどう扱われているかを取り扱うことにします。
それを理解することで、パフォーマンス向上などが期待できます。
※検証したのはMacのUnity5.4.1系になります。
※本稿は推測を含むため、その点は留意下さい。
マスクの有無での動作確認
uGUIでステンシルを使う用途はマスク(Mask)機能だけということです。
(他にあるのかもしれませんが、今回はこれだけに着目します。)
Mask機能自体の説明は割愛します。
では、Maskの有無で描画の仕方がどう変わるかFrame Debuggerで確認してみましょう。
Imageのみ | ←にMaskも追加したもの |
今回はDraw Call数、つまりFrame Debuggerでは行数に着目してみます。
(Clear処理は無視します。)
左のシンプルなImageのみの場合は、Draw Meshが1つのみになっています。
右はそれにMaskも加えたものですが、その場合はDraw Meshが3つにもなっています!
公式のMaskのドキュメントでは、「ステンシルをまず書いて、本来のイメージはステンシル比較を行ってマスク処理を行う」(意訳)となっているのですが、それなら2つで済むはずです。
なぜDraw Callが3つになるのでしょう?
3つ目のDraw Callの真意
UI描画前はクリア処理が入っていてステンシルもクリアされるので、もし3つ目のDraw Callがない場合はステンシルも少し荒れているハズです。
スクリプトとシェーダを作成し、スクリプトのOnPostRenderで「ステンシルが0以外の部分」を真っ赤に塗りつぶすシェーダで描画してみます。
(Canvasを「Screen Space – Overlay」から「Screen Space – Camera」に変更していますが、原理は変わりません。)
「Draw GL」というのがその塗りつぶしの描画になりますが、変化が起こりませんでした。
つまり、「ステンシルは荒れていない」という事になります。
ここからは推測ですが、3番目のDraw Callは「荒れたステンシルを綺麗にする為の描画」であると考えます。
uGUI側でステンシルを保全している(と思われる)ので、例えば複数Canvasの際に、都度、デプスクリアなどを行わなくても良くなるというメリットが生まれます。
その他にもメリットがあるかもしれません。
次回はUI系のシェーダを掘り下げてみます。
※お知らせ
株式会社ロジカルビートでは、一緒に働いてくれる仲間を募集しています!
興味を持たれた方は採用ページを是非ご覧下さい!
【免責事項】
本サイトでの情報を利用することによる損害等に対し、株式会社ロジカルビートは一切の責任を負いません。
「【Unity】UIシェーダとステンシル」への1件のフィードバック
コメントは受け付けていません。