0

我有一个问题,我认为是由于 CPU 上的浮点错误。

我目前正在研究阴影贴图,起初我在 GPU 上进行了 MVP 计算,例如

layout(location = 0) in vec3 inPos;

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;

void main(void)
{
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(inPos, 1.0);
}

这显然不是所有着色器代码,但这些计算得到了以下结果:

在此处输入图像描述

然后我想稍微优化一下代码并将 MVP 计算转移到 CPU 并将其作为统一传递给着色器,如下所示:

uniform mat4 MVP;

layout(location = 0) in vec3 inPos;

void main(void)
{
gl_Position = MVP * vec4(inPos, 1.0);
}

这些是结果:

在此处输入图像描述

几个小时以来,我一直在查看我的 CPU 矩阵乘法,所以我 > 90% 确定那里的一切都是正确的。

我为容器类提供了带有集合函数的矩阵,并使用单个 getter 检索它们。

void setModelMatrix(const glm::mat4& inModelMatrix){mModelMatrix = inModelMatrix;};
void setViewMatrix(const glm::mat4& inVewMatrix) {mViewMatrix = inVewMatrix;};
void setProjectionMatrix(const glm::mat4& inProjectionMatrix){mProjectionMatrix = inProjectionMatrix;};

//Calculates the MVP matrix and returns it
glm::mat4 getMVPMatrix() {
    return (mProjectionMatrix * mViewMatrix * mModelMatrix);
}

所以..关于可能是什么问题的任何想法?会不会是浮点错误?感谢您的所有回复!

4

1 回答 1

0

这些绝对不是转换矩阵的精度问题;与此相关的任何问题都将显示为(阴影或对象的)未对齐,而不是渲染伪影。

这看起来更像是缓冲区采样分辨率错误;您的变换矩阵在这里可能有问题,但不是因为矩阵的精度有限,而是因为在进行光距离传递时,您选择的投影矩阵会将所有深度信息压缩到一个非常小的范围内。一般来说,您希望任何投影near矩阵的参数尽可能大;由传统投影矩阵生成的深度缓冲区值是非线性的(它们遵循 1/x 关系),因此如果 near 非常小,则大多数可用数字范围会压缩到非常接近 near 剪辑平面。如果您在阴影映射中使用这种生成的缓冲区,则在反转深度压缩后,您会以一种看似随机的方式分散深度位。

两种可能的解决方案:

  • 为光通使用更好的平衡投影矩阵。

或者

  • 不要为阴影贴图使用光通(非线性)深度缓冲区,而是通过“手动”将世界空间单位中的“绝对”距离写入阴影贴图来生成线性深度图像,显式地在光通片段着色器中(您也可以将这些值写入深度缓冲区,但这通常会带来一些性能损失)。
于 2015-07-17T09:54:53.197 回答