データ変換規則

次の各セクションでは、Direct3D 10 でデータ型の変換がどのように処理されるかについて説明します。

データ型の用語集

さまざまなフォーマット変換の特徴を説明するために、ここでは次の用語を使用します。

用語定義
SNORM符号付き正規化整数。n ビットの 2 の補数をとり、最大値は 1.0f で (たとえば、5 ビット値 01111 は 1.0f にマップされます)、最小値は -1.0f です (たとえば、5 ビット値 10000 は -1.0f にマップされます)。さらに、2 番目に小さい数値も -1.0f にマップされます (たとえば、5 ビット値 10001 は -1.0f にマップされます)。したがって、-1.0f には 2 つの整数表現があります。0.0f の整数表現は 1 つ、1.0f の整数表現も 1 つです。その結果、-1.0f ~ 0.0f の範囲の均等間隔の浮動小数点値に対する整数表現のセットと、同様に 0.0f ~ 1.0f の範囲の数値表現の補集合が存在することになります。
UNORM符号なし正規化整数。n ビットの数値では、すべての桁が 0 の場合は 0.0f、すべての桁が 1 の場合は 1.0f を表します。0.0f ~ 1.0f の均等な間隔の一連の浮動小数点値が表されます。たとえば、2 ビットの UNORM は、0.0f、1/3、2/3、および 1.0f を表します。
SINT符号付き整数です。2 の補数の整数です。たとえば、3 ビットの SINT は整数値の -4、-3、-2、-1、0、1、2、3 を表します。
UINT符号なし整数。たとえば、3 ビットの UINT は整数値の 0、1、2、3、4、5、6、7 を表します。
FLOATDirect3D 10 で定義された任意の表現の浮動小数点値。
SRGBn ビットの数値ですべての桁が 0 の場合は 0.0f、すべての桁が 1 の場合は 1.0f を表す点で UNORM と同様です。ただし、UNORM とは異なり、SRGB では、すべての桁が 0 である値からすべての桁が 1 である値までの符号なし整数エンコードのシーケンスは、0.0f ~ 1.0f の数値の浮動小数点で表した値に対して直線関係にはなりません。大まかにいえば、この非線形の数列である SRGB をカラーのシーケンスとして表示すると、平均的な視聴者には、平均的な表示条件下および平均的なディスプレイ上で、輝度レベルの直線的な変化に見えます。詳細については、IEC (国際電気標準会議) の SGRB カラー規格である IEC 61996-2-1 を参照してください。

浮動小数点の変換

浮動小数点以外の表現との変換を含め、さまざまな表現間で浮動小数点の変換が発生する場合、必ず以下の規則を適用します。

範囲が広い表現から範囲が狭い表現への変換

  • 別の浮動小数点形式への変換時には、ゼロへの丸め (round-to-zero) を使用します。変換先が整数または固定小数点形式の場合、最も近い偶数への丸め (round-to-nearest-even) を使用します。ただし、FLOAT から SNORM、FLOAT から UNORM、FLOAT から SRGB の各変換で使用する最も近い値への丸め (round-to-nearest) などのように、別の丸め動作を使用した変換が明示されている場合は除きます。この他の例外としてシェーダー命令の ftoi と ftou があります。この場合は、ゼロへの丸め (round-to-zero) を使用します。最後に、テクスチャーのサンプラーとラスタライザーで使用する浮動小数点から固定小数点への変換では、無限に理想的な精度に対する指定の許容誤差があります。この許容誤差は、ULP (Unit-Last-Place) の単位で表します。
  • 変換元の値のうち、変換先のダイナミック レンジより大きいものは (たとえば、大きな 32 ビットの浮動小数点値を 16 ビットの浮動小数点型 RenderTarget に書き込む場合)、表現可能な最大の値 (適切な符号付き) に変換されます。ただし、前述の round-to-zero により、符号付きの無限大にはなりません。
  • 範囲が広い形式にある NaN を範囲の狭い形式に変換する場合、その変換先の形式に該当の NaN 表現があればその表現に変換されます。範囲が狭い変換先の形式に NaN 表現がない場合、結果はゼロになります。
  • 範囲が広い形式にある INF を範囲が狭い形式に変換する場合、その変換先の形式に該当の INF があればその INF に変換されます。範囲が狭い変換先の形式に INF 表現がない場合、表現可能な最大の値に変換されます。符号は、変換先の形式で使用できれば保持されます。
  • 範囲が広い形式にある非正規化数を範囲が狭い形式に変換する場合、その変換先の形式に非正規化表現があり、その表現への変換が可能ならば、該当の非正規化表現に変換されます。それ以外の場合、結果はゼロになります。符号ビットは、変換先の形式で使用できれば保持されます。

