我在我的terrain的片段着色器中使用纹理混合来从一个纹理混合到下一个纹理。在仅使用我的草纹理和在泥土/草地或雪/草纹理之间混合的缝隙处,mipmaps似乎会造成难看的缝隙(见下图)。禁用mipmapping可以解决问题但会使我的地形在远处变得非常颗粒状/丑陋。有没有办法在不禁用mipmapping的情况下消除这种接缝?
地形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;
}
地形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 ::初始化
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);
配置:
普通视图
放大了
答案 0 :(得分:8)
GPU需要知道渐变以对纹理进行采样。您可以显式提供渐变(textureGrad),也可以让GPU为您计算渐变。使用局部差分计算自动计算的梯度。有关详细信息,请参阅函数dFdx(http://www.opengl.org/sdk/docs/manglsl/xhtml/dFdx.xml)。
当函数计算一个像素而不是附近像素(非均匀控制流)时,计算导数会产生未定义的结果。
答案1中的着色器效果很好,因为纹理总是被采样,无论结果是否被使用。
更多信息在这里http://www.opengl.org/wiki/Sampler_(GLSL)#Non-uniform_flow_control
答案 1 :(得分:0)
据我所知,下面的片段着色器基本上与我上面提供的相同,但是当传递给a
的参数接近1.0或0.0时,显然混合做了一些时髦的事情。不使用混合和手动混合着色器似乎解决了这个问题。
更新了片段着色器:
precision mediump float;
uniform sampler2D dirt_texture;
uniform sampler2D grass_texture;
uniform sampler2D snow_texture;
varying vec2 texCoord;
varying float y;
void main(void) {
vec4 dirt = texture2D(dirt_texture, texCoord);
vec4 grass = texture2D(grass_texture, texCoord);
vec4 snow = texture2D(snow_texture, texCoord);
float dirt_weight = 0.0;
float grass_weight = 0.0;
float snow_weight = 0.0;
if (y < -5.0) {
dirt_weight = 1.0;
} else if (y < 0.0) {
grass_weight = (y + 5.0) / 5.0;
dirt_weight = 1.0 - grass_weight;
} else if (y < 3.0) {
grass_weight = 1.0;
} else if (y < 5.0) {
snow_weight = (y - 3.0) / 2.0;
grass_weight = 1.0 - snow_weight;
} else {
snow_weight = 1.0;
}
gl_FragColor = dirt * dirt_weight + grass * grass_weight + snow * snow_weight;
}