1

次のフラグメントと頂点シェーダーがあり、テクスチャを繰り返します。

//Fragment
vec2 texcoordC = gl_TexCoord[0].xy;
texcoordC *= 10.0;
texcoordC.x = mod(texcoordC.x, 1.0);
texcoordC.y = mod(texcoordC.y, 1.0);
texcoordC.x = clamp(texcoordC.x, 0.0, 0.9);
texcoordC.y = clamp(texcoordC.y, 0.0, 0.9);
vec4 texColor = texture2D(sampler, texcoordC);
gl_FragColor = texColor;

//Vertex
gl_TexCoord[0] = gl_MultiTexCoord0;
colorC = gl_Color.r;
gl_Position = ftransform();

追加:このプロセスの後、テクスチャ座標をフェッチし、テクスチャパックを使用します。

vec4 textureGet(vec2 texcoord) {
    // Tile is 1.0/16.0 part of texture, on x and y
    float tileSp = 1.0 / 16.0;

    vec4 color = texture2D(sampler, texcoord);
    // Get tile x and y by red color stored
    float texTX = mod(color.r, tileSp);
    float texTY = color.r - texTX;
    texTX /= tileSp;
    // Testing tile
    texTX = 1.0 - tileSp;
    texTY = 1.0 - tileSp;

    vec2 savedC = color.yz;
    // This if else statement can be ignored. I use time to move the texture. Seams show without this as well.
    if (color.r > 0.1) {
        savedC.x = mod(savedC.x + sin(time / 200.0 * (color.r * 3.0)), 1.0);
        savedC.y = mod(savedC.y + cos(time / 200.0 * (color.r * 3.0)), 1.0);
    } else {
        savedC.x = mod(savedC.x + time * (color.r * 3.0) / 1000.0, 1.0);
        savedC.y = mod(savedC.y + time * (color.r * 3.0) / 1000.0, 1.0);
    }
    vec2 texcoordC = vec2(texTX + savedC.x * tileSp, texTY + savedC.y * tileSp);

    vec4 res = texture2D(texturePack, texcoordC);
    return res;
}

ただし、(1ピクセルのように見える)継ぎ目を表示するのに問題があります。texcoord * = 10.0を省略した場合、継ぎ目は表示されません(またはほとんど表示されません)。そのままにしておくと、継ぎ目が表示されます。座標をクランプします(1.0より低く0.0より大きくしようとしても)無駄になります。どこかで丸め誤差だと強く感じますが、どこにあるのかわかりません。追加:実際の場合、texcoordCxおよびyを8ビットフロートに変換することに注意してください。原因はここにあると思います。上記でこれを説明する別のシェーダーを追加しました。

私が示すケースは実際にはもう少し複雑なので、シェーダー(!)の外でこれを行うことはできません。ケースについて少し説明する前の質問を追加しました。

編集:ご覧のとおり、自然なテクスチャスパンは10で除算され、テクスチャが繰り返されます(10回)。継ぎ目は、繰り返されるすべてのテクスチャの境界に表示されます。スクリーンショットも追加しました。継ぎ目は非常に細い線(〜1ピクセル)です。写真はスクリーンショットから切り抜いたもので、拡大縮小されていません。繰り返されるテクスチャは16x16で、合計256サブピクセルです。縫い目

編集:これは次のフォローアップ質問です:この質問ですが、必要なすべての情報をここに含める必要があります。

ここに画像の説明を入力してください 最後の写真には時間が追加されていません。

テクスチャタイルチャネルのように、UVの座標は緑、青、赤です。

赤のない別の

4

1 に答える 1

2

UV座標のレンダリングを見ると、それらはフィルタリングされています。これにより、前の質問と同じ問題が発生しますが、スケールは小さくなります。何が起こっているのかというと、2つの不連続な値の間のポイント(つまり、テクスチャ座標がラップされている2つの隣接するポイント)でUV座標テクスチャをサンプリングすると、テクスチャの右側にない補間値が得られます。したがって、テクスチャタイル間の境界は、そのタイル全体からのピクセルの混乱です。

ここに画像の説明を入力してください

画面のピクセルとキャプチャされたUV値の間で1:1のマッピングを取得する必要があります。最も近いサンプリングを使用すると、ある程度の方法が得られる可能性がありますが、そもそも適切なテクスチャとピクセル座標があれば、それを使用せずに行うことができるはずです。

次に、テクセルのサンプリング方法を考慮していないため、テクスチャアトラスルックアップを実行している方法が原因で出血効果が発生する場合があります。これは、ミップマッピングを使用すると増幅されます。理想的には、境界線が必要であり、場合によっては、ハーフテセルオフセットを考慮して座標をマッサージする必要があります。しかし、それがあなたがここで見ている主な問題ではないと思います。

于 2013-01-27T12:52:33.007 に答える