【问题标题】:CPU vs GPU floating point precision of the MVP matrixMVP 矩阵的 CPU 与 GPU 浮点精度
【发布时间】:2015-10-06 23:00:34
【问题描述】:

我有一个问题,我认为是由于 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% 确定那里的一切都是正确的。

我为容器类提供了带有 set-functions 的矩阵,并使用单个 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);
}

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

【问题讨论】:

  • 不,我怀疑代码有问题。与您的代码相比,我对浮点表示(> 90%)更有信心。此外,如果 IEEE 浮点数存在缺陷,则无济于事。至少如果你的代码不好,你有机会找到并修复它。
  • 很公平。感谢您的回复!
  • @duffymo - 虽然 GLSL 浮点输入应为 IEEE 754,但标准规定操作“不一定按照 IEEE 754 的要求执行”(第 4.1.4 节)
  • 阴影中的那些方块指向未设置的阴影贴图或计算方式错误

标签: opengl math floating-accuracy glm-math shadow-mapping


【解决方案1】:

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

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

两种可能的解决方案:

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

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

【讨论】:

  • 你很有可能是对的。但我发现问题在于我混合使用了 CPU 计算的 MVP 和 GPU 计算的 MVP。因为在阴影着色器中,我需要光的 P 和 V 矩阵以及世界 P 和 V 矩阵,但两个计算都需要相同的 M 矩阵。我仍然使用 GPU 进行这些 MVP 计算,但在所有其他着色器中我使用 CPU。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 2015-05-01
  • 2015-12-22
  • 1970-01-01
  • 2020-03-12
相关资源
最近更新 更多