多重采样,如何读回“独特”的纹素

时间:2016-07-21 10:39:56

标签: glsl multisampling vulkan deferred-rendering

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

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

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

如果可以在第一遍中创建片段着色器,则只写入三角形覆盖的第一个子像素。它允许您忽略光照过程中未写入的纹理像素。然后最后在第二个几何通道中,以某种方式只读回三角形匹配的第一个子像素,这是我们原来写的那个,然后照明(现在正常写入所有被覆盖的纹素,所以结果可以解决)。这样,只有“独特”的纹素才能在第2和第3遍中进行评估。

有人可以说如何在glsl中完成这项工作(或确认不可能)?我真的没有理由认为这在理论上是不可能的,但也没有看到任何方法在glsl中这样做。

1 个答案:

答案 0 :(得分:1)

暂时,我将忽略您问题的目标,而是专注于具体请求:

  1. 您是否只能从片段着色器中写入“第一个”样本?
  2. 是。你需要做的是让你的片段着色器使用装饰SampleMask声明一个输入整数数组(或者,用GLSL的说法,使用gl_SampleMaskIn, an array of signed integers)。然后,您将逐位遍历此数组,以找到设置的第一个位。

    这个位是“第一个样本”。然后,您使用装饰SampleMask声明输出整数数组(在GLSL用语中,gl_SampleMask, an array of signed integers)。将“第一个样本”位设置为1,将所有其他位设置为零。

    1. 您能知道为多重采样图像中的特定像素编写的“第一个样本”是什么吗?
    2. 除非您将该数据写入其他内存,例如SSBO或其他内容。多重采样图像不知道哪些样本已被写入,因此无法知道哪个是第一个。

      即使你可以:

      你的整个想法将无效。

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

      如果两个三角形重叠,那么您的“第一个样本”方法毫无意义。为什么?因为有两个“第一个样本”:来自三角形1的第一个样本和来自三角形2的第一个样本。并且三角形2可能覆盖了来自三角形1的“第一个样本”。

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