使用GLSL,我正在进行照明计算,纹理和各种各样的事情;但它在哪个着色器中完成会有什么不同?例如,在顶点着色器而不是片段着色器中执行光照计算是否有性能优势?我只需要将最终结果传递给片段着色器并将其添加到片段颜色中。可以这样反过来吗?
我的下一个问题是关于顶点属性和制服:
顶点属性是否对任何着色器程序中的所有着色器都是全局的?例如,假设我们有:
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices), (GLvoid*)0);
如果我然后在顶点着色器中声明:
layout (location = 0) in vec3 VertexPosition;
我是否也可以在片段着色器中执行相同的操作?我是否也可以在与第二个着色器程序相关的顶点着色器中执行相同的操作?
关于制服,我可以在着色器程序的所有着色器中使用制服,只要我声明它们吗?
uniform mat4 modelMatrix; // In the vertex shader
uniform mat4 modelMatrix; // In the fragment shader
我的最后一个问题是,所有顶点属性是否应该在整个主程序中保持一致?如果我将顶点属性0分配为VertexPosition,那么我就不能再将该属性分配给其他类似的东西了作为VertexNormal,对吗?除非我使用:
禁用顶点属性数组,否则只会发生这种情况glDisableVertexAttribArray(0);
答案 0 :(得分:4)
我将进行灯光计算,纹理和各种各样的事情;但它在哪个着色器中完成有什么不同呢?
大多数基元由1(点),2(线)或3(三角)顶点组成,但可能产生数千个碎片。因此,由于顶点着色器的运行频率较低,因此每个顶点可以计算的任何内容都比每个片段便宜。
通常,您尝试不计算每个顶点(gouraud)的整个光照方程,因为除非使用过多的顶点,否则它看起来很糟糕。但是,您可以将所有光照矢量转换为顶点着色器中的相同坐标空间,以简化片段着色器并提高性能。
顶点属性是否对任何着色器程序中的所有着色器都是全局的?
将顶点属性分配给通用位置,这些位置是全局的。但片段着色器操作每个片段并且没有顶点概念(再次回想一下数据流)。
只要我声明它们,我是否可以在该着色器程序的所有着色器中使用制服?
另一方面,制服在所有着色器阶段之间共享。只要名称和类型一致,您就可以从顶点,几何,曲面细分或片段着色器中使用它们。
所有顶点属性是否应该在整个主程序中保持一致?
这无关紧要,可编程管道是可编程的。只要你知道在执行着色器时顶点属性 N 表示什么,就可以了。但是,如果建立标准约定,则可以在不更改顶点属性指针的情况下即时交换着色器程序。
在固定功能管道的时代,有一个standardized convention,其中顶点位置别名为 0 ,颜色别名为 3 ,正常别名为 2 等等。但这纯粹是历史性的,如果你想要或创造自己的约会,你可以遵循这个惯例。