Unity のレンダリングパイプライン
Replaced Shaders でのレンダリング

シェーダーを書く場合のパフォーマンスのヒント

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

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

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

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

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

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

計算の精度

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

できるかぎり低い精度を使用します。これは iOS や Android などモバイルプラットフォームでは特に重要です。経験則から以下のようにします。

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

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

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

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

アルファテスト

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

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

カラーマスク

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

Unity のレンダリングパイプライン
Replaced Shaders でのレンダリング