向上或向下看时剔除视锥体变窄

问题描述

我在 OpenGL 中实现视锥体剔除时遇到问题。 我使用这个 Lighthouse3d 教程(引擎的其余部分来自 learnopengl.com)在世界空间中实现了平面提取。 它运作良好,但仅当相机指向地平线时。如果相机朝上或朝下,视锥体会逐渐变窄。

确实,远视锥平面的大小在指向地平线时是 1023 * 828,但在指向上或下时只有 17 * 14。近视锥平面也会出现同样的问题。

这里是每帧更新视锥体的代码(C++):

  tang = (float) tan(glm::radians(45.0f) * 0.5f);
  ratio = SCR_WIDTH * 1.0 / SCR_HEIGHT;

  // Direction vectors
  cameraZ = cameraFront * -1.0f;
  cameraRight = glm::cross(glm::vec3(0.0f,1.0f,0.0f),cameraZ);
  cameraUp = glm::cross(cameraZ,cameraRight);

  // Dimensions of near and far frustum planes
  Hnear = neardist * tang; // Hnear = near plane height
  Wnear = Hnear * ratio; // Wnear = near plane width
  Hfar = fardist  * tang; // Hfar = far plane height
  Wfar = Hfar * ratio; // Wfar = far plane width

  // distance of near and far planes
  fc = cameraPos - cameraZ * fardist; // fc = far center
  nc = cameraPos - cameraZ * neardist; // nc = near center

  // Extraction of frustum points
  ntl = nc + (cameraUp * Hnear) - (cameraRight * Wnear);
  ntr = nc + (cameraUp * Hnear) + (cameraRight * Wnear);
  nbl = nc - (cameraUp * Hnear) - (cameraRight * Wnear);
  nbr = nc - (cameraUp * Hnear) + (cameraRight * Wnear);

  ftl = fc + (cameraUp * Hfar) - (cameraRight * Wfar);
  ftr = fc + (cameraUp * Hfar) + (cameraRight * Wfar);
  fbl = fc - (cameraUp * Hfar) - (cameraRight * Wfar);
  fbr = fc - (cameraUp * Hfar) + (cameraRight * Wfar);

  // computation of the 6 frustum planes
  topPlane = {ntr,ntl,ftl};
  bottomPlane = {nbl,nbr,fbr};
  leftPlane = {ntl,nbl,fbl};
  rightPlane = {nbr,ntr,fbr};
  nearPlane = {ntl,nbr};
  farPlane = {ftr,ftl,fbl};

结果如下:

Frustum culling bug

解决方法

问题是由于 cameraUp 和 cameraRight 值没有标准化。