メインコンテンツまでスキップ

シェーダーが1フレームをどう描くか

このページは解説です。サーフェスモードを今すぐ選ぶには基本設定ガイドをご覧ください。

一行まとめ​

MingToonは1つのマテリアルを6つのパスに分けて描画します。 サーフェスモードは、それらのパスが使うレンダーステートをまとめて切り替えます。

ここに書かれた数はソースで宣言された数です

1フレームで実際に発行されるドロー数とは異なります。 ベイク、機能の切り替え、カメラとライトによって変わります。実際の回数はFrame Debuggerで確認します。

何が起きるのか​

Built-inシェーダーが宣言するパスは6つです。

順序パス役割
1FORWARD_BASE_BACKFACE両面2パスで裏面を先に描きます
2FORWARD_BASE主光源、環境光、本体の効果
3FORWARD_ADDポイント・スポットなどの追加ライト
4TRANSPARENT_DEPTH_PREPASS色を出さずに深度だけ先に書き込みます
5OUTLINE_HULL_DIRECTメッシュを拡張して描くノーマルアウトライン
6SHADOW_CASTERライトの影とBuilt-inのカメラ深度

URPはパス構成が異なります。同じ順序や数を当てはめないでください。 URPではアウトラインと深度効果がRenderer Featureで接続されます。 対応環境も併せてご覧ください。

本体​

表面効果のほとんどは2番のパスで計算されます。両面2パスを有効にすると、1番のパスが裏面を担当します。

通常の透明は、色を描くパスで深度を使いません。 4番のパスが色を出さずに深度だけ先に残しておくと、アウトラインが自分の表面を突き抜けなくなります。 ただし奥の半透明レイヤーが隠れることがあるため、すべてのソート問題を解決するスイッチではありません。

影とカメラ深度​

次の3つはそれぞれ別の条件です。 6番のパスが有効であること、この表面がカメラ深度に入ること、この表面がライトの影を落とすこと。

パスがあるというだけでカメラ深度に入るわけではありません。 カメラ深度への参加は、ほかのマテリアルのデプス効果がこの表面を遮蔽対象として読むかどうかを決めます。

サーフェスモードが実際に変える値​

サーフェスモードRenderTypeキューブレンドZWrite深度の先行書き込み
不透明Opaque2000One / Zeroオンなし
カットアウトTransparentCutout2450One / Zeroオンなし
半透明Opaque2499SrcAlpha / OneMinusSrcAlphaオンなし
透明Transparent3000SrcAlpha / OneMinusSrcAlphaオフあり

半透明は色を混ぜながら深度も書きます。 キュー2499は不透明の範囲内なので、手前から奥へソートされます。 その順序で最も手前の面が勝つには深度が必要です。 両面の髪が内側の房を外側に重ねて描かないのは、これが理由です。

透明は奥から手前へソートされ、深度を書きません。 不透明な体、透けるショートパンツ、スカートが1つのマテリアルに混ざっている場合が、このモードの出番です。

シェーダーキーワード​

モジュールごとに、キーワードとプロパティが組み合わさって動作します。 キーワードが有効でも、その効果が常に画面に見えるとは限りません。 全体効果の切り替え、マテリアルの役割、強度、テクスチャ、カメラ深度も同時に条件になります。

レイヤーティアのキーワード​

モジュール追加ティア
サーフェスレイヤー_MING_STACK_4, _MING_STACK_10
ノーマルレイヤー_MING_NORMAL_2, _MING_NORMAL_5
マットキャップレイヤー_MING_MATCAP_2, _MING_MATCAP_5

ティアはコンパイルされるスロット範囲を決めます。実際のレイヤー数は実行時の分岐にも使われます。

そこから生じる制約​

  • 同じティア内でレイヤーを減らしても、コンパイルされるコード量は変わりません。ティアの境界を越えて初めて減ります。
  • 無効なパスで三角形を消す経路があっても、頂点処理とドローの送信が無料になるわけではありません。
  • 編集用シェーダーは、値を変更できるようにコードを残しておきます。実際に減った結果はベイクしたシェーダーで確認します。
  • VRChatのfallbackはVRCFallbackタグとホストの方針に従い、MingToonの効果を再現しません。

関連ページ​