I'm using texture blending in my terrain's fragment shader to blend from one texture to the next. Right at the seam between using only my grass texture and blending between dirt/grass or snow/grass textures, the mipmaps seem to cause an ugly seam (see photo below). Disabling mipmapping fixes the problem but makes my terrain very grainy/ugly at a distance. Is there a way to eliminate this seam without disabling mipmapping?
terrain-vs.glsl:
precision mediump float;
attribute vec3 Position;
attribute vec2 TextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec2 texCoord;
varying float y;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(Position, 1.0);
texCoord = TextureCoord;
y = Position.y;
}
terrain-fs.glsl:
precision mediump float;
uniform sampler2D dirt_texture;
uniform sampler2D grass_texture;
uniform sampler2D snow_texture;
varying vec2 texCoord;
varying float y;
void main(void) {
if (y < -5.0) {
gl_FragColor = texture2D(dirt_texture, texCoord);
} else if (y < 0.0) {
gl_FragColor = mix(
texture2D(dirt_texture, texCoord),
texture2D(grass_texture, texCoord),
(y + 5.0) / 5.0
);
} else if (y < 3.0) {
gl_FragColor = texture2D(grass_texture, texCoord);
} else if (y < 5.0) {
gl_FragColor = mix(
texture2D(grass_texture, texCoord),
texture2D(snow_texture, texCoord),
(y - 3.0) / 2.0
);
} else {
gl_FragColor = texture2D(snow_texture, texCoord);
}
}
TextureManager::initialize
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
Configuration:
normal view
zoomed in
GPU needs to know gradients to sample a texture. You either supply the gradients explicitly (textureGrad) or you let GPU to compute the gradients for you. The automatically computed gradient are computed using local differencing. See function dFdx (http://www.opengl.org/sdk/docs/manglsl/xhtml/dFdx.xml) for details.
Computing derivatives produces undefined result when the function evaluates for one pixel but not for nearby pixels (non uniform control flow).
The shader in Answer 1 works well because the textures are always sampled, no matter if their result is used or not.
More info is here http://www.opengl.org/wiki/Sampler_(GLSL)#Non-uniform_flow_control
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With