在OpenGL中使用正方形纹理贴图一个梯形

11
我一直在尝试使用OpenGL渲染一个GL_QUAD(梯形形状),并使用一个正方形纹理。我想尝试只使用OpenGL来完成这个任务。目前纹理被严重扭曲,非常恼人。
通常情况下,我会加载纹理计算单应性,但这意味着很多工作和额外的线性编程库/直接线性变换函数。我认为OpenGL可以简化这个过程。
我在网上搜索了“透视校正纹理,Q坐标和GLSL”“OpenGL中的倾斜/剪切纹理映射”
所有这些都似乎假定您将执行某种类型的单应性计算或使用我不知道的OpenGL部分...有什么建议吗?
更新:
我一直在阅读“使用图像空间简化和变形导航静态环境”[PDF] - 附录A第9页。
似乎他们通过将模型的世界空间z分量与(s,t,r,q)纹理坐标的顶点相乘来禁用透视校正。
因此,对于一个呈梯形形状的四边形的给定纹理坐标(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(svert.z, rvert.z, t, q*vert.z) 一样简单?或者我漏掉了什么步骤?比如搞乱了 GL_TEXTURE glMatrixMode?
更新 #2:
这解决了问题!记住这个方法,这个问题在网络上到处都是,没有简单的答案。大多数涉及使用原始形状和变换形状之间的单应性重新计算纹理...即大量线性代数和外部 BLAS 库依赖。

1
你能提供一个带有“错误”纹理的截图链接吗? - przemo_li
我找到了解决问题的方法。请查看链接的论文,以获取更多关于平面纹理的信息。 - ct_
你能否给出一个更好的总结,说明你是如何修复这个问题的? - ioquatix
1
@MrSamuel我建议您查看链接论文的第9页,标题为“禁用透视校正”的部分。 - ct_
更新#1和#2拯救了我的一天 - 即使是我的一周!只需添加三个乘法的一分钟,然后就完成了!令人惊讶,我已经与这个问题搏斗了几天。如果可以的话,我会投票给你当总统!(见鬼,现在我甚至考虑把我的房子和车捐给你。)我必须珍惜这个时刻,我再也不会对stack overflow上的问题感到如此高兴了。 - Jonas Byström
3个回答

12

这里有一个关于问题和解决方案的好解释。

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

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

部分内容复制并改编自上述链接,由 Cass 创建

纹理映射中比较有趣的一个方面是纹理坐标所在的空间。大多数人喜欢将纹理空间视为简单的二维仿射平面。在大多数情况下,这是完全可接受且非常直观的,但有时会出现问题。
例如,假设您有一个四边形,在其空间坐标中是梯形,但在其纹理坐标中是正方形。OpenGL将该四边形分成三角形,并计算纹理坐标的斜率(ds/dx、ds/dy、dt/dx和dt/dy),并使用这些斜率在多边形内部插值纹理坐标。对于左下三角形,dx=1且ds=1,但对于右上三角形,dx<1而ds=1。这使得右上三角形的ds/dx大于左下三角形的ds/dx。这会导致纹理映射时产生不愉快的图像。
纹理空间并不仅仅是一个二维仿射平面,即使我们通常保持r=0和q=1默认值不变。它实际上是一个完整的投影空间(P3)! 这很好,因为我们可以将上顶点的纹理坐标指定为(0, width, 0, width)和(width, width, 0, width)的(s,t,r,q)坐标,而不是(0, 1)和(1, 1)的(s,t)坐标! 这些坐标对应于纹理图像中的相同位置,但请看ds/dx发生了什么——现在对于两个三角形它是相同的!! 它们都有相同的dq/dx和dq/dy。
请注意,它仍然位于z=0平面上。当使用透视相机投影时,由于这种技术产生的“虚假深度感”,它可能会变得非常混乱。但是,与仅使用(s,t)相比,它可能更好。这取决于您自己的决定。

你能详细说明一下吗?比如说 strq 中的 width 是什么意思,我们需要为所有顶点都使用 strq 格式吗? - Naruto26

2
我猜想大多数想在梯形上放置矩形纹理的人都会考虑以下两种结果之一:
1.透视投影:梯形看起来像从斜角度看到的矩形。
2.“拉伸”变换:梯形看起来像一个被拉伸/收缩成形的矩形橡皮。
大多数在SO上的解决方案属于第一组,而我最近发现自己属于第二组。
我发现实现效果2最简单的方法是将梯形分成一个矩形和两个直角三角形。在我的情况下,梯形是规则的,所以一个四边形和两个三角形就解决了问题。

根据定义,矩形无法通过仿射映射变换成梯形。你所做的三角剖分只是一种分段仿射映射 - 三角形到三角形。 - derhass
啊,你说得对。我没想到从相关帖子中重复使用了一个术语。我已经更新了答案,使用了正确的术语。 - Tyler Daniel
中间矩形的UV是什么? - Naruto26

1
希望这可以帮助: 引用论文中的话: “在每个像素处,使用插值值(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/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接