Version: 2022.1
言語: 日本語
Understanding shader performance
Visual Studio を使ったシェーダーのデバッグ

シェーダーのランタイムパフォーマンスの最適化

異なる種類のプラットフォームには、かなり大きなパフォーマンス能力の違いがあります。ハイエンドの PC GPU はグラフィックスとシェーダーの面で、ローエンドのモバイル GPU に比べ、ずいぶん多くを処理できます。個々のプラットフォームに関しても同じことが言えます。GPU が速いと、GPU が遅いものに比べ、十数倍速く処理を行います。

GPU performance on mobile platforms and low-end PCs is likely to be much lower than on your development machine. It’s recommended that you manually optimize your shaders to reduce calculations and texture reads, in order to get good performance across low-end GPU machines. For example, some built-in Shader objects have “mobile” equivalents that are much faster, but have some limitations or approximations.

This page contains information on optimizing your shaders for runtime performance.

必要なものだけを計算する

シェーダーコードが行う計算や処理が多ければ多いほど、ゲームのパフォーマンスに影響を与えます。例えば、各マテリアルごとのカラーをサポートするのはシェーダーを柔軟にするにはよいですが、常にカラーが白のままに設定すると、画面上にレンダリングされる各頂点やピクセルのために不要な計算が行われます。

もう一つ頭に入れておくべきことは計算の頻度です。通常、ピクセル(ピクセルシェーダーとして実行)のほうが頂点(頂点シェーダーとして実行)より多くのがレンダリングされ、さらに頂点ほうがオブジェクトより多くレンダリングされます。このため、一般的にはできることならば、ピクセルシェーダーコードの計算を頂点シェーダーコードに移動する、あるいはシェーダーから計算を完全に除いてスクリプトから値を設定するようにします。

計算の精度

Cg/HLSL でシェーダーを書く場合、3 つの基本的な数値タイプがあります。 floathalffixed です(詳細は シェーダーのデータタイプと精度 ページを参照してください)。

For good performance, always use the lowest precision that is possible. This is especially important on lower-end hardware. Good rules of thumb are:

  • ワールド空間の位置とテクスチャ座標には、float 型を使用してください。
  • 上記以外 (ベクトル、HDR カラーなど) には、half で始めます。必要なときだけ、増加します。
  • テクスチャデータのとても簡易な操作には、fixed を使用します。

実際には、正確にはどの数の型を使用すべきかは、プラットフォームや GPU に依存します。一般的な概要は以下のとおりです。

  • あらゆる現代のデスクトップ GPU は、常にすべての事を完全な 浮動小数点数精度で計算していて、そのため、根底では float/half/fixed の結果はまったく同じになります。この事がテストを少し困難にしており、half/fixed の精度で実際は十分なのかどうか、PC上では判りにくいです。作成したシェーダーを、実際にモバイルデバイスで試してください。
  • モバイル GPU は実質的な 精度浮動小数点数をサポートしており、大抵は計算がより早く、より省エネです。
  • Fixed の精度は、一般的に古いモバイル GPU でのみ使いやすいものです。現代の多くの GPU(OpenGL ES 3 や Metal を実行することができるもの)は 固定 小数点数と 精度浮動小数点数を、内部的にはまったく同じものとして取り扱います。

詳細は、シェーダーのデータタイプと精度 を参照してください。

Complex mathematical operations

Transcendental mathematical functions (such as pow, exp, log, cos, sin, tan) are quite resource-intensive, so avoid using them where possible on low-end hardware. Consider using lookup textures as an alternative to complex math calculations if applicable.

独自の操作 (normalizedotinversesqrt など) を書くことを避けてください。Unity のビルトインオプションは、ドライバがより優れたコードを生成できることを確証しています。アルファテスト (discard) の操作がしばしばフラグメントシェーダーを遅くすることに気を付けてください。

汎用サーフェイスシェーダーを減らす

サーフェスシェーダー はライティングと相互作用するシェーダーを書く場合に優れています。しかし、これらのデフォルトのオプションは、ある特定の状況向けに最適化されているのではなく、一般的なケース向けに対応できるようになっています。多くの場合、それを微調整することでシェーダーの実行を速くするか、サイズを小さくすることができます。

  • approxview ディレクティブは、ビュー方向を使用するシェーダー(鏡面)のためにあり、ピクセルごとでなく頂点ごとにビュー方向を正規化します。概算ですが、通常はこれで十分です。
  • halfasview は鏡面シェーダータイプをさらに早くします。Half-vector (ライティング方向とビューベクトルの中間)が計算され頂点ごとに正規化され、ライティングの関数 はあらかじめ、中間ベクトルをビューベクトルの代わりに、引数として受け取ります。
  • noforwardadd によりシェーダーは、フォワードレンダリングで指向性ライトのみ完全にサポートします。残りのライトは、頂点ライトや球面調和としてのエフェクトを、引き続き表現することができます。これはシェーダーを小さくすることに優れていて、複数のライトが存在していても、常にひとつのパスでレンダリングされます。
  • noambient により、シェーダーの環境光ライティングおよび球面調和を、無効化しますこれによりわずかに速くなります。

アルファテスト

固定関数の アルファテストやそのプログラマブル同等物である clip() は、異なるプラットフォームで異なるパフォーマンス特性を示します。

  • 一般的に、ほとんどのプラットフォームで、完全に透過のピクセルのカリングを使用するのは小さな利点があります。
  • しかし、iOS といくつかの Android デバイスでみられる PowerVR GPU では、アルファテストは高価です。ゲームがかえって遅くなるため、このプラットフォームでは、パフォーマンス最適化として使用しないでください。

カラーマスク

いくつかのプラットフォーム(たいてい、モバイル GPU は iOS と Android デバイスでみられます)では、ColorMask を使用してチャネルを除くこと(すなわち ColorMask RGB )は、高価であり、本当に必要な場合のみ使用してください。

Understanding shader performance
Visual Studio を使ったシェーダーのデバッグ