5

以前の質問を改善したい:

球体をスクリーンに投影するにはどうすればよいですか?

(2)は簡単な解決策を提供します:

画面上のおおよその半径[CLIP SPACE] = 世界半径 * cot(fov / 2) / Z

と:
fov = 視野角
Z = カメラから球までの z 距離

結果はクリップスペースにあり、ビューポートのサイズを掛けてサイズをピクセル単位で取得します

今私の問題は、FOV がないことです。ビュー行列と射影行列だけが知られています。(そして、それが役立つ場合はビューポートのサイズ)

射影行列からFOVを抽出する方法を知っている人はいますか?

アップデート:

私の場合、この近似はよりうまく機能します。

float radius = glm::atan(radius/distance);
radius *= glm::max(viewPort.width, viewPort.height) / glm::radians(fov);
4

4 に答える 4

4

私はこのパーティーに少し遅れています。しかし、同じ問題を調べていたときに、このスレッドに出くわしました。私はこれを調べるのに 1 日を費やし、ここで見つけたいくつかの優れた記事に取り組みました: http://www.antongerdelan.net/opengl/virtualcamera.html

射影行列から始めて、逆方向に作業することになりました。上記の投稿で言及したのと同じ式を取得しました。(ここで、cot(x) = 1/tan(x) )

radius_pixels = (radius_worldspace / {tan(fovy/2) * D}) * (screen_height_pixels / 2)

(ここで、D はカメラからターゲットの境界球までの距離です)

このアプローチを使用して、オブジェクトを回転させるために使用する架空のトラックボールの半径を決定しています。

ところで、フロリアンは、次のように射影行列から fovy を抽出できます。

ここに示すように、射影行列から Sy コンポーネントを取得すると、次のようになります。

Sx  0   0   0
0   Sy  0   0
0   0   Sz  Pz
0   0  -1   0

where Sy = near / range

and where range = tan(fovy/2) x near

(これらの定義は、上でリンクしたページで見つけることができます)

上記の Sy eqn で range を代入すると、次のようになります。

Sy = 1 / tan(fovy/2) = cot(fovy/2)

再配置:

tan(fovy/2) = 1 / Sy

両辺の arctan (tan の逆数) を取得すると、次のようになります。

fovy/2 = arctan(1/Sy)

それで、

fovy = 2 x arctan(1/Sy)

まだ気にしているかどうかわかりません - しばらく経ちました! -しかし、これは他の誰かを助けるかもしれません。

于 2013-11-07T18:39:56.487 に答える
2

更新:以下を参照してください。

ビューと投影のマトリックスがあるので、これを行う1つの方法がありますが、おそらく最短ではありません。

  • ビュー行列を使用して球の中心をビュー空間に変換します。結果ポイントCを呼び出します。
  • 球の表面上の点、たとえば、rが球の世界半径である世界座標のC +(r、0、0)をビュー空間に変換します。結果点をSと呼ぶ
  • rv = CからSまでの距離を計算します(ビュースペース内)
  • ビュー座標の点S1をC+(rv、0、0)とします。つまり、線C-> S1が「ルック」ベクトルに垂直である、ビュー空間の球の表面上の別のポイントです。
  • 投影行列をCsおよびS1として使用して、CおよびS1を画面座標に投影します。
  • 画面半径の計算=CsとS1sの間の距離

しかし、ええ、ブランドルフが言ったように、FOVyのようにカメラ変数を保存できれば、はるかに簡単になります。:-)

更新: 上記のより効率的な変形は次のとおりです。射影行列の逆行列を作成します。これを使用して、ビューポートのエッジをビュースペースに変換し直します。そうすれば、すべてのボックスを画面座標に投影する必要がなくなります。

さらに良いことに、ビューマトリックスで同じことを行い、カメラの錐台をワールドスペースに戻します。これは、多くのボックスを比較するのにより効率的です。しかし、数学を理解するのは難しいです。

于 2010-09-15T15:52:48.007 に答える
0

FOV は射影行列に直接格納されるのではなく、gluPerspective を呼び出して結果の行列を作成するときに使用されます。

最良の方法は、gluPerspective などを呼び出すときにメンバー変数が使用される錐台クラスなど、独自のクラスにすべてのカメラ変数を保持することです。

マトリックスからFOVyを取り戻すことは可能かもしれませんが、必要な数学は私にはわかりません。

于 2010-09-15T15:27:21.690 に答える