0

I have a problem that I believe is due to floating point errors on the CPU.

I'm currently working on shadowmaps and at first I had the MVP calculations on the GPU e.g

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);
}

This is not all the shader code obviously, but these calculations got the following result:

enter image description here

Then I wanted to optimize the code a bit and move the MVP calculations to the CPU and pass it to the shaders as a uniform like so:

uniform mat4 MVP;

layout(location = 0) in vec3 inPos;

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

These are the results:

enter image description here

I have been looking at my CPU matrix multiplications for a few hours now so I'm >90% certain that everything is correct there.

I give a container class the matrices with set-functions and retrieve them with a single 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);
}

So.. any ideas on what might be the problem? Could it be floating point errors? Thanks for any and all replies!

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Edvin
  • 1,841
  • 4
  • 16
  • 23
  • No, I'd suspect the code has an issue. I have more confidence in floating point representation (> 90%) than I do in your code. Besides, if IEEE floating point numbers are flawed there's nothing to be done. At least if your code is bad there's a chance you'll find and fix it. – duffymo Jul 17 '15 at 09:18
  • Fair enough. Thanks for your reply! – Edvin Jul 17 '15 at 09:20
  • @duffymo - While GLSL float inputs are expected to be IEEE 754, the standard states that operations "are not necessarily performed as required by IEEE 754" (section 4.1.4) – GuyRT Jul 17 '15 at 09:30
  • those squares in the shadow point to a miss-set shadowmap or a mistake in how you calculate it – ratchet freak Jul 17 '15 at 09:33

1 Answers1

0

These are definitely not precision issues with your transformation matrices; any issue related to this would show up as misalignment (of the shadow or objects), not as rendering artifacts.

This looks much more like a buffer sampling resolution error; your transformation matrices may be at fault here, but not due to limited precision of the matrix, but because when doing the light distance pass the projection matrix you choose compresses all of the depth information into a very small range. In general you want the near parameter of any projection matrix to be as large as possible; depth buffer values as generated by traditional projection matrices are nonlinear (they follow an 1/x relation), so if near is very small, most of the available number range gets compresses very close to the near clip plane. If you use such a generated buffer in shadow mapping, after reversing the depth compresses you've spread out your depth bits in such a seemingly random way.

Two possible solutions:

  • Use a better balanced projection matrix for the light pass.

or

  • Don't use the light pass (nonlinear) depth buffer for the shadow map, but generate a linear depth image by "manually" writing the "absolute" distance in world space units into the shadow map, explicitly in the light pass fragment shader (you may as well write these values to the depth buffer, but this usually comes with some performance penality).
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • You are most likely right. But I found the problem to be that I used a mixture of CPU calculated MVP's and GPU calculated MVP's. Since in the shadows shaders I need both the light's P and V matrix and the worlds P and V matrix but the same M matrix for both calculations. I stilled used the GPU for these MVP calculations but in all the other shaders I used the CPU. – Edvin Jul 21 '15 at 08:49