繁体   English   中英

将 vec3 传递给 glm::lookAt 似乎对其进行了修改

[英]Passing a vec3 to glm::lookAt appears to modify it

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

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

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 使用,并且每帧输出正确的值。

frustumCenter: 573.41 -93.2823 -133.848 1

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

frustumCenter:南南南南

怎么会这样?

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM