如果我们将纹理空间定义为X:Y {0-1}的纹理坐标,和世界空间作为四边形的实际坐标,我如何给定四边形上的点p1找出其纹理坐标是什么?给定一个纹理坐标点p2,我将如何计算它的真实坐标?
请记住,四边形可以是任何四边形,而不一定总是平行四边形。
作为一个附加说明,让我们在四边形上定义纹理坐标,使它们像这样
#1 楼
(实际上,使用三角形来思考(和计算)起来比较容易,但是为了回答这个问题,让我们先来看一下四边形示例。)为此,您只需要定义点即可您对四边形(或任何原始图元)的顶点感兴趣。这称为重心坐标系。实际上,基本上是给点$ n $权重,每个权重都描述了四边形的$ i $顶点对该点的影响。这些是相对于该四边形的点的重心坐标。
因此,例如,四边形的中心点(或“质心”)的权重为$ \ frac {1} {4} $,$ \ frac {1} {4} $,$ \ frac {1} {4} $和$ \ frac {1} {4} $。左边缘中间的一个点,左两个顶点的权重分别为$ \ frac {1} {2} $和右两个顶点的权重为$ 0 $。 (请注意,它们如何总和为$ 1 $?)
然后这些重心坐标可用于插值所需的每种顶点值,无论是位置坐标还是纹理坐标。所有这些都减少为一个简单的加权和。甚至还不止这些,如果给定了点的值,它们也可以通过简单的矢量代数从任何现有的每个顶点值中很容易地计算出来(归结为三角形的几个2x2行列式,或者类似的简单计算) 。这意味着,如果您知道像素的屏幕空间位置和顶点位置,则可以计算其重心坐标。然后,您可以使用这些来从每个顶点的值内插像素的纹理坐标(或法线,或其他),反之亦然。
理论上有很多要注意的方面请记住,尤其是像在GPU中那样在光栅化器中使用它们进行插值时。
除了三角形以外,对于任何重心坐标,都不必为任何任意点唯一定义。这就是为什么考虑三角形要容易得多的原因,特别是对于计算机而言。
由于只有当点实际上不在三角形内时,它们才是负数,因此也可以用来检查点完全属于三角形,因此或多或少是光栅化器已经执行的将三角形光栅化的三角形像素测试的副产品。即,当使用透视变形将3D世界投影到平面上时,它变得更加复杂,因为您必须考虑以下事实:屏幕空间中的一条线的长度与世界空间中的一条线的长度不同,或更确切地说,它的屏幕当沿着世界空间中的三角形边缘时,空间长度不会线性增加。此处的关键字是透视正确插值。但这仍然使用该点的重心坐标。
当然,在实际的光栅化器中,您还必须考虑共享三角形的边缘,并且仅光栅化共享边缘一次,这需要特殊规则来确定共享边缘属于哪个三角形,以及可能会使重心坐标的计算稍微复杂一点,同时使用定点坐标或任何优化的计算。
(这是此问题及其一般工作原理的更一般性概述。针对特定数学和技术细节,我建议您进一步阅读,也许从上面的维基百科文章开始。)
评论
$ \ begingroup $
好答案。但这主要是关于使用重心坐标,它最适合三角形。那么,GPU是否将四边形分成两个三角形?如果可以,那么是否存在与交叉路口连续性相关的一些问题?
$ \ endgroup $
–布巴
17年3月3日,0:41
$ \ begingroup $
是的,他们愿意。是的,有(或可以是),但是根据您的几何形状,它们相对较小。实际上,用于硬件加速栅格化的现代API完全放弃了四边形的概念,因为与两个三角形相比,它一直只是一种便利功能而没有任何特殊处理。因此,如今即使分成两个三角形也不是由GPU完成的,而必须由您完成。
$ \ endgroup $
–克里斯蒂安·劳(Christian Rau)
17年11月3日,13:32
评论
从问题标题开始,我以为您正在询问双线性插值。对于其他来这里寻求信息的人,这里是一个链接(但也可以明确提出问题)blog.demofox.org/2015/04/30/…我正在“将四边形分割成两个三角形”集中营。我在这里详细介绍了插值如何在三角形中工作:gabrielgambetta.com/computer-graphics-from-scratch / ...它根本不使用重心坐标,因此很好地补充了其他答案:)
Nathan Reeds博客上有一个很好的解释。通常,我不建议在此处发布许多链接,但这是对这个问题的很多唯一的正确答案。
使用拆分多边形时,有些情况下可以解决错误问题。每当有退化的顶点时,分割映射都会出错,因此存在真正的四边形映射的原因。但是,在99%的用例上,效果很好。