写给大家看的“透视除法” —— 齐次坐标和投影

3D投影

图片来源:Joachim Baecker.

术语

在大多数3D工作中,我们参照的依据是欧几里得几何学中的三维空间(X, Y, Z)。但在某些情况下,参照投影几何更适用,除了 X, Y, Z 分量外,增加一个 W 分量,这个四维空间叫做“投影空间”,在四维空间中的坐标叫“齐次坐标”。
为了达到3D软件的目的,“投影的” 和 “齐次的” 可以理解为 "4D"。

不是四元数

虽然四元数跟齐次坐标长得很像,都是 4D 矢量,通常用(X, Y, Z, W)来表示。但是,四元数和齐次坐标是不同的概念,适用的领域也不同。
这篇文章跟“四元数”没有一毛钱关系。

类比2D

了解3D之前,我们先看看2D的投影是怎么回事儿。
想象投影仪在一个屏幕上投影一张2D图片,很容易就可以得到投影图片的 X, Y 分量。


在屏幕上投影2D图片

现在,看投影仪和屏幕之间,你就可以发现 W 分量了。
W 分量是投影仪到屏幕的距离

W分量

那么 W 分量的作用是什么呢?想象一下,如果我们移动投影仪的位置,来增加或减少 W分量的值,那么投影出的2D图片会发生什么?如果将投影仪靠近屏幕,2D图片缩小,如果投影仪远离屏幕,2D图片放大。没错,这就是 W 分量的作用。

W 分量的值,影响了投影出 2D 图片的大小

投影仪靠近屏幕

应用到3D

到目前为止,还没有一个3D投影仪,很难想象3D中的投影几何,但是 3D 下的 W 分量与 2D 的作用相同。当 W 增大,坐标被拉伸;W 缩小,坐标被压缩, W 对3D坐标做缩放变换。

W = 1时

通常,给3D编程初学者的建议是,无论什么时候将 3D 坐标转换为 4D 坐标时,让 W=1。原因是,当缩放坐标的 W 为1时,坐标不会增大或缩小,保持原有的大小。所以,当 W=1,不会影响到 X, Y, Z 分量的值。
因此,当谈论到 3D 计算机图形学时,当坐标中 W=1时被称作“正确”。如果渲染使用 W>1 的坐标,每一个3D物体看起来都会变大,反之,W<1 的坐标中,3D物体会变小;如果渲染时试图让 W=0,那么你的程序会奔溃,当做透视除法的时候除数为0;如果 W<0,每一个物体都会上下翻转,水平翻转。
在数学中,没有所谓的“不正确”的齐次坐标,使用齐次坐标时让 W=1 仅仅是用于计算机图形学中的投影转换。

数学原理

现在,让我们来看一些例子,了解数学原理
在距屏幕3米远的位置放一个投影仪,投影出一个点(15, 21)在 2D 图像中,相应的投影坐标中的向量为 (X, Y, W)=(15, 21, 3)。


距屏幕3米远投影一个点

现在,想象推动投影仪向屏幕靠近,直到距离1米,越靠近屏幕投影,投影出的图像越小。投影仪靠近了3倍,因此图像缩小了3倍。如果我们将原向量的 X, Y, W 分量都除以 3,我们得到一个新向量 W=1:


W=1的新向量

投影出的点在坐标中的新位置(5, 7)


同一个点在距屏幕1米远处投影

这就是怎样将一个“不正确”齐次坐标转换到一个“正确”坐标的方法:所有分量除以 W,这个过程对 2D 和 3D 同样适用。
通过给向量乘以 W 的倒数,来实现向量的所有分量除以 W,下面是一个4D的例子:


透视除法

用 GLM 库编写,类似如下实现:

glm::vec4 coordinate(10, 20, 30, 5);
glm::vec4 correctCoordinate = (1.0/coordinate.w) * coordinate;
//now, correctCoordinate == (2,4,6,1) 

在计算机图形学中使用齐次坐标

就像开始提到的,针对3D 计算机图形学中,有些情况下使用齐次坐标很有用,下面我们来看看这些情况:

3D 坐标中的转换矩阵

