9

ここに示されている HLSL の mul( x, y) のパラメーター:

  • x がベクトルの場合、行ベクトルとして扱われます。
  • y がベクトルの場合、列ベクトルとして扱われます。

これは次のことを意味しますか?

を。

  • x がベクトルの場合、y はrow-major matrix
  • y がベクトルの場合、x はcolumn-major matrix

b.

ID3DXBaseEffect::SetMatrix() は を渡すrow-major matrixため、次の順序でシェーダーに渡されたマトリックスを使用します。

元。Output.mPosition = mul( Input.mPosition, SetMatrix()value );?

私はシェーダーから始めたばかりで、現在行列の計算を再学習しています。誰かがこれを明確にできるといいですね。

4

2 に答える 2

21

いいえ。「行優先」と「列優先」という用語は、純粋にメモリ内の行列コンポーネントの格納順序を指します。行列とベクトルの乗算の順序とは関係ありません。実際、D3D9 HLSLmul呼び出しは、すべての場合において行列引数を列優先として解釈します。呼び出しは、そのID3DXBaseEffect::SetMatrix()行列引数を行優先として解釈し、舞台裏でmul期待される列優先の順序に転置します。

抽象的に次のようなマトリックスがある場合:

[ a b c d ]
[ e f g h ]
[ i j k l ]
[ m n o p ]

次に、行優先順に格納すると、そのメモリは次のようになります。

a b c d e f g h i j k l m n o p

つまり、行の要素はすべてメモリ内で連続しています。列優先順に格納すると、そのメモリは次のようになります。

a e i m b f j n c g k o d h l p

列の要素がすべて連続しています。ただし、これはどの要素が which であるかにまったく影響しません。どちらの方法でも、要素bはまだ最初の行と 2 番目の列にあります。要素のラベル付けは変更されておらず、メモリへのマッピング方法のみが変更されています。

Cのように配列を宣言すると、float matrix[rows][cols]行優先ストレージが使用されます。ただし、FORTRAN などの他の一部の言語では、既定で多次元配列に列優先のストレージが使用されます。OpenGL も列優先のストレージを使用します。

ここで、完全に個別に、の規則の選択があります。それは、行ベクトルまたは列ベクトルの演算を使用するかどうかです。これは、行列のメモリ レイアウトとはまったく関係ありませんが、行列の作成方法と乗算の順序に影響します。行ベクトルを使用する場合は、ベクトルと行列の乗算を行います。

            [ a b c d ]
[x y z w] * [ e f g h ] = [x*a + y*e + z*i + w*m, ... ]
            [ i j k l ]
            [ m n o p ]

列ベクトルを使用する場合は、行列とベクトルの乗算を行います。

[ a b c d ]   [ x ]
[ e f g h ] * [ y ] = [x*a + y*b + z*c + w*d, ... ]
[ i j k l ]   [ z ]
[ m n o p ]   [ w ]

これは、行ベクトル演算では、ベクトルは実際には 1×n 行列 (単一の行) であり、列ベクトル演算では n×1 行列 (単一の列) であり、行列のサイズに関するルールは一緒に乗算することが許可されている順序が決まります。(4×4 行列に 1×4 行列を掛けることはできませんが、4×4 行列に 4×1 行列を掛けることはできます。)

上記の 2 つの方程式の間で行列が変化していないことに注意してください。ベクトルの解釈のみが変更されました。

したがって、元の質問に戻るには:

ベクトルを HLSL の に渡すと、mul引数に応じて「正しく」自動的に解釈されます。ベクトルが左側にある場合は行ベクトルであり、右側にある場合は列ベクトルです。

ただし、行列は常に同じように解釈されます。行列は、左側の行ベクトルまたは右側の列ベクトルで乗算されているかどうかに関係なく、行列です。一貫性がある限り、コードで行ベクトル演算と列ベクトル演算のどちらを使用するかを自由に決定できます。D3DX 数学ライブラリは行ベクトルを使用しますが、HLSL はこの点にとらわれません。

mulそして、なんらかの理由で、D3D9 HLSL では行列が常に列優先順で格納されることを期待していることが判明しました。ただし、D3DX 数学ライブラリは行列を行優先順で格納し、ドキュメントに記載されているように、ID3DXBaseEffect::SetMatrix()その入力は行優先順であると想定しています。で使用する行列を準備するために、舞台裏で転置を行いmulます。

ところで、D3D11 HLSL はデフォルトで列優先順ですが、コンパイラ ディレクティブを使用して、代わりに行優先順を使用するように指示できます。行ベクトル対列ベクトルの計算に関しては、まだ不可知論的です。また、OpenGL GLSL も列優先順序を使用しますが、(私の知る限り)それを変更する方法は提供していません。

これらの問題に関する詳細情報:

于 2013-12-07T07:06:57.240 に答える
7

はい、x がベクトルの場合、x は行主ベクトルとして扱われ、y は行主行列として扱われます。列優先の場合はその逆なので、行優先の行列システムの場合:

float4 transformed = mul(position, world);

および列優先の場合:

float4 transformed = mul(world, position);

行列の乗算が機能する方法のため、行列が列優先の場合、正しい結果を得るには、列ベクトルで乗算をポストする必要があります。行列が行優先の場合、事前に行ベクトルを乗算する必要があります。

実際、hlsl は行列が行優先か列優先かを気にしません。正しい結果を得るために正しい順序でベクトル乗算を適用するのはあなた次第です。

于 2013-05-16T09:58:21.407 に答える