5

テレインのフラグメント シェーダーでテクスチャ ブレンディングを使用して、あるテクスチャから次のテクスチャにブレンドしています。草のテクスチャのみを使用し、土/草または雪/草のテクスチャをブレンドする間の継ぎ目で、ミップマップが醜い継ぎ目を引き起こしているようです (下の写真を参照)。ミップマッピングを無効にすると問題は解決しますが、遠方の地形が非常に粗く/醜くなります。ミップマッピングを無効にせずにこの継ぎ目をなくす方法はありますか?


地形-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);

構成:

  • ウィンドウズ 7 プロ SP1
  • Google Chrome 24.0.1312.57 m
  • NVIDIA GTX 680

通常のビュー 通常のビュー

ズームイン ズームイン

4

2 に答える 2

8

元のフラグメント シェーダーがアーティファクトを生成する理由の説明

GPU は、テクスチャをサンプリングするために勾配を知る必要があります。勾配を明示的に指定するか (textureGrad)、GPU に勾配を計算させます。自動計算された勾配は、ローカル差分を使用して計算されます。詳細については、関数 dFdx ( http://www.opengl.org/sdk/docs/manglsl/xhtml/dFdx.xml ) を参照してください。

関数が 1 つのピクセルを評価し、近くのピクセルを評価しない場合 (不均一な制御フロー)、導関数を計算すると未定義の結果が生成されます。

結果が使用されるかどうかに関係なく、テクスチャは常にサンプリングされるため、回答 1 のシェーダは適切に機能します。

詳細はこちらhttp://www.opengl.org/wiki/Sampler_(GLSL)#Non-uniform_flow_control

于 2013-02-17T17:25:21.753 に答える
0

私の知る限りでは、次のフラグメント シェーダーは基本的には上で提供したものと同じですが、渡されたパラメーターがa1.0 または 0.0 に近い場合、mix はおかしな動作をするようです。混合を使用せず、シェーダーを手動で混合すると、これが修正されたようです。


更新されたフラグメント シェーダー:

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;
}
于 2013-02-16T21:49:53.093 に答える