【问题标题】:Per vertex shading vs per fragment shading on large models大型模型上的每个顶点着色与每个片段着色
【发布时间】:2013-10-10 18:35:30
【问题描述】:

我是 GLSL 的新手,正在编写一个小型应用程序,该应用程序将显示 3d 模型并具有一些用户输入来旋转、缩放等。模型相当大(例如 600 万个顶点,1500 万个面)。现在,我正在使用逐顶点着色,并且在我的个人电脑上性能还可以。但我可能需要使用更大的模型(有 10-1500 万个顶点)。

我的问题与逐顶点和逐片段着色之间的性能比较有关。从大量资源以及搜索网络中,我得出结论,每个片段着色具有更好的输出,尤其是对于镜面高光,但是它的性能较低,因为它对多边形的每个像素而不是每个顶点进行计算(与每个顶点着色一样)。

也许我的想法完全错误,但是如果顶点数很大,我是否应该期望每个片段着色运行得更快,例如在我的情况下(6-10 百万个顶点)?每个片段着色的性能是否取决于被绘制到屏幕上的像素数,而每个顶点着色则不是?

【问题讨论】:

    标签: opengl glsl


    【解决方案1】:

    片段着色的性能取决于在屏幕上绘制的片段数量,包括那些因为某些三角形与其他三角形重叠并发生过度绘制而被绘制两次或更多次的片段。 Z 缓冲可以以某种方式减少过度绘制,但并不完美。在相对便宜的 Z 通道期间,延迟(或光预通道)着色可能仍然存在过度绘制,但或多或​​少使 实际 着色部分与屏幕区域严格成比例,无论某些三角形是否重叠(或如何重叠)他们中的许多人都在那里)。

    顶点着色(以及后续阶段)的性能主要取决于顶点的数量(如果您有几何着色器或曲面细分着色器处于活动状态,则还需要一些其他细节)。通常,现在大多数应用程序都不受顶点处理的限制。几百万个顶点这样通常不是问题(当然不画看不见的东西总是更好)。
    然而,随着三角形变得更小(接近 2x2 片段四边形的大小),更高的顶点数会导致额外的片段着色工作(当然还有组装/光栅化工作和 ROP),而视觉质量没有任何改善,有时甚至由于时间混叠而导致质量较差。
    这与实际处理的顶点数量没有太大关系,而是与单个三角形的屏幕面积变小有关。

    因此,您应该有一个 LOD(细节级别)系统,以确保没有太多太小的三角形(例如在远处的要素上),如果这些大型模型是建筑物或类似的,您可以考虑使用门户系统可以剪掉对可见结果没有贡献的整个几何层次结构。

    【讨论】:

    • 理论上,如果您有 600 万个子片段(子像素)三角形 - 片段着色可能会更快,因为它永远不会被执行,而几何/顶点处理将一直发生(不要做任何事都比做something快)。所以它延续了“不要画任何对结果图像没有影响的东西”的想法。
    • 不一定,光栅化器为三角形“接触”的每个光栅网格单元生成一个片段(必须至少是一个)。不幸的是,不存在单个片段这样的东西。这意味着像素着色器针对 2x2 片段组运行(这是必要的 a)因为硬件只是为了以这种方式工作而 b)因为导数计算)。因此,3 个顶点产生 4 个着色片段(可能带有纹理查找等),这些片段不会增加视觉质量,最终会被丢弃或权重过低,以至于它们的贡献不可见。
    • 在最坏的情况下,一个片段大小(或更小)的三角形会接触属于 3 个不同的 2x2 屏幕四边形的 3 个片段。现在 3 个顶点导致 12 个片段被着色,什么都不做......
    • 使用多重采样 - 也许,但没有它 - 它们应该在片段着色器执行之前被丢弃,只是因为没有任何着色器可以更改以防止丢弃,所以这种测试更早。但肯定不能保证,只是硬件中通常的性能优化。大约 2x2 - 确切地说,它可能会更大(我记得一些具有 4x4 执行四边形的显卡)。
    • 有时,这取决于。严格按照标准,深度测试发生在片段着色器之后。但是,如果不修改深度,则实现可以使用插值深度并在之前进行测试。此外,如果缓冲区已被正确清除并且测试条件尚未在帧中反转,则现在大多数实现将执行分层深度测试以更早地拒绝片段。为获得最佳效果,您需要清除深度缓冲区(而不是覆盖)并首先绘制大遮挡物,从最近到最远。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    相关资源
    最近更新 更多