【翻译】OpenGL 投影矩阵

概述

电脑显示器是一个 2D 平面。一个通过 OpenGL 渲染的场景必须作为一个 2D 图像投影到电脑屏幕上。矩阵 GL_PROJECTION 就是用来做这个投影转换的。首先,它将顶点数据从视点坐标转换到裁剪坐标。然后,这些裁剪坐标通过除以 w 分量又被转换到标准化设备坐标(NDC)

一个被截头椎体裁剪的三角形

因此,我们必须记住,裁剪(截头椎体剔除)和 NDC 转换都被整合到了 GL_PROJECTION 矩阵中。接下来的章节讲述如何用 6 个参数来构建投影矩阵:leftrightbottomtopnearfar 边界值。

注意,截头椎体剔除(裁剪)是在裁剪空间中执行的,就在除以 wc, 之前。裁剪坐标 xc, yc, zc ,和 wc 比较。如果任何一个裁剪坐标小于 -wc ,或者大于 wc ,那么这个顶点就将被丢弃。

然后,OpenGL 会在裁剪的地方重新构建多边形的边界。


透视投影

透视截头椎体和标准化设备坐标(NDC)

在透视投影中,截头椎体中的一个 3D 点(视点坐标),被映射到一个立方体中(NDC);x 坐标的范围从 [l, r] 映射到 [-1, 1] ,y 坐标从 [b, t] 到 [-1, 1] ,z 坐标从 [n, f] 到 [-1, 1] 。

注意,视点坐标是右手坐标系,但是 NDC 是左手坐标系。就是说,在视点空间中,位于原点的摄像机,是看向 -Z 轴方向的,但在 NDC 中是看向 +Z 轴方向的。既然 glFrustum()nearfar 距离只接收正值,我们需要在构建 GL_PROJECTION 矩阵时将它们取反。

OpenGL 中,视点空间中的 3D 点被投影到近平面(投影平面)上。下面这个图片展示了视点空间中的一个点 (xe,ye,ze)是如何投影到近平面上的 (xp,yp,zp)的。

截头椎体顶视图
截头椎体侧视图

在截头椎体顶视图中,视点空间中的 x 坐标,xe被映射到 xp,这是根据相似三角形计算得到的。

在截头椎体侧视图中,yp也是通过相似的方法计算的。

注意,xp 和 yp 都取决于 ze;它们和 -ze 成反比。就是说,他们都除以 -ze。这是我们构建 GL_PROJECTION 矩阵的第一条线索。视点坐标乘以 GL_PROJECTION 后,裁剪坐标仍然是一个齐次坐标。它通过除以裁剪坐标的 w 分量最终成为标准化设备坐标(NDC)。(可以在 OpenGL Transformation 上查看更多细节


因此,我们可以设置齐次坐标的 w 分量为 -ze 。这样,GL_PROJECTION 矩阵的第四行成为了 (0, 0, -1, 0)。

下一步,我们通过一个线性关系将 xp 和 yp 映射到 xn 和 yn; [l, r] ⇒ [-1, 1] 和 [b, t] ⇒ [-1, 1] 。


Xp 映射到 Xn

Yp 映射到 Yn

然后,我们将 xp 和 yp 代入上面的方程式。


注意我们将每个方程式的项的都除以 -ze 以进行透视除法 (xc/wc, yc/wc)。我们前面已经将 wc 设为 -ze 了,所以括号里的项成为了裁剪坐标的 xc 和 yc

我们可以从这些方程式里找到 GL_PROJECTION 矩阵的第 1 行和第 2 行。

现在我们只有 GL_PROJECTION 矩阵的第 3 行需要求解了。找到 zn 和其它的是有些不同的,因为在视点空间中, ze 永远都投影到近平面 -n 上。但我们需要一个唯一的 z 值来进行裁剪和深度测试。并且,我们应该可以进行反投影(逆变换)。既然我们知道 z 和 x 或 y 值无关,我们借用 w 分量来找到 zn 和 ze 之间的关系。所以,我们可以像这样指定 GL_PROJECTION 矩阵的第三行。

在视点空间中, we 的值是 1。因此,方程式成为了这样;

我们使用 (ze, zn) 的关系: (-n, -1) 和 (-f, 1) 来寻找系数 AB,将它们代入上面的方程式中。

为了解 AB 的方程式,为 B 重写方程式 (1):

将方程式 (1') 代入方程式 (2) ,然后求解 A

A 代入方程式 (1) 求解 B;

我们找到了 AB 。因此, ze 和 zn 之间的关系成为了:

最终,我们建立了整个 GL_PROJECTION 矩阵。完整的投影矩阵是:

OpenGL 透视投影矩阵

这个投影矩阵是用于一般的截头椎体。如果视椎是对称的,也就是说

那么它可以被简化为

在我们继续之前,请看一下 ze 和 zn 之间的关系,方程式 (3) 。你知道它是一个非线性的关系。它意味着在近平面的精度很高,但是在远平面的精度很低。如果范围 [-n, -f] 变大,将会导致一个深度精度的问题(z-fighting);在远平面周围的 ze 的微小改变不会影响到 zn 的值。为了尽量减少深度缓存精度的问题,nf 之间的距离应该尽可能的小。

深度缓存精度的对比

正交投影

正交体积和标准化设备坐标(NDC)

为正交投影构建 GL_PROJECTION 矩阵比透视模式简单多了。

视点空间中的 xe, ye 和 ze 分量都被线性映射到 NDC。我们只需要缩放矩形体积到立方体,然后将它移动到原点。让我们使用线性关系来找到 GL_PROJECTION 的元素。

从 Xe 到 Xn 的映射
从 Ye 到 Yn 的映射
从 Ze 到 Zn 的映射

因为正交投影是不需要 w 分量的,所以 GL_PROJECTION 矩阵的第四行保持为 (0, 0, 0, 1)。因此正交投影完整的 GL_PROJECTION 矩阵为:

OpenGL 正交投影矩阵

如果视椎是对称的话,它可以更加简单, r = -lt = -b
.


原文地址

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

推荐阅读更多精彩内容