📝 ASP における各シェーダーのパフォーマンスについて
ASP/Character と ASP/Eye の Static Branching
ASP の character shader と eye shader は、どちらも forward rendering の shader です。
また、開発時には shader keyword を厳密に使い、機能ごとの static branching を行っています。
たとえば ASP/Character を使用しているマテリアルで、rim lighting カテゴリ内の fresnel rim light や depth-based rim light を使っていない場合、そのマテリアルは runtime 中に rim lighting 関連の計算を一切行いません。同様に、テクスチャ property も使用していなければサンプリングは発生しません。
そのため、1 つのマテリアルで有効になっている機能が少ないほど、runtime の負荷は小さくなります。
Texture Sampling Count(重要)
一般的に Shader を最適化する際は、各 frame で GPU に渡すテクスチャ数をできるだけ減らし、skinned mesh のマテリアル数を減らしたうえで、異なるマテリアルのテクスチャを 1 枚の atlas にまとめるのが理想です。 理論上は、部位ごとに異なる ramp map を 1 枚の ramp map atlas にまとめ、別の lookup texture や vertex color で UV を制御することもできます(この手法は一部のモバイルゲーム、たとえば原神などでよく見られます)。 ただし、この方法はプロジェクトごとの要件に合わせた厳密な制作フローと運用ルールが必要です。ASP は複数のプロジェクトで使われるプラグインであり、利用上の柔軟性を保つために特定の制作フローを強制していません(唯一の例外は PBR テクスチャのチャンネルです)。 各マテリアルがそれぞれ独立したテクスチャを使う構成では、bandwidth overhead が大きくなります。これはモバイルや VR / Switch のようなプラットフォームの GPU には不向きなため、ASP の既定ターゲットは一貫して PC のみです。
💡 プロジェクト要件に応じたテクスチャ統合の仕組みを作ること自体は、それほど複雑ではありません。モバイルなどのプラットフォームをターゲットにしているチームであれば、ASP の shader をトゥーンレンダリングの土台として使い、独自に改造・拡張することも可能です。
self-shadow 除去のパフォーマンス
Cube Proxy(推奨)
Cube Proxy は、追加の shadow texture、cascade、キャラクターの ShadowCaster draw call を作成しません。有効にすると、ASP/Character と ASP/Eye は表示中のキャラクターピクセルごとに ray-AABB 交差判定を 1 回行い、Proxy 表面で Unity の主光源 Shadow Map をサンプリングします。そのため、コストは Skinned Mesh Renderer 数よりも、主に画面上のキャラクターピクセル占有率に応じて変化します。
💡 外部からの影を正しく判定できるよう、Cube Proxy はキャラクターをなるべく隙間なく包むサイズにしてください。self-shadow 除去が不要なキャラクターでは、ASP Character Panel から無効にするとこの処理を省略できます。Unity 6.5 ではこの方法のみを提供します。
ASP ShadowMap(Legacy/Unity 2022.3、6.0、6.3 のみ)
キャラクターのみを個別に描画する ASP Shadow Map は、最大 4 段の cascade shadow map に対応しています。
Cascade shadow map は、いわば影の LOD のようなものです。shadow map を複数の小さな tile に分割し、それぞれを異なる影距離で描画します。
cascade count を増やすことで、shadow map resolution を小さく保ったまま、距離ごとにより安定した影品質を得られます。

一個2層cascsade的shadow map
ただし、cascade が 1 段増えるごとに draw call も 1 回増えます。4 段 cascade の worst case では、キャラクターを shadow map に 4 回描画する必要があります。さらに、キャラクター用 mesh は面数が多い傾向があり、skinned mesh 自体も CPU 側の overhead が高いため(ボーン計算は高コスト)、多段 cascade は CPU bound を招きやすくなります。
💡 ゲームプロジェクトで人物描画に使う skinned mesh renderer 自体が、もともと計算コストの高いオブジェクトであることを忘れないでください。
| 状況 | 推奨設定 |
|---|---|
| CPU bound だが bandwidth に余裕がある | Cascade Count を下げ、できるだけ 1 または 2 にします。その代わり、より大きい shadow map resolution(2048x2048 など)を使用できます。 |
| Bandwidth bound | shadow map resolution を下げます。 |
| 性能を最優先したい | 1 段 cascade を使用し、shadow map resolution を下げます。同時に clip distance を短くして近距離の影品質を上げ、高めの shadow fade ratio を使ってカメラが離れたときに影をフェードさせます。さらに遠距離では、偽の blob shadow へ切り替える構成が有効です(現在 ASP には含まれていません)。 |
Mesh Outline / Depth Offset Shadow
Mesh ベースの outline pass と Depth Offset Shadow pass は、通常の draw call と同じように扱われます(もちろん、これらの pass の per-pixel 計算量自体は非常に低いです)。そのため、これらの pass の実行時間は、描画対象となるオブジェクト数や複雑さにほぼ比例します。
したがって、Rendering Layer Mask を積極的に使い、これらの pass に描画されるオブジェクトを制御して、対象 renderer 数をできる限り減らしてください。
ポストプロセス Shader(スクリーンスペース輪郭線、Tone Mapping)
RTX 3060 Laptop 上での、ASP のポストプロセス pass と Unity の SSAO pass のパフォーマンス比較です。
| ポストプロセス効果 | 実行時間 |
|---|---|
| Unity SSAO | 0.6ms~0.95ms |
| ASP Screen Space Outline | 画面上でキャラクターが占める pixel 数に依存し、通常は 0.4ms~0.5ms、worst case では 0.95ms |
| ASP ToneMapping | 0.2ms |
スクリーンスペース輪郭線の計算では、エッジの細部を最大限に検出するために、_CameraDepthTexture と _CameraNormalTexture を複数回サンプリングし、Material Pass の RT も参照します。
ASP のエッジ検出におけるサンプリング回数は Sobel operator の半分以下ですが、検出できるディテールは Sobel operator と同等以上です。
Enable Scene Object Outline が無効な場合、スクリーンスペースアウトライン Shader は現在の pixel が ASP キャラクターかどうかを先に判定し、不要なシーン pixel の計算を省略します。そのため、画面上のキャラクター占有率が小さいほど、通常は低コストになります。Enable Scene Object Outline を有効にすると、有効な scene depth / normals を持つ非キャラクターオブジェクトも Depth / Normals edge の対象になるため、コストはフルスクリーン pass に近づきます。
現在の Screen Space Outline は単一のフル解像度パスを使用します。品質 enum、半解像度モード、アウトライン専用の追加 FXAA pass はありません。不要な edge タイプを無効にし、シーンにもアウトラインが必要な場合だけ Enable Scene Object Outline を有効にしてください。Tone Mapping は Tone Map Type の Volume override が有効なときだけ実行され、Ignore Character Pixels を有効にした場合だけ Material Pass とキャラクター depth を要求します。
Profiling 結果
以下は、RTX 3060 Laptop で 9 体のキャラクター(36 個の Skinned Mesh Renderer)がいるシーンを計測した nsight frame capture です。


Project Setting : Script Backend - Mono
Graphics API : DX 12
GPU Skinning : ON
Graphics Jobs : OFF
| ポストプロセス効果 | 占有 Frame Time |
|---|---|
| Unity SSAO | 0.61ms |
| ASP Shadow Map(Legacy/Unity 6.5 では利用不可) | 0.07ms |
| Draw OpaquesObjects | 0.45ms |
| ASP Tone Map Pass | 0.27ms |
| ASP Screen Space Outline | 0.61ms |
| Render Post Processing(Bloom..etc) | 0.35ms |
| Total Frame Time | 3.37ms (~270FPS) |
Draw OpaquesObjects の実行時間は、mesh の数と複雑さ、面数、そして draw call 数の影響を受けます。
mesh の複雑さによる影響を除くと、ASP Screen Space Outline は ASP の shader 群の中でも比較的高コストです。Outline + ToneMapping は 3060 Laptop 環境で合計およそ 0.8~1ms かかります。