46

私は 3D エンジンを書いている最中で、DirectX のドキュメントで説明されている LookAt アルゴリズムに出くわしました。

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

これで、回転側でどのように機能するかがわかりましたが、マトリックスの平行移動コンポーネントをこれらの内積にする理由はよくわかりません。少し調べてみると、目/カメラの位置への新しい基底ベクトルの投影に基づいて、カメラの位置を少し調整しているようです。

問題は、なぜこれを行う必要があるのか​​ということです。それは何を達成しますか?

4

8 に答える 8

64

与えられた例は、左手系の行優先行列であることに注意してください

したがって、操作は次のとおりです。最初に原点に移動し( - eyeで移動)、次に回転して、からAtまでのベクトルが +z と並ぶようにします。

基本的に、回転行列を平行移動で事前に乗算すると、同じ結果が得られます - eye :

[ 1 0 0 0 ] [ xaxis.x yaxis.x zaxis.x 0 ]
[ 0 1 0 0 ] * [ xaxis.y yaxis.y zaxis.y 0 ]
[ 0 0 1 0 ] [ xaxis.z yaxis.z zaxis.z 0 ]
[ -eye.x -eye.y -eye.z 1 ] [ 0 0 0 1 ]

  [ 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 ]

その他の注意事項:

表示変換は (意図的に)反転されていることに注意してください。すべての頂点にこの行列を掛けて「世界を移動」し、表示したい部分が正規のビュー ボリュームに収まるようにします。

また、LookAt 行列の回転行列 ( Rと呼びます) コンポーネントは、基底行列の反転された変更であり、 Rの行は古い基底ベクトルに関して新しい基底ベクトルであることに注意してください (したがって、変数名 xaxis.x, . . xaxis は、基底の変更が発生した後の新しいx 軸です)。ただし、反転のため、行と列は転置されます。

于 2011-07-23T18:29:03.140 に答える
19

ここで行ったように3x3回転行列を作成し、それを右下隅にゼロと単一の1を含む4x4に展開することにより、ルックアット行列を作成します。次に、負のアイポイント座標(内積なし)を使用して4x4の変換行列を作成し、2つの行列を乗算します。私の推測では、この乗算により、例の一番下の行にある内積と同等の結果が得られると思いますが、確認のために紙で計算する必要があります。

3D回転により、軸が変換されます。したがって、アイポイントをこの新しい座標系に変換せずに直接使用することはできません。これが、行列の乗算(この場合は3つの内積値)が達成することです。

于 2008-12-09T14:44:53.663 に答える
4

その変換コンポーネントは、原点にある「目」と、その原点 (「目」) および 3 つの軸に関して表される他のすべての正規直交基底を作成するのに役立ちます。

概念は、マトリックスがカメラの位置を調整しているということではありません。むしろ、数学を単純化しようとしているのです。自分の「目」の位置から見ることができるすべての画像をレンダリングしたい場合、自分の目が宇宙の中心であると仮定するのが最も簡単です。

つまり、簡単な答えは、これにより数学がはるかに簡単になるということです。

コメントの質問に答える: すべてから「目」の位置を差し引くだけではない理由は、操作の順序に関係しています。このように考えてください: 新しい基準フレーム (つまり、x 軸、y 軸、および z 軸で表される頭の位置) に入ると、この新しい (回転した) 基準フレームで距離を表現したいとします。そのため、新しい軸と目の位置の内積を使用します。これは、物が移動する必要があるのと同じ距離を表しますが、新しい座標系を使用します。

于 2008-12-08T14:28:29.717 に答える
4

いくつかの一般的な情報:

ルックアット マトリックスは、空間内の別のポイントから、空間内のポイントを指す (見る) ために何かを配置/回転するマトリックスです。

このメソッドは、カメラ ビューの目的の「中心」である「上」ベクトルを取得します。これは、カメラの「上」方向を表します (上はほとんどの場合 (0,1,0) ですが、必ずしもそうである必要はありません)。 )、およびカメラの位置である「目」ベクトル。

これは主にカメラに使用されますが、シャドウやスポットライトなどの他のテクニックにも使用できます。

率直に言って、このメソッドで翻訳コンポーネントがそのまま設定されている理由は完全にはわかりません。( gluLookAtOpenGL から) では、カメラは常に 0,0,0 にあると見なされるため、変換コンポーネントは 0,0,0 に設定されます。

于 2008-12-09T17:44:23.003 に答える
2

内積は、単に点を軸に投影して、目の x、y、または z 成分を取得します。カメラを後方に移動しているため、(10, 0, 0) と (100000, 0, 0) から (0, 0, 0) を見ると効果が異なります。

于 2008-12-08T10:12:45.990 に答える
2

lookat マトリックスは、次の 2 つの手順を実行します。

  1. モデルをオリジンに変換し、
  2. アップベクターと視線方向によって設定された向きに従って回転させ
    ます。

内積とは、単純に、最初に平行移動してから回転することを意味します。2 つの行列を乗算する代わりに、内積は行と列を乗算するだけです。

于 2008-12-09T17:50:38.420 に答える
1

変換 4x4 行列には、次の 2 ~ 3 つのコンポーネントが含まれます。1. 回転行列 2. 追加する移動。3. スケール (多くのエンジンはこれをマトリックスで直接使用しません)。

それらの組み合わせは、点を空間 A から空間 B に変換するため、これは変換行列 M_ab です。

ここで、カメラの位置は空間 A にあるため、空間 B の有効な変換ではありません。そのため、この位置に回転変換を掛ける必要があります。

唯一の未解決の問題は、なぜドットなのかということです。3 つの点を紙に書くと、X、Y、Z の 3 つの点が、回転行列の乗算とまったく同じであることがわかります。

その 4 番目の行/列の例は、ワールド空間でゼロ点 (0,0,0) を取ることです。これはカメラ空間のゼロ点ではないため、回転とスケールがゼロのままになるため、カメラ空間での表現が何であるかを知る必要があります!

乾杯

于 2009-02-15T07:25:36.637 に答える
0

ワールド空間ではなく、軸空間に視点を置く必要があります。x、y、z の 1 つである座標単位の基底ベクトルをベクトルにドットすると、その空間での目の座標が得られます。最後の場所 (この場合は最後の行) に 3 つの平行移動を適用して、場所を変換します。次に、マイナスを使用して目を後方に移動すると、残りのスペースをすべて前方に移動することと同じになります。エレベーターで上に移動すると、他の世界があなたの下から抜け落ちているように感じるのと同じように.

最後の列ではなく最後の行として翻訳を使用して左手行列を使用することは、答えとはまったく関係のない宗教的な違いです。しかし、それは絶対に避けるべき教義です。ツリー スケッチを描画するときは、自然な読み取り順序で、グローバルからローカルへの (フォワード キネマティック) 変換を左から右に連鎖させるのが最善です。左手行列を使用すると、これらを右から左に書く必要があります。

于 2014-04-24T01:10:39.193 に答える