【问题标题】:MSAA and vertex interpolation cause out-of-range valuesMSAA 和顶点插值导致超出范围的值
【发布时间】:2021-01-01 17:10:44
【问题描述】:

我将GLSL 与顶点着色器和片段着色器一起使用。

顶点着色器在[0,1]范围内输出highp float

当它到达片段着色器时,我看到值(在三角形边缘)超过 1.1 不少!

如果我...,这个问题就会消失。

如果启用了 MSAA,一个钳位的 0 到 1 高精度浮点数如何以远大于 1 的值到达片段着色器?

顶点着色器代码:

out highp float lightcontrib2;
...
lightcontrib2 = clamp( irrad, 0.0, 1.0 );

片段着色器代码:

in highp float lightcontrib2;
...
if (lightcontrib2>1.1) { fragColor = vec4(1,0,1,1); return; }

果然,使用 MSAA 4x,这是 OpenGL 生成的图像。 (观察窗口中心的磁色像素。)

我已经排除了非数字值。

GL_VERSION:3.2.0 NVIDIA 450.51.06

【问题讨论】:

    标签: glsl interpolation msaa


    【解决方案1】:

    如果启用了 MSAA,0 到 1 的高精度浮点数如何以远大于 1 的值到达片段着色器?

    多重采样的核心是超级采样的一种变体:从图元的像素大小区域获取多个样本。对该像素大小区域的空间内的不同位置进行采样以产生结果值。

    但是,当您处于图元边缘时,该像素大小区域中的某些位置在图元实际覆盖的区域之外。在超级采样中很好;你只是不使用这些样本。

    但是,多重采样是不同的。在多重采样中,深度样本不同于片段着色器生成的样本。也就是说,系统可能只执行一次 FS,但会获取 4 个深度样本并针对深度缓冲区中的 4 个样本进行测试。通过深度测试的任何样本都从执行的单个 FS 调用中获取其颜色值。如果这 4 个深度样本中的一些在图元区域之外,那很好;他们不算数。

    但是,通过将 FS 调用值从深度采样中分离出来,我们现在遇到了一个问题:该单个 FS 调用究竟是在何处在像素区域内执行的?

    这就是我们遇到问题的地方。如果 FS 调用在原语区域之外的位置执行,通常会被丢弃。但是如果任何深度样本都在图元区域内,那么这些深度样本仍然需要获取颜色数据。 MSAA 的重点是不为每个样本执行 FS,因此它们可能会从在不同位置执行的 FS 调用中获取颜色数据。

    理想情况下,它将来自在原语区域内的某个位置执行的 FS 调用。但硬件不能保证这一点。好吧,无论如何,它不能默认保证它。如果 FS 位置恰好落在基元区域之外,并不是每个算法都会出现问题。

    但有些算法确实存在问题。这就是我们有the centroid qualifier for fragment shader inputs 的原因。它确保将在图元区域内生成特定的插值。

    您可能已经猜到了,这不是默认值,因为它比非centroid 插值要慢。所以只在需要时使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      相关资源
      最近更新 更多