天天看點

GPU渲染3D圖形的粗略步驟,雖然粗略但也是通用步驟

1,由于我們導入Unity的模型或者我們再Unity建立的模型,它們自身都有一個屬于自己的坐标系,就像人一樣,無論你站在什麼方位,你總是知道自己的前後左右是什麼方向,而這個前後左右就建立在你自身的坐标系,是以Unity裡每一個模型并不知道其他模型的坐标系,那麼為了友善計算和操作我們就要把他們轉換到一個統一的空間坐标系裡,前者是物體的模型空間,後者是世界空間,這是第一個空間變換:"模型空間"->"世界空間",然後我們要确定我們在錄影機裡具體能看到哪些東西,同樣為了友善計算和處理,我們要再一次把物體從世界空間轉換到錄影機空間,其實就是以錄影機為坐标系原點建立一個三維空間,經過這一步操作就能知道每一個物體從錄影機的位置來看他在什麼方位,這是第二個空間變換:"世界空間"->"錄影機空間".現在雖然知道了物體在相機空間的位置,但是還不能立刻進行渲染,為了友善後面要進行的空間裁剪和,螢幕坐标映射當然也是為了友善計算,我們要把錄影機空間内所有物體的坐标再一次轉換到一個坐标範圍是(-1,-1,-1)到(1,1,1)的正方體空間區域中,也就是整個空間變換中最難了解的"投影變換",這是第三個空間變換:"錄影機空間"->"投影空間".接下來就是把投影空間裡的物體映射到螢幕坐标上去.第四個空間變換(嚴格來說這不應該叫空間變換):"投影空間"->"視窗空間".以上大概屬于空間變換部分的内容,很多書本上的地方叫法和說法都不盡相同,了解大概意思即可.

  2,顯示卡來處理圖形的過程中一般有三個最基本的要素:點,線,面(一般指三角面),而在上一步中我們隻是針對模型中單個頂點來一一處理,接下來我們就把經過空間變換剩下來的頂點(為什麼說剩下來呢,因為上一步有一點沒有提,就是在投影變換的過程中, 會進行一步剔除處理,把一些不在顯示區域内的頂點根據一定規則過濾點,這樣可以減少接下來的運算量)進行組裝,組裝成點,線,面.也就是所謂的圖元裝配,圖元裝配進行完之後,我們需要進行栅格化:大家都知道我們面前的螢幕是由像素矩陣構成的,而我們處理的模型隻是由有限的頂點構成的,經過圖元裝配後形成的基本圖元(點線面),我們要把它和螢幕上的像素區域對應起來,也就是進行像素填充,一般模型的每個頂點都會帶有一些基本資訊(例如,法線,位置,紋理坐标,顔色等),即一個三角面其實隻有三個頂點是有基本屬性的,而其他填充進來的像素區域是并不直接擁有這些基本屬性的,他們的屬性都是通過在頂點間內插補點計算得來的(其實上面提到的像素應該稱為片元fragment).有些書籍中把圖元裝配也歸到栅格化中,請注意.經過這些處理模型基本在GPU中已經形成了他所要繪制到螢幕上的樣子了.不過這并沒有結束.

  3,經過上面的處理我們就仿佛得到了一個預備要繪制到螢幕上的臨時資料區域,不過到底是将這些像素是否最終繪制到螢幕上,怎麼繪制到螢幕上,還需要經過一些判斷.制作遊戲中最常見的現象,離錄影機近的物體要繪制在前面,會把離錄影機較遠的物體擋住(不考慮半透明物體),如果沒有某些判斷的話,那如果GPU先渲染了離螢幕較近的物體,而後處理了離螢幕較遠的物體,那麼近的先畫到螢幕上,遠的後畫就會把之前的覆寫掉了,這顯然不是我們需要的效果(并不是所有引擎都可以自由的去控制物體的渲染順序,即使可以控制,很多時候也十分麻煩,并不十分常用).是以說我們就需要在繪制的時候進行檢測,上面這個問題使用的是ZTest(還有很多檢測這裡隻提這一個,其他的以後遇到了再具體說),對于GPU來說擁有兩個最基本的緩沖區:幀緩沖區和Z緩沖區(也叫深度緩沖區),這兩個緩沖區都與螢幕上的每個像素一一對應,其中幀緩沖區對應着螢幕上的像素點的最終顔色,GPU最終都是通過把顔色寫入這個區域來呈現在螢幕上的,而另一個深度緩沖區則存儲着螢幕上每個像素的深度值,所謂的深度值就是離錄影機的遠近(一般都被規範化為一個0~1的數值),數值越大說明離錄影機越遠,剛才我們提到的ZTest就是通過将光栅化後的像素的深度值和目前螢幕上像素對應的深度值進行相應的比較,來絕定是不是把新的像素點覆寫掉原來的像素點(當然這并不是最終是否寫入幀緩沖區的判斷條件,還有一些其他判斷),至于以什麼模式來判斷并無硬性要求,根據你具體的要求來選擇判斷方式.經過這一系列的判斷和處理之後GPU會把最終結果寫入幀緩沖區,我們會在下一幀看到剛剛處理過的最新畫面了

繼續閱讀