5

在阅读 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;
   }

我的困惑是它vFragColor在 out 声明中说,而gl_FragColor在 main() 中说。

另一方面,在网站的代码中,它已被更正为 'vFragColor = vColorValue;' 在主循环中。

我的问题是,除了本书中的错字之外,out着色器命名值的规则是什么?他们必须遵循特定的名称吗?

在 OpenGL.org 上,我发现顶点着色器外需要 gl_Position。片段着色器有这样的东西吗?或者只是如果只有一个输出,那么它将是缓冲区中的颜色?

当片段着色器中有多个时会发生什么?GLSL 编译器如何知道在缓冲区中使用哪一个?

4

2 回答 2

7

1.3 版的 GLSL 规范中所述,gl_FragColor不推荐在片段着色器中使用 。相反,您应该使用用户定义的输出变量,例如 vFragColor片段着色器中描述的变量。正如你所说,这是一个错字。

命名着色器值的规则是什么?

变量名称可以是您喜欢的任何名称,除非它与任何现有名称冲突。

当片段着色器中有多个时会发生什么?GLSL 编译器如何知道在缓冲区中使用哪一个?

当片段着色器中有多个输出时,您应该通过调用BindFragDataLocation将插槽分配给片段着色器输出。然后,您可以通过调用DrawBuffers来说明哪些插槽将渲染到哪个渲染目标。

规范规定,如果您在片段着色器中定义了一个输出变量,它将被分配给索引 0 并输出 0。有关更多信息,我建议您自己一下。

于 2012-08-05T18:15:22.160 回答
0

gl_FragColor 是 GLSL 早期版本中的原始输出变量。这是要绘制的片段的颜色。

您最初的困惑是有道理的,因为没有理由声明该out变量然后写入 glFragColor。

在以后的版本中,它变得可定制,这样您就可以为输出变量指定任意名称。您可以使用命令将这些任意输出映射到特定缓冲区glBindFragDataLocation

我不是 100% 肯定的,但我相信如果你在链接之前不调用这个函数,那么你的输出变量将被随机分配给缓冲区。如果您只有一个输出,则应始终将其分配给缓冲区 0。

于 2012-08-04T17:43:55.243 回答