Glsl MSAA和顶点插值会导致值超出范围

Glsl MSAA和顶点插值会导致值超出范围,glsl,interpolation,msaa,Glsl,Interpolation,Msaa,我正在使用顶点着色器和片段着色器 顶点着色器在[0,1]范围内输出一个highp float 当它到达片段着色器时,我看到值(在三角形边上)超过1.1甚至更少 如果我 或者禁用MSAA 或使用GLSL平面禁用插值 如果启用了MSAA,那么钳制的0到1高精度浮点值如何在片段着色器中作为大大大于1的值到达 顶点着色器代码: out highp float lightcontrib2; ... lightcontrib2 = clamp( irrad, 0.0, 1.0 ); in highp

我正在使用顶点着色器和片段着色器

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

当它到达片段着色器时,我看到值(在三角形边上)超过1.1甚至更少

如果我

  • 或者禁用MSAA
  • 或使用GLSL
    平面
    禁用插值
如果启用了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; }
片段着色器代码:

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; }
毫无疑问,使用MSAA4X,这是OpenGL生成的图像。(观察车窗中央的magneta彩色像素。)

我已经排除了非数字值

GL_版本:3.2.0 NVIDIA 450.51.06

如果启用了MSAA,那么钳制的0到1高精度浮点值如何在片段着色器中作为大大大于1的值到达

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

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

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

然而,通过将FS调用值与深度采样分离,我们现在遇到了一个问题:单个FS调用在像素区域内的具体执行位置

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

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

但有些算法确实存在问题。这就是为什么我们有。它确保在基本体区域内生成特定的插值

正如您可能猜到的,这不是默认值,因为它比非质心插值慢。所以,只有在你需要的时候才使用它