XNA是使用DirectX 9Rendering pipeline來繪製圖形,而下圖就是一個簡單的概觀:

接下來就針對這些區塊的來做簡介。

Vertex Data(頂點資料):

Vertex Data他是一個Buffer,用來儲存頂點的資訊,包含像是頂點的座標(position)、頂點的法相量(normal)、頂點顏色(color)和貼圖座標(texture coordinate)等。在XNA中你可以用VertexDeclaration來描述上述的資訊,而這些頂點的資料將會被放到VertexBuffer中。

        Primitive Data:

        這邊主要提供的概念就是Index Buffer,而Index buffer就是用來決定幾何圖形的連接順序。

3D世界中,所有的模型都是幾何資料組成,像是點(point)、線(line)、三角形(triangle)等等,而Index buffer儲存的就是頂點位置,然後在pipeline中,會依據index buffer的順序,將頂點給組合起來,像是點、線、三角形或是多邊形等。

而當然使用者可以不指定Index Buffer,然後他就會用預設的方式去做連結,而這個結果可能是你無法預期的,所以我們通常將頂點設定完畢以後,會在設定Index Buffer設定連結順序。

        EX:

        Vertex Buffer:

        1 2 3 4…

        a b c d…(這些就包含座標、法向量、貼圖座標等)

    Index Buffer:

        1 2 3 4 5 6

        1 2 3 1 3 2

        就可以得到以下圖形的連接方式:

這邊我只是概略的簡介想法,當中這邊涉及很多內容,像是甚麼是front face,還有就是使用的座標系等等。

Front face:

        3D空間中,我們可以由三個點可以組成一個平面,而每個平面都會有法向量(normal),而所謂的Front face就是指,法向量方向跟眼睛觀察的方向的內積結果為負值,則該平面就是Front face。如下圖:

3D座標系的部分分為兩種,左手座標系跟右手座標系兩種。(DirectX使用左手座標系)

 

Vertex Processing:

        這個階段會接收Vertex dataPrimitive data的資訊內容。在這個階段,這邊會包含一個Shader(著色器) – Vertex shader,這是一個可程式化的操作,而XNADirectX使用的Shader語言是HLSL(High level shader language)

        在傳統的Rendering pipeline中,我們只能接收頂點,然後再將它畫到畫面來,無法針對頂點去做操作,像是改變顏色之類的,這些操作根本不可能做到。而有了Vertex Shader以後,現在我可以對Normal或是頂點顏色,去做些計算改變。打破了以往很多都要先在CPU計算完畢以後再送入Pipeline的情況。

        同時,這邊還會去做一個計算,也就是將Local的點,轉換至World coordinate上。(因為每個模型都會有一個Local coordinate的點座標,所以我們需要經由一個轉換,轉換至World coordinate上,而所有的3D物件,都會在相同的世界座標系上面)。這個轉換就包含了View matrixprojection matrix等。

View matrix做的事情主要就是將,Camera的位置移動到原點上面,讓Camera成為座標系的原點,而當然全部場景也會跟著一起轉換,如下圖:

進行這種轉換的好處:

  1. 在後面做projection的時候比較方便。
  2. 方便做Clip的動作,clip指的就是將View frustum之外的物件移除掉。如下圖:

Projection matrix就是將View Frustum normalize,也就是將它的範圍變到[-1, 1],稱為unit cube或是canonical。如下圖:

        所以,在Vertex processing中,我們可以去對頂點去做處理。

 

        Geometry Processing

        這邊做的事情包含上面所說的Clipback face cullingrasterization等。

        Clip: 將在View Frustum之外的polygon給切掉。因為那些部分不會被畫出來,所以我們先把它移除掉。之後的所有處理都不會在計算他們。

        Back face culling: 上面有解釋過甚麼是front face,而這邊做的事情就是將Back face的部分剔除掉。

        上面兩個操作,都是為了降低計算量,因為這些多邊形使用者並不能看到,所以我們先將它處理掉,這樣後面就不用再去計算它。

        Rasterization: 到目前為止我們現在接收到的是primitive,也就是只有頂點和邊的連接。以三角形當作連接方式來說,rasterization接收的資料就是三角形(三個頂點),而我們要把它畫到螢幕上的話,就會有一個問題產生,螢幕上是pixel,我們將三角形切成一個一個的pixel,並且內插它的座標、貼圖座標和法向量等。然後在將這些pixel(fragment)送往下一個階段進行計算。

 

        Texture sampler:

        這邊的操作會由pixel processing中的Shader來存取貼圖。

 

        Pixel processing:

        包含一個shader – pixel shader,針對現在接收進來的Pixel去做一些計算,像是貼圖和打光等等。

 

        Pixel rendering:

        這個階段有些Test的機制,使用者可以用這些Test來做些操作。

  1. Alpha test: 進行Alpha的透明度測試,可能會需要用到混色的效果。
  2. Depth test: 進行深度上的測試,因為在現在的volumn中,包含了很多的pixel,而我們在乎的就是最前面的部分,因為這個部分是使用者可以看到的,所以經由這個test我們可以獲得到使用者可以看到的深度值。如下圖:

  1. Stencil test: 模板測試,指定現在這個畫面中甚麼Pixel可以畫到螢幕上面。

這三個Test的操作流程為

  1. 先檢查看看現在這個畫面中的Pixel是不是通過Stencil test
  2. 如果通過以後,在檢察alpha test,這邊做這個檢查的好處是,因為透明的物件也是會有深度的影響,所以我要先檢查這個部分,在做深度測試,先排除掉透明的物件,以免影響到深度的測試。
  3. 深度檢察,計算遮擋效應。

 

完成這些操作以後,就會將畫面畫到螢幕中的畫面。

上述的pipelineXNA使用DirectX 9.0Pipeline,而下張圖片是貼出目前最新的DirectX 11 Pipeline:

        先簡介Geometry shader,在這邊使用者可以新增頂點或是刪除頂點等的操作,這些操作在以前9.0pipeline是無法做到的,而有了geometry shader,現在我們可以對一個粗糙的模型,去做細緻的動作(讓模型看起來更細緻,這邊有一個詞叫做tessellation)

        上面的geometry shader是在DirectX 10中所提出。

        11新增兩個Shader - Hull shaderDomain shader,用來增強tessellation的部分。

 

最後就是跟大家說一下,XNA在360上面的限制。

XNA的遊戲專案如果你要部屬到360上面,你不可以用到P-Invoke的pointer。

而甚麼是P-Invoke,也就是所謂的platform invoke,是用unmanage code來撰寫的dll檔案。

而用.net framework寫的DLL檔案就是manage code,而要傳送到360上面的話,需要是用manage code才行。

這個限制僅限於360,PC上面是沒有關係的。

 

檔案下載: http://140.126.21.8/~teexit/xna/pic/Rendering/render%20pipeline.pdf

創作者介紹
創作者 teexit1224 的頭像
teexit1224

StreamWhite

teexit1224 發表在 痞客邦 留言(0) 人氣()