1

在多重采样中,在光栅化过程中,每个像素中存在多个采样点,并确定构成图元的采样点。

像素中每个样本的哪些属性相同?我在某处读到颜色和纹理值相同,但像素中样本的深度和模板值不同。但是由于对每个样本点执行片段着色器,所以它们应该是不同的。

另外,在片段着色器之后,何时在管道中解析多个样本?它们是线性平均的吗?

4

1 回答 1

7

首先,您必须了解多重采样的工作原理以及创建它的原因。

我将从抗锯齿的角度来处理这个问题,因为在 GL3 中引入多采样纹理之前,这是多采样的主要用例。

当某物被多重采样时,这意味着每个采样点都包含多个样本。如果一个基元具有相对一致的特征(例如,到处都有相同的深度),这些样本可能彼此相同,并且智能 GL/硬件实现能够识别这种情况并通过智能地读取/写入共享样本来减少内存带宽(类似于颜色/深度缓冲区压缩)。但是,4x MSAA 帧缓冲区所需的存储成本与 4x SSAA 相同,因为 GL 必须适应最坏的情况,即 4 个样本中的每一个都是唯一的。

像素中每个样本的哪些属性相同?

每个片段可以覆盖多个采样点的属性,如颜色、纹理坐标等。与其频繁调用片段着色器 4x 来实现 4x 抗锯齿,设计了一个技巧,每个属性将在片段中心进行采样(这是默认值),然后将单个输出写入每个覆盖的样本位置。在片段的中心不是实际覆盖区域的一部分的情况下,默认行为有些缺乏 - 为此,引入了质心采样......顶点属性将被插值在片段内图元覆盖区域的中心而不是片段本身的中心。

稍后,当需要将颜色写入帧缓冲区时,需要对所有这些样本进行平均以产生单个像素;我们称之为多样本解析。这对某些事情很有效,但它不能解决在片段着色本身期间发生的别名问题。

纹理在片段着色器的执行过程中发生,这意味着纹理的采样频率保持不变,因此 MSAA 通常对纹理混叠没有帮助。因此,虽然超采样抗锯齿改善几何边缘的锯齿纹理/着色器锯齿(例如镜面高光),但多重采样通常只会减少“锯齿”。

我在某处读到颜色和纹理值相同,但像素中样本的深度和模板值不同。

简而言之,在片段着色器中计算的任何内容对于所有覆盖的样本都是相同的。在片段着色(例如深度)之前可以确定的任何内容都可能会有所不同。

对每个子样本进行碎片测试,例如深度/模板。但是多重采样深度缓冲区有一些限制。在 D3D 10.1 之前,不需要硬件来支持多重采样深度纹理,因此您无法在片段着色器中对多重采样深度缓冲区进行采样。

但是由于对每个样本点执行片段着色器,所以它们应该是不同的。

有一个称为样本着色的功能,它可以通过提高着色片段与光栅化期间生成的样本之间的比率来强制 MSAA 的实现更像 SSAA。但默认情况下,您描述的行为不是多重采样。

在片段着色器之后,何时在管道中解析多个样本?它们是线性平均的吗?

多采样分辨率发生片段着色之后,任何时候您必须将多采样缓冲区的内容写入单采样缓冲区。这包括诸如glBlitFramebuffer (...). 如果您使用多重采样纹理,您也可以自己片段着色器中手动实现多重采样分辨率。

最后,关于用于多样本分辨率的过程,这是特定于实现的,样本布局也是如此。如果您曾经打开显示驱动程序的控制面板并查看无数可用的抗锯齿选项,您将看到示例布局和 MSAA 解析算法的多个选项。


我强烈建议你看看这篇文章。虽然它与 D3D10+ 而不是 OpenGL 相关,但通用规则适用于两种 API(D3D9 的规则略有不同),并且图表的质量非常出色。

特别要特别注意关于三角形的 MSAA 光栅化规则的部分,其中指出:

对于三角形,对每个样本位置(而不是像素中心)执行覆盖测试。如果覆盖了多个样本位置,则像素着色器将运行一次,并在像素中心插入属性。为通过深度/模板测试的像素中每个覆盖的样本位置存储(复制)结果。

于 2014-03-25T20:10:11.410 回答