Skip to content

值得您信賴的旅遊品牌 | 團體旅遊、自由行的專家‎

機場接送

Menu
  • 首頁
  • 旅遊天地
  • 裝潢設計
  • 環保清潔
  • 發燒車訊
Menu

[OpenGL](翻譯+補充)投影矩陣的推導

Posted on 2021-03-162021-03-16 by admin

簡介

基本是翻譯和補充 http://www.songho.ca/opengl/gl_projectionmatrix.html

計算機显示器是一個2D的平面,一個3D的場景要被OpenGL渲染必須被投影到2D平面上以生成2D的圖像。在OpenGL中,GL_PROJECTION矩陣可以用來進行投影變換。首先,它將所有的頂點數據從相機坐標系(eye coordinates)轉換到裁剪坐標系(clip coordinates),然後通過除以裁剪空間坐標的w值,將裁剪空間坐標系轉換到歸一化設備坐標系(normalized device coordinates,NDC)

我們需要注意的一點就是,裁剪和NDC變換都通過GL_PROJECTION矩陣來完成。之後的文章,將會利用6個參數來構建投影矩陣,這六個參數是:left,right,bottom,top,near,far,分別為近裁剪面的左右下上邊界,近裁剪面,遠裁剪面。

視錐體剔除是在裁剪坐標下進行的,在轉換到NDC坐標系之前。已經變換到裁剪坐標系的坐標\(x_c,y_c,z_c\)會和\(w_c\)進行比較,如果裁剪坐標大於\(w_c\)或小於\(-w_c\),則頂點會被剔除,OpenGL會重建多邊形的邊。
ps.解釋一下為什麼要和\(w_c\)進行比較。因為NDC坐標的範圍是\([-1,1]\),而裁剪坐標和NDC坐標之間的關係是\(x_c/w_c = x_n\),所以\(x_c\)必須得在\([-w_c,w_c]\)之間才可見,其他兩個軸同理。不是在NDC坐標階段進行裁剪,是因為不可見的頂點,沒有必要在對其進行運算,會消耗資源。在作用完投影矩陣后,得到的是齊次坐標,OpenGL會自動除以\(w_c\),以得到笛卡爾坐標,OpenGL應該是在除以\(w_c\)之前進行視錐體剔除工作。

透視投影

在透視投影中,1個3D的點在一個像被切了一刀的金字塔的視錐體中,此時的坐標系是相機坐標系,這個坐標系會被映射正方體的NDC坐標系中。

  • \(x:[l,r]->[-1,1]\)
  • \(y:[b,t]->[-1,1]\)
  • \(z:[-n,-f]->[-1,1]\)

相機坐標系定義在右手坐標系,NDC是左手坐標系,所以相機朝着-Z的方向看去,而NDC朝着+Z的方向看去。因為glFrustum()裁剪面的參數必須為正數,所以在創建投影矩陣的時候,我們要對其進行去取反。
ps.glFrustum是opengl類庫中的函數,它是將當前矩陣與一個透視矩陣相乘,把當前矩陣轉變成透視矩陣,在使用它之前,通常會先調用glMatrixMode(GL_PROJECTION).
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal),left,right指明相對於垂直平面的左右坐標位置,bottom,top指明相對於水平剪切面的下上位置,nearVal,farVal指明相對於深度剪切面的遠近的距離,兩個必須為正數。

在OpenGL中,1個3D的點將會被投影到近裁剪平面上,下圖展示了點\((x_e,y_e,z_e)\)如何投影到\((x_p,y_p,z_p)\)。

在視錐體的頂視圖,我們可以利用相似三角形計算\(x_p\)的值

\[\frac{x_p}{x_e} = \frac{-n}{z_e}\\ x_p = \frac{-nx_e}{z_e}=\frac{nx_e}{-z_e} \]

同理,在側視圖中,利用相似三角形計算\(y_p\)的值

\[\frac{y_p}{y_e} = \frac{-n}{z_e}\\ y_p = \frac{-ny_e}{z_e}=\frac{ny_e}{-z_e} \]

我們觀察到\(x_p,y_p\)都依賴於\(z_e\),他們都除以\(z_e\),這是第一個線索,來幫助我們構建透視投影矩陣。當相機坐標系經過透視投影矩陣變換后,得到的是裁剪坐標系的齊次坐標,最後通過除以齊次坐標的\(w_c\),來得到NDC

\[\begin{bmatrix} x_c\\ y_c\\ z_c\\ w_c \end{bmatrix} =M_{projection} \begin{bmatrix} x_e\\ y_e\\ z_e\\ w_e \end{bmatrix} , \begin{bmatrix} x_n\\ y_n\\ z_n\\ \end{bmatrix} = \begin{bmatrix} x_c/w_c\\ y_c/w_c\\ z_c/w_c\\ \end{bmatrix} \]

因此我們可以設置\(w_c\)的值為\(-z_e\),現在投影矩陣看起來是

