0

使用 OpenGL 的 MSAA。

我只是使用“glutSolidSphere”绘制了一个白色球体,并在“dot(Normal, CameraVec) < threshold”处填充黑色作为轮廓。
我在内部白色圆圈的轮廓处发现了一个奇怪的结果。看起来 MSAA 不起作用。
顺便说一句,它在黑色圆圈的轮廓(最外面)上效果很好。

如果我增加样本数量,即使在内白色圆圈的轮廓上也能很好地工作。
我认为它应该与样本数量无关,因为解析样本发生在片段着色器之后。

这是正确的结果吗?如果是,为什么?

下面是 4 个样本(左)和 32 个样本(右)的结果。

MSAA x4 MSAA x32

4

1 回答 1

2

MSAA 仅有助于平滑多边形边缘和交叉点。它对平滑由着色器代码创建的锐利过渡没有任何作用。

MSAA 背后的主要思想是片段着色器仍然每个片段只执行一次。每个片段有多个样本,覆盖率由样本决定。这意味着片段的一些样本可以在渲染的多边形内部,而一些在外部。然后将片段着色器输出仅写入覆盖的样本。但是片段中所有覆盖的样本都得到相同的值。

深度缓冲区还具有每个样本的分辨率,这意味着多边形之间的交叉点也可以从 MSAA 产生的平滑中受益。

一旦您了解了 MSAA 的工作原理,就会明白它对多边形内部的急剧过渡没有任何作用,这可能是着色器中应用逻辑的结果。为了在这种情况下实现平滑,您必须评估每个样本的片段着色器,而 MSAA 不会发生这种情况。

MSAA 很有吸引力,因为它确实为许多用例执行了足够的抗锯齿,而且开销相对较小。但正如您所注意到的,这显然不足以适用于所有情况。

您可以对此做些什么超出了此处的答案范围。主要有两个方向:

  • 您可以避免在着色器代码中生成尖锐的过渡。如果您使用标准纹理,则使用 mipmap 会有所帮助。对于程序转换,您可以在代码中平滑它们,可能基于梯度值。
  • 您可以使用不同的抗锯齿方法。这里有太多要说的了。使用超级采样很容易获得完美的抗锯齿,但它非常昂贵。大多数方法都试图在获得比普通 MSAA 更好的结果方面取得折衷,同时不增加太多开销。

我对使用 32x MSAA 可以在内侧边缘进行一些平滑这一事实感到有些困惑。我不认为这是预期的。我想知道在下采样过程中是否发生了什么会产生某种形式的平滑。

于 2015-11-20T04:40:44.133 回答