我有一个类似于这篇文章的问题: glTexGen in OpenGL ES 2.0
我在网上查了几个其他网站,却没有找到如何解决我的问题。
基本上,我想在设置正交投影后将纹理映射到2D四边形。我遇到的问题是纹理是扭曲的,你可以在这张图片上看到我使用彩色图案而不是纹理:
我希望纹理的线条在四边形上保持笔直,但正如您所看到的,它们是扭曲的。我想我应该修改顶点着色器,以便纹理坐标映射四边形,但我无法弄清楚如何。
非常感谢, 吉姆
答案 0 :(得分:1)
你需要的是一种不同的插值(我相信这将是二次插值),因为在这种情况下(空间中的边长不与纹理中的边长相对应),线性插值不会削减它。 / p>
不幸的是,在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
另一个选择是使用3D中的真实四边形并将其手动旋转到看起来像2D四边形的位置。或者设计四边形的“深度”纹理坐标,计算顶点着色器中的1 /深度,插值(u /深度,v /深度,1 /深度),然后在片段着色器中将插值1 /深度除以得到好的值。虽然这看起来很简单,但请注意,很难提出良好的深度值。