\[\begin{bmatrix} x_c\\ y_c\\ z_c\\ w_c \end{bmatrix} = \begin{bmatrix} .&.&.&.\\ .&.&.&.\\ .&.&.&.\\ 0&0&-1&0\\ \end{bmatrix} \begin{bmatrix} x_e\\ y_e\\ z_e\\ w_e \end{bmatrix} \]

接着,我們需要將\(x_p,y_p\)映射到\(x_n,y_n\),\([l,r]->[-1,1],[b,t]->[-1,1]\)。
相當於是給定l,我要得到-1,給定r,我要得到1,這不就是給定二維平面上的兩個點,求其直線方程的問題。

\[令x_n = kx_p+\beta,求其斜率為\frac{1-(-1)}{r-l}=\frac{2}{r-l}\\ 帶入點(r,1),1 = \frac{2r}{r-l}+\beta\\ 化簡求得\beta=-\frac{r+l}{r-l}\\ 最終得x_n = \frac{2x_p}{r-l}-\frac{r+l}{r-l} \]

\[令y_n = ky_p+\beta,求其斜率為\frac{1-(-1)}{t-b}=\frac{2}{t-b}\\ 帶入點(t,1),1 = \frac{2t}{t-b}+\beta\\ 化簡求得\beta=-\frac{t+b}{t-b}\\ 最終得y_n = \frac{2y_p}{t-b}-\frac{t+b}{t-b} \]

現在有了從\(x_e,y_e\)到\(x_p,y_p\)和從\(x_p,y_p\)到\(x_n,y_n\),現在聯立一下就可以得到從\(x_e,y_e\)到\(x_n,y_n\)的關係表達式。

\[x_n = \frac{2x_p}{r-l}-\frac{r+l}{r-l}\\ x_p = \frac{-nx_e}{z_e}=\frac{nx_e}{-z_e}\\ 最終可以化簡為(\underbrace{\frac{2n}{r-l}x_e+\frac{r+l}{r-l}z_e}_{x_c})/-z_e \]

同理

\[y_n = \frac{2y_p}{t-b}-\frac{t+b}{t-b}\\ y_p = \frac{-ny_e}{z_e}=\frac{ny_e}{-z_e}\\ 最終可以化簡為(\underbrace{\frac{2n}{t-b}y_e+\frac{t+b}{t-b}z_e}_{y_c})/-z_e \]

現在我們的透視矩陣現在是這個樣子

\[\begin{bmatrix} x_c\\ y_c\\ z_c\\ w_c \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&-1&0\\ \end{bmatrix} \begin{bmatrix} x_e\\ y_e\\ z_e\\ w_e \end{bmatrix} \]

現在還剩下矩陣的第三行。\(z_n\)和其他兩個軸的坐標稍有不同,因為\(z_e\)總是投影到-n的近裁剪面,但是我們需要不同的z值來進行裁剪和深度測試,另外我們應該可以進行逆操作(逆變換)。因為我們知道z的值不依賴於x,y,我們借用w的值來尋找\(z_n,z_e\)之間的關係,因此我們指定第三行矩陣為

\[\begin{bmatrix} x_c\\ y_c\\ z_c\\ w_c \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&A&B\\ 0&0&-1&0\\ \end{bmatrix} \begin{bmatrix} x_e\\ y_e\\ z_e\\ w_e \end{bmatrix} \]

\[z_n = z_c/w_c = \frac{Az_e+Bw_e}{-z_e} \]

在相機坐標系中,\(w_e\)的值是1,因此有\(z_n = \frac{Az_e+B}{-z_e}\),為了獲得A和B的值,我們使用\((z_e,z_n)\)的關係,\((-n,-1),(-f,1)\),然後將他們代入表達式。

\[\frac{-An+B}{n}=-1\\ \frac{-Af+B}{f}=1 \]

聯立,這是一個簡單二元一次方程組,容易求得

\[A = -\frac{f+n}{f-n}\\ B = -\frac{2fn}{f-n} \]

所以最終得到

\[z_n = \frac{-\frac{f+n}{f-n}z_e–\frac{2fn}{f-n}}{-z_e} \]

最終整個投影矩陣的表達式為

\[\begin{bmatrix} x_c\\ y_c\\ z_c\\ w_c \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+n}{f-n}&-\frac{2fn}{f-n}\\ 0&0&-1&0\\ \end{bmatrix} \begin{bmatrix} x_e\\ y_e\\ z_e\\ w_e \end{bmatrix} \]

這個投影矩陣是一般的視錐體,如果是對稱的話,有\(r=-l,t=-b\),那麼有

\[r+l=0,r-l=2r(width)\\ t+b=0,t-b=2t(height) \]

最後矩陣可以簡單的化為

\[\begin{bmatrix} \frac{n}{r}&0&0&0\\ 0&\frac{n}{t}&0&0\\ 0&0&-\frac{f+n}{f-n}&-\frac{2fn}{f-n}\\ 0&0&-1&0\\ \end{bmatrix} \]

