我看到很多不同的片段着色器,
#version 130
out vec4 flatColor;
void main(void)
{
flatColor = vec4(0.0,1.0,0.0,0.5);
}
Run Code Online (Sandbox Code Playgroud)
并且它们都使用不同的变量来表示"颜色"(在这种情况下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);
}
Run Code Online (Sandbox Code Playgroud)
无论我使用x还是使用它都很好y.
此外,我们有一个预定义的gl_FragColor.有什么区别,为什么人们通常坚持使用他们自己的变量?
Nic*_*las 135
此外,我们有一个预定义的gl_FragColor.
让我们从这开始吧.不,您没有预定义的gl_FragColor.这已从核心OpenGL 3.1及更高版本中删除.除非你使用兼容性(在这种情况下,你的3.30着色器应该#version 330 compatibility在顶部说),你永远不应该使用它.
现在,返回用户定义的片段着色器输出.但首先,快速类比.
还记得在顶点着色器中你有输入吗?而这些投入表示顶点属性索引,你传递给数字glVertexAttribPointer和glEnableVertexAttribArray等等?您可以设置哪个输入来自哪个属性.在GLSL 3.30中,您使用以下语法:
layout(location = 2) in color;
Run Code Online (Sandbox Code Playgroud)
这将color顶点着色器输入设置为来自属性位置2.在3.30之前(或没有ARB_explicit_attrib_location),您必须glBindAttrbLocation在链接或查询属性索引的程序之前显式设置它glGetAttribLocation.如果您没有明确提供属性位置,GLSL将任意分配一个位置(即:以实现定义的方式).
在着色器中设置它几乎总是更好的选择.
在任何情况下,片段着色器输出的工作方式几乎完全相同.片段着色器可以写入多种输出颜色,这些颜色本身会映射到帧缓冲区中的多个缓冲区.因此,您需要指明哪个输出转到哪个片段输出颜色.
此过程从片段输出位置值开始.它的设置与顶点着色器输入位置非常相似:
layout(location = 1) out secColor;
Run Code Online (Sandbox Code Playgroud)
还有一些API函数glBindFragDataLocation和glGetFragDataLocation,这是类似于glBindAttribLocation和glGetAttribLocation.
如果您不进行任何显式赋值,则实现通常会将您的一个输出变量分配给位置0.但是,OpenGL标准不需要此行为,因此您也不应该依赖它.
现在公平地说,当你使用两个没有得到不同输出位置的输出时,你的程序应该无法链接.可能发生的事情是你的编译器优化了你没有写出来的那个,所以在检查链接器错误的时候忘了它.