打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
透視投影詳解

概述

投影變換完成的是如何將三維模型顯示到二維視口上,這是一個三維到二維的過程。你可以將投影變換看作是調整照相機的焦距,它模擬了为照相機選擇鏡頭的過程。投影變換是所有變換中最复雜的一個。

視錐體

視錐體是一個三維體,他的位置和攝像機相關,視錐體的形狀决定了模型如何從camera space投影到屏幕上。最常見的投影類型-透視投影,使得離攝像機近的物體投影後較大,而離攝像機較遠的物體投影後較小,透視投影使用棱錐作为視錐體,攝像機位於棱錐的椎頂。該棱錐被前後兩個平面截斷,形成一個棱台,叫做View Frustum,只有位於Frustum內部的模型才是可見的。

透視投影的目的

透視投影的目的就是將上面的棱台轉換为一個立方體(cuboid),轉換後,棱台的前剪裁平面的右上角點變为立方體的前平面的中心(下圖中弧線所示)。由圖可知,這個變換的過程是將棱台較小的部分放大,較大的部分縮小,以形成最終的立方體。這就是为什麼投影變換會產生近大遠小的效果的原因。變換後的x坐標範圍是[-1, 1],y坐標範圍是[-1, 1],z坐標範圍是[0, 1](OpenGL略有不同,z值範圍是[-1, 1])。

透視投影矩陣推導

下面來推導一下透視投影矩陣,這样我們就可以自己設置投影矩陣了,就可以模擬神奇的D3DXMatrixPerspectiveLH函數的功能了。那麼透視投影到底做了什麼工作呢?這一部分算是個難點,無論是DX SDK的幫助文檔,還是大多數圖形學書籍,對此都是一帶而過,很少有詳細討論的,早期的DX SDK文檔還討論的稍微多一些,而新近的文檔則完全取消了投影矩陣的推導過程。

我們可以將整個投影過程分为兩個部分,第一部分是從Frustum內一點投影到近剪裁平面的過程,第二部分是由近剪裁平面縮放的過程。假設Frustum內一點P(x,y,z)在近剪裁平面上的投影是P'(x',y',z'),而P'經過縮放後的最終坐標設为P''(x",y",z")。假設所求的投影矩陣为M,那麼根據矩陣乘法可知,如下等式成立。

PM=P'',即

先看第一部分,为了簡化問題,我們考慮YOZ平面上的投影情況,見下圖。設P(x, y, z)是Frustum內一點,它在近剪裁平面上的投影是P'(x', y', z')。(注意:D3D以近剪裁平面作为投影平面),設視錐體在Y方向的夾角为Θ。

 

 由上圖可知,三角形OP'Q'與三角形OPQ相似,於是有如下等式成立。

在看第二部分,將P'縮放的過程,假設投影平面的高度为H,由於轉換後cuboid的高度为2。所以有

又因为投影平面的縱橫比为Aspect,所以

最後看z'',因为在光柵化之前,我們需要對z坐標的倒數進行插值,所以可以將z''寫成z的一次表達式形式,如下

在映射前,z的範圍是[n,f],這裏n和f分別是近遠兩個剪裁平面到原點的距離,在映射後,z''的範圍是[0,1],將數據代入上面的一次式,可得下面的方程組

解這個方程組得到

所以

整理一下得

將X'',y'',z''代入最開始的矩陣乘法等式中得

由上式可見,x'',y'',z''都除以了Pz,於是我們將他們再乘以Pz(這並不該變齊次坐標的大小),得到如下等式。

注意這裏,x即Px,y即Py,z即Pz,解矩陣的每一列得到

於是所求矩陣为

代碼

一般來說,在程序中我們通常给定四個参數來求透視投影矩陣,分別是y方向的視角,縱橫比,近剪裁平面到原點的距離及遠剪裁平面到原點的距離,通過這四個参數即可求出上面的矩陣,代碼如下。

D3DXMATRIX BuildProjectionMatrix(float fov, float aspect, float zn, float zf){    D3DXMATRIX proj;    ZeroMemory(&proj, sizeof(proj));    proj.m[0][0] = 1 / (tan(fov * 0.5f) *aspect) ;    proj.m[1][1] = 1 / tan(fov * 0.5f) ;    proj.m[2][2] = zf / (zf - zn) ;    proj.m[2][3] = 1.0f;     proj.m[3][2] = (zn * zf) / (zn - zf);    return proj ;}

矩陣求解完畢,現在可以用如下代碼試試效果,這和使用D3D函數D3DXMatrixPerspectiveFovLH所得效果是一致的。

D3DXMATRIX proj = BuildProjectionMatrix(D3DX_PI / 4, 1.0f, 1.0f, 1000);g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj) ;

Happy Coding!!!


From:CNBLOGS
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
基本形体投影.ppt
OpenGL 矩阵变换
GPU图形绘制管线
269平面向量投影向量夹角
空间几何体的表面积和体积
機械製圖展開圖的原理和展開放樣方法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服