Reputation: 3417
I'm rendering a terrain with multiple textures that includes smooth transitions between the textures, based on the height of each fragment. Here's my fragment shader:
#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' will always be in the range [0,1].
Here's the weird flickering I get. From what I can see they happen when 'height' equals one of the rangeN variables when using mix()
.
What may be the cause of this? I also tried playing around with adding and subtracting a 'bias' variable in some computations but had no luck.
Upvotes: 2
Views: 1037
Reputation: 1862
Your problem is non-uniform flow control. Basically, you can't call texture() inside an if.
Two solutions:
In very simple cases, the first solution may be slightly faster. The second one is the way to go if you want to have many textures (normal maps etc.) But don't take my word for it, measure.
Upvotes: 1