【Unity】UIシェーダとステンシル

投稿者: | 2016年10月4日

はじめに

こんばんは、代表の堂前です!

本日はUnityのUI、主にuGUIで使われるシェーダですが、ステンシルバッファがどう扱われているかを取り扱うことにします。
それを理解することで、パフォーマンス向上などが期待できます。

※検証したのはMacのUnity5.4.1系になります。
※本稿は推測を含むため、その点は留意下さい。


マスクの有無での動作確認

uGUIでステンシルを使う用途はマスク(Mask)機能だけということです。
(他にあるのかもしれませんが、今回はこれだけに着目します。)

Mask機能自体の説明は割愛します。
では、Maskの有無で描画の仕方がどう変わるかFrame Debuggerで確認してみましょう。

unity_ugui_imageonly unity_ugui_imageandmask
Imageのみ ←にMaskも追加したもの

今回はDraw Call数、つまりFrame Debuggerでは行数に着目してみます。
(Clear処理は無視します。)

左のシンプルなImageのみの場合は、Draw Meshが1つのみになっています。
右はそれにMaskも加えたものですが、その場合はDraw Meshが3つにもなっています!

公式のMaskのドキュメントでは、「ステンシルをまず書いて、本来のイメージはステンシル比較を行ってマスク処理を行う」(意訳)となっているのですが、それなら2つで済むはずです。

unity_ugui_drawcall0

なぜDraw Callが3つになるのでしょう?


3つ目のDraw Callの真意

UI描画前はクリア処理が入っていてステンシルもクリアされるので、もし3つ目のDraw Callがない場合はステンシルも少し荒れているハズです。
スクリプトとシェーダを作成し、スクリプトのOnPostRenderで「ステンシルが0以外の部分」を真っ赤に塗りつぶすシェーダで描画してみます。
(Canvasを「Screen Space – Overlay」から「Screen Space – Camera」に変更していますが、原理は変わりません。)

unity_ugui_stenciltest

「Draw GL」というのがその塗りつぶしの描画になりますが、変化が起こりませんでした。
つまり、「ステンシルは荒れていない」という事になります。

ここからは推測ですが、3番目のDraw Callは「荒れたステンシルを綺麗にする為の描画」であると考えます。

unity_ugui_drawcall1

uGUI側でステンシルを保全している(と思われる)ので、例えば複数Canvasの際に、都度、デプスクリアなどを行わなくても良くなるというメリットが生まれます。
その他にもメリットがあるかもしれません。

次回はUI系のシェーダを掘り下げてみます。


※お知らせ

株式会社ロジカルビートでは、一緒に働いてくれる仲間を募集しています!
興味を持たれた方は採用ページを是非ご覧下さい!


 

 

【免責事項】
本サイトでの情報を利用することによる損害等に対し、株式会社ロジカルビートは一切の責任を負いません。

【Unity】UIシェーダとステンシル」への1件のフィードバック

  1. ピンバック: 【Unity】UIシェーダの高速化を図る – 株式会社ロジカルビート

コメントは停止中です。