我有一个基本的相机类,其中有以下值得注意的功能:
// 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);
zn
函数中的参数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;
}
GetFarWindowWidth()
执行相同计算的位置,当然用mNearWindowHeight
替换mFarWindowHeight
。
现在已经完全没事了,有些东西告诉我,我正在不正确地计算近距离和远距离剪辑平面的高度和宽度。特别是,我认为造成这种混淆的原因是我在y轴上以度为单位指定视野,然后在切线函数中将其转换为弧度。 我认为这引起问题的是我的视锥体剔除功能,它使用近平面和远平面的宽度/高度来获得顶部,右侧,左侧和底部平面的点,如好。
所以,我是否正确,因为我完全错了?如果是这样,我该怎么做才能解决它?
声明
这段代码最初源于一本D3D11书,我决定退出阅读并回到OpenGL。为了减少这个过程的痛苦,我认为将一些原始代码转换为更符合OpenGL标准会很好。到目前为止,它的工作相当不错,只有一个小问题......
修改
我本来应该提到一些事情:
这不是我第一次使用OpenGL;我很清楚转换过程,以及GL和D3D之间的坐标系差异。
这不是我的整个相机类,虽然在这种情况下我认为可能唯一可疑的另一件事就是使用相机的mOrientation
矩阵来计算外观通过分别在+ x,+ y和-z基础上变换每个方向向量,向上和向右方向向量。因此,举例来说,为了计算我的外观向量,我会做:mOrientation * vec4(0.0f, 0.0f, -1.0f, 1.0f)
,然后将其转换为vec3
。我在这里提到的背景涉及这些基础向量如何与剔除平截头体结合使用。