旋转缩放的转换矩阵只需要3列,但是为了处理平移,至少需要4列矩阵,这就是为什么矩阵变换通常用4×4的矩阵。然而,4列矩阵不能与3维向量相乘,只能与4维向量相乘,这就是为什么我们使用齐次的4维向量取代3维向量。

4列矩阵只能与4维向量相乘,这就是为什么我们常常使用齐次的4维向量取代3维向量。

通过齐次坐标处理矩阵变化,第4维 W 分量通常不用改变。从3D转换到4D,只需将 W 分量设置为1,并且经过变换矩阵处理后,W 分量的值任为1,这意味着我们忽略 W 分量即可转换回 3D坐标。这个对目前为止大多数的矩阵变化都适用,如平移旋转缩放。需要注意的例外是投影矩阵会影响 W 分量。

透视变换

在 3D 世界,物体离相机越远看起来越小,这个现象叫做透视。在镜头中,如果猫离相机足够近,远处的大山会比猫看上去小。

透视,远处的大山比镜头前的猫看上去小

在3D计算机图形学中,透视是通过变换矩阵改变向量的 W 分量来实现的。在变换到相机空间后(对向量应用了相机矩阵),还没有进行投影变换(还没有对向量应用投影矩阵),每个向量的 Z 分量表示了距离相机的距离。因此,Z 分量越大,矢量应该越小。W 分量影响这个缩放,所以投影矩阵用 Z 分量的值改变 W 分量的值。

在3D计算机图形学中,透视是通过投影矩阵变换,改变每一个向量中 W 分量的值来实现透视的

下面看一个透视例子,通过投影矩阵变换到齐次坐标。


投影矩阵变化到齐次坐标

注意投影矩阵是怎样用 Z 分量改变 W 分量的。
经过投影矩阵透视变换后,每一个向量即经过了“透视除法”。

透视除法只是将齐次坐标中的 W 分量转换为1的专用名词

继续上面的例子,透视除法这步如下:


透视除法

完成透视除法后,W分量就没用了,我们就得到了一个完全符合3D透视投影规则的3D坐标。
在GLM中,透视投影矩阵可以通过使用 glm::perspectiveglm::frustum方法来创建。在老式的 OpenGL 中,通常使用gluPerspectivegluFrustum 方法。在 OpenGL 中,在顶点 shader 作用了每一个顶点后,自动进行透视除法。这就是顶点 shader 中 main 方法输出的 gl_position 变量,是4维向量,而不是3维向量。

设置平行光

齐次坐标中的一个属性,是允许有一个无限远的点(或无限长的向量),在3D坐标中这个是不允许的。当 W=0 时,这点表示无限远的一个点。如果你尝试将一个 W=0 的齐次坐标转换为一个普通的 W=1的齐次坐标,这会导致4次除0操作:

试图将 W=0 的齐次坐标转换为普通的 W=1 的齐次坐标

这意味着,不能将 W=0 的齐次坐标转换到 3D 坐标。
那这有什么用呢?用处说来就来了,平行光可以认为是一个无限远处的点光源。当一个点光源在无限远的位置,光线就会变成平行的,并且所有光线都在同一方向,这就是平行光的基本定义。想想太阳吧。
所以在传统的3D图形中,平行光可以通过改变点光源位置向量中的 W 分量来表示,当 W= 1时,是一个点光源;当 W= 0 时,是一个平行光。
在实现光照代码时,这更多的是一种传统的约定,但不是一种有用的方法。因为平行光和点光源的行为不同,通常分开实现。一个经典的光照 shader 实现如下:

if (lightPosition.w == 0.0) {    
  //directional light code here
} else {
  //point light code here
}

总结

齐次坐标有一个额外的维度叫 W 分量,用来缩放X, Y, Z三个分量的值。平移和透视投影的矩阵变换只能在齐次坐标中使用,所以在3D计算机图形学中,当 W=1时,X, Y, Z 分量被称为“正确的”。任何齐次坐标,只要 W 不为0,都可以通过将每一个分量除以 W 来转换到 W=1的向量。当 W=0 时,这个坐标表示无穷远的一个点(或者表示无限长的一个向量),通常用于表示平行光的方向。

原文:Explaining Homogeneous Coordinates & Projective Geometry

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容