6

r、g、b、およびコンポーネントを使用して各テクスチャをどれだけブレンドするかを決定する5番目の画像に従ってそれらをマージすることにより、地形に4つのテクスチャ詳細タイルをロードするために使用されるシェーダーを実行しようとしています。ブレンディングは正常に機能しますが、「ミックスマップ」画像を追加しようとすると、テクスチャ座標の問題が原因で失敗します。

まず、シェーダーは次のとおりです。
頂点シェーダー

void main() {
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
}

フラグメントシェーダー

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;

varying vec3 pos;

void main()
{

    vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
    vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
    vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
    vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
    vec4 mixmapTexel = texture2D(Mixmap, gl_TexCoord[0].st).rgba;

    texel0 *= mixmapTexel.r;
    texel1 = mix(texel0,  texel1, mixmapTexel.g);
    texel2 = mix(texel1, texel2, mixmapTexel.b);
    gl_FragColor = mix(texel2, texel3, mixmapTexel.a);
}

私が言ったように、ブレンドはうまくいきます。問題は、私の mixmap から読み取った値が正しいものではないという事実から来ています。

ここに私がやっていることについてのもう少しの説明があります。高さマップから地形をロードするページング地形システムを構築しています。次に、ミックスマップ イメージを使用して、高さに応じて各テクスチャをどれだけブレンドする必要があるかを rgba コンポーネントで表現したいと考えています。

  • rは水

  • gは砂

  • bは草

  • はロックです

したがって、テクスチャを正しくブレンドするには、シェーダーから正しいピクセル値を取得できる必要があります。

クレートとテキストのブレンド

これは、テクスチャがどのように適用されているかを明確に確認できるように、クレートとテキストをブレンドする例です。

ここで単純な mixmap 画像 (半分が赤、半分が緑) を使用すると、地形の左側にクレートが表示され、右側にテキストが表示されるはずです。 argb アルファ スプラッティングあり rgba 画像の例

以下は、地形生成プロセスの一部です。頂点の配列を繰り返し処理し、地形の三角形を作成します。

void TerrainPage::generateDisplayList()
{
    // create one display list
    mDisplayListIndex = glGenLists(1);

    // compile the display list, store a triangle in it
    glNewList(mDisplayListIndex, GL_COMPILE);
    glFrontFace( GL_CW  ); //   Vertex are added clockwise. Used to calculate normals
    std::vector<Vertex>::iterator it;
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE);
    texShader.enable();
    texShader.bindTexture(mTexture0, "Texture0", 0);
    texShader.bindTexture(mTexture1, "Texture1", 1);
    texShader.bindTexture(mTexture2, "Texture2", 2);
    texShader.bindTexture(mTexture3, "Texture3", 3);
    texShader.bindTexture(mMixmapTexture, "Mixmap", 4);
    Vertex v;
    int j=0;
    glEnable(GL_TEXTURE_2D);
    //mTexture.bind();
    glBegin(GL_TRIANGLE_STRIP);
    for(int i = 0; i<mVertices.size(); i++) {
        if(i%(2*mWidth) == 0) glEnd(); glBegin(GL_TRIANGLE_STRIP);
        v = mVertices[i];
        glTexCoord2f(v.texcoords[0], v.texcoords[1]);
        glVertex3f(v.position[0], v.position[1], v.position[2]);
    }
    glEnd();
    glDisable(GL_TEXTURE_2D);
    texShader.disable();
    glEndList();
}

必要に応じて、さらにスクリーンショットとコードの一部を提供できます。

提供された回答の続きとして、シェーダーで UV を計算してみました。

まず、これが新しいシェーダーです

頂点シェーダー

varying vec4 VertexPosition;

void main() {

    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
    VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
}

フラグメントシェーダー

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;

varying vec4 VertexPosition;
float side = 500.;

void main()
{

   vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
   vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
   vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
   vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
   vec4 mixmapTexel = texture2D(Mixmap, VertexPosition.xz/(2.*side)).rgba;

   texel0 *= mixmapTexel.r;
   texel1 = mix(texel0,  texel1, mixmapTexel.g);
   //texel2 = mix(texel1, texel2, mixmapTexel.b);
   //vec4 tx  = mix(texel2, texel3, mixmapTexel.a);
   //vec4 tx = mixmapTexel; //vec4(1, 1, 1, 1.);
    gl_FragColor = texel1;

    //if(test > 250. )
    //    gl_FragColor = vec4(1.,1.,1.,1.);
}

そして、これが結果です

ここに画像の説明を入力

しかし、カメラを動かすと:

ここに画像の説明を入力

ご覧のとおり、今度はクレートとテキストが並んでいます。しかし、ワールド座標ではなくスクリーン座標で計算しているようです。座標系でまた混乱したに違いない。頑張って適当に探してみます!正しい方向に進んでいることを確認したいだけです。マルチ テクスチャ座標も探します。仕組みがわかれば、より便利になるかもしれません ;)

4

1 に答える 1

8

私があなたを正しく理解している場合、ミックスマップには異なるテクスチャ座標が必要になります。現在、セルごとにミックスマップ全体を使用しているため、セルごとに半分のテキストと半分のクレートが得られます。

複数の texcoords を使用してみてください。シェーダーで正しい UV を計算することもできます。それには、頂点の現在の x 位置を x 方向の地形の長さで割って、y についても同じ値を使用します。ただし、テレインをスケーリングする場合は、テレインの長さにスケーリングを掛けてください。

私が言っていることがわからない場合は、地形のすべてのセルが (0,0)、(1,0)、(0,1)、または (1,1) のいずれかの UV を取得しています。これはクレートとテキスト テクスチャには問題ありませんが、ミックスマップはもっと部分的で多様でなければなりません。

これは別の地形チュートリアルへのリンクです。DirectX を使用していますが、頂点/UV 生成は同等です。最大の違いは、地形全体に 1 つの大きなテクスチャを使用することです。これは、ミックスマップには必要ですが、他のテクスチャには必要ありません。

何が悪いのか理解できたと思います。頂点の位置を明示的に保存します。これに modelviewmatrix を掛けないでください。

varying vec4 VertexPosition;

void main() {

    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
    //VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
    VertexPosition = gl_Vertex;
}

これで修正されます。申し訳ありませんが、固定シェーダーを rendermonkey に投入したところ、カメラと共に動かなくなりました。お役に立てれば。パンを取得していましたが、今では次のようになります。

固定レンダリング

于 2012-11-17T20:01:01.787 に答える