webgl 的空間變換(下):空間變換

  在網上看了不少關於在三維世界中怎麼把一個頂點通過一步步變化,最終呈如今咱們的屏幕上的。web

  其實不少博客或者書籍已經講的很清楚了,那爲何我還要特別再寫一次博客來闡述本身觀點呢?(這裏只針對那些學習webgl時,想完全瞭解清楚空間過程的同窗而言)編程

  由於在我一開始對三維不是很懂的狀況下,看了不少書和博客,以爲他們寫的已經很牛逼了,並且讓我受益不淺,可是隨着知識量的不斷增長 ,我意識到一個問題,那就是我好像理解缺點什麼,或者說有的地方的理解甚至是錯的,好比說一個問題,也是我記錄這篇文章的主要目的,之前我對三維空間的座標變化理解是這樣的:windows

    模型座標----(模型矩陣,即吧模型座標系下的座標變換到世界座標系下的座標的過程,其餘矩陣也是同樣,好比視圖矩陣就是把世界座標系下的座標變換到視圖座標系下的座標的過程)----世界座標 ---- 視圖矩陣----投影矩陣----屏幕座標學習

    基本書上(webgl編程指南)或者網上90%的博客都是這樣講的,這是能夠的,可是是不嚴謹的,由於從投影矩陣到屏幕座標的轉換過程,是不須要你進行處理的,這部分是渲染管線本身執行的。webgl

若是不是由於在工做中遇到一些奇奇怪怪的參數和新的東西,以及和同事的討論中,發現好多概念根本不懂, 我也不會懷疑本身的理解。因此我找到了webgl的祖宗opengl去一探究竟。spa

    如下是opengl中完整的對三維空間變換的介紹,頗有價值:對象

    另外我補充一點,webgl編程指南中之因此會省略一部分細節不去講,並非說webgl裏面有錯,而是那部分細節,不在可編程渲染管線範圍內(就是說咱們能夠本身編寫代碼參與到渲染的部分,大概包括,定義頂點位置, 編寫頂點着色器和片元着色器。)因此,webgl並無細講。ip

      

在使用 OpenGL 的應用程序中,當咱們指定了模型的頂點後,頂點依次會變換到不一樣的 OpenGL 空間中:博客

  • 世界空間
  • 模型空間(也稱爲對象空間)
  • 視圖空間(也稱爲視點空間、攝像機空間)
  • 裁剪空間
  • 標準設備座標空間
  • 窗口空間

在通過這一系列的空間變換以後,頂點纔會被顯示在屏幕上。cli

世界空間(World Space)

世界空間相對於其餘座標空間來講是固定不變的。因此,它也被用做空間變換的參考系。咱們把它的座標系稱爲世界座標系。在沒有特別說明的狀況下,咱們用來描述一個幾何對象(點、向量或座標)的數值數據,都是基於世界座標系來設定的。

世界座標系用矩陣來表示就是一個單位矩陣。

模型空間(Model Space)

模型空間,也稱爲對象空間。若是把世界空間比做現實世界的話,那麼模型就比如一座房子或者房子裏的一我的等等。假設以人的重心爲原點,正面向前的方向爲 z-軸,頭頂的方向爲 y-軸,左側方向爲 x-軸來構建一個座標系。咱們能夠用這個座標系來描述這我的自身的模型空間。這個座標系也稱爲模型座標系(或對象座標系)。

模型座標系並非絕對的,若是以人的鼻尖爲原點,頭頂的方向改成 z-軸,正面向前的方向爲 y-軸,右側方向爲 z-軸來構建其模型座標系。這個模型座標系一樣能夠用來描述這我的自身的模型空間。只不過用不一樣座標系來描述時,描述出來的數據不必定相同。

通常來講,咱們都是基於世界座標系來描述模型座標系的。在這種狀況下,世界座標系能夠看做是模型座標系的父座標系:

其中,黑色的座標系爲世界座標系;灰色的座標系爲模型座標系。

模型變換(模型-世界變換)

默認狀況下模型座標系的原點位於世界座標系的原點,而且座標軸的方向與世界座標系的座標軸一致。咱們能夠經過一系列的縮放、旋轉和平移,將模型以任意角度擺在任意位置上。這種狀況下,模型上的頂點以及模型自身的座標系都會相對世界座標系發生了變化。

模型變換的實質就是將模型上的頂點在模型空間中的描述,轉換爲在世界空間中的描述。假設有一個模型座標系表示爲矩陣 M(基於世界座標系來描述),一個頂點在該模型座標系上的座標表示爲列向量 D。 那麼,該頂點在世界座標系中的座標 D‘,有以下變換關係:M·D = D’。M 也稱爲模型矩陣。模型矩陣本質上是一系列縮放、旋轉和平移矩陣的複合矩陣。

視圖空間(View Space)