範囲が狭い表現から範囲が広い表現への変換

  • 範囲が狭い形式にある NaN を範囲の広い形式に変換する場合、その変換先の形式に該当の NaN 表現があればその表現に変換されます。範囲が広い形式に NaN 表現がない場合は、ゼロに変換されます。
  • 範囲が狭い形式にある INF を範囲の広い形式に変換する場合、その変換先の形式に該当の INF 表現があればその表現に変換されます。範囲が広い形式に INF 表現がない場合、表現可能な最大の値 (その形式の MAX_FLOAT) に変換されます。符号は、変換先の形式で使用できれば保持されます。
  • 範囲が狭い形式にある非正規化数を範囲が広い形式に変換する場合、変換先の形式の正規化表現に変換可能であれば、その表現に変換されます。変換が不可能な場合、範囲が広い形式に該当の非正規化表現があれば、その表現に変換されます。範囲が広い形式に非正規化表現がなければ、ゼロに変換されます。符号は、変換先の形式で使用できれば保持されます。32 ビット浮動小数点型の数値は、非正規化表現のない形式として扱います (D3D10 では、32 ビット浮動小数点型の演算における非正規化数を、符号付きのゼロにフラッシュする必要があるからです)。

整数の変換

次の表で、前述のさまざまな表現から別の表現への変換について説明します。ここでは、Direct3D 10 で実際に発生する変換のみを掲載します。

変換元のデータ型変換先のデータ型変換規則
SNORMFLOAT

符号付きの -1.0f ~ 1.0f の範囲を表す n ビットの整数値から浮動小数点型への変換は次のとおりです。

  • 負数側の最小値が -1.0f にマップされます。たとえば、5 ビット値 10000 は -1.0f にマップされます。
  • その他の値はすべて浮動小数点型 (これを c とします) に変換され、結果は c * (1.0f / (2(n-1)-1)) となります。たとえば、5 ビット値 10001 は -15.0f に変換された後、15.0f で除算され、-1.0f となります。
FLOATSNORM

浮動小数点値から符号付きの -1.0f ~ 1.0f の範囲を表す n ビットの整数値への変換は次のとおりです。

  • 変換元の値を c とします。
  • c が NaN の場合、結果はゼロです。
  • c > 1.0f の場合 (INF を含む)、1.0f にクランプされます。
  • c < -1.0f の場合 (-INF を含む)、-1.0f にクランプされます。
  • 次のように浮動小数点のスケールから整数のスケールに変換します: c = c * (2n-1-1)
  • 次のように整数へ変換します。
    • c >= 0 ならば c = c + 0.5f とし、それ以外の場合は c = c - 0.5f とします。
    • 小数部を除外し、残りの浮動小数点値 (整数値) を整数に直接変換します。

この変換では、整数側で D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place ULP の誤差が許容されます。つまり、浮動小数点スケールから整数スケールへの変換後、変換先の表現可能な形式の値に対して D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ULP 以内にある値はすべてその変換先の値にマップできます。また、データ可換性の要件により、変換は範囲全体にわたって非減少であること、およびすべての出力値が達成可能であることが保証されます。

UNORMFLOAT

変換元の n ビット値は浮動小数点型 (0.0f、1.0f、2.0f など) に変換された後、(2n-1) で除算されます。

FLOATUNORM

変換元の値を c とします。

  • c が NaN の場合、結果はゼロです。
  • c > 1.0f の場合 (INF を含む)、1.0f にクランプされます。
  • c < 0.0f の場合 (-INF を含む)、0.0f にクランプされます。
  • 次のように浮動小数点のスケールから整数のスケールに変換します: c = c * (2n-1)
  • 整数に変換します。
    • c = c + 0.5f
    • 小数部を除外し、残りの浮動小数点値 (整数値) を整数に直接変換します。

この変換では、整数側で D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ULP の誤差が許容されます。つまり、浮動小数点スケールから整数スケールへの変換後、変換先の表現可能な形式の値に対して D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ULP 以内にある値はすべてその変換先の値にマップできます。また、データ可換性の要件により、変換は範囲全体にわたって非減少であること、およびすべての出力値が達成可能であることが保証されます。

SRGBFLOAT

SRGB から FLOAT への最適な変換は次のとおりです。

  • 変換元の n ビット値を浮動小数点型 (0.0f、1.0f、2.0f など) に変換します。これを c とします。
  • c = c * (1.0f / (2n-1))
  • c < = D3D10_SRGB_TO_FLOAT_THRESHOLD の場合、結果は c / D3D10_SRGB_TO_FLOAT_DENOMINATOR_1 です。それ以外の場合、結果は ((c + D3D10_SRGB_TO_FLOAT_OFFSET)/D3D10_SRGB_TO_FLOAT_DENOMINATOR_2)D3D10_SRGB_TO_FLOAT_EXPONENT となります。

この変換では、SRGB 側で D3D10_SRGB_TO_FLOAT_TOLERANCE_IN_ULP ULP の誤差が許容されます。

FLOATSRGB

FLOAT から SRGB への最適な変換は次のとおりです。

変換先の SRGB カラー成分を n ビットと仮定します。

  • 変換元の値を c とします。
  • c が NaN の場合、結果はゼロです。
  • c > 1.0f の場合 (INF を含む)、1.0f にクランプされます。
  • c < 0.0f の場合 (-INF を含む)、0.0f にクランプされます。
  • c <= D3D10_FLOAT_TO_SRGB_THRESHOLD の場合、c = D3D10_FLOAT_TO_SRGB_SCALE_1 * c です。それ以外の場合、c = D3D10_FLOAT_TO_SRGB_SCALE_2 * c(D3D10_FLOAT_TO_SRGB_EXPONENT_NUMERATOR/D3D10_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR) - D3D10_FLOAT_TO_SRGB_OFFSET となります。
  • 次のように浮動小数点のスケールから整数のスケールに変換します: c = c * (2n-1)
  • 整数に変換します。
    • c = c + 0.5f
    • 小数部を除外し、残りの浮動小数点値 (整数値) を整数に直接変換します。

この変換では、整数側で D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ULP の誤差が許容されます。つまり、浮動小数点スケールから整数スケールへの変換後、変換先の表現可能な形式の値に対して D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ULP 以内にある値はすべてその変換先の値にマップできます。また、データ可換性の要件により、変換は範囲全体にわたって非減少であること、およびすべての出力値が達成可能であることが保証されます。

SINTよりビット数が多い SINT

SINT からそれよりもビット数が多い SINT に変換する場合、変換元の数値の最上位ビット (MSB) が変換先の形式の追加ビットに符号拡張 (sign-extended) されます。

UINTよりビット数が多い SINT

UINT からそれよりもビット数が多い SINT に変換する場合、その数値が変換先の形式の最下位ビット (LSB) 側にコピーされ、余った MSB 側ビットがゼロで埋められます。

SINTよりビット数が多い UINT

SINT からそれよりもビット数が多い UINTに変換する場合、負の値はゼロにクランプされます。それ以外の数値は変換先の形式の LSB 側にコピーされ、余った MSB 側がゼロで埋められます。

UINTよりビット数が多い UINT

UINT からそれよりもビット数が多い UINT に変換する場合、その数値が変換先の形式の LSB 側にコピーされ、余った MSB 側がゼロで埋められます。

SINT または UINTビット数が同じか少ない SINT または UINT

SINT または UINT からビット数が同じか少ない SINT または UINT に変換 (符号の有無の変更を伴うことも可) する場合、変換元の値が変換先の形式の範囲に単純にクランプされます。

固定小数点整数の変換

固定小数点整数とは単に、暗黙の小数点が固定位置にある一定のビット長の整数です。

よく使用されるデータ型「整数」は、数値の末尾に小数点を置いた、固定小数点整数の特殊なケースです。

固定小数点数は i.f という形式で表現します。i は整数部ビット数、f は小数部ビット数を表します。たとえば、16.8 は 16 ビットの整数の後ろに 8 ビットの小数が続くことを示します。整数部は、少なくともここでの定義では、2 の補数として格納されます (符号なし整数についても同様です)。小数部は符号なしの形式で格納されます。小数部は、負数側の最小値から、互いに最も近い 2 つの整数値の間で必ず正の小数となります。

固定小数点数に対する加算演算および減算演算は、単純に通常の整数演算で実行します。暗黙の小数点の位置は考慮されません。16.8 の固定小数点数に対する 1 の加算は、この数値の最下位端から 8 桁は小数部なので、256 を加算することを意味します。乗算などのその他の演算も、固定小数点への影響を考慮したうえで、単純に整数演算によって実行できます。たとえば、2 つの 16.8 の整数を整数乗算すると、結果は 32.16 になります。

Direct3D 10 では、次の 2 つの状況で固定小数点整数表現を使用します。

  • ラスタライザーでのクリップ後の頂点位置は固定小数点にスナップされ、RenderTarget 領域全体で精度分布が均一になります。面のカリングをはじめ、多くのラスタライザー処理は固定小数点のスナップ位置で発生しますが、属性のインターポレータ セットアップなどの処理では、固定小数点のスナップ位置から浮動小数点に逆変換した位置を使用します。
  • フィルターのタップ位置/重みの選択では、サンプリング処理のテクスチャー座標が (テクスチャー サイズに合わせてスケーリングされた後) 固定小数点にスナップされ、テクスチャー領域全体で精度分布が均一になります。重み値は、実際のフィルタリング演算を実行する前に浮動小数点に逆変換します。
変換元のデータ型変換先のデータ型変換規則
FLOAT固定小数点整数

浮動小数点型の数値 n を固定小数点整数 i.f に変換する一般的な手順は次のとおりです。ここで、i は整数部ビット数 (符号付き)、f は小数部ビット数です。

  • FixedMin = -2(i-1) を計算します。
  • FixedMax = 2(i-1) - 2(-f) を計算します。
  • n が NaN の場合、結果はゼロです。n が +Inf の場合の結果は FixedMax*2fで、n が -Inf の場合の結果は FixedMin*2f です。
  • n >= FixedMax の場合の結果は Fixedmax*2f で、n <= FixedMin の場合の結果は FixedMin*2f です。
  • それ以外の場合は、n*2f を計算して整数に変換します。

Direct3D 10 の実装では、上の最後の手順実行で得られた整数と無限大精度値 n*2f との比較で、D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place ULP の誤差が許容されます。

固定小数点整数FLOAT

浮動小数点型に変換する固定小数点表現があり、その合計ビット数は 24 ビット以下で、うち小数部は 23 ビット以下であるとします。特定の固定小数点数 fxp を i.f の形式とします (i ビットの整数、f ビットの小数)。浮動小数点型への変換は次に示すコードのようになります。

 float result = (float)(fxp >> f) +              // extract integer                ((float)(fxp & (2f - 1)) / (2f)); // extract fraction             

関連項目

リソース (Direct3D 10)

表示: