【问题标题】:Does it make any difference which shader calculations are performed in?在哪个着色器计算中执行有什么区别吗?
【发布时间】:2015-02-11 11:00:55
【问题描述】:

使用 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);

【问题讨论】:

    标签: c++ opengl graphics opengl-es glsl


    【解决方案1】:

    我将执行光照计算、纹理和各种操作;但它在哪个着色器中完成有什么区别吗?

    想想 OpenGL 管道中的数据流。

    大多数图元由 1 个(点)、2 个(线)或 3 个(三角形)顶点组成,但可能会生成数千个片段。因此,由于顶点着色器的运行频率要低得多,因此您可以按顶点计算的任何东西都将比按片段便宜。

    通常,您尽量不要计算每个顶点的整个光照方程 (gouraud),因为除非您使用过多的顶点,否则它看起来很糟糕。但是,您可以将所有光照矢量转换到顶点着色器中的相同坐标空间,以简化片段着色器并提高性能。

    顶点属性是否对任何着色器程序中的所有着色器都是全局的?

    顶点属性分配给通用位置,并且这些位置是全局的。但是片段着色器对每个片段进行操作,并且没有顶点的概念(再次回想一下数据流)。

    我是否可以在该着色器程序的所有着色器中使用制服,只要我声明它们?

    另一方面,Uniforms 在所有着色器阶段之间共享。只要名称和类型一致,您就可以在顶点、几何、细分或片段着色器中使用它们。

    所有的顶点属性是否应该在整个主程序中保持一致?

    这真的没关系,可编程流水线是可编程的。只要知道当你的着色器执行时N代表什么顶点属性,你就可以开始了。但是,如果您建立标准约定,则可以在不更改顶点属性指针的情况下即时交换着色器程序。

    在固定功能管道的日子里,有一个standardized convention,其中顶点位置别名为0,颜色别名为3,法线别名为 >2 以此类推。但这纯粹是历史性的,如果您愿意,可以遵循该约定或创建自己的约定。

    【讨论】:

    • 我根本不会使用 Goraud 着色。我只问是否可以在顶点着色器中进行 Phong 光照计算,然后简单地将光照强度传递给片段着色器。
    • @Poriferous:这就是所谓的“Gouraud shading”。
    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 2021-01-05
    • 2018-11-28
    • 2021-01-30
    • 2013-12-10
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多