在OpenGL中将矩阵类型用作片段着色器输出

时间:2019-04-24 19:55:38

标签: opengl glsl shader

在OpenGL中,矩阵在着色器中占据多个位置(每列一个)。因此,在顶点着色器中使用矩阵作为输入时,必须多次调用glVertexAttribPointer()

我想知道当渲染到多个帧缓冲区时,是否可以对矩阵类型做类似的事情作为片段着色器中的输出。也就是说,在绑定到颜色附件0到3的帧缓冲区中,我将拥有4种不同的纹理,然后我可以使用片段着色器写入layout(location = 0) out matrix4 out_mat

我能假设这行得通吗?

2 个答案:

答案 0 :(得分:4)

对于片段着色器的输出,不允许使用矩阵数据类型:

请参见OpenGL Shading Language 4.60 Specification - 4.3.6. Output Variables,第54页:

  

片段输出每片段数据,并使用out存储限定符声明。在片段着色器输出声明中使用辅助存储限定符或插值限定符是编译时错误。 声明具有以下任意类型或包含以下任何类型的片段着色器输出是编译时错误

     
      
  • 布尔类型
  •   
  • 双精度标量或向量(double,dvec2,dvec3,dvec4)
  •   
  • 不透明类型
  •   
  • 矩阵类型
  •   
  • 结构
  •   

但是片段着色器的输出允许为数组:

例如

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

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

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

矩阵可以由数组构造函数分配给数组(请参见4.1.13. Arrays,第36页):

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

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

    fragOut = vec4[4](m[0], m[1], m[2], m[3]);
}

答案 1 :(得分:1)

GLSL规范说(版本4.5、4.3.6输出变量):

  

声明包含以下任何内容的片段着色器输出是编译时错误:

     

...

     
      
  • 任何矩阵类型
  •   

因此

layout(location = 0) out mat4 out_mat;

是非法的。

相反,您应该将矩阵的元素输出到四个单独的输出中:

 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
 }