在 OpenGL 中使用正方形纹理映射梯形的纹理

发布于 2024-11-05 10:41:50 字数 1267 浏览 4 评论 0原文

我一直在尝试用方形纹理渲染 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 (svert.z, r垂直 z、t、q*垂直 z)?或者我错过了一些步骤?喜欢搞乱 GL_TEXTURE glMatrixMode 吗?

更新 #2:

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

I've been trying to render a GL_QUAD (which is shaped as a trapezoid) with a square texture. I'd like to try and use OpenGL only to pull this off. Right now the texture is getting heavily distorted and it's really annoying.

Normally, I would load the texture compute a homography but that means a lot of work and an additional linear programming library/direct linear transform function. I'm under the impression OpenGL can simplify this process for me.

I've looked around the web and have seen "Perspective-Correct Texturing, Q Coordinates, and GLSL" and "Skewed/Sheared Texture Mapping in OpenGL".

These all seem to assume you'll do some type of homography computation or use some parts of OpenGL I'm ignorant of ... any advice?

Update:

I've been reading "Navigating Static Environments Using Image-Space Simplification and Morphing" [PDF] - page 9 appendix A.

It looks like they disable perspective correction by multiplying the (s,t,r,q) texture coordinate with the vertex of a model's world space z component.

so for a given texture coordinate (s, r, t, q) for a quad that's shaped as a trapezoid, where the 4 components are:

(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) 

This is as easy as glTexCoord4f (svert.z, rvert.z, t, q*vert.z)? Or am I missing some step? like messing with the GL_TEXTURE glMatrixMode?

Update #2:

That did the trick! Keep it in mind folks, this problem is all over the web and there weren't any easy answers. Most involved directly recalculating the texture with a homography between the original shape and the transformed shape...aka lots of linear algebra and an external BLAS lib dependency.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

就是爱搞怪 2024-11-12 10:41:50

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

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。 1,而 ds = 1。这使得右上三角形的 ds/dx 大于下三角形的 ds/dx。当纹理映射时,这会产生令人不快的图像。

纹理空间不仅仅是一个二维仿射平面,尽管我们通常不考虑 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) 更好。这由你决定。

Here is a good explanation of the issue & solution.

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

working link: http://replay.web.archive.org/20080209130648/http://www.r3.nu/~cass/qcoord/

Partly copied and adapted from above link, created by Cass

One of the more interesting aspects of texture mapping is the space that texture coordinates live in. Most of us like to think of texture space as a simple 2D affine plane. In most cases this is perfectly acceptable, and very intuitive, but there are times when it becomes problematic.

For example, suppose you have a quad that is trapezoidal in its spatial coordinates but square in its texture coordinates.

OpenGL will divide the quad into triangles and compute the slopes of the texture coordinates (ds/dx, ds/dy, dt/dx, dt/dy) and use those to interpolate the texture coordinate over the interior of the polygon. For the lower left triangle, dx = 1 and ds = 1, but for the upper right triangle, dx < 1 while ds = 1. This makes ds/dx for the upper right triangle greater than ds/dx for the lower one. This produces an unpleasant image when texture mapped.

Texture space is not simply a 2D affine plane even though we generally leave the r=0 and q=1defaults alone. It's really a full-up projective space (P3)! This is good, because instead of specifying the texture coordinates for the upper vertices as (s,t) coordinates of (0, 1) and (1, 1), we can specify them as (s,t,r,q) coordinates of (0, width, 0, width) and (width, width, 0, width)! These coordinates correspond to the same location in the texture image, but LOOK at what happened to ds/dx - it's now the same for both triangles!! They both have the same dq/dx and dq/dy as well.

Note that it is still in the z=0 plane. It can become quite confusing when using this technique with a perspective camera projection because of the "false depth perception" that this produces. Still, it may be better than using only (s,t). That is for you to decide.

一曲爱恨情仇 2024-11-12 10:41:50

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

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

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

我发现实现效果 2. 的最简单方法是将梯形分成矩形和直角三角形。就我而言,梯形是规则的,所以一个四边形和两个三角形解决了问题。

I would guess that most people wanting to fit a rectangular texture on a trapezoid are thinking of one of two results:

  1. perspective projection: the trapezoid looks like a rectangle seen from an oblique angle.
  2. "stretchy" transformation: the trapezoid looks like a rectangular piece of rubber that has been stretched/shrunk into shape.

Most solutions here on SO fall into the first group, whereas I recently found myself in the second.

The easiest way I found to achieve effect 2. was to split the trapezoid into a rectangle and right triangles. In my case the trapezoid was regular, so a quad and two triangles solved the problem.

梦一生花开无言 2024-11-12 10:41:50

希望这可以帮助:
引自论文:

在每个像素处,使用 (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 -限定符-glsl-tutorial/

Hope this can help:
Quoted from the paper:
"
At each pixel, a division is performed using the interpolated values of (s=w; t=w; r=w; q=w), yielding (s=q; t=q), which
are the final texture coordinates. To disable this effect, which is not
possible in OpenGL directly. "

In GLSL, (now at least) this is possible. You can add:

noperspective out vec4 v_TexCoord;

there's an explanation:
https://www.geeks3d.com/20130514/opengl-interpolation-qualifiers-glsl-tutorial/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文