为了绘制一帧,或者说给定一个顶点数组,当这个数组在着色程序的各个阶段传递和通过时,前一个阶段和后一个阶段之间是否存在严格的对应关系?
例如。给定 3 个顶点 (0,1,0) , (1,1,0) , (1,0,0) ,如果它是 vec3 aPos 中的 layout (location = 0);,vertex-shader 将执行 3 次 写在着色器的顶部。因为顶点着色器会针对每个顶点执行(由顶点属性决定有多少个顶点,所以即使一开始有6个vector3类型的变量,如果一半变量视为正常,VS仍然会执行3次)一个顶点)
我不知道 GS 会执行多少次,因为与输入相比,GS 后可以生成更多顶点。那FS呢?
我知道 FS 之前有光栅化。它将模拟信号(εR。保真度仅受浮点大小限制)转换为数字信号(我们的屏幕,受像素数量限制)。三角形与 FS 在该三角形上执行的次数之间是否存在对应关系,就像给定一个三角形(3 个向量)一样,程序将对其进行光栅化,并且 FS 将执行的次数等于覆盖区域中有多少像素)?
或者FS执行的总次数是否等于屏幕尺寸的像素数,就像用滚轮覆盖墙壁一样?
编辑:我猜 GS 是按原语执行的。因为您有一组表示一个基元中的多个顶点的结构体。
顶点着色器运行的次数与您指定为
glDrawArrays
最后一个参数(该参数称为 count
)的次数相同。
几何着色器运行的次数与您拥有的图元(点、线、三角形)一样多。但是,请记住,曲面细分着色器(如果有的话)通常会增加图元的数量。
理论上,片段着色器的运行次数大致与基元覆盖的像素数相同。然而,这有点复杂,因为很多因素都会影响这一点。如果启用深度测试或模板测试,GPU(很可能)不会在测试失败的像素上运行片段着色器。显然,GPU 不会对您使用
glViewport
设置的视口之外的像素进行光栅化。当您使用多重采样或保守光栅化时,片段着色器可能会运行更多次。还有一件更重要的事情:GPU 无法光栅化单个像素,它以 2x2 为单位进行光栅化,以便您可以使用导数。
假设您有一个包含 6 个顶点的顶点缓冲区。如果您使用 6 的
glDrawArrays
来调用 count
,则无论您使用哪种基元模式,顶点着色器都将运行 6 次。如果您使用 GL_POINTS
调用它,几何着色器将运行 6 次,因为您单独绘制所有顶点。如果用 GL_LINES
调用它,几何着色器将运行 3 次,因为每条线都由 2 个顶点组成。如果用 GL_TRIANGLES
调用它,几何着色器将运行 2 次,因为每个三角形都由 3 个顶点组成。片段着色器取决于。例如,如果您有更高分辨率的屏幕,它会运行更多次,因为相同的基元覆盖更多像素,但同样,这取决于我之前提到的很多配置。
因此很难说出片段着色器调用的数量,尤其是对于复杂的场景。幸运的是,您可以在 OpenGL 中使用参数
GL_SAMPLES_PASSED
创建一个查询对象,并且可以让 OpenGL 计算深度测试中通过的像素数。
由于片段着色器通常是性能最重的着色器阶段(并且通常运行次数最多),因此尽可能少地运行它非常重要。例如,某些游戏引擎根据距相机的距离对网格进行排序,并首先渲染较近的网格,因为靠近相机的网格可能会覆盖较远的网格。但是还有很多其他方法可以减少片段着色器调用的数量,例如遮挡剔除、动态分辨率缩放、棋盘渲染、图像放大(例如 DLSS、FSR 或 XeSS)等。