简体   繁体   English

三维纹理坐标的透视校正

[英]perspective correction of texture coordinates in 3d

I'm writing a software renderer which is currently working well, but I'm trying to get perspective correction of texture coordinates and that doesn't seem to be correct. 我正在编写一个目前运行良好的软件渲染器,但我正在尝试对纹理坐标进行透视校正,这似乎不正确。 I am using all the same matrix math as opengl for my renderer. 我使用与我的渲染器的opengl相同的矩阵数学。 To rasterise a triangle I do the following: 要光栅化三角形,我执行以下操作:

  1. transform the vertices using the modelview and projection matrixes, and transform into clip coordinates. 使用模型视图和投影矩阵变换顶点,并转换为剪辑坐标。

  2. for each pixel in each triangle, calculate barycentric coordinates to interpolate properties (color, texture coordinates, normals etc.) 对于每个三角形中的每个像素,计算重心坐标以插入属性(颜色,纹理坐标,法线等)

  3. to correct for perspective I use perspective correct interpolation: (w is depth coordinate of vertex, c is texture coordinate of vertex, b is the barycentric weight of a vertex) 校正透视我使用透视校正插值:(w是顶点的深度坐标,c是顶点的纹理坐标,b是顶点的重心权重)

 1/w = b0*(1/w0) + b1*(1/w1) + b2*(1/w2) c/w = b0*(c0/w0) + b1*(c1/w1) + b2*(c2/w2) c = (c/w)/(1/w) 

This should correct for perspective, and it helps a little, but there is still an obvious perspective problem. 这应该纠正透视,它有点帮助,但仍然存在明显的透视问题。 Am I missing something here, perhaps some rounding issues (I'm using floats for all math)? 我在这里遗漏了一些东西,也许是一些舍入问题(我使用花车进行所有数学运算)?

See in this image the error in the texture coordinates evident along the diagonal, this is the result having done the division by depth coordinates. 在该图像中看到沿着对角线明显的纹理坐标中的误差,这是通过深度坐标进行划分的结果。

图像显示错误的透视校正

Also, this is usually done for texture coordinates... is it necessary for other properties (eg normals etc.) as well? 此外,这通常是针对纹理坐标进行的......是否还需要其他属性(例如法线等)?

You need to inform OpenGL that you need perspective correction on pixels with 您需要告知OpenGL您需要对像素进行透视校正

glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)

What you are observing is the typical distortion of linear texture mapping. 你所观察到的是线性纹理映射的典型失真。 On hardware that is not capable of per-pixel perspective correction (like for example the PS1) the standard solution is just subdividing in smaller polygons to make the defect less noticeable. 在不能进行逐像素透视校正的硬件上(例如PS1),标准解决方案只是细分为较小的多边形,以使缺陷不那么明显。

The only correct transformation from UV coordinates to a 3D plane is an homographic transformation. 从UV坐标到3D平面的唯一正确转换是单应变换。

http://en.wikipedia.org/wiki/Homography http://en.wikipedia.org/wiki/Homography

You must have it at some point in your computations. 您必须在计算中的某个时刻拥有它。

To find it yourself, you can write the projection of any pixel of the texture (the same as for the vertex) and invert them to get texture coordinates from screen coordinates. 要自己找到它,你可以编写纹理的任何像素的投影(与顶点相同)并反转它们以从屏幕坐标获得纹理坐标。 It will come in the form of an homographic transform. 它将以同形变换的形式出现。

I cracked the code on this issue recently. 我最近在这个问题上破解了代码。 You can use a homography if you plan on modifying the texture in memory prior to assigning it to the surface. 如果计划在将其分配到曲面之前修改内存中的纹理,则可以使用单应性。 That's computationally expensive and adds an additional dependency to your program. 这在计算上很昂贵,并为您的程序增加了额外的依赖性。 There's a nice hack that'll fix the problem for you. 有一个很好的黑客可以解决你的问题。

OpenGL automatically applies perspective correction to the texture you are rendering. OpenGL会自动将透视校正应用于渲染的纹理。 All you need to do is multiply your texture coordinates (UV - 0.0f-1.0f) by the Z component (world space depth of an XYZ position vector) of each corner of the plane and it'll "throw off" OpenGL's perspective correction. 您需要做的就是将纹理坐标(UV - 0.0f-1.0f)乘以平面每个角的Z分量(XYZ位置矢量的世界空间深度),它将“抛弃”OpenGL的透视校正。

I asked and solved this problem recently. 我最近问了并解决了这个问题。 Give this link a shot: 给这个链接一个镜头:

texture mapping a trapezoid with a square texture in OpenGL 纹理在OpenGL中映射具有方形纹理的梯形

The paper I read that fixed this issue is called, "Navigating Static Environments Using Image-Space Simplification and Morphing" - page 9 appendix A. 我读过的论文修正了这个问题,称为“使用图像空间简化和变形导航静态环境” - 第9页附录A.

Hope this helps! 希望这可以帮助!

ct CT

Yeah, that looks like your traditional broken-perspective dent. 是的,这看起来像你传统的破碎透视凹痕。 Your algorithm looks right though, so I'm really not sure what could be wrong. 你的算法看起来很正确,所以我真的不确定会出现什么问题。 I would check that you're actually using the newly calculated value later on when you render it? 我会在你渲染它时检查你实际上是否正在使用新计算的值? This really looks like you went to the trouble of calculating the perspective-correct value, and then used the basic non-corrected value for rendering. 这看起来好像你去了计算透视校正值的麻烦,然后使用基本的非校正值进行渲染。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM