トップページ > 記事閲覧
CreateLookAtMatrixの出力について
名前:Stnsllet 日時: 2021/08/10 22:55

大変お世話になっております。 ビュー行列を作成する関数CreateLookAtMatrixの出力結果について疑問があるので質問させていただきます。 まず、前提としてこちらはDirectXの関数D3DXMatrixLookAtLHと同等の関数で合ってますでしょうか。 過去に素のDirectXで作られたプログラムをDXライブラリへ移植している最中なのですが、 CreateLookAtMatrixの出力結果がD3DXMatrixLookAtLHと異なった為、問い合わせさせていただきました。 出力結果に差異が確認できたコードは以下の通りとなっています。 // DXLIB 3.22c MATRIX mView; VECTOR EyeVec(0.0f, 225.0f, 389.7f); VECTOR AtVec(0.0f, 0.0f, 0.0f); VECTOR UpVec(0.0f, -1.0f, 0.0f); CreateLookAtMatrix(&mView, &EyeVec, &AtVec, &UpVec); // DirectX(d3dx9math.h) D3DXMATRIX mViewDx; D3DXVECTOR3 EyeVecDx(0.0f, 225.0f, 389.7f); D3DXVECTOR3 AtVecDx(0.0f, 0.0f, 0.0f); D3DXVECTOR3 UpVecDx(0.0f, -1.0f, 0.0f); D3DXMatrixLookAtLH(&mViewDx, &EyeVecDx, &AtVecDx, &UpVecDx); ////コードここまで //問題の出力 mView.m[3] = {-0.00000000, -1.52587891e-05, 449.990112, 1.00000000} mViewDx.m[3] = {-0.00000000, 1.52587891e-05, 449.990143, 1.00000000} ここの配列[3][1]に当たる箇所なのですが、プラスマイナスが反転しています。 docs.microsoft.comによるとD3DXMatrixLookAtLHの計算式は以下の通りと示されていますが、 zaxis = normal(At - Eye) xaxis = normal(cross(Up, zaxis)) yaxis = cross(zaxis, xaxis) xaxis.x yaxis.x zaxis.x 0 xaxis.y yaxis.y zaxis.y 0 xaxis.z yaxis.z zaxis.z 0 -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1 以上の式をDXライブラリで実装した結果、D3DXMatrixLookAtLHの結果となりました。 私は正直数学として何が正しいかが分からないので、 結果としてはどちらが正しいかについての確認をさせて頂きたいと思います。 よろしくお願いします。
メンテ

Page: 1 |

Re: CreateLookAtMatrixの出力について ( No.1 )
名前:管理人 日時:2021/08/11 00:18

> 結果としてはどちらが正しいかについての確認をさせて頂きたいと思います。 今確認してみましたが、DXライブラリ内部で行っている計算は D3DXMatrixLookAtLH と同じでした ただ、プログラムコードが全く同じというわけではないので計算結果に若干の誤差が発生しているようです 計算結果が大きく異なっているわけではないので、片方が正しくて片方が間違っているということはなく どちらも正しいという状態です
メンテ
Re: CreateLookAtMatrixの出力について ( No.2 )
名前:Stnsllet(解決) 日時:2021/08/11 15:18

ご回答ありがとうございます、計算結果について承知しました。 一応DXライブラリのソースコードを眺めてみたのですが、全てがDirectXを直接ラッピングしているという訳ではなかったのですね。 計算結果の誤差についても納得がいきました。 この度もありがとうございました!
メンテ
Re: CreateLookAtMatrixの出力について ( No.3 )
名前:X16Y42 日時:2021/08/24 10:10

素朴な疑問ですが 4*4 個の要素の中でたった1つの要素だけの符号が異なるのですか?
メンテ
Re: CreateLookAtMatrixの出力について ( No.4 )
名前:Stnsllet(解決) 日時:2021/08/24 22:46

>X16Y42さん はい。[3][1]の箇所だけ反転されます。 一応上記のDxLibとDirectXによる各関数で出力された行列の全結果を張っておきます。 CreateLookAtMatrix 0x00000001000ff2d0 {1.00000000, 0.00000000, 0.00000000, 0.00000000} 0x00000001000ff2e0 {0.00000000, -0.866019070, -0.500010967, 0.00000000} 0x00000001000ff2f0 {0.00000000, 0.500011027, -0.866019070, 0.00000000} 0x00000001000ff300 {-0.00000000, -1.52587891e-05, 449.990112, 1.00000000} D3DXMatrixLookAtLH 0x00000001000ff3c0 {0.999999940, 0.00000000, 0.00000000, 0.00000000} 0x00000001000ff3d0 {0.00000000, -0.866019070, -0.500011027, 0.00000000} 0x00000001000ff3e0 {0.00000000, 0.500010967, -0.866019130, 0.00000000} 0x00000001000ff3f0 {-0.00000000, 1.52587891e-05, 449.990143, 1.00000000}
メンテ
Re: CreateLookAtMatrixの出力について ( No.5 )
名前:X16Y42 日時:2021/08/26 10:50

実際にfloat型で計算させてみた結果から推測するに,おそらく, zaxis = normal(At - Eye) xaxis = normal(cross(Up, zaxis)) yaxis = cross(zaxis, xaxis) と計算する場合(D3DXMatrixLookAtLH)と, zaxis = (At - Eye) xaxis = (cross(Up, zaxis)) yaxis = cross(zaxis, xaxis) とした後で {xaxis, yaxis, zaxis}の3つを正規化 と計算する場合(CreateLookAtMatrix)との,違いかと見えます. --- 数学的な(?)意味合いでは同じなので,「誤差」と呼んでも差し支えないかな? と思いますが, (関数引数の意味合い的に,ふつーは Up に極端なノルムのベクトルをわざわざ与えないでしょうから) Upが単位ベクトルであることを期待して実装するならば 前者側の方が「各演算に用いる値のスケールが同じくらいに揃う」形であり,精度的に良いのかもしれません. (その辺に関して私はあまり詳しくないので,「ぼんやりとそう思う」程度の話ですが)
メンテ
Re: CreateLookAtMatrixの出力について ( No.6 )
名前:X16Y42 日時:2021/08/26 10:52

※補足 後者側の計算は, CreateLookAtMatrixの実装を見たわけではなくて,あくまでも結果からの私の推測です.
メンテ
Re: CreateLookAtMatrixの出力について ( No.7 )
名前:Stnsllet(解決) 日時:2021/08/27 12:27

>X16Y42さん 実装を確認してみたところ、おっしゃる通り最後に各axisを正規化していました。 例え誤差と言えど何故起きたかが納得出来ました。 もう少し細かく勉強してみたいと思います。 ありがとうございました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存