シェーダーコンパイルターゲットレベル
ShaderLab シンタックス

シェーダーのデータタイプと精度

Unity の標準的なシェーダー記述言語は Cg/HLSL です。 そして、一般的な HLSL のデータタイプをサポートしています。さらに、Unity には 特にモバイルプラットフォームのサポートをより強化するために、 HLSL タイプに、いくらか追加があります。

基本的なデータタイプ

シェーダーの計算の大半は浮動小数点 (C# などの標準的なプログラミング言語では float にあたります) で行われています。浮動小数点には、いくつかタイプがあります: floathalf そして fixed です ( vector/matrix が持つバリエーション half3 や `float4x4 などと同様です) 。これらのタイプでは精度 (および、精度の違いから生じるパフォーマンスや消費電力) が異なります。

高精度: float

float は最高精度の浮動小数点値で、通常のプログラミング言語の float と同じように一般な 32 ビットです。

ワールド空間位置、テクスチャ座標、複雑な関数を含むスカラー計算 (三角法、累乗法など) には、 たいてい 32 ビットの float が使用されます。

中精度: half

half は中精度の浮動小数点値で、一般に 16 ビットです (–60000 から +60000 の範囲で、小数点以下約 3 桁)。

Half は、ショートベクトル、方向、オブジェクト空間位置、HDR カラー に使用されます。

低精度: half

fixed は低精度で、固定小数点数です。一般的に 11 ビットで、–2.0 から +2.0 の範囲で、1/256 精度です。

固定精度は、標準カラー (一般的に標準テクスチャに保管されるので) とそれらの単純な制御に使用されます。

整数データ型

整数 (int データ型) はしばしばループカウンターや配列のインデックスとして使用されます。そのため、通常は、さまざまなプラットフォームで問題なく使用できます。

プラットフォームによっては、整数型がGPU にサポートされていないことがあります。例えば、Direct3D 9 と OpenGL ES 2.0 GPU は、浮動小数点データ上でのみ作動します。そのため、シンプルに見える整数表現 (ビットやロジカルオペレーションに関する) は、ある程度複雑な浮動小数点の数式を使用してエミュレーションされていることがあります。

Direct3D 11、OpenGL ES 3、Metal やその他の現段階で使用されている多くのプラットフォームでは、整数のデータ型は適切にサポートされています。そのため、ビットシフトやビットマスクを使用しても、想定通り作動します。

ベクトル型、行列型の作成

HLSL には、基本の型から作成されたビルトインのベクトル型と行列型があります。例えば、float3 は .x、.y、.z コンポーネントを含む 3D ベクトルです。また、half4 は、中精度の 4D ベクトル (.x、.y、.z、.w コンポーネントを含む) です。あるいは、カラーを使用するときに有用な .r、.g、.b、.a コンポーネントを使用して、ベクトルをインデックス化することができます。

行列型も同様に作成されます。例えば、float4x4 は 4x4 変換行列です。プラットフォームによっては、OpenGL ES 2.0 でよく知られているように正方行列だけしかサポートしないものもあるので注意してください。

テクスチャ/サンプラー型

一般的に、HLSL コード内のテクスチャを以下のように宣言します。

sampler2D _MainTex;
samplerCUBE _Cubemap;

モバイルプラットフォーム用に、データは「低精度」に変換されます。 つまり、それらのテクスチャのデータは低精度であるといえます。 テクスチャに HDR カラーを使用する場合は、 中精度 (half) のサンプラーを使用します。

sampler2D_half _MainTex;
samplerCUBE_half _Cubemap;

テクスチャに float 浮動小数点型データ (例えば Depth Texture) を使用している場合は、 高精度のサンプラーを使用してください。

sampler2D_float _MainTex;
samplerCUBE_float _Cubemap;

精度、ハードウェアのサポートとパフォーマンス

float/half/fixed データ型の使用で 1 つ問題となることは、PC の GPU は 常に 高精度だということです。 つまり、シェーダーを float, half , fixed のどのデータ型で作成しようと、 PC (Windows/Mac/Linux) の GPU にとっては まったく 関係ないということです。 どんな PC も常に、すべてを 32 ビットの浮動小数点精度で計算します。

halffixed 型はモバイル GPU をターゲットとしている場合に関連があります。これらの型は、主に省エネのためで、パフォーマンスや制約の理由で使用されることもあります。

必ずモバイル上でシェーダーをテストして、 精度や数の問題の有無を確認するようにしてください。

モバイル GPU の中でさえ、精度のサポートは GPU のグループによって異なります。 以下は、各 GPU グループでの、浮動小数点データ型 (使用ビット数で表示) の適用概要です。

GPU グループ float half fixed
PowerVR Series 6/7 32 16
PowerVR SGX 5xx 32 16 11
Qualcomm Adreno 4xx/3xx 32 16
Qualcomm Adreno 2xx 32 vertex 24 fragment
ARM Mali T6xx/7xx 32 16 11
ARM Mali 400/450 32 vertex 16 fragment
NVIDIA X1 32 16
NVIDIA K1 32
NVIDIA Tegra 3/4 32 16

表のように、現段階で一般的に使用されているモバイル GPU のほとんどでは、 32 ビット (float 型) か 16 ビットの数 (half 型 と fixed 型) のいずれかがサポートされています。 旧 GPU の中には、頂点シェーダーとフラグメントシェーダーの計算に表とは異なる精度を使用しているものもあります。

低精度を使用すると、向上した GPU メモリアロケーションか、 低精度計算用の特別な「高速パス」実行ユニットのおかげで、しばしば短時間で処理が済みます。 本来の性能の利益がない場合でさえ、低精度を使用することにより、GPU の電力消費を抑え、バッテリーを長持ちさせることができます。

一般的に推奨される使用法は、位置とテクスチャ座標を除くすべてに half (中精度) を使用します。計算で精度にいくらか不十分な個所がある場合にのみ、精度を上げます。

無限、NaN、他の特別な浮動小数点値の適用

計算に使用される精度が異なる GPU グループ (ほとんどモバイル) によって異なるように、特別な浮動小数点値のサポートも異なります。

Direct3D 10 をサポートするすべての PC GPU は IEEE 754 で規定された浮動小数点の基準を適用しています。 つまり、浮動小数点数は、CPU 上での 通常のプログラミング言語によるものとまったく同じように機能するという事です。

モバイル GPU の中には、若干異なるレベルのサポートをするものがあります。0 を 0 で割ると NaN (非数)になるものもあれば、 無限大を返すものや、 0 もしくはその他の指定外の値になるものもあります。ターゲットとしているデバイスでシェーダーをテストし、サポートされていることを確認することを忘れないでください。

外部 GPU ドキュメンテーション

GPU 製造者が GPU の詳しいパフォーマンスや機能に関する手引きを提供しています。 以下を参照してください。

関連項目

シェーダーコンパイルターゲットレベル
ShaderLab シンタックス