我有一个基本的相机类,其中有以下值得注意的功能:
// 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
inSetLens
函数分别对应近剪裁平面距离和远剪裁平面距离。
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;
}
WhereGetFarWindowWidth()
执行相同的计算,当然替换mNearWindowHeight
为mFarWindowHeight
.
现在这一切都已经解决了,有些事情告诉我,我正在不正确地计算近端和远端剪辑平面的高度和宽度。特别是,我认为导致这种混乱的原因是我在 y 轴上以度数指定视场,然后在切线函数中将其转换为弧度。我认为这是导致问题的地方在于我的截锥体剔除功能,它使用近平面和远平面的宽度/高度来获取顶部、右侧、左侧和底部平面的点。
那么,我这样做完全错了吗?如果是这样,我应该怎么做才能修复它?
免责声明
这段代码最初源于一本 D3D11 书,我决定放弃阅读并回到 OpenGL。为了让这个过程不那么痛苦,我认为将一些原始代码转换为更符合 OpenGL 会很好。到目前为止,它工作得相当好,这个小问题......
编辑
我本来应该提到几件事:
这不是我第一次使用 OpenGL。我非常了解转换过程,以及 GL 和 D3D 之间的坐标系差异。
这不是我的整个相机类,尽管我认为在这种情况下可能有问题的唯一另一件事是使用我的相机
mOrientation
矩阵来计算外观、向上和右方向矢量,通过在 +x、+y 上转换每个矢量, 和 -z 基础,分别。因此,作为示例,要计算我的外观向量,我会这样做:mOrientation * vec4(0.0f, 0.0f, -1.0f, 1.0f)
,然后将其转换为vec3
. 我在这里所指的上下文涉及如何将这些基向量与剔除截锥体结合使用。