OpenGL正交投影和透视投影矩阵推导

1.整体流程图

20140918202127843.jpg

2.个人推导总结

参考文档在这里这里
为了方便性,这里使用左手坐标系来推导

  • 正交投影推导
    20140407181049609.jpg

    结合图,我们知道,正交投影其实就是将目标视域体[L,B,N]至[R,T,F]的区域
    度量到规则视域体[-1,-1,0]至[1,1,1]的区域中,请仔细理解这句话,这意味着,我可以将很大的一个区域映射到的规则视域体cvv中,也可以将很小的区域映射到使视域体中,而这个区域的具体的大小是由L,B,N 至R,T,F的区域大小决定的。
    下面是推导过程,假设有一个点(x,y,z)位于视域体[L,B,N]至[R,T,F]的区域中 ,那么x,y,z 分别满足如下不等式

L<x<R
B<y<T
N<z<F

对第一个不等式
L<x<R

做如下变换
两边减去L: 0<x-L<R-L
两边除以R-L: 0< \frac{x-L}{R-L}<1
两边乘以2:0<2*\frac{x-L}{R-L}<2
两边减去1:-1<2*\frac{x-L}{R-L} - 1<1

整理得: -1<\frac{2x}{R-L}-\frac{R+L}{R-L}<1

也就是说,原先在目标视域体[L,B,N]至[R,T,F]的区域中的x ,如果规范到[-1,-1,0]至[1,1,1]的区域中变成x',则有如下关系

x'=\frac{2x}{R-L}-\frac{R+L}{R-L}

只所以我们能进行上述变化是因为这里的映射关系是线性关系

这里有一个容易忽略的事实,为啥说叫裁剪,对上面的等式我们可以尝试一下,
x'=\frac{2x}{R-L}-\frac{R+L}{R-L}
如果x取一个大于R的数,比如x=2R
那么经过变换后得到x'=\frac{3R+L}{R-L}=\frac{2R+2L+R-L}{R-L}=\frac{2(R+L)}{R-L}+1>1
也就是任何的x的取值不在[L,R]之间的数值都会被映射到[-1,1]的区间之外, 而这些区间之外的点会被后续裁剪掉,也就是裁剪真正的逻辑判断

那么同样的道理我们只需要将x,R,L替换成y,T,B就能得到y'的映射关系式如下

y' = \frac{2y}{T-B}-\frac{T+B}{T-B}

如果z的范围也是映射到[-1,1]则可以继续同理,但这里因为是[0,1],所以做一些微的改变

N<z<F

两边减去N:
0<z-N<F-N

两边除以F-N:
0<\frac{z-N}{F-N}<1

因此z'的映射关系为
z'=\frac{z}{F-N}-\frac{N}{F-N}

又因为这里只涉及简单的缩放和平移,
于是齐次项w=1

于是一共得到四个式子

x'=\frac{2x}{R-L}-\frac{R+L}{R-L}
y' = \frac{2y}{T-B}-\frac{T+B}{T-B}
z'=\frac{z}{F-N}-\frac{N}{F-N}
w=1

将上述四个个等式写成矩阵形式(对此抱有疑问的童鞋请自觉阅读矩阵乘法相关知识)

\begin{bmatrix}x'\\y'\\z'\\w'\end{bmatrix}=\begin{bmatrix}\frac{2}{R-L}&0&0&-\frac{R+L}{R-L}\\0&\frac{2}{T-B}&0&-\frac{T+B}{T-B}\\0&0&\frac{1}{F-N}&-\frac{N}{F-N}\\0&0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}

也就是说,映射过程其实使用的就是上述矩阵,更进一步的,我们来看看这个矩阵都做了什么

\begin{bmatrix}\frac{2}{R-L}&0&0&-\frac{R+L}{R-L}\\0&\frac{2}{T-B}&0&-\frac{T+B}{T-B}\\0&0&\frac{1}{F-N}&-\frac{N}{F-N}\\0&0&0&1\\\end{bmatrix}=\begin{bmatrix}\frac{2}{R-L}&0&0&0\\0&\frac{2}{T-B}&0&0\\0&0&\frac{1}{F-N}&0\\0&0&0&1\end{bmatrix}*\begin{bmatrix}1&0&0&-\frac{R+L}{2}\\0&1&0&-\frac{T+B}{2}\\0&0&1&-N\\0&0&0&1\end{bmatrix}

可以看到,正交投影矩阵可以拆分成两个矩阵的乘积,首先进行矩阵

\begin{bmatrix}1&0&0&-\frac{R+L}{2}\\0&1&0&-\frac{T+B}{2}\\0&0&1&-N\\0&0&0&1\\\end{bmatrix}

的位移操作,即将整个v视域体的x方向和y方向的中心位置对齐cvv中心位置,同时cv视域体z方向移动到贴近cvv原点的位置。
然后进行vv视域体的拉伸,即左乘以矩阵

\begin{bmatrix}\frac{2}{R-L} & 0 &0&0\\0&\frac{2}{T-B}&0&0\\0&0&\frac{1}{F-N}&0\\0&0&0&1\\\end{bmatrix}

