[英]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
计算frustumCenter
: frustumCenter = invertedLight * frustumCenter;
所以我对这里发生的事情的有根据的猜测是:
lightView
矩阵未正确初始化/初始化为奇异矩阵(如全零)。 因此,将不会定义倒数,导致frustumCenter
全部变为NaN
,进而导致lightView
全部变为NaN
。
但是,如果您在第一次迭代中不使用frustumCenter
, lightView
将被正确初始化,并且frustumCenter
将在下一次迭代中计算为一个合理的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.