次の方法で共有


データ型の変換

次のセクションでは、Direct3D がデータ型の間の変換を処理する方法について説明します。

データ型に関する用語

さまざまな形式変換の特徴を示すために、今後、次の用語のセットを使用します。

任期 定義
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) 内の等間隔浮動小数点値には 1 セットの整数表現があり、範囲 (0.0f...1.0f) 内の数値には 1 セットの補数表現があります。
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 を表します。
FLOAT Direct3D によって定義された任意の表現の浮動小数点値。
SRGB UNORM と同様に、n ビットの数値の場合、すべて 0 であると 0.0f を意味し、すべて 1 であると 1.0f を意味します。 ただし、UNORM とは異なり、SRGB では、すべて 0 からすべて 1 の間の符号なし整数エンコードのシーケンスは、数値の浮動小数点解釈において 0.0f から 1.0f までの非線形の増加を表現します。 大まかに言えば、この非線形増加である SRGB が一連の色として表示される場合、"平均的な" ディスプレイで "平均的な" 表示条件の下、"平均的な" 観察者に対して光度レベルが線形に増加していくように見えます。 詳細については、IEC (国際電気標準会議) の SRGB 色標準 IEC 61996-2-1 を参照してください。

 

上記の用語は、多くの場合、"形式名修飾子" として使用されます。ここでは、メモリ内でのデータのレイアウト方法と、メモリとシェーダーなどのパイプライン ユニットとの間の転送パスで実行する変換 (フィルター処理を含む可能性あり) の両方について説明します。

浮動小数点の変換

浮動小数点以外の表現との間も含め、異なる表現間で浮動小数点変換が行われるたびに、次のルールが適用されます。

高い範囲表現から低い範囲表現への変換

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

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

  • 範囲が狭い形式での NaN は、範囲が広い形式で使用可能な場合は、範囲が広い形式での NaN 表現に変換されます。 範囲が広い形式に NaN 表現がない場合は、0 に変換されます。
  • 範囲が狭い形式での INF は、範囲が広い形式で使用可能な場合は、範囲が広い形式での INF 表現に変換されます。 範囲が広い形式に INF 表現がない場合、表現可能な最大の値 (その形式の MAX_FLOAT) に変換されます。 ターゲット形式で使用できる場合、符号は保持されます。
  • 範囲が狭い形式での非正規化数は、可能な場合は範囲が広い形式で正規化された表現に変換され、可能でない場合で非正規化表現が存在すれば、範囲が広い形式での非正規化表現に変換されます。 これらの条件が成り立たない場合で、範囲が広い形式に非正規化表現がない場合は、0 に変換されます。 ターゲット形式で使用できる場合、符号は保持されます。 32 ビット浮動小数点数は、非正規化表現のない形式としてカウントされることに注意してください (32 ビット浮動小数点数での演算で非正規化数は符号を保持した 0 にフラッシュされるため)。

整数の変換

次の表では、上記のさまざまな表現から他の表現への変換について説明します。 Direct3D で実際に発生する変換のみが表示されます。

整数では、特に指定しない限り、以下で説明する整数表現から浮動小数点表現への変換および逆方向の変換はすべて正確に行われます。

変換元のデータ型 変換先のデータ型 変換規則
SNORM FLOAT

符号付き範囲 [-1.0f から 1.0f] を表す n ビット整数値については、浮動小数点への変換は次のようになります。

  • 負の最小値は -1.0f にマップされます。 たとえば、5 ビット値 10000 は -1.0f にマップされます。
  • 他のすべての値は浮動小数点数に変換され (c と呼びます)、結果は c * (1.0f / (2⁽ⁿ⁻¹⁾-1)) になります。 たとえば、5 ビット値 10001 は -15.0f に変換してから 15.0f で除算され、-1.0f になります。
FLOAT SNORM

浮動小数点数については、符号付き範囲 [-1.0f から 1.0f] を表す n ビット整数値への変換は次のようになります。

  • c は最初の値を表します。
  • c が NaN の場合、結果は 0 になります。
  • c > 1.0f の場合 (INF の場合を含む)、1.0f にクランプされます。
  • c < -1.0f の場合 (-INF の場合を含む)、-1.0f にクランプされます。
  • 浮動小数点スケールから整数スケールに変換します: c = c * (2ⁿ⁻¹-1)。
  • 次のように整数に変換します。
    • c >= 0 の場合、c = c + 0.5f、それ以外の場合、c = c - 0.5f。
    • 小数部を切り捨て、残りの浮動小数点 (整数) 値が整数に直接変換されます。

この変換では、D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place Unit-Last-Place の許容誤差があります (整数側)。 これは、浮動小数点から整数スケールに変換した後、表現可能なターゲット形式の値の D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place 以内の任意の値がその値にマップされていることが許容されることを意味します。 データ反転可能性に関する追加の要件により、変換が範囲全体で非減少であり、すべての出力値に到達可能であることが保証されます。 (ここに示す定数では、xx は 10、11、12 などの Direct3D バージョンに置き換える必要があります。)

UNORM FLOAT

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

FLOAT UNORM

c は最初の値を表します。

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

この変換では、D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place の許容誤差があります (整数側)。 これは、浮動小数点から整数スケールに変換した後、表現可能なターゲット形式の値の D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place 以内の任意の値がその値にマップされていることが許容されることを意味します。 データ反転可能性に関する追加の要件により、変換が範囲全体で非減少であり、すべての出力値に到達可能であることが保証されます。

SRGB FLOAT

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

  • 変換元は n ビット値であるとして、浮動小数点型 (0.0f、1.0f、2.0f など) に変換します。これを c と呼びます。
  • c = c * (1.0f / (2ⁿ-1))
  • If (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) then: result = c / D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_1, else: result = ((c + D3Dxx_SRGB_TO_FLOAT_OFFSET)/D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_2)D3Dxx_SRGB_TO_FLOAT_EXPONENT

この変換では、D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP Unit-Last-Place の許容誤差があります (整数側)。

FLOAT SRGB

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

ターゲット SRGB カラー コンポーネントは n ビットと仮定します。

  • 最初の値は c であるとします。
  • c が NaN の場合、結果は 0 になります。
  • c > 1.0f の場合 (INF の場合を含む)、1.0f にクランプされます。
  • c < 0.0f の場合 (-INF の場合を含む)、0.0f にクランプされます。
  • If (c <= D3Dxx_FLOAT_TO_SRGB_THRESHOLD) then: c = D3Dxx_FLOAT_TO_SRGB_SCALE_1 * c, else: c = D3Dxx_FLOAT_TO_SRGB_SCALE_2 * c(D3Dxx_FLOAT_TO_SRGB_EXPONENT_NUMERATOR/D3Dxx_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR) - D3Dxx_FLOAT_TO_SRGB_OFFSET
  • 浮動小数点スケールから整数スケールに変換します: c = c * (2ⁿ-1)。
  • 次のように整数に変換します。
    • c = c + 0.5f。
    • 小数部を切り捨て、残りの浮動小数点 (整数) 値が整数に直接変換されます。

この変換では、D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place の許容誤差があります (整数側)。 これは、浮動小数点から整数スケールに変換した後、表現可能なターゲット形式の値の D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place 以内の任意の値がその値にマップされていることが許容されることを意味します。 データ反転可能性に関する追加の要件により、変換が範囲全体で非減少であり、すべての出力値に到達可能であることが保証されます。

SINT ビット数が多い SINT

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

UINT ビット数が多い SINT

UINT からそれよりもビット数が多い SINT に変換する場合、数値がターゲット形式の下位ビットにコピーされ、その他の上位ビットに 0 が埋め込まれます。

SINT ビット数が多い UINT

SINT からそれよりもビット数が多い UINT に変換する場合、負であれば、値は 0 にクランプされます。 それ以外の場合、数値はターゲット形式の下位ビットにコピーされ、その他の上位ビットに 0 が埋め込まれます。

UINT ビット数が多い UINT

UINT からそれよりもビット数が多い UINT に変換する場合、数値がターゲット形式の下位ビットにコピーされ、その他の上位ビットに 0 が埋め込まれます。

SINT または UINT ビット数が少ない、または等しい SINT または UINT

SINT または UINT からそれよりもビット数が少ないか等しい SINT または UINT に変換する場合 (および/または符号付きかどうかを変更する場合)、変換元の値は単にターゲット形式の範囲にクランプされます。

 

固定小数点整数変換

固定小数点整数は、固定の場所に暗黙的な小数点を持ついくつかのビット サイズの整数です。

ユビキタス "整数" データ型は、数値の末尾に小数点を持つ固定小数点整数の特殊なケースです。

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

固定小数点数に対する加算と減算は、暗黙的な小数点がどこにあるかを考慮せずに、単に標準の整数演算を使用して実行されます。 16.8 の固定小数点数 に 1 を加えることは、小数点が数値の最下位端から 8 桁目にあるため、256 を加算することを意味します。 乗算などの他の演算は、固定小数点への影響が考慮されていれば、単に整数演算を使用して同様に実行できます。 たとえば、整数乗算を使用して 16.8 の整数を 2 つ乗算すると、32.16 の結果が生成されます。

固定小数点整数表現は、Direct3D では 2 つの方法で使用されます。

  • ラスタライザー内のクリップ後の頂点位置は固定小数点にスナップされ、RenderTarget 領域全体に精度が均一に分散されます。 一例としてフェイス カリングを含む多くのラスタライザー演算は固定小数点スナップ位置で発生しますが、属性補間の設定など他の演算では、固定小数点スナップ位置から浮動小数点に変換された位置が使用されます。
  • サンプリング演算のテクスチャ座標は、(テクスチャ サイズでスケーリングされた後に) 固定小数点にスナップされ、フィルタータップの位置/重みを選択する際にテクスチャ空間間で精度が均一に分散されます。 重みの値は、実際のフィルター演算が実行される前に再び浮動小数点に変換されます。
変換元のデータ型 変換先のデータ型 変換規則
FLOAT 固定小数点整数

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

  • FixedMin = -2⁽ⁱ⁻¹⁾ を計算します
  • FixedMax = 2⁽ⁱ⁻¹⁾ - 2(-f) を計算します
  • n が NaN の場合、結果は 0 です。n が +Inf の場合、結果は FixedMax*2f です。n が -Inf の場合、結果は FixedMin*2f です
  • n >= FixedMax の場合、結果は Fixedmax*2f です。n <= FixedMin の場合、結果は FixedMin*2f です
  • それ以外の場合は、n*2f を計算し、整数に変換します。

実装に対しては、上記の手順を最後まで実行した後の値は、無限に正確な値 n*2f ではなく、整数の結果として D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place の誤差が許容されています。

固定小数点整数 FLOAT

浮動小数点に変換される特定の固定小数点表現に、合計 24 ビットを超える情報が含まれていないとし、そのうち小数部に含まれるのは 23 ビット以下だとします。 指定された固定小数点数 fxp が i.f 形式 (i ビットの整数部、f ビットの小数部) であるとします。 浮動小数点への変換は、次の擬似コードと同様になります。

float result = (float)(fxp >> f) + // 整数部を抽出する

((float)(fxp & (2f - 1)) / (2f)); // 小数部を抽出する

 

付録