2

私はこの投稿に似た問題を抱えています: OpenGLES2.0のglTexGen

私は自分の問題を解決する方法を見つけることなく、他のいくつかのWebサイトをWebで調べました。

基本的に、正投影を設定した後、テクスチャを2Dクワッドにマッピングしたいと思います。私が抱えている問題は、テクスチャの代わりに色付きのパターンを使用したこの写真でわかるように、テクスチャが歪んでいることです。

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

テクスチャの線をクワッド上にまっすぐに保ちたいのですが、ご覧のとおり、歪んでいます。テクスチャ座標がクワッドをマップするために頂点シェーダーを変更する必要があると思いますが、その方法がわかりません。

どうもありがとう、ジム

4

1 に答える 1

1

必要なのは別の種類の補間です (二次補間になると思います)。この場合 (空間のエッジの長さはテクスチャのエッジの長さと一致しません)、線形補間はそれをカットしません。

残念ながら、OpenGL で行うのはかなり複雑なタスクです (ただし、ソフトウェアのラスタライズを使用すると非常に簡単です)。画面空間の任意の四角形をテクスチャ空間の単位正方形に変換しようとしています。ここで問題の完全な解決策を見つけることができます: http://alumni.media.mit.edu/~cwren/interpolator/これにより、正しいテクスチャ座標を取得するためにスクリーンスペース座標を乗算する必要があるマトリックスが得られます (フラグメントシェーダーで) )。

それにはかなり厄介な数学が含まれているため、単純な静的ケースで実際に機能する単純なソリューションを提案します(手動で調整する必要があります)。頂点シェーダーで計算されたテクスチャ座標は、実際には中央のエッジでのみオフになっており、残りは正しいです。texcoords が (0, 0)、(1, 0)、(1, 1)、(0, 1) であると仮定すると、補正係数は次のようになります。

u * v // for the first triangle
(1 - u) * (1 - v) // for the second triangle

補正ベクトルを推定してから、すべてをまとめる必要があります。シンプルな C++ OpenGL アプリを使用してテストしました。次のように描画します。

Vector2f ta(0, 1), tb(1, 1), tc(1, 0), td(0, 0);
Vector2f a(-.1f, 1), b(1, .7f), c(1, .1f), d(0, 0);
// quad texcoords and vertices

Vector2f t_corr(-.01f, .5f);
// correction for the above quad

glBegin(GL_TRIANGLES);
glMultiTexCoord2f(GL_TEXTURE1, 1, -1); // first triangle
glTexCoord4f(ta.x, ta.y, t_corr.x, t_corr.y);
glVertex2f(a.x, a.y);
glTexCoord4f(tb.x, tb.y, t_corr.x, t_corr.y);
glVertex2f(b.x, b.y);
glTexCoord4f(tc.x, tc.y, t_corr.x, t_corr.y);
glVertex2f(c.x, c.y);

glMultiTexCoord2f(GL_TEXTURE1, 0, 1); // second triangle
glTexCoord4f(ta.x, ta.y, t_corr.x, t_corr.y);
glVertex2f(a.x, a.y);
glTexCoord4f(tc.x, tc.y, t_corr.x, t_corr.y);
glVertex2f(c.x, c.y);
glTexCoord4f(td.x, td.y, t_corr.x, t_corr.y);
glVertex2f(d.x, d.y);
glEnd();

頂点シェーダーは次のようになります。

void main()
{
    gl_Position = ftransform();
    gl_FrontColor = gl_Color;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_TexCoord[1] = gl_MultiTexCoord1; // just copy coords, nothing else to do
}

フラグメント シェーダー:

uniform sampler2D sam;
void main()
{
    vec2 corr = vec2(gl_TexCoord[1].x + gl_TexCoord[1].y * gl_TexCoord[0].x,
                     gl_TexCoord[1].x + gl_TexCoord[1].y * gl_TexCoord[0].y);
    gl_FragColor = texture2D(sam, gl_TexCoord[0].xy + gl_TexCoord[0].zw * corr.x * corr.y);
}

これは非常に単純ですが、修正ベクトルを適切に調整することで、これを次のようにすることができます: http://www.luki.webzdarma.cz/up/deskew.png

もう 1 つのオプションは、3D の実際のクワッドでこれを行い、2D クワッドのように見える位置まで手動で回転させることです。または、クワッドの「深さ」テクスチャ座標を考案し、頂点シェーダーで 1/深さを計算し、補間 (u/深さ、v/深さ、1/深さ) し、後でフラグメント シェーダーで補間された 1/深さで割り、適切な値を取得します。 . これは単純に思えるかもしれませんが、適切な深さの値を見つけるのは非常に難しいことに注意してください。

于 2012-01-20T15:17:46.787 に答える