与 mix() 一起使用时 Opengl 纹理闪烁

Opengl texture flickering when used with mix()

我正在渲染一个具有多个纹理的地形,其中包括基于每个片段高度的纹理之间的平滑过渡。 这是我的片段着色器:

#version 430

uniform sampler2D tex[3];

uniform float renderHeight;

in vec3 fsVertex;
in vec2 fsTexCoords;

out vec4 color;

void main()
{
    float height = fsVertex.y / renderHeight;

    const float range1 = 0.2;
    const float range2 = 0.35;
    const float range3 = 0.7;
    const float range4 = 0.85;

    if(height < range1)
        color = texture(tex[0], fsTexCoords);
    else if(height < range2) //smooth transition
        color = mix( texture(tex[0], fsTexCoords), texture(tex[1], fsTexCoords), (height - range1) / (range2 - range1) );
    else if(height < range3)
        color = texture(tex[1], fsTexCoords);
    else if(height < range4) //smooth transition
        color = mix( texture(tex[1], fsTexCoords), texture(tex[2], fsTexCoords), (height - range3) / (range4 - range3) );
    else
        color = texture(tex[2], fsTexCoords);
}

'height' 将始终在 [0,1].

范围内

这是我遇到的奇怪的闪烁。据我所知,当 'height' 等于使用 mix().

的 rangeN 变量之一时,它们就会发生

这可能是什么原因造成的?我还尝试在某些计算中添加和减去 'bias' 变量,但没有成功。


您的问题是non-uniform flow control。 基本上,您不能在 if.

中调用 texture()

两种解决方案:

  • 首先对 texture() 进行所有调用,然后将结果与 mix() 混合
  • 计算纹理坐标的偏导数(使用dFdx & co.,上面link中有例子)并使用textureGrad()代替texture()

在非常简单的情况下,第一种解决方案可能会稍微快一些。如果你想要很多纹理(法线贴图等),第二个是要走的路但是不要相信我的话,测量。