片段着色器如何知道用于像素颜色的变量?

时间:2012-02-10 03:14:51

标签: opengl glsl

我看到很多不同的片段着色器,

#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。有什么区别,为什么人们通常会坚持使用他们自己的变量?

2 个答案:

答案 0 :(得分:134)

  

此外,我们有一个预定义的gl_FragColor。

让我们从这开始吧。不,您拥有预定义的gl_FragColor。这已从核心OpenGL 3.1及更高版本中删除。除非你使用兼容性(在这种情况下,你的3.30着色器应该在顶部说#version 330 compatibility),否则你不应该使用它。

现在,返回用户定义的片段着色器输出。但首先,快速类比。

还记得在顶点着色器中你有输入吗?这些输入表示顶点属性索引,您传递给glVertexAttribPointerglEnableVertexAttribArray的数字等等?您可以设置哪个输入来自哪个属性。在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函数glBindFragDataLocationglGetFragDataLocation,它们类似于glBindAttribLocationglGetAttribLocation

如果你没有做任何明确的赋值,实现通常会将你的一个输出变量分配给位置0.但是,OpenGL标准不会要求这种行为,所以你不应该依赖它要么。

现在公平地说,当你使用两个没有得到不同输出位置的输出时,你的程序应该失败进行链接。可能发生的事情是你的编译器优化了你没有写出来的那个,所以在检查链接器错误的时候忘了它。

答案 1 :(得分:7)

我想为使用GLSL_ES_3.10 link的OpenGLES 3.1指定这个:

  

§4.4.2

     

如果[片段着色器]中只有一个输出,则为   不需要指定位置,在这种情况下默认为   零。