初探Stage3D(一) 3D渲染基礎原理

關於本文

本文主要想介紹一下3D渲染的基本流程,及怎樣把一個三角形(0,1,0),(1,0,1),(0,0,1)最終渲染到屏幕上來。文章的目的是對3D渲染流程作一個簡單的介紹,其中不涉及任何語言的APIhtml

參考資料算法

 

局部座標和世界座標編程

接觸Flash的人應該不太難理解這個概念吧,好比在庫中創建一個邊長爲50的正方形,設置其左上角爲原點,局部座標的(0,0)爲原點測試

pic1pic2

而後將其拖入Flash的主舞臺上面之後,就會獲得一個全局座標(84,110).net

pic3pic4

那剛纔拖動的一下操做,完成的是怎樣的一個運算呢?3d

拋開填充的藍色先不談,那麼幾何上面來講,正方形是由4個點構成的,A(0,0) B(0,50) C(50,0) D(50,50)htm

剛纔作的操做能夠理解把該正方形拖放到舞臺的(84,100)位置。對應的獲得ABCD四點座標分別爲A’(0+81,0+100) B’(0+84,0+50) C’(50+84,0+100) D’(50+84,50+100)blog

這樣也就是完成了一次局部座標到世界座標的轉換遊戲

那一樣的道理,對於一個3D座標點A(0,0,0) 也能夠執行一次座標變換,好比(84,100,37),這樣也能獲得一個對應的3D座標點A’(0+81,0+100,0+37)遊戲開發

 

爲什麼要進行局部座標到世界座標轉換

在日常咱們作Flash時候也同樣,好比要作一個小人站在房子邊上的圖,那確定是單獨創建兩個元件 元件::小人 元件::房子 ,而後將其拖入主舞臺拼湊在一塊兒。3D中也是同樣的各類物體也是如今本身的座標系內製做好,

最後放入場景內進行的拼接

 

瞭解矩陣

在進一步介紹3D以前,首先須要瞭解一下矩陣。原本想給出一些本身的例子,不過參考了一下現有資料,發現沒有太多好補充的東西。若是對矩陣的基本改變還不是很瞭解

(好比矩陣是作什麼用的,矩陣相乘,旋轉矩陣,平移矩陣等)

請參考以下部分

《3D遊戲編程大師技巧》 P161~P165

《3D數學基礎:圖形與遊戲開發》 P85~P107

 

攝像機&視景體

在把全部物體完成了從局部座標系到全局座標系的轉化,及完成了構建一個3D場景,只是這個場景中所有是由點構成的。這個時候就須要引入攝像機的概念,攝像機就像一雙在這3D世界中的眼睛,眼睛的位置不一樣,

看的方向不一樣,那最終看到的景象也就不一樣.

和現實世界中的攝像機稍微有些不一樣,在於須要給這個攝像空間定義一個區域,及近剪裁面和遠剪裁面。也就是小於近剪裁面和大於遠剪裁面的物體將不會被渲染

pic6_thumb

pic8_thumb

在遠剪裁面以外的物體: 能夠理解爲即便渲染了該物體也會是一個點,因此不進行渲染。在玩兒一些早期的3D遊戲時候有時候會出現這種狀況,一直向前走,前方的建築物會忽然從遠處出現,我想也是這種緣由吧

在近剪裁面以外的物體: 若是渲染的話會是一個很是大的物體,因此也不進行渲染。(近剪裁面若是用現實中的相機作比喻彷佛不是很容易理解,當時若吧這個放入數學定義中去理解,反而容易一些)

 

世界座標到相機座標的轉換

當肯定好視景體後,也就能夠肯定了哪些物體最終能夠見,哪些是不能夠見。剔除這些不可見的物體後,須要將其他物體進行世界座標到相機座標的轉換。

在一種極端狀況下是不須要進行該步驟的,就是相機在原點(0,0,0)且方向和座標軸的方向是一致的,此時不須要再進行轉換

pic9

可是大部分時候,相機實際上是不在原點的,且所朝的方向也不是座標軸方向。

pic10

此時就要對這些物體(物體的每一個頂點)進行世界座標到相機座標的變換。

變換一共分爲幾個步驟,

第一步 平移

pic11

如圖,也就是假設相機的座標點爲(cam_x,cam_y,cam_z),那對全部剩餘物體的頂點均執行平移操做(world_x-cam_x,world_y-cam_y,world_z-cam_z)

平移矩陣

第二步 旋轉

此時相機已經處於座標原點處了,不過相機鏡頭仍舊是歪的,仍舊須要對其進行x,y,z三方向旋轉才能夠將相機還原爲最開始那張圖所畫的樣子。

旋轉相機

對於先旋轉哪一個,後旋轉哪一個是無所謂的。及按xyz仍是zyx方向旋轉都是同樣

最終流程:

代碼

 

爲什麼要進行相機座標轉換

