延迟明暗处理抗锯齿

bhmjp9jg  于 2022-09-26  发布在  其他
关注(0)|答案(3)|浏览(161)

许多人注意到,MSAA不适用于延迟着色。为什么会这样呢?在我的脑海里听起来没问题。

根据wikipedia
..。由于将照明舞台与几何舞台分开,硬件抗锯齿不再产生正确的结果,因为插值子采样将导致无意义的位置、法线和切线属性。

你能解释一下吗?

我还有其他的AA替代方案吗?

bxgwgixi

bxgwgixi1#

多重采样确实适用于延迟渲染。延迟渲染只会改变您为其支付的价格

多重采样的基本思想是,对于该像素内特定三角形的光栅化所覆盖的所有采样,只需执行一次碎片着色器。因此,当您写入多个采样(如使用超级采样)时,您只需执行一次片段着色器,从而节省了大量纹理访问。在多采样图像中的所有采样之间写入相同的值。

通过延迟渲染,这仍然是可行的。在多重采样规则下,几何体过程仍然有意义。或者至少,它和以前一样有意义。

问题是在光照过程中你必须做什么。

因为几何体过程是多采样的,所以照明过程必须读取多采样数据。您不能对几何缓冲区进行多样本解析(这将是维基百科所说的“无意义的”部分);您的光照过程必须读取每个样本并对其进行处理。每盏灯。因此,如果您执行8倍多采样操作,您的片段着色器将必须为每个像素运行8次。每盏灯。

这通常不是很多人愿意付出的代价。

其他的选择是任何一种“我不敢相信这不是反走样”技术,比如FXAA或其他任何技术。

uqcuzwp8

uqcuzwp82#

多采样抗锯齿在多个子像素位置对基本体的可见性进行采样,但是着色仅在每个基本体的像素内计算一次。延迟明暗处理对几何属性进行采样,并且明暗处理被推迟到第二阶段,在该阶段,基元和可见性样本之间的对应关系丢失,这使得很难避免冗余明暗处理。此外,在高屏幕分辨率和高可见度采样的情况下,几何缓冲区可能会变得大得令人望而却步,因为每个采样需要存储所有属性。-摘自延迟属性内插着色的介绍。

iih3973s

iih3973s3#

使用MSAA进行延迟着色是完全可能的,但这当然会增加渲染器的复杂性。

执行此操作的简单方法是(我暂时假设您在片段/像素着色器中应用灯光):

  • 使用每像素N个采样渲染GBuffers(包括深度缓冲区)
  • 在光线过程中,对于每个像素,在N个采样之间迭代以执行着色(并对结束时的值进行平均)。

这显然有一个巨大的成本(因为如果你运行8个采样每像素的全高清渲染,你实际上是在8x全高清分辨率着色)。

值得庆幸的是,有一些优化可以应用于这个过程(我假设您的深度缓冲区是支持模具的格式(d24s8在这方面很常见):

  • 如上所述,使用每像素N个采样来渲染GBuffers。
  • 在模板状态上设置模板位(如果您已经使用模板,则需要为此保留一个位标志),并将写掩码设置为仅写入该位(我假设您的模板被清除到帧的零开始)。禁用读取测试,该位将为只写。
  • 运行“样本边缘检测”过程,你想要检查样本之间的深度/法线/颜色差异,如果它们中的一些高于某个值,这是一个边缘,需要每个样本着色。如果不是,则可以按像素运行着色。如果您的像素不是边缘,请执行丢弃(以便模具位设置为1仅包含边缘像素)。
  • 将模具测试读取掩码设置为与写入掩码相同的值,并将比较设置为NOT_EQUAL,参考值=1
  • 按像素运行着色过程(边缘像素不会通过模具测试,因此不会为这些像素调用碎片着色器)。
  • 将模板测试的比较设置为相等
  • 运行每采样像素xN采样的着色过程(非边缘像素不会通过模具测试,因此不会为这些像素调用片段着色器)。

这会让你多花2次,但可能会让你在每个样本中运行总像素的5%(当然,根据场景的不同,可能会更低)。

现在,如果您在计算着色器(基于瓷砖的延迟)中应用灯光,则MSAA和Deffed也可以很好地工作。这主要用于无阴影的点/聚光灯。这是一个很长的主题,但粗略地说,您将使用迷你平截体和TGSM为屏幕的一小部分剔除灯光和边缘检测,并使用TGSM屏障首先对剔除的灯光应用所有非边缘像素,然后应用边缘像素,所有这些都在一个过程中完成。

小灯光的另一种技术是为所有的点灯光渲染小剪裁四边形(可以使用N个示例绘制6个顶点的示例,其中N是灯光的数量)。在顶点着色器中构建包围球体/圆锥体的四边形,并在碎片着色器中执行点/聚光灯距离测试。这大大限制了处理的像素量。在这种情况下,您可以使用与上面相同的模板技术。

此时,您有一个包含着色不透明内容的非多采样缓冲区,但您可能有一些透明对象(当然,您希望在这些对象上使用MSAA)。

因此,通常透明对象将以某种形式的简化前向着色过程进行处理。

流程如下:

  • 附加MSAA颜色纹理(无深度)。
  • 将着色纹理斑驳到MSAA纹理上。
  • 将深度模板贴回MSAA颜色目标的顶部。
  • 将深度写入设置为FALSE,将深度测试设置为LESS或LESSEQUAL(此处为您的首选项)。
  • 绘制透明对象(然后将启用MSAA,并正确进行深度测试)。

备注:

  • 如果使用计算瓷砖,可以将每瓷砖灯光索引/计数存储到缓冲区中,以便透明过程可以利用它(在透明碎片材质中计算瓷砖索引,然后只需迭代预计算剔除的灯光)。
  • 由于现在可以(同时)写入片段着色器中的缓冲区和纹理,如果使用剪裁四边形技术,还可以同时构建瓷砖数据(从像素计算瓷砖索引并在缓冲区中附加灯光索引),因此也可以使用此技术为进一步的透明过程构建一些加速结构。
  • 由于您将使用模具进行边缘检测,因此您还可以保留由所有不透明对象设置的另一位(这也将避免在灯光着色器中出现“天空碎片”)。它还允许您设置不发光的材料(在抽奖之前,只需确保您没有写入该位。这将需要在应用着色之前的斑点过程(写入所有未照明的像素,就像在着色纹理中一样),但这真的很快。

相关问题