在OpenGL中,矩阵占用着色器中的多个位置(每列一个)。因此,当在顶点着色器中使用矩阵作为输入时,需要多次调用glVertexAttribPointer()
。
我想知道在渲染到多个帧缓冲区时,是否可以对矩阵类型执行与片段着色器中的输出类似的操作。也就是说,我会在帧缓冲区中有4个不同的纹理绑定到颜色附件0到3,然后我可以有一个layout(location = 0) out matrix4 out_mat
,我可以用片段着色器写入。
我认为这可行吗?
对于片段着色器的输出,不允许使用矩阵数据类型:
见OpenGL Shading Language 4.60 Specification - 4.3.6. Output Variables,第54页:
片段输出每片段数据的输出,并使用
out
存储限定符声明。在片段着色器输出声明中使用辅助存储限定符或插值限定符是编译时错误。使用或包含以下任何类型声明片段着色器输出是编译时错误:
- 布尔类型
- 双精度标量或矢量(double,dvec2,dvec3,dvec4)
- 不透明的类型
- 矩阵类型
- 一个结构
但片段着色器的输出可以是一个数组:
EG
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]);
}
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
}