3D引擎的基本功能是將三維空間中的物體,經過一些變換和處理,映射到二維屏幕上。
要理解這一過程,3D圖形程序員,不管是3D引擎的maker還是user,都必須徹底理解從3D空間映射到2D平面需要的變換過程,特別是背后蘊含的數學原理。網上有不少介紹的文章,有的蜻蜓點水,有的專注于某一方面,幾乎沒有人能夠或者愿意全面、徹底的,以面向初學者的口吻來解釋其中的機理,這篇文章嘗試來做這件事,借此機會順便鞏固下自己的圖形學基礎。
經典的OpenGL固定渲染管線變換流程,如下圖所示,雖然目前的3D圖形API(OpenGL和Direct3D )都已經采用了可編程的渲染管線,但變換的思路都是一樣的。
gl_tranformation.png
坐標變換的基本流程是:
object
物體坐標系 ->world
世界坐標系 ->camera
視覺坐標系 ->clip
裁剪坐標系 ->normalized device
規范化設備坐標系 ->window
窗口坐標系。
初學者看到這,別說理解,就是去強記也很費勁,但3D引擎并非街頭小食,讓我們有點耐心,一點點啃吧。
-
object
坐標系
描述某一個物體
的坐標系, 和world
坐標系 描述 整個世界
相比,它是一個局部
坐標系, 只負責描述某一個物體。因為是建模時采用的坐標系,也常稱之為模型坐標系
。這里的物體
,在3D引擎
的語境里,主要是指mesh
、camera
等 對象。mesh
有兩種,靜態網格
和骨架網格
,一般由 3DS Max,Maya等建模軟件制作并導入。
關于object
坐標系,網上不少教程、文章寥寥幾句帶過,對初學者來說,原理雖然簡單,細節還是不少的,我試著從中心點、方向、坐標單位三個方面一一闡述。
- 中心點
一般來說,object
坐標系的中心點會選擇物體的中心點,也可以是物體底部的中心點, 主要是為了方便使用。舉例來說,球體的坐標系中心點一般選擇在球心,而路燈,建筑的坐標系中心點則會選擇位于底部中心。 - 方向
object
坐標系方向選擇是任意的,但一般的習慣是,將XY平面作為水平面,Z軸表示垂直方向 或者 XZ平面作為水平面,Y軸表示垂直方向。此外,要特別注意左右手坐標系。OpenGL API 接受右手,Direct3D是左手。3D引擎
, 會選擇其中一個規則,而在底層作Z軸翻轉適配即可。 - 單位
object
坐標系取米或厘米。但某些特殊的場景,需要考慮浮點數表示精度,IEEE754
規則:float
有效數字6-7 位,double
15 -16 位。舉例來說,在最小精度厘米的情況下,你打算給一個方圓幾十甚至上百公里城市建筑整體建模,用float
肯定不合適,當然用double
,也顯得浪費。3D引擎
的精度的選擇,遵循夠用就好,高精度意味著性能損失,不要輕易的采用double
,特別是在性能和耗電量極其敏感的移動端。 實際開發中,給城市這種大規模靜態物體
建模,會將它分成一塊塊的tile
,每塊tile
一平方公里面積, 這種情況下,float
足夠了。
- 通過
模型變換
將object
坐標空間變換到world
坐標空間
模型變換有 縮放、旋轉、平移,接下來,龐大的數學開始了, 整理下思路,待續...
最近太忙了,仔細想了下,要寫透的話,這篇文章字數會很長。。。