映射到cvv视域体的范围区间[-1,-1,0]至[1,1,1]。。这样,cv视域体的物体就完整的映射到ccv视域盒子中了。
正交投影先到这个位置。接下来推导透视投影。

  • 透视投影推导
    20140407181827046.jpg

同样,结合图形我们可以知道透视投影本质上是对视锥体的映射到cvv盒子的过程。
我们回想前面讲的正交投影,想一想透视投影会有什么不同。。
透视投影实际上是对现实世界近大远小的模拟,如果观察铁轨,你会发现两条平行轨道最终交汇于一点。即灭点。

前面的关于正交投影的工作其实并不是毫无作用,借助一下前面正交投影的推导,我想到一种方式来拆分这个从视锥体到cvv的映射过程,
1.首先将视锥体转化为正交投影的vv体,注意下图中的蓝色盒子区域,


QQ截图20171201110233.png

2.接下来执行和正交投影一模一样的操作,即vv到cvv。


QQ截图20171201111933.png

这么一拆分是不是清晰明白了很多呢有木有。
接下来是验证过程,
首先是计算步骤1
观察一下这个视锥体

QQ截图20171201110233.png

我们换个x0z切面视角

QQ截图20171201114647.png

要将视锥体转换成规则视域体,由上图根据相似三角形规则,我们有

\frac{x}{x_0}=\frac{n}{z_0}

整理得

x=\frac{n}{z_0} * x0

同理可得y的关系式为

y=\frac{n}{z_0}*y_0

假设我们需要映射一个坐标点(x_0,y_0,z_0)到标准cvv视域体(x,y,z)从上的等式中,我们发现上面两个等式包含一项\frac{1}{z_0},也就是说这里的x,y的取值和原始坐标点z_0是一个反比的关系,即距离越远(即z_0值越大),xy越小
那对于z(x_0,y_0,z_0)的映射关系应该怎么写呢
其实简单的处理就是z=z_0

这样z的取值范围就刚好映射到(n,f)之间,这样当z_0=n时,z=n,而z_0=f时,z=f,非常的合理
然而图形学大佬做出了一个违背祖宗的决定,他们说,既然x,y,都是和z_0是反比关系
那么我们构造一个等式,(这么做的理由目前没想明白,直觉上来看,是在构造矩阵的时候,可以把z_0提取出来,做统一透视除法操作,先留个坑,-----已填坑,看文末
z=p+\frac{q}{z_0},让z也和z_0成反比关系,p,q是两个待定系数,

求解过程如下,
给定约束条件,z_0=n时,z=n 而z_0=f时候,z=f
于是有
n*n=p*n+q
f*f=p*f+q
解方程组
p=f+nq=-nf
pq代入原来的假设
于是自然得到
z=(f+n)-\frac{nf}{z_0}

将z的表达式重新替换,得到新的四个等式写到一起,如下
x=\frac{n}{z_0} * x0
y=\frac{n}{z_0}*y_0
z=(f+n)-\frac{nf}{z_0}
w=1
写成矩阵形式

\begin{bmatrix}x\\y\\z\\w\end{bmatrix}=\frac{1}{z0}*\begin{bmatrix}N&0&0&0\\0&N&0&0\\0&0&F+N&-NF\\0&0&1&0\end{bmatrix}\begin{bmatrix}x0\\y0\\z0\\1\end{bmatrix}

请注意,这里仅仅是视锥体到规则视域体,并不是直接就到了cvv盒子体内,如果没看懂,请往回翻
以上是第一步骤部分,

那么接下来就简单了,
2.第二步骤,即vv到cvv的正交投影过程,当得到这个规则视域体中的点(x,y,z,1)之后,我们只需要对规则视域体进行正交投影,就能变成最终我们需要的标准cvv体
我们可以很简单的得到这个矩阵
使用
\begin{bmatrix}N&0&0&0\\0&N&0&0\\0&0&F+N&-NF\\0&0&1&0\end{bmatrix}
左乘正交投影矩阵,还记得吧,就是这个
\begin{bmatrix}\frac{2}{R-L}&0&0&-\frac{R+L}{R-L}\\0&\frac{2}{T-B}&0&-\frac{T+B}{T-B}\\0&0&\frac{1}{F-N}&-\frac{N}{F-N}\\0&0&0&1\end{bmatrix}

忘记的请往回翻)即
\\\begin{bmatrix}\frac{2N}{R-L}&0&-\frac{R+L}{R-L}&0\\0&\frac{2N}{T-B}&-\frac{T+B}{T-B}&0\\0&0&\frac{F}{F-N}&-\frac{FN}{F-N}\\0&0&1&0\end{bmatrix}=\begin{bmatrix}\frac{2}{R-L}&0&0&-\frac{R+L}{R-L}\\0&\frac{2}{T-B}&0&-\frac{T+B}{T-B}\\0&0&\frac{1}{F-N}&-\frac{N}{F-N}\\0&0&0&1\end{bmatrix}*\begin{bmatrix}N&0&0&0\\0&N&0&0\\0&0&F+N&-NF\\0&0&1&0\end{bmatrix}

