1

In OpenGL, a matrix takes up multiple locations in a shader (one for each column). So when using a matrix in a vertex shader as an input it is necessary to call glVertexAttribPointer() multiple times.

I am wondering if it is possible to do something similar for matrix types as outputs in a fragment shader when rendering to multiple framebuffers. That is, I would have 4 different textures in a frame buffer bound to color attachments 0 through 3, and then I could have a layout(location = 0) out matrix4 out_mat that I could write to with the fragment shader.

Am I correct in assuming that this would work?

3
  • 1
    You can writhe ach column of the matrix to a different target (plane), of the buffer. out0 = m[0]; out1 = m[1]; ... Commented Apr 24, 2019 at 20:10
  • So does that mean that this doesn't work? Commented Apr 24, 2019 at 20:40
  • @InformationAether: "In OpenGL, a matrix takes up multiple locations in a shader" Matrices only take more than one location when used as vertex shader inputs. In every other case where they can be used (intra-shader in/out variables, uniforms), they only take up one location. Commented Apr 24, 2019 at 22:53

2 Answers 2

4

For the output of a fragment shader, a matrix data type is not allowed :

See OpenGL Shading Language 4.60 Specification - 4.3.6. Output Variables, page 54:

Fragment outputs output per-fragment data and are declared using the out storage qualifier. It is a compile-time error to use auxiliary storage qualifiers or interpolation qualifiers in a fragment shader output declaration. It is a compile-time error to declare a fragment shader output with, or that contains, any of the following types:

  • A boolean type
  • A double-precision scalar or vector (double, dvec2, dvec3, dvec4)
  • An opaque type
  • A matrix type
  • A structure

But the output of a fragment shader is allowed to be an array:

e.g.

layout (location = 0) out vec4 fragOut[4];

void main()
{
    mat4 m = [...];

    fragOut[0] = m[0];
    fragOut[1] = m[1];
    [...]
}

The matrix can be assigned to the array by an array constructor (see 4.1.13. Arrays, page 36):

layout (location = 0) out vec4 fragOut[4];

void main()
{
    mat4 m = [...];

    fragOut = vec4[4](m[0], m[1], m[2], m[3]);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Do you know if arrays of vectors are allowed though? Couldn't find it in the spec.
@ybungalobill It is not expressly forbidden. In general an output variable can be an array. I just tried it and it works.
2

GLSL spec says (Version 4.5, 4.3.6 Output Variables):

It is a compile-time error to declare a fragment shader output that contains any of the following:

...

  • Any matrix type

Therefore

layout(location = 0) out mat4 out_mat;

is illegal.

Instead you should output the elements of the matrix into four separate outputs:

 layout(location = 0) out vec4 out_mat0;
 layout(location = 1) out vec4 out_mat1;
 layout(location = 2) out vec4 out_mat2;
 layout(location = 3) out vec4 out_mat3;

 void main() {
     mat4 M = ...;
     out_mat0 = M[0]; // column 0
     out_mat1 = M[1]; // column 1
     out_mat2 = M[2]; // column 2
     out_mat3 = M[3]; // column 3
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.