【问题标题】:Opengl texture flickering when used with mix()与 mix() 一起使用时,Opengl 纹理闪烁
【发布时间】:2024-01-18 14:29:01
【问题描述】:

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

#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] 范围内。

这是我得到的奇怪闪烁。据我所见,当使用mix() 时,'height' 等于 rangeN 变量之一时会发生这种情况。

这可能是什么原因?我还尝试在某些计算中添加和减去“偏差”变量,但没有运气。


【问题讨论】:

  • 我很确定这两个工件都发生在统一的高度
  • 是的,你是对的。我必须自己在图像编辑器中将这些点连接起来才能正确看到它……对于肉眼来说,这是一种视错觉。我添加了一张使高度更清晰的图像。
  • 谢谢。你能想象这可能是什么原因吗?我还是想不通...

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


【解决方案1】:

您的问题是non-uniform flow control。 基本上,你不能在 if 中调用 texture()。

两种解决方案:

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

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

【讨论】:

    最近更新 更多