視圖空間,也稱爲視點空間或攝像機空間。它是以攝像機(或者觀察者)的角度來定義的一個空間。視圖空間能夠經過視圖座標系(也稱爲視點座標系或攝像機座標系)來描述。從攝像機的角度來看,視圖座標系 x-軸和 y-軸的正方向分別指向攝像機右方和上方,而 z-軸的負方向則指向攝像機的鏡頭指向。在透視投影中,攝像機位於視圖座標系的原點。因此 z 座標爲正的模型位於攝像機的背後,攝像機沒法拍到它;而在正交投影中,攝像機被認爲是位於在視圖座標系 z-軸正方向上的無窮遠處。


透視投影中,攝像機與視圖座標系的位置關係圖


正交投影中,攝像機與視圖座標系的位置關係圖

與模型座標系相似,咱們通常也會基於世界座標系來描述視圖座標系的。因此在這種狀況下,世界座標系能夠看做是視圖座標系的父座標系:

其中,黑色的座標系爲世界座標系;藍色的座標系爲視圖座標系。

視圖變換(世界-視圖變換)

默認狀況下,視圖座標系位於世界座標系的原點,而且座標軸的方向與世界座標系的座標軸一致。咱們能夠經過一系列的縮放、旋轉和平移,將攝像機以任意角度擺在任意位置,以方便咱們的拍攝。當攝像機的位置、角度發生變化時,拍攝到的場景也會發生變化(也就是說空間中的模型相對於視圖座標系來講都發生了變化)。

視圖變換的實質就是將某個頂點在世界空間中的描述,轉換爲在視圖空間中的描述。假設有一個頂點在在世界座標系中的座標表示爲列向量 D‘,一個視圖座標系表示爲矩陣 V(基於世界座標系來描述的),那麼該頂點在視圖座標系 V 中的座標 D,有以下變換關係:V·D = D’(道理和模型變換相似)。設 V 的逆矩陣爲 V’,能夠推導出變換關係 V‘·D‘ = D,V’ 也被咱們稱爲視圖矩陣

模型視圖矩陣(Model-View)

爲了渲染一個模型,咱們一般會先將它從模型空間變換到世界空間,而後再從世界空間變換到視圖空間。這兩個過程都有對應的變換矩陣:模型矩陣和視圖矩陣。咱們能夠將這兩個矩陣結合起來用一個複合矩陣來表示,這樣的一個複合矩陣咱們稱爲模型視圖矩陣。經過模型視圖矩陣,咱們能夠將模型上的頂點從模型空間直接變換到攝像機的視圖空間。這樣作有兩個好處:

  • 假如在世界空間中有許多模型,而且每一個模型包含許多頂點。那麼用一個複合矩陣把單個模型的全部頂點一次性變換到視圖空間,比對全部頂點都作兩次矩陣變換要高效得多。

  • 由於一個空間能夠是無限大的,因此將頂點從模型空間變換到世界空間中,所作的變換經常須要用到不一樣的精度去計算,這主要依賴於頂點離世界座標的原點有多遠。一樣的,當咱們再把頂點從世界空間變換到視圖空間時,所作變換的精度也須要依賴於頂點到攝像機的距離有多遠。對那些距離攝像機很近的頂點採用高精度是合適的,但對於距離攝像機很遠的頂點一樣採用高精度則會產生精度損失。想象一下,當模型與攝像機離得很近,而且二者又離世界座標系的原點很遠時,變換兩次容易產生精度損失。用複合矩陣能夠有效減小精度損失,提升結果的精確性。

裁剪空間(Clip Space)

不難理解,攝像機是沒法同時拍攝到場景內全部的東西的。每一個攝像機都會定義一個視景體,視景體決定了攝像機能夠看到的空間。徹底位於視景體內的模型將會被保留;徹底位於視景體外的模型將被剔除;而與視景體裁剪平面相交的模型則會被裁減(即保留在視景體內的部分,剔除在視景體外的部分)。這個決定模型是保留仍是剔除的過程,咱們稱之爲裁剪

視景體指的是空間中的一塊區域,它由六個平面包圍而成,這些平面被統稱爲裁剪平面。其中,有兩塊平面比較重要,它們都垂直都於攝像機的鏡頭指向,離攝像機比較近的那塊被稱爲近裁剪平面,而離攝像機比較遠的那塊則被稱爲遠裁剪平面。這兩塊平面決定了攝像機能夠看到的深度範圍。


透視投影的視景體示意圖


正交投影的視景體示意圖

對於不一樣的投影,其對應視景體的形狀也有所不一樣。好比正交投影的視景體是一個長方體。而透視投影的視景體則是一個平截頭體(像一個頂部被平截掉的金字塔)。若是咱們直接使用視景體所定義的空間來進行裁剪,那麼對不一樣的視景體就要採用不一樣的處理過程,特別是判斷一個頂點是否處於一個平截頭體內是比較麻煩的。所以,咱們採用更加通用的裁剪空間來描述不一樣視景體所定義的空間。在裁剪空間中,咱們能夠用統一的方式來處理不一樣視景體的裁剪。

