OpenGL投影矩阵

概述

电脑显示器是2D平面,一个3D物体通过OpenGL渲染投影到2D显示器平面形成图像,GL_PROJECTION是OpenGL用于投影转换的矩阵。首先,转换3D物体的顶点数据从相机空间到裁剪空间,然后,通过除以W(齐次坐标)从裁剪空间再转换到标准设备空间(NDC)。
因此,我们需要意识到裁剪计算和NDC转换都是整合到了GL_PROJECTION矩阵里了。接下来的内容将探讨怎么构建投影矩阵,使用6个代表边界值的参数分别是:left,right,bottom,top,near , far(下面简写为l、r、b、t、n、f)。有一点注意一下,裁剪计算是在转换成NDC坐标之前发生的,即在除以w_c(齐次坐标)之前。通过裁剪坐标x_c,y_c,z_cw_c(这里的c下标表示裁剪空间)做对比,如果裁剪坐标小于-w_c或大于w_c将被裁减掉(-w_c < x_c,y_c,z_c < w_c),然后OpenGL会重新构建网格边缘。

一个被平头视锥裁剪的三角形

透视投影

在透视投影里,一个3D点在一个平头视锥体里面(相机空间)是要被映射到一个正方体(NDC空间)里的,x坐标的区间从[l,r]映射到[-1,1],y坐标的区间从[b,t]映射到[-1,1],z坐标的区间从[-n,-f]映射到[-1,1]。

投影视锥和标准设备空间(NDC)

注意一点,相机空间是使用右手坐标系统,但是NDC坐标空间使用左手坐标系统,这就是相机在原点沿着-Z方向看,但是在NDC空间是反过来的。因为glFrustum()仅仅接收正的near和far值,在构造GL_PROJECTION矩阵时我们需要给他们变成负值。
在OpenGL里,一个3D点在相机空间是被投影到near平面(projection plane 即下图的-n平面)。下面的图片展示一个点(x_e,y_e,z_e)在相机空间投影到near平面上的点(x_p,y_p,z_p)。
从上往下看视锥体

从侧面看视锥体

从上往下看视锥体,相机空间的x坐标点x_e投影到x_p,通过相似三角形原理得: x_p \over x_e = -n \over z_e => x_p = -n * x_e \over z_e = n*x_e \over -z_e
同理,从侧边看视锥体可得:y_p \over y_e = -n \over z_e => y_p = -n * y_e \over z_e = n * y_e \over -z_e
注意到,x_py_p都依赖z_e,他们和-z_e成相反的比例,也就是说他们都需要除以-z_e。这是非常有用的线索,用于构建GL_PROJECTION矩阵上,通过乘以GL_PROJECTION矩阵从相机空间转换到裁剪空间,坐标仍然是齐次坐标,除以裁剪空间的w最终变成规范化设备坐标空间(NDC)(更多资料请查阅OpenGL Transformation
投影矩阵乘以相机空间坐标得到裁剪空间坐标
裁剪空间坐标除以W得到NDC空间坐标

因此,我们可以设置裁剪空间的w坐标等于-z_e,然后投影矩阵GL_PROJECTION的第四行就变成(0,0,-1,0)。
根据矩阵乘法公式计算得,裁剪空间的w值等于相机空间的-z值

下一步,我们通过线性关系映射x_p(p下标表示投影空间未有裁剪的)和y_p(p下标表示投影空间未有裁剪的)到NDC坐标空间的x_n(n下标表示NDC空间)和y_n(n下标表示NDC空间),即:[l,r] => [-1,1] [b,t] => [-1,1]

为了直观点,可以把映射值连成的直线平移经过原点再平移回来
映射的最大点和最小点是已知的,代入上式可以求出平移值推导出映射公式

为了直观点,可以把映射值连成的直线平移经过原点再平移回来
映射的最大点和最小点是已知的,代入上式可以求出平移值推导出映射公式

然后使用上面的x_py_p两个等式替换到x_ny_n等式里:
求出NDC空间坐标,构造成除以w的形式
求出NDC空间坐标,构造成除以w的形式

注意到,我们故意把等式构造成除以-z_e的形式,即与透视除法(x_c/w_c,y_c/w_c)等同,只要把w_c看成-z_e上面等式括号的值就是裁剪空间的x_cy_c
从上面的等式总结,我们可以找到GL_PROJECTION矩阵第一行和第二行的构造方法
裁剪空间坐标等于投影矩阵乘以相机空间坐标

现在GL_PROJECTION矩阵只剩下第三行没构造好,构造z_n稍微不同于x_ny_n,因为在相机空间ze总是投影在near平面的-n点上,由于我们需要z值方便做深度测试和裁剪,另外也需要逆转换投影,我们知道z是不依赖于x或y的值,我们可以借用w表示z_nz_e之间的关系,因此我们可以构造GL_PROJECTION矩阵的第三行如下图:

z是不依赖于x和y的,因此第三行矩阵x和y的值是0

在相机空间,w_e等于1,因此等式变成:
在相机空间的坐标w为1,因此可以略去

为了求出系数A和B,根据上面等式得出z_ez_n的关系,假设z_e等于-n(即近平面)那么z_n等于-1(即映射到NDC空间的坐标应为-1),z_e等于-f(即远平面)那么z_n等于1(映射到NDC空间的坐标应为1),带入上面等式:

由等式(1)推出:

把B等式代入等式(2):

把A等式代入等式(1):


得到A和B的等式可导出z_ez_n的关系等式:
NDC空间坐标的z值和相机空间坐标的z值的关系等式

最终,可得到整个GL_PROJECTION矩阵:
完整的投影矩阵公式

当视锥体是个对称视锥体时,r = -l , t = -b 所以可以简化矩阵公式:


最后,再审视一下上面等式(3)表达的z_ez_n的关系。注意到这个等式函数是非线性关系的,意思是在近平面时会有非常高的精度,反过来在远平面会有非常低的精度。如果区间[-n,-f]是个很大的范围会导致出现深度(z值)精度的问题(z-fighting),z_e改变很小的值不会计算得到对应的z_n的值。所以,n和f之间的区间应该小点以减少z深度的精度问题。
z-fighting,可以看到右图跨度大,打圈处的f值由于精度问题都会对应1

正交投影

构造正交投影矩阵 GL_PROJECT比构造透视投影矩阵简单多了,只需要在相机空间里线性的映射x_e,y_e,z_e到NDC空间。我们只需要缩放长方体变成正方体,然后移到原点位置,让我们看看GL_PROJECTION的各元素之间的线性关系吧。


相机空间的x映射到NDC空间的x,同透视投用一样,可以先平移到原点再平移回来

注意,没有投影,NDC空间的x直接和相机空间的x成线性关系
相机空间的y映射到NDC空间的y,同透视投用一样,可以先平移到原点再平移回来
注意,没有投影,NDC空间的y直接和相机空间的y成线性关系
相机空间的z映射到NDC空间的z,可以先平移到原点再平移回来

注意,没有投影,NDC空间的z直接和相机空间的z成线性关系

因为正交投影矩阵是不需要用w计算z值的(z值也是线性关系直接求出来,透视投影需要用w来间接计算z_e和z_n的关系),矩阵GL_PROJECTION的第四行保留为(0,0,0,1),因此完整的正交投影矩阵为:
正交投影矩阵公式

当视锥体是对称长方体,即r = -l、t = -b,有:

坐标转换:模型坐标 -> 世界坐标 -> 相机坐标 -> 裁剪坐标 -> NDC坐标
原文链接

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

推荐阅读更多精彩内容