我看到很多不同的片段着色器,
#version 130
out vec4 flatColor;
void main(void)
{
flatColor = vec4(0.0,1.0,0.0,0.5);
}
他们都使用不同的变量作为“out color”(在这种情况下为flatColor
)。那么OpenGL如何知道你想要做什么?
我猜这是有效的,因为flatColor
是唯一定义为out
的变量,但您可以添加更多out
变量不是吗?或者那会崩溃吗?
实际上,作为测试,我只是运行了这个:
#version 330
in vec2 TexCoord0;
uniform sampler2D TexSampler;
out vec4 x;
out vec4 y;
void main()
{
y = texture2D(TexSampler, TexCoord0.xy);
}
无论我使用x
还是y
,都能正常使用。
此外,我们还有一个预定义的gl_FragColor
。有什么区别,为什么人们通常会坚持使用他们自己的变量?
答案 0 :(得分:134)
此外,我们有一个预定义的gl_FragColor。
让我们从这开始吧。不,您不拥有预定义的gl_FragColor
。这已从核心OpenGL 3.1及更高版本中删除。除非你使用兼容性(在这种情况下,你的3.30着色器应该在顶部说#version 330 compatibility
),否则你不应该使用它。
现在,返回用户定义的片段着色器输出。但首先,快速类比。
还记得在顶点着色器中你有输入吗?这些输入表示顶点属性索引,您传递给glVertexAttribPointer
和glEnableVertexAttribArray
的数字等等?您可以设置哪个输入来自哪个属性。在GLSL 3.30中,您使用以下语法:
layout(location = 2) in color;
这将color
顶点着色器输入设置为来自属性位置2.在3.30之前(或没有ARB_explicit_attrib_location),您必须在链接或查询程序之前使用glBindAttrbLocation
显式设置它对于glGetAttribLocation
的属性索引。如果您没有明确提供属性位置,GLSL将分配任意的位置(即:以实现定义的方式)。
在着色器中设置它几乎总是更好的选择。
在任何情况下,片段着色器输出的工作方式几乎完全相同。片段着色器可以写入multiple output colors,它们自己被映射到multiple buffers in the framebuffer。因此,您需要指明哪个输出转到哪个片段输出颜色。
此过程从片段输出位置值开始。它的设置与顶点着色器输入位置非常相似:
layout(location = 1) out secColor;
还有API函数glBindFragDataLocation
和glGetFragDataLocation
,它们类似于glBindAttribLocation
和glGetAttribLocation
。
如果你没有做任何明确的赋值,实现通常会将你的一个输出变量分配给位置0.但是,OpenGL标准不会要求这种行为,所以你不应该依赖它要么。
现在公平地说,当你使用两个没有得到不同输出位置的输出时,你的程序应该失败进行链接。可能发生的事情是你的编译器优化了你没有写出来的那个,所以在检查链接器错误的时候忘了它。
答案 1 :(得分:7)
我想为使用GLSL_ES_3.10 link的OpenGLES 3.1指定这个:
§4.4.2
如果[片段着色器]中只有一个输出,则为 不需要指定位置,在这种情况下默认为 零。