16

游戏性能优化杂谈(十三)

 3 years ago
source link: https://zhuanlan.zhihu.com/p/300092826
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

光栅化的另外一个常见的性能问题在于保序。

我们都知道,Z测试(也就是深度测试)的引进将画面绘制顺序解放了出来,也就是我们可以以任意顺序绘制画面但是得到相同的结果。

但是现实是这只对于完全不透明的场景对象有效。况且,当两个多边形(三角形)位于同一个Z平面且相互交叠的时候,Z测试就无法保证渲染结果的稳定性。但是这种情况在诸如墙角,或者是deco(贴花)的情况下非常常见。

为了解决(缓解)这个问题,GPU的光栅化模块通常会对fragment进行保序。也就是先进入管线的三角形离散出的fragment,其计算(PS)结果,总是先输出。

这看起来似乎没有什么问题。但是实际上,不同的三角形可能分属于不同的场景物体,对应不同的材质,PS渲染工作量可能天差地别。加上GPU的并行处理特性,相对较晚进入管线的PS可能会领先执行完毕。这个时候,因为上述的保序要求,在前序三角形对应的PS没有执行完毕并输出计算结果时,后续三角形所对应的工作量将会因为需要等待输出结果的机会,一直滞留在管线当中。

这种情况在渲染的后处理阶段比较十分常见。渲染的后处理通常是一个全屏图像计算的过程,通过一个足以覆盖全屏的三角形,或者两个直角三角形来产生覆盖全屏的fragment。

但是事实上,大部分后处理过程当中因为并没有三角形相互覆盖的问题,也就是不存在Z测试的需求。这个时候的保序就成了累赘。

而且很多后处理在画面的各个位置的计算量并不是均匀的。比如AO、SSR这些计算,往往会有很明显的计算量差异。

这样的话就会发生大量结束的PS,因为要等待其前序PS计算完成才能向RT进行写出,导致的管线占用。从而其它任务进不来,影响效率。

所以近代的做法对于这些不严格依赖三角形顺序的算法,往往是采用CS来实现。因为CS有启动快、退出快、不需要保序的特点。

当然这意味着需要重写shader。我在GPUOpen上面也有看到比较新的A卡有提供关闭PS保序的功能。这样的话就可以很好地解决这个问题。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK