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

时间:2015-01-13 17:24:25

标签: opengl shader texture-mapping fragment-shader terrain

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

#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);
}

&#39;高度&#39;将始终在[0,1]范围内。

这是我得到的奇怪的闪烁。从我所看到的情况来看,他们发生在“身高”的时候。使用mix()时等于rangeN变量之一。

flickering

Contours highlighted

可能是什么原因造成的?我也尝试过添加和减少偏见&#39;在一些计算中变量但没有运气。


1 个答案:

答案 0 :(得分:1)

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

中调用texture()

两种解决方案:

  • 首先调用texture()然后将结果与mix()
  • 混合
  • 计算纹理坐标的偏导数(使用dFdx&amp; co。,上面的链接中有一个例子)并使用textureGrad()代替texture()

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