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
にあたります) で行われています。浮動小数点には、float
、half
、fixed
などのいくつかの型があります (ベクトル/行列のバリアントである 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 (中精度) を使用します。計算で精度にいくらか不十分な個所がある場合にのみ、精度を上げます。
計算に使用される精度が異なる GPU グループ (ほとんどモバイル) によって異なるように、特別な浮動小数点値のサポートも異なります。
Direct3D 10 をサポートするすべての PC GPU は IEEE 754 で規定された浮動小数点の基準を適用しています。 つまり、浮動小数点数は、CPU 上での 通常のプログラミング言語によるものとまったく同じように機能するという事です。
モバイル GPU の中には、若干異なるレベルのサポートをするものがあります。0 を 0 で割ると NaN (非数)になるものもあれば、 無限大を返すものや、 0 もしくはその他の指定外の値になるものもあります。ターゲットとしているデバイスでシェーダーをテストし、サポートされていることを確認することを忘れないでください。
GPU 製造者が GPU の詳しいパフォーマンスや機能に関する手引きを提供しています。 以下を参照してください。