颜色属性与使用gl_Color

时间:2016-02-06 05:37:54

标签: glsl shader vertex-shader

大多数GLSL着色器在顶点着色器中使用颜色属性,该属性将作为变化转发到片段着色器。像这样:

attribute vec4 position;
attribute vec4 color;
uniform mat4 mvp;
varying vec4 destinationColor;

void main(){
  destinationColor = color;
  gl_Position = mvp * position;
};

可以使用glVertexAtribPointer()设置颜色,以便为每个顶点传递一种颜色或使用glVertexAttrib4fv()传递所有顶点的全局颜色。我尝试理解顶点着色器中预定义变量gl_Color的差异(如果有任何差异)。即。

attribute vec4 position;
uniform mat4 mvp;
varying vec4 destinationColor;

void main(){
  destinationColor = gl_Color;
  gl_Position = mvp * position;
};

并使用glColorPointer()为每个顶点传递一种颜色或使用glColor4fv()为所有顶点使用全局颜色。对我来说,第二个着色器看起来更好(=效率更高?),因为它使用较少的属性。但是所有的教程和在线资源正在使用第一种方法 - 所以我想知道我是否遗漏了任何东西或者根本没有差别。 编写GLSL着色器时有什么更好的做法?

2 个答案:

答案 0 :(得分:3)

  

对我来说,第二个着色器看起来更好(=效率更高?),因为它使用较少的属性。

它不使用更少的属性。它只使用较少的显式属性声明。为OpenGL获取该颜色值所需的所有工作仍然存在。它还在做。硬件仍在从缓冲区对象获取数据或从glColor上下文值或其他任何内容获取数据。

您只是在着色器的文字中看不到它。但仅仅因为你没有看到它并不意味着它是免费发生的。

出于以下原因,首选用户定义的属性:

  • 用户定义的属性可以清楚着色器使用的资源数量。如果您想知道需要为着色器提供多少属性,请查看全局声明。但是使用预定义的属性,你不能这样做;您必须在整个顶点着色器中扫描任何命名预定义属性的gl_*名称。
  • 用户定义的属性可以做更多事情。如果要将整数值作为整数传递给顶点着色器,则必须使用用户定义的属性。如果需要将双精度浮点数传递给顶点着色器,同样,预定义属性也无法帮助您。
  • 从核心OpenGL上下文中删除了预定义的属性。例如,OSX不允许兼容性配置文件。您仍然可以使用OpenGL 2.1,但如果您想在OSX上使用任何OpenGL 3.2或更高版本,则无法使用已删除的功能。并且在OpenGL 3.1中删除了内置顶点属性。
  • 预定义的属性从不是OpenGL ES 2.0+的一部分。因此,如果您想编写可在OpenGL ES中工作的着色器,您再次无法使用它们。

所以基本上,这些天没有理由使用它们。

答案 1 :(得分:1)

如果我没记错,gl_Color已弃用旧版 API ,不使用 VAO / VBO 使用glBegin() ... glEnd()。如果您转到核心配置文件,则不再有gl_Color ...所以我假设您使用旧的OpenGL版本或兼容性配置文件。

如果您尝试在核心配置文件中使用gl_Color(例如4.00),您可以:

0(35) : error C7616: global variable gl_Color is removed after version 140

这意味着gl_Color已从 GLSL 1.4

中删除

如果您愿意,这不仅仅是性能问题,而是图形渲染 SW 架构或 GL 层次结构的变化。