異なる種類のプラットフォームには、かなり大きなパフォーマンス能力の違いがあります。ハイエンドの 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 つの基本的な数値タイプがあります。 float
、half
、fixed
です(詳細は シェーダーのデータタイプと精度 ページを参照してください)。
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
型を使用してください。half
で始めます。必要なときだけ、増加します。fixed
を使用します。実際には、正確にはどの数の型を使用すべきかは、プラットフォームや GPU に依存します。一般的な概要は以下のとおりです。
浮動
小数点数精度で計算していて、そのため、根底では float/half/fixed
の結果はまったく同じになります。この事がテストを少し困難にしており、half/fixed の精度で実際は十分なのかどうか、PC上では判りにくいです。作成したシェーダーを、実際にモバイルデバイスで試してください。半
精度浮動小数点数をサポートしており、大抵は計算がより早く、より省エネです。Fixed
の精度は、一般的に古いモバイル GPU でのみ使いやすいものです。現代の多くの GPU(OpenGL ES 3 や Metal を実行することができるもの)は 固定
小数点数と 半
精度浮動小数点数を、内部的にはまったく同じものとして取り扱います。詳細は、シェーダーのデータタイプと精度 を参照してください。
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.
独自の操作 (normalize
、dot
、inversesqrt
など) を書くことを避けてください。Unity のビルトインオプションは、ドライバがより優れたコードを生成できることを確証しています。アルファテスト (discard
) の操作がしばしばフラグメントシェーダーを遅くすることに気を付けてください。
サーフェスシェーダー はライティングと相互作用するシェーダーを書く場合に優れています。しかし、これらのデフォルトのオプションは、ある特定の状況向けに最適化されているのではなく、一般的なケース向けに対応できるようになっています。多くの場合、それを微調整することでシェーダーの実行を速くするか、サイズを小さくすることができます。
approxview
ディレクティブは、ビュー方向を使用するシェーダー(鏡面)のためにあり、ピクセルごとでなく頂点ごとにビュー方向を正規化します。概算ですが、通常はこれで十分です。halfasview
は鏡面シェーダータイプをさらに早くします。Half-vector (ライティング方向とビューベクトルの中間)が計算され頂点ごとに正規化され、ライティングの関数 はあらかじめ、中間ベクトルをビューベクトルの代わりに、引数として受け取ります。noforwardadd
によりシェーダーは、フォワードレンダリングで指向性ライトのみ完全にサポートします。残りのライトは、頂点ライトや球面調和としてのエフェクトを、引き続き表現することができます。これはシェーダーを小さくすることに優れていて、複数のライトが存在していても、常にひとつのパスでレンダリングされます。noambient
により、シェーダーの環境光ライティングおよび球面調和を、無効化しますこれによりわずかに速くなります。固定関数の アルファテストやそのプログラマブル同等物である clip()
は、異なるプラットフォームで異なるパフォーマンス特性を示します。
いくつかのプラットフォーム(たいてい、モバイル GPU は iOS と Android デバイスでみられます)では、ColorMask を使用してチャネルを除くこと(すなわち ColorMask RGB
)は、高価であり、本当に必要な場合のみ使用してください。