基本的なカメラ クラスがあり、次の注目すべき機能があります。
// Get near and far plane dimensions in view space coordinates.
float GetNearWindowWidth()const;
float GetNearWindowHeight()const;
float GetFarWindowWidth()const;
float GetFarWindowHeight()const;
// Set frustum.
void SetLens(float fovY, float aspect, float zn, float zf);
関数内の paramszn
とは、それぞれニア クリップ プレーンとファー クリップ プレーンの距離に対応します。zf
SetLens
SetLens
基本的に遠近両方のクリップ プレーンの高さを計算すると共に、透視投影マトリックスを作成します。
void Camera::SetLens(float fovY, float aspect, float zn, float zf)
{
// cache properties
mFovY = fovY;
mAspect = aspect;
mNearZ = zn;
mFarZ = zf;
float tanHalfFovy = tanf( 0.5f * glm::radians( fovY ) );
mNearWindowHeight = 2.0f * mNearZ * tanHalfFovy;
mFarWindowHeight = 2.0f * mFarZ * tanHalfFovy;
mProj = glm::perspective( fovY, aspect, zn, zf );
}
したがって、GetFarWindowHeight()
当然GetNearWindowHeight()
、それぞれの高さクラスのメンバー値を返します。ただし、対応する幅は、それぞれの高さの値にビューの縦横比を掛けた値を返します。したがって、次の場合GetNearWindowWidth()
:
float Camera::GetNearWindowWidth()const
{
return mAspect * mNearWindowHeight;
}
Whereは同じ計算を実行しGetFarWindowWidth()
ますが、もちろん に置き換えます。mNearWindowHeight
mFarWindowHeight
これで問題は解決しましたが、ニア クリップ プレーンとファー クリップ プレーンの高さと幅を正しく計算していないことがわかりました。特に、この混乱の原因は、y 軸の視野を度単位で指定し、それを正接関数でラジアンに変換しているという事実だと思います。これが問題を引き起こしていると思われる場所は、近くの平面と遠い平面の幅/高さを使用して、上、右、左、および下の平面のポイントも取得する錐台カリング関数にあります。
それで、私はこれを完全に間違っているという点で正しいですか?もしそうなら、私はそれを修正するために何をすべきですか?
免責事項
このコードはもともと D3D11 の本に由来するもので、読むのをやめて OpenGL に戻ることにしました。プロセスの負担を軽減するために、元のコードの一部をより OpenGL に準拠するように変換するとよいと考えました。これまでのところ、この 1 つの小さな問題を除いて、かなりうまく機能しています...
編集
最初にいくつかのことを言及する必要がありました。
OpenGL を使用するのはこれが初めてではありません。GL と D3D の座標系の違いだけでなく、変換プロセスもよく知っています。
これは私のカメラクラス全体ではありませんが、このコンテキストで疑わしいと思われる他の唯一のことは、カメラの行列
mOrientation
を使用して、+x、+y でそれぞれを変換することにより、ルック、アップ、右方向のベクトルを計算することです。 、および -z 基準、それぞれ。したがって、例として、ルック ベクトルを計算するには: を実行しmOrientation * vec4(0.0f, 0.0f, -1.0f, 1.0f)
、それを に変換しvec3
ます。ここで言及しているコンテキストには、これらの基底ベクトルを錐台のカリングと組み合わせて使用する方法が含まれます。