这便是最终的投影矩阵,从上述过程也可以看出投影矩阵本质上依然包含了正交投影部分的过程。有没有一种豁然开朗的感觉,这便是透视投影矩阵的本质,即先进行视锥体到规则视域体的变换,然后规则视域体进行正交投影变换

需要强调的是,相机空间的点p(x_0,y_0,z_0,1)
经过投影矩阵变化后的点是在齐次裁剪空间的点p_{clip}(x,y,z,w)
为了更加详细的说明,我们简单再列一下
\begin{bmatrix}x\\y\\z\\w\end{bmatrix}=\begin{bmatrix}\frac{2N}{R-L}&0&-\frac{R+L}{R-L}&0\\0&\frac{2N}{T-B}&-\frac{T+B}{T-B}&0\\0&0&\frac{F}{F-N}&-\frac{FN}{F-N}\\0&0&1&0\end{bmatrix}\begin{bmatrix}x0\\y0\\z0\\1\end{bmatrix}

x=\frac{2N}{R-L}x_0-\frac{R+L}{R-L}z_0
y=\frac{2N}{T-B}y_0-\frac{T+B}{T-B}z_0
z=\frac{F}{F-N}z_0-\frac{FN}{F-N}
w=z_0
即投影矩阵只是虚晃一枪,并没有执行真正的透视除法操作,因为在执行透视除法之前,还有一个步骤是进行裁剪判断,这里判断方法是计算
-w\leq x\leq w

-w\leq y\leq w
0\leq z\leq w

这么判断的前提是因为cvv的范围是xy的取值范围均是-11,z最终的取值范围是01,因此可以再执行透视除法之前先这么简单判断,如果透视除法的cvv换个样子,那么裁剪判断也需要相应的去改变

最后,当需要真实的展示在cvv中,则需要再进行透视除法,即,各项除以z_0,才能得到cvv中的p_{cvv}(x,y,z,1)

相关问题说明,为何你发现很多地方的看到的投影矩阵有些微的差别,那么我分析主要有几个原因

  • 这里的cvv体是[-1,-1,0][1,1,1]这个区间内。而其他地方可能使用的是[-1,-1,-1][1,1,1]作为cvv盒子区间,比如使用[-1,-1,-1][1,1,1]作为标准cvv区间,则投影矩阵应该是下面的形式
    (最开始推导的时候没特别注意,后来翻阅opengl的投影矩阵实现,确实其中Z值使用的是-1,1的区间)

\begin{bmatrix}\frac{2N}{R-L}&0&\frac{R+L}{R-L}&0\\0&\frac{2N}{T-B}&\frac{T+B}{T-B}&0\\0&0&-\frac{F+N}{F-N}&-\frac{2NF}{F-N}\\0&0&-1&0 \end{bmatrix}= \begin{bmatrix}\frac{2}{R-L}&0&0&-\frac{R+L}{R-L}\\0&\frac{2}{T-B}&0&-\frac{T+B}{T-B}\\0&0&-\frac{\\2}{F-N}&-\frac{F+N}{F-N}\\0&0&0&1\end{bmatrix} * \begin{bmatrix}N&0&0&0\\0&N&0&0\\0&0&F+N&NF\\0&0&-1&0\end{bmatrix}

  • 很多矩阵你会发现,R+L部分写成0,T+B部分写成了0,那是因为他们默认R=-L,以及T=-B写成的简略模式所致,其实真实情况未必如此,R不一定非要等于-L,且T也不一定非要等于-B,那么在这里我还是更喜欢保留T+B,R+L等等,因为这才是投影矩阵本来的样子。

以上~~

填坑---2023-02-14

对于投影矩阵的推导取z=p+\frac{q}{z_0}的填坑解释

image.png

image.png

这里有两条线,一条是y=x,这里等价于前面提到的z=z_0,
也就是说假如z_0的深度从14的时候,z的取值也从14

而另一条线y=1+4-\frac{4}{x},等价于z=(f+n)-(\frac{n+f}{z_0}),即从近平面深度1到远平面深度4

可以看到,通过上述方式z=p+\frac{q}{z_0}待定系数求出的最终曲线函数,本质上还是增函数,即随着深度z_0的增大,z值也增大
区别在于
z=z_0是线性函数
z=p+\frac{q}{z_0}是非线性函数,那这样到底有什么好处呢,

我们知道在三维世界中,距离玩家或者说相机观察视角近的位置是需要更加精确的表达的,
也就是对于近处的深度,我们希望近处物体的深度值相对更具有区分度
而对于远处的物体的深度,其实我们没有那么在乎,因为已经很远了,在视野中远处的物体其实占比非常小,也不太需要精确渲染

有了上面这个概念,我们再来看这个曲线函数y=1+4-\frac{4}{x},可以看到,当z_0定义域在(1,2)的范围内时候,其值域范围是(1,3)
反观y=x函数,当z_0定义域在(1,2)的范围内,其值域范围还是(1,2)
也就是说,曲线函数y=1+4-\frac{4}{x}的形式,提供了近处深度更大范围的值域取值,这对于对深度敏感的一些操作是非常有好处的

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

推荐阅读更多精彩内容