0

我正在研究如何在延迟照明渲染器中实现抗锯齿。所以三个通道,一个几何通道,一个光照累积通道,然后是第二个用于着色的几何通道。

使用正常的多重采样 MSAA,目标是仅对多边形边缘上的像素进行多重采样。对于每个三角形,只将片段着色器的结果写入它所覆盖的子像素。但当然,这是一个已知问题,这对于延迟照明来说有点问题。

目标是避免评估第 2 次和第 3 次中的所有子像素,因为这基本上是超级采样。如果有人知道实现这一目标的另一种(更好/可能的)方法,我非常想听听。但这是我的想法:

如果您可以在第一遍中使片段着色器仅写入三角形覆盖的第一个子像素。它允许您忽略光照通道中未写入的纹素。然后最后在第二个几何通道中,以某种方式仅读取三角形匹配的第一个子像素,这是我们最初写入的子像素,然后进行照明(现在正常写入所有覆盖的纹素,所以结果可以解决)。这样,在第 2 次和第 3 次传递中只会评估“独特”的纹素。

有人可以说如何在 glsl 中做到这一点(或确认这是不可能的)吗?我真的看不出这在理论上是不可能的原因,但也看不到在 glsl 中这样做的任何方法。

4

1 回答 1

1

一会儿,我将忽略您的问题的目标,而是专注于特定的请求:

  1. 你可以只从片段着色器写入“第一个”样本吗?

是的。您需要做的是让片段着色器使用装饰声明一个输入整数数组SampleMask(或者,用 GLSL 的说法,使用gl_SampleMaskIn一个有符号整数数组)。然后,您将逐位遍历此数组,以找到设置的第一位。

该位是“第一个样本”。因此,然后您使用装饰声明一个输出整数数组SampleMask(在 GLSL 用语中gl_SampleMask,一个有符号整数数组)。您将“第一个样本”位设置为 1,将所有其他位设置为零。

  1. 你能知道为多样本图像中的特定像素编写的“第一个样本”是什么吗?

除非您将该数据写入其他内存,例如 SSBO 或其他内存,否则不会。多样本图像不知道已写入哪些样本,因此无法知道哪个是第一个。

即使你可以:


你的整个想法都行不通。

多重采样只是基于单一简化假设的超级采样。也就是说,可以为三角形生成的所有样本提供相同的每个片段值(深度除外)。在所有其他方面,它只是超级采样:为每个像素添加更多样本。

如果两个三角形重叠,那么你的“第一个样本”方法是没有意义的。为什么?因为有两个“第一个样本”:三角形 1 的第一个样本和三角形 2 的第一个样本。三角形 2 可能覆盖了三角形 1 的“第一个样本”。

即使没有覆盖第一个样本,您仍然不知道每个三角形贡献了多少样本。如果一个三角形贡献了右侧 50% 的像素样本,而一个重叠三角形贡献了底部 50% 的像素样本,那么您应该只获得第一个三角形贡献的 25%。你怎么知道用你的方法做到这一点?

于 2016-07-21T15:02:44.407 回答