片段着色器如何知道要用于像素颜色的变量? [英] How does the fragment shader know what variable to use for the color of a pixel?

查看:348
本文介绍了片段着色器如何知道要用于像素颜色的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I see a lot of different fragment shaders,

#version 130

out vec4 flatColor;

void main(void)
{
    flatColor = vec4(0.0,1.0,0.0,0.5);
}

并且它们都为"out color"(在本例中为flatColor)使用了不同的变量.那么OpenGL如何知道您要做什么?

And they all use a different variable for the "out color" (in this case flatColor). So how does OpenGL know what you're trying to do?

我猜这可行,因为flatColor是唯一定义为out的变量,但是您可以添加更多的out变量,不是吗?还是会崩溃?

I'm guessing this works because flatColor is the only variable defined as out, but you're allowed to add more out variables aren't you? Or would that just crash?

实际上,作为测试,我只是运行了此

Actually, as a test, I just ran this:

#version 330

in vec2 TexCoord0;

uniform sampler2D TexSampler;

out vec4 x;
out vec4 y;

void main()
{
    y = texture2D(TexSampler, TexCoord0.xy);
}

无论我使用x还是y,效果都很好.

It worked fine whether I used x or y.

此外,我们有一个预定义的gl_FragColor.有什么区别?为什么人们通常坚持使用自己的变量?

Furthermore, we have a predefined gl_FragColor. What's the difference, and why do people usually insist on using their own variables?

推荐答案

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

Furthermore, we have a predefined gl_FragColor.

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

Let's start with this. No, you don't have the predefined gl_FragColor. That was removed from core OpenGL 3.1 and above. Unless you're using compatibility (in which case, your 3.30 shaders should say #version 330 compatibility at the top), you should never use this.

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

Now, back to user-defined fragment shader outputs. But first, a quick analogy.

还记得顶点着色器中的输入吗?这些输入代表顶点属性索引,传递给glVertexAttribPointerglEnableVertexAttribArray的数字等等?您可以设置从哪个属性提取哪个输入.在GLSL 3.30中,您使用以下语法:

Remember how, in vertex shaders, you have inputs? And these inputs represent vertex attribute indices, the numbers you pass to glVertexAttribPointer and glEnableVertexAttribArray and so forth? You set up which input pulls from which attribute. In GLSL 3.30, you use this syntax:

layout(location = 2) in color;

这会将color顶点着色器输入设置为来自属性位置2.在3.30之前(或没有ARB_explicit_attrib_location的情况下),您将必须使用

This sets the color vertex shader input to come from attribute location 2. Before 3.30 (or without ARB_explicit_attrib_location), you would have to either set this up explicitly with glBindAttrbLocation before linking or query the program for the attribute index with glGetAttribLocation. If you don't explicitly provide an attribute location, GLSL will assign a location arbitrarily (ie: in an implementation-defined manner).

在着色器中进行设置几乎总是更好的选择.

Setting it in the shader is almost always the better option.

无论如何,片段着色器输出的工作方式几乎完全相同.片段着色器可以写入多种输出颜色,它们自身会映射到帧缓冲区中有多个缓冲区.因此,您需要指示哪个输出转到哪个片段输出颜色.

In any case, fragment shader outputs work almost exactly the same way. Fragment shaders can write to multiple output colors, which themselves get mapped to multiple buffers in the framebuffer. Therefore, you need to indicate which output goes to which fragment output color.

此过程从片段输出位置值开始.与顶点着色器输入位置的设置非常相似:

This process begins with the fragment output location value. It's set very similarly to vertex shader input locations:

layout(location = 1) out secColor;

还有API函数 glBindFragDataLocation

There are also the API functions glBindFragDataLocation and glGetFragDataLocation, which are analogous to glBindAttribLocation and glGetAttribLocation.

如果您不进行任何显式分配,则实现通常会将您的输出变量之一分配给位置0.但是,OpenGL标准不要求此行为,因此您不应依赖要么.

If you don't do any explicit assignments, implementations usually will assign one of your output variables to location 0. However, the OpenGL standard does not require this behavior, so you should not depend on it either.

为了公平起见,当您使用两个没有获得不同输出位置的输出时,您的程序应该链接为 failed .可能发生的是您的编译器优化了您没有写出的代码,因此在检查链接器错误时有点忘记了.

Now to be fair, your program should have failed to link when you used two outputs that didn't get different output locations. What probably happened was that your compiler optimized the one you didn't write to out, so it kinda forgot about it when it came time to check for linker errors.

这篇关于片段着色器如何知道要用于像素颜色的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