注意觀察\(z_e,z_n\)的關係式,這是一個非線性的反比例函數,這意味着,在近裁剪平面的是很好,精度很高,而在遠裁剪面的時候,精度很低。當\([-n,-f]\)很大時,可能導致深度精度問題(z-fighting),一個較小的\(z_e\)的變化,在遠裁剪面可能不會影響\(z_n\)的值,n和f之間的距離應該短一些,從而最小化這個問題。
ps.因為浮點數會存在精度問題,畢竟計算機的存儲是離散的。

正交投影

正交投影的要比透視投影簡單許多,\(x_e,y_e,z_e\)相機坐標系將會線性映射到NDC坐標系。我們僅需要將長方體變為正方體,然後移動至原點。

\[x_n = \frac{1-(-1)}{r-l}x_e+\beta\\ 代入(r,1),最終可得\\ x_n = \frac{2}{r-l}x_e-\frac{r+l}{r-l} \]

同理

\[y_n = \frac{1-(-1)}{t-b}y_e+\beta\\ 代入(t,1),最終可得\\ y_n = \frac{2}{t-b}y_e-\frac{t+b}{t-b} \]

同理

\[z_n = \frac{1-(-1)}{-f-(-n)}z_e+\beta\\ 代入(-f,1),最終可得\\ z_n = \frac{-2}{f-n}z_e-\frac{f+n}{f-n} \]

因為w的值在正交投影中不必要,所以我們設置為1,因此正交投影矩陣為

\[ \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} \frac{1}{r}&0&0&0\\ 0&\frac{1}{t}&0&0\\ 0&0&-\frac{2}{f-n}&-\frac{f+n}{f-n}\\ 0&0&0&1\\ \end{bmatrix} \]

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

※網頁設計最專業,超強功能平台可客製化

※別再煩惱如何寫文案,掌握八大原則!

好站推薦

  • 健康醫療 減重知識專區
  • 婚紗世界 婚紗攝影寫真網
  • 成人話題 未滿18請勿進入
  • 流行時尚 時下流行愛美情報
  • 理財資訊 當舖借貸信用卡各式理財方法
  • 生活情報 各行各業情報資訊
  • 科技資訊 工業電子3C產品
  • 網路資訊 新奇趣味爆笑內容
  • 美食分享 全台各式名產 伴手禮
  • 裝潢設計 買屋賣屋裝修一羅框
  • 視覺設計 T恤、團體服、制服、polo衫

近期文章

  • 疑似小米手環 6 規格與新功能現身!加入血氧飽和偵測、GPS、更多運動模式_網頁設計公司
  • Microsoft 365 還是 Google Workspace?一文看懂企業生產力工具選哪套_如何寫文案
  • Sony Mobile 全新 Xperia Compact 小尺寸手機回歸?爆料大神釋出高清晰渲染圖_網頁設計公司
  • 微軟最新的廣告,直白地跟你說 Surface Pro 7 就是比 MacBook Pro 好_網頁設計
  • MagSafe 會干擾心律調節器?蘋果支援頁面有正式解答了_貨運

標籤

USB CONNECTOR  南投搬家公司費用 古典家具推薦 台中室內設計 台中室內設計師 台中搬家 台中搬家公司 台中電動車 台北網頁設計 台東伴手禮 台東名產 地板施工 大圖輸出 如何寫文案 婚禮錄影 宜蘭民宿 家具工廠推薦 家具訂製工廠推薦 家具訂製推薦 實木地板 床墊 復刻家具推薦 新竹婚宴會館 木地板 木質地板 柚木地板 桃園機場接送 桃園自助婚紗 沙發修理 沙發換皮 海島型木地板 潭子電動車 牛軋糖 租車 網站設計 網頁設計 網頁設計公司 貨運 超耐磨木地板 銷售文案 隱形鐵窗 電動車 馬賽克拼貼 馬賽克磁磚 馬賽克磚

彙整

  • 2021 年 4 月
  • 2021 年 3 月
  • 2021 年 2 月
  • 2021 年 1 月
  • 2020 年 12 月
  • 2020 年 11 月
  • 2020 年 10 月
  • 2020 年 9 月
  • 2020 年 8 月
  • 2020 年 7 月
  • 2020 年 6 月
  • 2020 年 5 月
  • 2020 年 4 月
  • 2020 年 3 月
  • 2020 年 2 月
  • 2020 年 1 月
  • 2019 年 12 月
  • 2019 年 11 月
  • 2019 年 10 月
  • 2019 年 9 月
  • 2019 年 8 月
  • 2019 年 7 月
  • 2019 年 6 月
  • 2019 年 5 月
  • 2019 年 4 月
  • 2019 年 3 月
  • 2019 年 2 月
  • 2019 年 1 月
  • 2018 年 12 月
©2021 值得您信賴的旅遊品牌 | 團體旅遊、自由行的專家‎ | Built using WordPress and Responsive Blogily theme by Superb