投影行列には、シーンの3D点からビューポートの2D点へのマッピングが記述されています。それは、アイ空間からクリップ空間に変換し、クリップ空間の座標は、クリップ座標のw
コンポーネントで除算することによって正規化装置座標(NDC)に変換されます。 NDCは(-1、-1、-1)から(1,1,1)の範囲内にある。
投影法では、投影行列は、ピンホールカメラから見た世界の3D点からビューポートの2D点へのマッピングを記述します。
カメラ錐台(切り捨てられたピラミッド)内のアイ空間座標は、立方体(正規化されたデバイス座標)にマッピングされます。
透視投影行列:
r = right, l = left, b = bottom, t = top, n = near, f = far
2*n/(r-l) 0 0 0
0 2*n/(t-b) 0 0
(r+l)/(r-l) (t+b)/(t-b) -(f+n)/(f-n) -1
0 0 -2*f*n/(f-n) 0
:Iビュー行列は恒等行列であると仮定し、したがって、ビュー空間座標が等しい
aspect = w/h
tanFov = tan(fov_y * 0.5);
prjMat[0][0] = 2*n/(r-l) = 1.0/(tanFov * aspect)
prjMat[1][1] = 2*n/(t-b) = 1.0/tanFov
世界の座標に
頂点の座標が1:1に変換されたポリゴンを描画する場合は、ポリゴンをビューポートに平行な平面に描画する必要があります。これは、すべての点が同じ深さの描画でなければならないことを意味します。
深さは、逆投影行列による正規化されたデバイス座標内の点の変換がピクセル内の頂点座標を与えるように選択する必要があります。逆投影行列による変換によって与えられる同次座標は、同次座標のw
成分で除算されて、デカルト座標を得る必要があることに注意してください。
これは飛行機の深さは投影の視野角に依存すること、を意味:飛行機の
float vp_w = .... // width of the viewport in pixel
float vp_h = .... // height of the viewport in pixel
float fov_y = ..... // field of view angle (y axis) of the view port in degrees < 180°
gluPerspective(fov_y, vp_w/vp_h, 1.0, vp_h*2.0f);
その後depthZ
と:
あなたは、このような透視投影を設定すると仮定すると、 1:頂点座標の画素1の関係は、次のように計算される:
float angRad = fov_y * PI/180.0;
float depthZ = -vp_h/(2.0 * tan(angRad/2.0));
注、ビューポートへの投影の中心点は(0,0)であるので、左下隅ポイント(-vp_w/2
,-vp_h/2
,depthZ
)であり、右上の角点は(vp_w/2
,,)である。遠近法プロジェクションの近平面が-depthZ
より小さく、遠方平面が-depthZ
より大きいことを確認してください。
はさらに参照:視点変換を非につながることができます分割ステップを伴うため
2つの要件は、両方を同時に達成することが本質的に不可能です整数座標。あなたが望むことができる最高のものは、頂点座標が1:1をピクセルに変換する1つの "z平面"を持つことですが、その平面の前または後ろに、非整数で終わります。 – Thomas
この "z平面"を達成する最良の方法は何でしょうか?私はこれがまさに私が望むものだと思う。 – Met
その「ピクセル平面」の「z」値は、投影のFOVに依存します。シンプルな三角ジオメトリで簡単に見つけることができます。 – derhass