片段着色器是不是处理来自顶点着色器的所有像素?

Posted

技术标签:

【中文标题】片段着色器是不是处理来自顶点着色器的所有像素?【英文标题】:Does fragment shader process all pixels from vertex shader?片段着色器是否处理来自顶点着色器的所有像素? 【发布时间】:2015-07-04 03:31:53 【问题描述】:

如果我的管道中只有顶点着色器和片段着色器,我想知道的是片段着色器是从顶点着色器接收每个单独处理的顶点还是等到所有传入的值顶点着色器在将它们提供给片段着色器之前进行处理,然后单独处理每个像素或一次处理它们?

在顶点着色器获取下一个顶点或顶点输入进行处理之前,片段着色器是否会在每个顶点着色器执行后立即执行?

如果我有我的片段着色器这样做的意思:

const GLchar * vertex_shader_source = 
    "#version 430 core\n"
    "layout(location = 0) in vert;\n"
    "void main(void)\n"
    "\n"
    "gl_Position = vert;\n"
    "\n"
;
const GLchar * fragment_shader_source = 
    "#version 430 core\n"
    "out vec4 color;\n"
    "void main(void)\n"
    "\n"
    "color = vec4(gl_VertexID/100,gl_VertexID/100,gl_VertexID/100,1.0f);\n"
    "\n"
;

片段着色器实际上会与从缓冲区处理的每个顶点索引同步吗?

【问题讨论】:

为什么重要(不是混蛋,只是一个直截了当的问题)? GPU 往往会并行执行很多操作,我认为您无法可靠地预测您想知道的内容,因为它可能会根据特定的 gpu 和驱动程序等而有所不同。例如,进行平铺渲染的 GPU 将场景渲染为平铺,因此在使用片段着色器进行光栅化之前,它们可能不会立即使用顶点着色器处理几何体中的所有顶点。 是,也许,或者不,取决于哪个 GPU。大多数 GPU 都会有一些东西来避免处理对最终图像没有贡献的顶点,并且着色器显然不会看到这种“剔除”的顶点。并且它是在很长一段时间之后是立即之后又取决于GPU设计。可能是它处理所有顶点,并在完成后运行片段着色器,或者它可能一次处理几个顶点,或者真正流水线化。最有可能的是,在任何实际系统中,它们都不是“同步”的——GPU 在异步时会表现得更好。 ...gl_VertexID 仅在顶点着色器中可用,在片段着色器中不可用! 【参考方案1】:

您的问题具有误导性。片段着色器不是接收顶点的情况。他们收到碎片。在顶点着色器和片段着色器之间,有很多硬件需要多个顶点,从中形成三角形,对它们进行一系列处理(剔除、剪裁......)然后将它们光栅化(将三角形转换为一堆覆盖的正方形) 来生成将在片段着色器上执行的片段。

也就是说,从顶点 id 到片段并没有自然的映射(实际上,您需要多个顶点来生成片段,而且在许多情况下,单个顶点也会对多个三角形产生影响)。

所以根本没有办法在片段着色器中有意义地使用 gl_VertexID。

现在,关于“是否在片段之前运行所有顶点着色器”或此类问题......生成的任何片段都必须已经计算了顶点位置(因为需要计算片段覆盖率)。但这是您能得到的唯一保证。

基于 Tile 的延迟渲染器,例如如果可以的话,通常会首先处理所有顶点(在整个帧上!),只有稍后一帧才会处理所有片段。相反,“即时模式渲染器”将倾向于在三角形可用时对其进行处理。真正观察这些事情的方法并不多,我不知道有多少人确实对少数可用的方法进行了观察。

【讨论】:

以上是关于片段着色器是不是处理来自顶点着色器的所有像素?的主要内容,如果未能解决你的问题,请参考以下文章

带有顶点/片段着色器的光。使用不同的变量。 (openGL)

顶点着色器的绘制操作

GLSL:使用片段着色器进行对象翻译

条件语句会减慢着色器的速度吗?

着色器的简单理解

Shader2.0的顶点着色器和片段着色器