对 Quadrilateral Interpolation, Part 1 的证明

最近在模拟2D像素阴影时,遇到了一个问题,对于任意形状的凸四边形,要如何计算其UV才能让最终的效果看起来正常?(想知道不正常的效果是什么样子?您也可以在下文中的连接中找到对应的图片。)

一番搜索之下,找到了如下链接:
https://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/

这里作者提供了一个通用的公式用于计算UV值,但是作者并没有解释这个公式是如何得来的。本文将试着证明该公式。

首先,我们先看一下作者提供的公式:

注意,这里的结果需要对4取模。当时,,当时,

同时,让我们看一下作者在这篇博客中提到的:

It’s well-known that to do perspective-correct interpolation for a triangle, you must calculate ,, and at each vertex, interpolate those linearly in screen space, then calculate and at each pixel. GPU rasterizers do this automatically, behind the scenes, for every interpolated attribute.

若您对这段话仍有疑问,建议参考此篇文章:
https://www.cnblogs.com/straywriter/articles/15889273.html

由此,我们可以推断出,这里的就是。也就是

那么,这个z究竟是个什么?

首先我们需要知道我们面临的问题是什么。

首先,我们有一个在图像平面(image plane)的四边形形状,而我们的目标就是找到一个平行四边形,使其投影到图像平面的形状恰好和我们要求的四边形重合。

(为什么是平行四边形?因为我们的Texture是矩形,从矩形到平行四边形是仿射变换,仿射变换不会影响我们对uv进行线性插值,具体请参考第一个链接的开头部分。为什么不是矩形?因为平行四边形已经足够我们实现我们的效果?同时使用矩形还需要额外证明一些不必要的东西,同时我们也无法保证真的存在这样的矩形(笔者并未尝试过证明该矩形是否一定存在)。)

而这个z,就是这个平行四边形的四个顶点距离摄像机的距离。

下面,我们就来证明为何这样的Z定义的平行四边形能够在图像平面恰好形成我们需要的四边形。

首先,这个平行四边形的四个点肯定都在从摄像机到图像平面四个点所确定的四条直线上。不然这个平行四边形在图像平面上的投影不会是我们所需要的四边形。

现在,我们设这个平行四边形的四个点为,且为两条对角线,这四个点在图像平面上的投影为

现在我们取其中一条对角线形成的线段中点记为。点在图像平面上的投影为,我们可以得到下图,其中是摄像机位置。

我们设A的坐标为,B的坐标为(这里的坐标仅用于计算,并不代表其在真实世界坐标系下的坐标。)

可以看出,点A的z坐标,点B的z坐标

同时,我们有:

这里的代表在原博客内容中的(这里我们设AB为所组成的对角线。)

这里需要证明一下就是我们的交点。首先因为平行四边形对角线相互平分,而的中点,所以一定是的交点。而透视投影保持共线性,所以也是的交点。

(什么是保持共线性?根据这篇文章的说法,保持共线性指的是变换后,原本在一条直线上的点仍然保持在同一条直线上。(Points on a line remain aligned post-transformation))

点Q的坐标可以表示为

因为点A’、点B’和点Q’都位于图像平面上,它们的,又因为相似三角形的原理,我们可以算出它们的y坐标,最终它们的坐标为:

又因为

同理

所以我们有

同理,我们也可以得到

至此,我们得到了对角线两边的点的z值和它到对角线交点长度的关系。我们可以试一下,如果按照原博客的公式,,符合我们的证明结果。

那么,的关系要如何计算呢?这里需要用到另一个限制,为了保证是一个平行四边形,的中点必须是同一个点,否则这四个点就不再共面。

首先,我们有:

我们设共同的中点。

同理

又因为的x均为1。

所以

由此,我们得出了的比例关系,且符合原博客中给出的答案。

可以注意到,这里我们给出的是比例关系,实际上这样的平行四边形是有无穷多个的,这也是符合我们的直觉的,只需要沿着z轴等比放大,我们生成的平行四边形总是可以在图像平面上投影成一样的形状。

笔者对于图形学来说也只是略懂皮毛,以上的证明可能包含错误或不准确的地方,如有问题请联系 wlzqkwd#Gmail.com。

最后,让我们以一张笔者目前正在尝试的像素光照的效果作为结尾吧: