1. 程式人生 > >Unity3D的著色器介紹(一)—軟渲染和著色器原理

Unity3D的著色器介紹(一)—軟渲染和著色器原理


              由於講圖形渲染這樣的東西比較抽象,而且結合三維數學方面的知識比較多,我自己的理解也不一定正確,所以先試寫一篇看看。如果有什麼意見,請在評論裡指出。
           一開始先講些理論性的東西吧。要講著色器,我覺得很有必要先說一下著色器是怎樣工作的。
在不知道什麼是著色器的前提之下,也沒有任何的三維引擎的幫助,假如我們需要渲染顯示下面一個立方體,我們需要怎樣做呢?




            如果只有得到這個立方體的8個頂點的座標,沒有其他任何的條件,我們是無法渲染顯示的,因為一個存在於空間中的三維物體,我們從不同的角度去觀察,看到的樣子是不一樣的,比如我們從camera1和camera2兩個不同的位置去觀察這個cube:





會得到不同的結果:




             這是因為我們我們在不同的角度觀察同一個物體時,物體投影在我們的視網膜上的點的位置是不一樣的。(由於只是介紹原理, 而不打算在這裡介紹一個引擎的寫法,所以我只會大概講一下實現的過程,而具體的演算法不在此討論範圍。)




從這裡可以得知,渲染一個模型的形狀,必要的條件是兩個:
1、模型各個點在世界空間的座標
2、我們觀察的角度。



           我們撇開整個模型,只觀察由P1、P3、P4組成的三角形,通過一定的演算法,我們可以計算出三個點分別投影在Camera1和Camera2上面的座標。






        當計算出了這三個點在投影上面的座標後,基本上我們就可以把模型的位置給渲染出來了,比如P1、P3、P4構成的三角形,我們只需要把它填滿紅色,就形成了三維物體在我們的眼中的渲染位置了。

由於我們現在所用的多邊形渲染方式都是以渲染三角形為基礎的,所以我們能渲染一個三角形,就能同理類推,把整個三維模型渲染出來。

一般來說,我們的三維模型都不止是純顏色的,比如這個立方體我們可以貼上一張汽車的貼圖。





         還是留意P1、P3、P4組成的三角形。在確定了三個點在投影的位置之後,三角形範圍內的畫素點應該顯示怎樣的內容?
這是我們渲染需要考慮的第二個問題。




            通常關於貼圖型別的顯示,我們需要知道這張貼圖的某個位置是對應著渲染的三角形的某個位置。這個位置的對應關係,是通過UV座標來表達的。通過UV座標,我們就能知道從P1到P3範圍的畫素點,是從貼圖的某個位置到某個位置,然後按照一定的比例縮放,從圖片上取得了該畫素點應該顯示的顏色。










                通過上面的2個步驟,我們首先知道了怎樣確定模型的點在投影面上的位置,然後知道了怎樣確定由點組成的三角形內的每個畫素點的顏色。到了這一步,實際上整個三維模型已經被渲染出來了。
最後一個問題是,通過畫素點離投影面的距離,求出面之間的疊加關係,這是深度排序的問題,暫時不在這裡討論。
以上整個過程,就是所謂的軟渲染。在沒有任何三維引擎的幫助下,我們就可以把一個三維模型從一堆資料裡面顯示出來。
至於三維引擎裡面的動畫渲染,其實步驟就是如下:


每次進入一幀:
1、清除畫布,把上一幀留下的畫面清除;
2、求出所有點在投影面的座標;
3、求出每個畫素的顏色值;
4、渲染出來。
結束渲染

              說了這麼多軟渲染的原理,有些朋友會說,這究竟和著色器有什麼關係呢?其實這個過程,正是著色器的工作過程。
一般來說,著色器會分為頂點著色器和片段著色器兩個部分。
頂點著色器要做的事情,其實就是第一個步驟,求出各個頂點在投影面的座標。所以傳進去的值需要有頂點的三維座標,還需要有攝像機的位移旋轉矩陣。
片段著色器需要做的事情,就是第二個步驟,通過給出的資料,結合從頂點著色器得到的座標值,計算出每一個畫素點應該顯示的顏色值。所以傳進去的值,會預設包括了頂點程式的座標,然後我們給予的貼圖資訊、顏色資訊和UV座標資訊。
片段著色器是針對於每個畫素點的,所以片段著色器的輸出,就是該畫素點應該顯示的顏色值。
最後提交給顯示卡,改變螢幕上的每一個畫素點的顏色,得到我們想要的畫面。

              於是,我們就可以通過編寫頂點著色器程式,通過一定的方式去改變頂點在投影面的座標,讓模型變形;或者通過編寫片段著色器程式,讓模型表現出來的顏色根據我們的需要而改變。
               瞭解了著色器的整個工作過程之後,應該會覺得實際上著色器也不是一個非常神祕的東西吧?