若是還不是很理解爲什麼要進行相機座標轉換,能夠再回到2D世界,仍是最先的例子,那個正方形A(0,0) B(0,50) C(50,0) D(50,50) 通過的局部到世界座標的轉換是A'(0+81,0+100)  B'(0+84,0+50)  C'(50+84,0+100) D'(50+84,50+100)

A'點也就是爲(0+81,0+100)->(81,100)

此時若是假設你本身就是相機,眼睛和舞臺的0,0點對齊,眼部和顯示器距離爲300,那麼A'點在你眼中的三維座標也就是(81,100,300)

此時也就是以前所說的極端狀況,攝像機和全局座標同軸且共相。那A'點(81,100,300) 也就是最終渲染到屏幕上面的座標點,可是

若是此時你離開顯示器一段距離,且歪一下腦殼,再看A'點(81,100,300),這時候其所在你本身眼睛(攝像機)中的位置就不是原來那個位置了,

假設此時你看到的景象是M,

那你能夠想象此時你回到原位,而後有另一我的,抱起你的顯示器放在另一個位置且稍微轉一個角度

此時你看到的景象仍舊是M,

那我的對那個物體進行的操做(抱起來放邊上且轉了一個角度)就是相機座標變換

 

物體剔除&背面消除

這塊知識我想簡單的說一下,在《3D遊戲編程大師技巧》 裏面有很是詳細的說明

物體剔除:

物體剔除在2D中也是存在的,對一個物體進行包圍盒測試,若是再也不場景內則不顯示該物體,3D中也是作一樣的操做,只不過包圍盒是三維的,且探測範圍也再也不是一個平面,而是整個視景體。

背面消除:

當一個物體確實是在視景體內部時候,也不是全部面均須要最終渲染出來,此時要作的就是背面剔除,將那些被徹底擋住的平面剔除出去

 

爲什麼要進行剔除

在渲染流程的前段步驟,全部操做均是針對點的,好比座標轉換,剔除等.當最終肯定了一個面確實要被渲染之後。後半段的操做及要對該面進行着色(設置紋理),光照處理等。

因此若是能夠在前期多剔除掉一個面,就應該多剔除一個。

 

透視變換

當完成了一切剔除操做後,對於剩下的平面(此時剩餘的僅爲一個個平面了),還須要進行透視變換。也就是將一個三維點A'(81,100,300) 變換爲一個二維的座標點。

這裏面的轉換涉及兩種

正交投影

正交投影

來源 http://baike.baidu.com/view/3153027.htm

這種投影比較簡單,及直接去除z點的值便可,通常用在工業製圖上面(AutoCAD),對於Starling(Flash上面使用Stage3D技術加速2D遊戲的引擎),目前我還不是很瞭解。不過爲本身寫的一個Demo,投影選擇的就是

正交投影。由於本來須要渲染的就是一個2D平面,只要其在視景體內,其大小就和所在位置無關了

透視投影

透視投影

來源 http://baike.baidu.com/view/1318206.htm

透視投影及實現了近大遠小的投影,及離攝像機距離較遠的物體看起來會相對小一些,離攝像機進的物體看起來更大一些。和真實世界中看到的是同樣的。在三維遊戲中用到的均爲這種投影

 

二者的區別下面這張圖很好的標示出來

pic7

左面的爲透視投影,右面的爲正交投影

 

總體流程概覽

3D渲染流程上面大致就是這樣了

總體渲染流程

圖中在背面消除後採起了兩種方式,

B路線爲畫家算法(http://baike.baidu.com/view/2020287.htm),

A路線爲在常規的物體消除後再進行一次空間剪裁(及把那些不是徹底在視景體內部的元件再剪裁,及AABB測試壓線的物體)

可是不管是通過A路線,仍是B路線 最終剩餘的平面就會開始光柵化(忽略屏幕座標變化,具體的請看書)。及真正的對其進行着色,打光等操做了

 

本文和Stage3D的關係

首先請閱讀兩篇文章

GPU大百科全書第二章 凝固生命的光柵化 http://vga.zol.com.cn/236/2366808.html

How Stage3D works http://www.adobe.com/devnet/flashplayer/articles/how-stage3d-works.html

看完這兩篇文章之後能夠看出,本文其實只是大致上面說明了一下3D渲染的基本過程,可是和目前真正的技術(我參考的資料已是十幾年前的東西了吧)仍是有必定出入的,

Stage3D最相關的東西也就是這張圖中的

Stage3D

VertexShader 還有 FragmentShader(也就是Pixel shaders)

我在初探Stage3D(二) 瞭解AGAL中作了一些說明,

VertexShader 主要做用就是3D流程中的前半段操做(對頂點進行一系列的矩陣變換)

FragmentShader 操做是對這些變換後的頂點(及流程中的光柵化部分)進行渲染

相關文章
相關標籤/搜索