天天看點

《OpenGL ES 2.0遊戲開發(上卷):基礎技術和典型案例》一6.5 光照的每頂點計算與每片元計算

本節書摘來異步社群《opengl es 2.0遊戲開發(上卷):基礎技術和典型案例》一書中的第6章,第6.5節,作者: 吳亞峰 責編: 張濤,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

opengl es 2.0遊戲開發(上卷):基礎技術和典型案例

細心的讀者會發現,本章前面的案例都是在頂點着色器中進行光照計算的。這是由于在頂點着色器中對每個頂點進行光照計算後得到頂點的最終光照強度,再由管線插值後傳入片元着色器以計算片元的顔色,這樣一方面效率比較高;另一方面産生的光照效果也不錯。

但由于這種計算方式插值的是基于頂點計算後的光照強度,是以在要求很高,希望有非常細膩光照效果的場合下就略顯粗糙了。本節将介紹另一種光照計算方式,其首先将插值後的法向量資料傳入片元着色器,然後在片元着色器中進行光照計算。這種新的方式也稱為每片元光照,可以取得為更細膩的光照效果。

進行案例開發之前需要首先了解一下本節兩個案例(sample6_9和sample6_10)的運作效果,具體情況如圖6-21所示。

《OpenGL ES 2.0遊戲開發(上卷):基礎技術和典型案例》一6.5 光照的每頂點計算與每片元計算
說明 圖6-21中左側是每片元計算一次光照的案例sample6_9的運作效果,右側是每頂點計算一次光照的案例sample6_10的運作效果。從兩幅圖的對比中可以看出,每片元執行一次光照使過渡更平滑,沒有明顯的邊緣。另外,僅從圖上觀察可能差別還不是很明顯,筆者建議讀者用真機運作一下兩個案例,将光源設定在不同的位置觀察比較,差別會更明顯。

了解了兩個案例的運作效果後,就可以進行開發了。實際上這兩個案例主要是将前面6.2.5小節中的案例sample6_5複制并修改了部分代碼而成的。其中sample6_10僅修改了java代碼中切割球面的角度以及繪制球體的次數,沒有本質變化,這裡不再贅述,需要的讀者請參考随書CD光牒中的源代碼。

而案例sample6_9除了也進行了sample6_10的java代碼改動外,還大面積修改了頂點着色器與片元着色器,具體情況如下所列。

(1)首先介紹sample6_9中修改後的頂點着色器,其具體代碼如下。

提示 從上述代碼中可以看出,頂點着色器比改動前簡單多了,沒有了計算光照的大量代碼,同時增加了将法向量通過易變變量傳入片元着色器的代碼。

(2)介紹完頂點着色器後,接着就應該介紹改動後的片元着色器了,其具體代碼如下。

讀者應該發現,上述片元着色器中的很多代碼都是本章前面案例中多次出現過的,隻不過前面的案例中都是在頂點着色器中出現,而這裡挪到了片元着色器中。是以,每片元計算光照與每頂點計算光照算法并沒有本質差別,隻是代碼執行的位置不同、效果與效率不同而已。實際開發中讀者應該權衡速度、效果的要求,選用合适的計算政策。