10

我一直在尝试用方形纹理渲染 GL_QUAD(形状为梯形)。我想尝试使用 OpenGL 来解决这个问题。现在纹理变得严重扭曲,真的很烦人。

通常,我会加载纹理计算单应性,但这意味着大量工作和额外的线性编程库/直接线性变换函数。我的印象是 OpenGL 可以为我简化这个过程。

我浏览了网络并看到了“透视校正纹理、Q 坐标和 GLSL”“OpenGL 中的倾斜/剪切纹理映射”

这些似乎都假设您将进行某种类型的单应性计算或使用我不知道的 OpenGL 的某些部分......有什么建议吗?

更新:

我一直在阅读“使用图像空间简化和变形导航静态环境” [ PDF ] - 第 9 页附录 A。

看起来他们通过将 (s,t,r,q) 纹理坐标与模型的世界空间 z 分量的顶点相乘来禁用透视校正。

所以对于一个给定的纹理坐标 (s, r, t, q) 对于一个梯形的四边形,其中 4 个分量是:

(0.0f, 0.0f, 0.0f, 1.0f),
(0.0f, 1.0f, 0.0f, 1.0f),
(1.0f, 1.0f, 0.0f, 1.0f),
(1.0f, 0.0f, 0.0f, 1.0f) 

这和 glTexCoord4f (s vert.z, r vert.z, t, q*vert.z) 一样简单吗?还是我错过了一些步骤?喜欢搞乱 GL_TEXTURE glMatrixMode?

更新#2:

那成功了!请记住,这个问题遍布网络,没有任何简单的答案。大多数涉及使用原始形状和转换后的形状之间的单应性直接重新计算纹理......也就是大量的线性代数和外部 BLAS lib 依赖项。

4

3 回答 3

11

这是对问题和解决方案的一个很好的解释。

http://www.xyzw.us/~cass/qcoord/

工作链接:http ://replay.web.archive.org/20080209130648/http://www.r3.nu/~cass/qcoord/

部分复制和改编自上面的链接,由Cass创建

纹理映射更有趣的方面之一是纹理坐标所在的空间。我们大多数人喜欢将纹理空间视为简单的 2D 仿射平面。在大多数情况下,这是完全可以接受的,并且非常直观,但有时它会出现问题。

例如,假设您有一个四边形,其空间坐标为梯形,但纹理坐标为正方形。

OpenGL 会将四边形划分为三角形并计算纹理坐标的斜率(ds/dx、ds/dy、dt/dx、dt/dy),并使用这些斜率在多边形内部插入纹理坐标。对于左下三角形,dx = 1 和 ds = 1,但对于右上三角形,dx < 1 而 ds = 1。这使得右上三角形的 ds/dx 大于右上三角形的 ds/dx。这在纹理映射时会产生令人不快的图像。

纹理空间不仅仅是一个 2D 仿射平面,尽管我们通常不考虑 r=0 和 q=1 默认值。这真的是一个完整的投影空间(P3)!这很好,因为不是将上顶点的纹理坐标指定为 (0, 1) 和 (1, 1) 的 (s,t) 坐标,我们可以将它们指定为 (s,t,r,q) 坐标(0,宽度,0,宽度)和(宽度,宽度,0,宽度)!这些坐标对应于纹理图像中的相同位置,但看看 ds/dx 发生了什么 - 现在两个三角形都相同!它们都具有相同的 dq/dx 和 dq/dy。

请注意,它仍然在 z=0 平面中。将这种技术与透视相机投影一起使用时会变得相当混乱,因为这会产生“错误的深度感知”。不过,它可能比仅使用 (s,t) 更好。那是你来决定的。

于 2011-09-11T15:30:01.003 回答
1

我猜想大多数想要在梯形上拟合矩形纹理的人都在考虑以下两个结果之一:

  1. 透视投影:从斜角看梯形看起来像一个矩形。
  2. “有弹性”的变形:梯形看起来像一块被拉伸/收缩成形状的矩形橡胶。

SO上的大多数解决方案都属于第一组,而我最近发现自己属于第二组。

我发现实现效果 2. 的最简单方法是将梯形拆分为矩形和直角三角形。在我的例子中,梯形是规则的,所以一个四边形和两个三角形解决了这个问题。

于 2017-06-29T20:06:18.020 回答
0

希望这可以帮助:从论文中引用:“在每个像素处,使用 (s=w; t=w; r=w; q=w) 的插值执行除法,产生 (s=q; t= q),这是最终的纹理坐标。要禁用此效果,这在 OpenGL 中是无法直接实现的。"

在 GLSL 中,(至少现在)这是可能的。你可以加:

noperspective out vec4 v_TexCoord;

有一个解释: https ://www.geeks3d.com/20130514/opengl-interpolation-qualifiers-glsl-tutorial/

于 2020-03-25T13:14:12.873 回答