【问题标题】:Passing a vec3 to glm::lookAt appears to modify it将 vec3 传递给 glm::lookAt 似乎可以修改它
【发布时间】:2021-10-22 19:58:11
【问题描述】:

我遇到过将 glm::vec3 传递给 glm::lookAt 函数似乎会对其进行修改的情况。

以下代码是关于 C++ / OpenGL 游戏引擎中的阴影截头体计算的。问题出现在最后的 glm::lookAt 函数中。

void Shadows::updateFrustumBoundingBox()
{

  // Here we convert main camera frustum coordinates in light view space
  std::array<glm::vec3,8> points = {
    // Near plane points
    lightView * glm::vec4(cameraPtr->ntl, 1.0),
    lightView * glm::vec4(cameraPtr->ntr, 1.0),
    lightView * glm::vec4(cameraPtr->nbl, 1.0),
    lightView * glm::vec4(cameraPtr->nbr, 1.0),
    // Far plane points
    lightView * glm::vec4(cameraPtr->ftl, 1.0),
    lightView * glm::vec4(cameraPtr->ftr, 1.0),
    lightView * glm::vec4(cameraPtr->fbl, 1.0),
    lightView * glm::vec4(cameraPtr->fbr, 1.0)};

  // Here we find the shadow bounding box dimensions
  bool first = true;
  for (int i=0; i<7; ++i)
  {
    glm::vec3* point = &points[i];

    if (first)
    {
            minX = point->x;
            maxX = point->x;
            minY = point->y;
            maxY = point->y;
            minZ = point->z;
            maxZ = point->z;
      first = false;
    }

        if (point->x > maxX)
            maxX = point->x;
    else if (point->x < minX)
            minX = point->x;

        if (point->y > maxY)
            maxY = point->y;
    else if (point->y < minY)
            minY = point->y;

        if (point->z > maxZ)
            maxZ = point->z;
    else if (point->z < minZ)
            minZ = point->z;
  }

  frustumWidth = maxX - minX;
  frustumHeight = maxY - minY;
  frustumLength = maxZ - minZ;

  // Here we find the bounding box center, in light view space
  float x = (minX + maxX) / 2.0f;
  float y = (minY + maxY) / 2.0f;
  float z = (minZ + maxZ) / 2.0f;
  glm::vec4 frustumCenter = glm::vec4(x, y, z, 1.0f);

  // Here we convert the bounding box center in world space
  glm::mat4 invertedLight = glm::mat4(1.0f);
  invertedLight = glm::inverse(lightView);
  frustumCenter = invertedLight * frustumCenter;

  // Here we define the light projection matrix (shadow frustum dimensions)
  lightProjection = glm::ortho(
    -frustumWidth/2.0f, // left
    frustumWidth/2.0f, // right
    -frustumHeight/2.0f, // down
    frustumHeight/2.0f, // top
    0.01f, // near
    SHADOW_DISTANCE); // far


  // Here we define the light view matrix (shadow frustum position and orientation)
  lightDirection = glm::normalize(lightDirection);
  target =  glm::vec3(0.0f, 100.0f, 200.0f) + lightDirection;

  lightView = glm::lookAt(
                  // Shadow box center
                     glm::vec3(0.0f, 100.0f, 200.0f), // THIS LINE
                  // glm::vec3(frustumCenter), // ALTERNATIVELY, THIS LINE. Here I convert it as a vec3 because it is a vec4

                  // Light orientation
                  target,

                  // Up vector
                  glm::vec3( 0.0f, 1.0f,  0.0f));

  cout << "frustumCenter: " << frustumCenter.x << " " << frustumCenter.y << " " << frustumCenter.z << endl;

  // Final matrix calculation
  lightSpaceMatrix = lightProjection * lightView;
}

照原样,第一个 glm::lookAt 参数是 glm::vec3(0.0f, 100.0f, 200.0f),它可以正常工作。 glm::vec4 frustumCenter 变量不被 glm::lookAt 使用,并且每帧输出正确的值。

截锥体中心:573.41 -93.2823 -133.848 1

但如果我将第一个 glm::lookAt 参数更改为“glm::vec3(frustumCenter)”:

frustumCenter:楠楠楠楠

怎么可能?

【问题讨论】:

    标签: c++ opengl game-engine glm-math


    【解决方案1】:

    我遇到过将glm::vec3 传递给glm::lookAt 函数似乎会对其进行修改的情况。”

    我不这么认为。您使用frustumCenter 计算lightView,但在此之前,您使用lightView 计算frustumCenterfrustumCenter = invertedLight * frustumCenter;

    所以我对这里发生的事情的有根据的猜测是:

    lightView 矩阵未正确初始化/初始化为奇异矩阵(如全零)。因此,不会定义逆向,导致frustumCenter 变为全部NaN,进而导致lightView 变为全部NaN

    但如果您在第一次迭代中不使用frustumCenterlightView 将被正确初始化,frustumCenter 将在下一次迭代中计算为一个合理的值。

    【讨论】:

    • 你指出来了!万分感谢。我首先用一个任意值初始化了 lightView,这样就可以计算出 frustumCenter 了。但是,frustumCenter 计算不正确(因为 lightView 矩阵为假)。那么lightView也计算不正确。在下一次迭代中,frustumCenter 仍然是基于不正确的 lightView 矩阵等计算的。你知道如何解决这个问题吗?我首先需要在视图空间中计算 frustumCenter。 (但我可能应该发布一个新问题)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 2014-03-16
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多