将 vec3 传递给 glm::lookAt 似乎修改了它
Passing a vec3 to glm::lookAt appears to modify it
我遇到过将 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 使用,并且每帧输出正确的值。
frustumCenter: 573.41 -93.2823 -133.848 1
但是如果我将第一个 glm::lookAt 参数更改为“glm::vec3(frustumCenter)”:
frustumCenter: nan nan nan nan
怎么可能?
I have encountered a situation where passing a glm::vec3
to the glm::lookAt
function appears to modify it."
我不这么认为。您使用 frustumCenter
计算 lightView
,但在此之前,您使用 lightView
计算 frustumCenter
:frustumCenter = invertedLight * frustumCenter;
所以我有根据的猜测是:
lightView
矩阵未正确初始化/未初始化为奇异矩阵(如全零)。因此,倒数将不会被定义,导致 frustumCenter
变成全 NaN
,进而导致 lightView
变成全 NaN
。
但是如果您在第一次迭代中不使用 frustumCenter
,lightView
将被正确初始化,并且 frustumCenter
将在下一次迭代中计算为合理的值。
我遇到过将 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 使用,并且每帧输出正确的值。
frustumCenter: 573.41 -93.2823 -133.848 1
但是如果我将第一个 glm::lookAt 参数更改为“glm::vec3(frustumCenter)”:
frustumCenter: nan nan nan nan
怎么可能?
I have encountered a situation where passing a
glm::vec3
to theglm::lookAt
function appears to modify it."
我不这么认为。您使用 frustumCenter
计算 lightView
,但在此之前,您使用 lightView
计算 frustumCenter
:frustumCenter = invertedLight * frustumCenter;
所以我有根据的猜测是:
lightView
矩阵未正确初始化/未初始化为奇异矩阵(如全零)。因此,倒数将不会被定义,导致 frustumCenter
变成全 NaN
,进而导致 lightView
变成全 NaN
。
但是如果您在第一次迭代中不使用 frustumCenter
,lightView
将被正确初始化,并且 frustumCenter
将在下一次迭代中计算为合理的值。