C++ 关于视图矩阵和截锥剔除

C++ 关于视图矩阵和截锥剔除,c++,opengl,glm-math,frustum,C++,Opengl,Glm Math,Frustum,我试图确定一个对象(球体)是否在视锥体内。我的策略是首先获取视图矩阵: glm::lookAt(摄影机位置,lookAtPosition,摄影机位置); 其中,cameraPosition是相机的位置,lookAtPosition是通过cameraPosition+camerradirection计算的,cameraUp几乎是不言自明的 在获得视图矩阵后,我计算相机视图中截锥体的8个顶点,然后将视图矩阵的逆矩阵乘以每个点,得到它们在世界空间中的坐标 使用世界空间中的这8个点,我可以使用叉积构造

我试图确定一个对象(球体)是否在视锥体内。我的策略是首先获取视图矩阵:

glm::lookAt(摄影机位置,lookAtPosition,摄影机位置);
其中,
cameraPosition
是相机的位置,
lookAtPosition
是通过
cameraPosition+camerradirection
计算的,
cameraUp
几乎是不言自明的

在获得视图矩阵后,我计算相机视图中截锥体的8个顶点,然后将视图矩阵的逆矩阵乘以每个点,得到它们在世界空间中的坐标

使用世界空间中的这8个点,我可以使用叉积构造6个平面(因此它们的法线将指向内部)。然后我取物体向量的点积(我通过减去物体在该平面上的任意点的位置得到向量)和每个平面的法向量,如果它对所有6个都是正的,我知道它在截锥体内

因此,我的问题是:

  • 摄影机视图是否始终设置为(0,0,0)并查看正z方向
  • 视图矩阵将世界视图转换为摄影机视图,如果我使用它的倒数将摄影机视图转换为世界视图,是否正确
我的平截头体与我的
cameraDirection
相反,这使得屏幕上看不到任何东西(但它仍然在我的相机后面画东西)

摄影机视图是否始终设置为(0,0,0)并查看正z方向

视图空间是定义场景外观的空间。
“看到”(投影到视口)的部分取决于投影矩阵。通常(在OpenGL中),原点为(0,0,0),视图空间z轴指向视口之外。但是,投影矩阵反转z轴。它从视图空间的系统转换为规范化设备空间的左手系统

将摄影机视图转换为世界视图的逆操作

视图矩阵从世界空间转换到视图空间。投影矩阵将视图空间的投影变换为剪辑空间的投影。通过将xyz分量除以w分量,将剪辑空间坐标转换为标准化设备空间

规范化设备空间是一个最小值为(-1,-1,-1)最大值为(1,1,1)的立方体。因此立方体的8个角点是标准化设备空间中观察体积的角点

(-1,-1,-1)(1,-1,-1)(1,1,-1)(-1,1,-1)//近平面
(-1,-1,1)(1,-1,1)(1,1,1)(-1,1,1)//远平面
如果要将点从标准化设备空间转换为视图空间,必须:

  • 逆投影矩阵变换
  • 逆视图矩阵变换
  • 将结果的xyz分量除以其w分量
glm::mat4视图;//视图矩阵
glm::mat4项目;//投影矩阵
glm::vec3 p_ndc;//标准化设备空间中的一个点
glm::mat4 inv_projetion=glm::inverse(projetion);
glm::mat4 inv_view=glm::inverse(视图);
glm::vec4 pth=库存视图*库存项目*glm::vec4(p\u ndc,1.0f);
glm::vec3 pt_world=glm::vec3(pth)/pth.w;

除了答案中已经提到的问题外,这也是一个问题:“然后我将对象向量的点积(我通过减去对象在该平面上的任意点的位置得到向量)与每个平面的法向量,如果所有6个向量都为正,我知道它在平截体内部。”即使对象的所有顶点都位于平截头体之外,对象也可以与平截头体相交。剔除对象最简单的方法是测试所有点是否位于同一平面之外。当然,使用边界体积而不是真实对象。