在阅读OpenGL SuperBible时,我在理解最基本(平面)着色器示例中的一行时遇到了一些问题。
在第6章,清单6.4和6.5中,它介绍了以下两个非常基本的着色器。
6.4 顶点着色器:
// Flat Shader
// Vertex Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130
// Transformation Matrix
uniform mat4 mvpMatrix;
// Incoming per vertex
in vec4 vVertex;
void main(void)
{
// This is pretty much it, transform the geometry
gl_Position = mvpMatrix * vVertex;
}
6.5 片段着色器:
// Flat Shader
// Fragment Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130
// Make geometry solid
uniform vec4 vColorValue;
// Output fragment color
out vec4 vFragColor;
void main(void)
{
gl_FragColor = vColorValue;
}
我的困惑是,在main()中说vFragColor
时,它在out声明中说gl_FragColor
。
另一方面,在网站的代码中,它已被更正为'vFragColor = vColorValue;'在主循环中。
我的问题是,除了书中的拼写错误之外,命名着色器out
值的规则是什么?他们必须遵循特定的名称吗?
在OpenGL.org上,我发现顶点着色器需要gl_Position。 片段着色器有没有这样的东西?或者只是如果只有一个输出,那么它将是缓冲区中的颜色?
当片段着色器中有多个出现时会发生什么? GLSL编译器如何知道在缓冲区中使用哪一个?
答案 0 :(得分:5)
如the GLSL specification for version 1.3中所述,不推荐在片段着色器中使用gl_FragColor。相反,您应该使用用户定义的输出变量,如 片段着色器中描述的 vFragColor 变量。正如你所说,这是一个错字。
命名着色器值的规则是什么?
变量名称可以是您喜欢的任何名称,除非它与任何现有名称冲突。
当片段着色器中有多个出现时会发生什么? GLSL编译器如何知道在缓冲区中使用哪一个?
如果片段着色器中有多个输出,则应通过调用BindFragDataLocation为片段着色器输出分配插槽。然后,您可以通过调用DrawBuffers来说明哪些插槽将呈现给哪个渲染目标。
规范声明如果在定义的片段着色器中有一个输出变量,它将被分配到索引0和输出0.有关详细信息,我建议您自己take a look at it。
答案 1 :(得分:0)
gl_FragColor是早期版本的GLSL中的原始输出变量。这是要绘制的片段的颜色。
您最初的混淆是合理的,因为没有理由声明out
变量然后写入glFragColor。
在以后的版本中,它可以自定义,这样您就可以为输出变量赋予任意名称。您可以使用命令glBindFragDataLocation
将这些任意输出映射到特定缓冲区。
我不是100%肯定,但我相信如果你在链接之前没有调用这个函数,那么你的输出变量将被随机分配给缓冲区。如果只有一个输出,则应始终将其分配给缓冲区0。