Version: 2017.2
シェーダーコンパイルターゲットレベル
サンプラー状態の利用

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

The standard Shader language in Unity is HLSL, and general HLSL data types are supported. However, Unity has some additions to the HLSL types, particularly for better support on mobile platforms.

基本的なデータタイプ

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

高精度: float

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

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

中精度: half

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

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

低精度: fixed

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

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

整数データ型

整数 (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;

For mobile platforms, these translate into “low precision samplers”, i.e. the textures are expected to have low precision data in them. If you know your texture contains HDR colors, you might want to use half precision sampler:

sampler2D_half _MainTex;
samplerCUBE_half _Cubemap;

Or if your texture contains full float precision data (e.g. depth texture), use a full precision sampler:

sampler2D_float _MainTex;
samplerCUBE_float _Cubemap;

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

One complication of float/half/fixed data type usage is that PC GPUs are always high precision. That is, for all the PC (Windows/Mac/Linux) GPUs, it does not matter whether you write float, half or fixed data types in your shaders. They always compute everything in full 32-bit floating point precision.

The half and fixed types only become relevant when targeting mobile GPUs, where these types primarily exist for power (and sometimes performance) constraints. Keep in mind that you need to test your shaders on mobile to see whether or not you are running into precision/numerical issues.

Even on mobile GPUs, the different precision support varies between GPU families. Here’s an overview of how each mobile GPU family treats each floating point type (indicated by the number of bits used for it):

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 (頂点)、24 (フラグメント)
ARM Mali T6xx/7xx 32 16
ARM Mali 400/450 32 (頂点)、16 (フラグメント)
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 の詳しいパフォーマンスや機能に関する手引きを提供しています。 以下を参照してください。

関連項目

シェーダーコンパイルターゲットレベル
サンプラー状態の利用