Shader parameter order bug

I think I see the problem!

  1. Since I’m not using LightScreenPos.z, that means I’m not using the 3rd column of LightViewProjection.
  2. When HLSL is converted to GLSL, matrices are each converted to 4 separate column vectors.
  3. The compiler is recognizing that the 3rd column is not being used, and it isn’t leaving space for it when pulling column vectors from the buffer. Columns 1, 2, and 4 are read consecutively.
  4. This vital info is being lost, however, when MonoGame is setting the buffer. Whenever you write a matrix to the buffer, it always writes all 4 columns consecutively.

So now what is the correct solution? I imagine there are two options:

  1. Change the shader compiler, or add a hack like above that uses the 3rd column so that it doesn’t get removed. This will cause the shader to always allocate an extra, unnecessary vector, but is easier to maintain. The shader will then match the current MonoGame implementation.
  2. Change my MonoGame framework to allow optionally (or intelligently – can info on which columns are being used get added to the gfx?) setting only certain columns of a matrix. This is potentially more difficult to maintain and synchronize, because the code must depend on how the shader is compiled, but the shader is more optimized and doesn’t need extra hacks.

Any opinions?
I’m going to look into the 2MGFX code and see if there’s a good way of adding some metadata that specifies which columns of a matrix need to be copied into the buffer.

UPDATE: It looks like that info is swallowed by MojoShader. The bytecode from SharpDX has the extra column, but the glsl that comes out of MojoShader doesn’t. The symbol is still marked as having 4 columns, and there’s no indication that anything was removed. Other than parsing the glsl code and identifying skipped variable indices, I don’t think there’s a way to get the info other than modifying MojoShader itself.

2 Likes