裁剪變換

將一個頂點從視圖空間變換到裁剪空間的過程叫做裁剪變換,咱們能夠經過一個裁剪矩陣(也稱爲投影矩陣)來實現該變換。這裏有個迷惑點,雖然裁剪矩陣也叫投影矩陣,但其實它並無進行真正的投影工做,只是在爲投影作準備工做,真正的投影工做發生在下一階段的變換中。

透視投影的裁剪變換

透視投影的視景體爲一個平截頭體,咱們能夠經過下面幾個參數來定義該平截頭體:近裁剪平面、遠裁剪平面在視圖座標系中的 z 座標:near、far,近裁剪平面上下兩條邊在視圖座標系中的 y 座標:top、bottom,還有近裁剪平面左右兩條邊在視圖座標系中的 x 座標:left、right。

咱們能夠根據以上這些已知的參數,來給出透視投影的裁剪矩陣:

對於視圖空間座標爲 (x, y, z, 1) 的頂點,通過透視裁剪矩陣變換後的結果以下:

該結果表示頂點在裁剪空間中的座標。咱們可能注意到了,此時頂點的 w 份量再也不是 1 了,而是變換前 z 份量的取反結果。雖然咱們在裁剪空間以前,就使用齊次座標來表示空間中的幾何對象(點、向量或座標系),並且 w 份量一直是固定的:點位置的 w 份量爲 1,向量的 w 份量表示爲 0。在變換到裁剪空間以後,咱們將賦予齊次座標的 w 份量更加豐富的含義:做爲一個臨界值來判斷一個通過裁剪變換後的頂點是否位於景視體內。若是變換後的座標值 x、y、z 均在區間 [-w, w] 內,則代表該頂點在視景體內。不然,代表該頂點不在視景體內,將會被拋棄。

正交投影的裁剪變換

正交投影的視景體爲一個長方體,平截頭體的參數概念對於長方體來講一樣適用。如今,咱們根據這些已知的參數,來給出正交投影的裁剪矩陣:

對於視圖空間座標爲 (x, y, z, 1) 的頂點,通過正交裁剪矩陣變換後的結果以下:

很明顯,當變換前的 x 座標在 right 與 left 之間時,變換後的 x 座標在區間 [-1, 1] 內。對於 y 和 z 座標同理可證。也就是說,若是變換後的座標值 x、y 、z 均在區間 [-1, 1] 內,則代表該頂點在視景體內。並且這裏的 w 爲 1,因此其裁剪的判斷規則與透視投影中是一致的。

裁剪空間使用同一套空間標準來描述不一樣視景體所定義的空間(經過執行不一樣的裁剪矩陣變換),把不一樣視景體的裁剪方式進行了統一。除此以外,裁剪空間也爲後面真正的投影工做提供了方便。

標準設備座標空間(NDC Space)

現在,顯示屏幕的分辨率多不勝數,咱們很難在每一種分辨率上都能把頂點顯示在正確的位置上。

爲了解決這個硬件適配的問題,咱們在頂點被渲染到屏幕上以前,將其變換到標準設備座標空間中。標準設備座標空間採用一種無量綱的單位座標來代替設備座標,直到頂點被輸出到屏幕時,單位座標纔會轉換爲具體的設備座標。標準設備座標系的 x、y、z 軸的範圍被定義爲 [-1, 1]。這樣能夠將應用程序與具體的顯示設備隔離開來,應用程序無需關心顯示設備的分辨率,增長了應用程序的可移植性。

對於正交投影,任意頂點在裁剪空間的座標值 x、y 、z 均在區間 [-1, 1] 內,這種狀況下無需任何變換,裁剪空間自己也是標準設備座標空間。

對於透視投影,咱們只須要對頂點在裁剪空間的座標執行齊次座標標準化,使其 w 份量變爲 1。對應的 x、y、z 也將會縮小到範圍 [-1, 1] 內。這種狀況下,標準化的過程其實也是將頂點從裁剪空間座標變換到到標準設備座標空間的過程。

並且,由於標準化前的 w 份量與頂點到攝像機的距離成正比。因此,頂點離攝像機越遠則 w 越大,w 越大則在標準化時 x、y、z 被縮得越小,這樣就達到了透視收縮和投影的效果。因此,標準化的過程也是真正的投影過程。

窗口空間(Windows Space)

窗口空間,實際上指的就是顯示屏幕或屏幕上某塊區域(好比屏幕桌面上的窗口)的空間。窗口空間不只取決於屏幕的分辨率或窗口的大小,也取決於窗口的位置。由於在標準設備座標空間中,任意頂點的座標值都在範圍 [-1, 1] 內。因此,不管窗口空間是什麼樣的,咱們都能很好的把頂點的標準設備座標映射到具體的屏幕或屏幕的指定顯示區域上。

相關文章
相關標籤/搜索