《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》——6.5节光照的每顶点计算与每片元计算...
本節書摘來自異步社區《OpenGL ES 2.0游戲開發(上卷):基礎技術和典型案例》一書中的第6章,第6.5節光照的每頂點計算與每片元計算,作者 吳亞峰,更多章節內容可以訪問云棲社區“異步社區”公眾號查看
6.5 光照的每頂點計算與每片元計算
OpenGL ES 2.0游戲開發(上卷):基礎技術和典型案例
細心的讀者會發現,本章前面的案例都是在頂點著色器中進行光照計算的。這是由于在頂點著色器中對每個頂點進行光照計算后得到頂點的最終光照強度,再由管線插值后傳入片元著色器以計算片元的顏色,這樣一方面效率比較高;另一方面產生的光照效果也不錯。
但由于這種計算方式插值的是基于頂點計算后的光照強度,因此在要求很高,希望有非常細膩光照效果的場合下就略顯粗糙了。本節將介紹另一種光照計算方式,其首先將插值后的法向量數據傳入片元著色器,然后在片元著色器中進行光照計算。這種新的方式也稱為每片元光照,可以取得為更細膩的光照效果。
進行案例開發之前需要首先了解一下本節兩個案例(Sample6_9和Sample6_10)的運行效果,具體情況如圖6-21所示。
圖6-21中左側是每片元計算一次光照的案例Sample6_9的運行效果,右側是每頂點計算一次光照的案例Sample6_10的運行效果。從兩幅圖的對比中可以看出,每片元執行一次光照使過渡更平滑,沒有明顯的邊緣。另外,僅從圖上觀察可能區別還不是很明顯,筆者建議讀者用真機運行一下兩個案例,將光源設置在不同的位置觀察比較,區別會更明顯。
了解了兩個案例的運行效果后,就可以進行開發了。實際上這兩個案例主要是將前面6.2.5小節中的案例Sample6_5復制并修改了部分代碼而成的。其中Sample6_10僅修改了Java代碼中切割球面的角度以及繪制球體的次數,沒有本質變化,這里不再贅述,需要的讀者請參考隨書光盤中的源代碼。
而案例Sample6_9除了也進行了Sample6_10的Java代碼改動外,還大面積修改了頂點著色器與片元著色器,具體情況如下所列。
(1)首先介紹Sample6_9中修改后的頂點著色器,其具體代碼如下。
1 uniform mat4 uMVPMatrix; //總變換矩陣 2 attribute vec3 aPosition; //頂點位置 3 attribute vec3 aNormal; //法向量 4 varying vec3 vPosition; //用于傳遞給片元著色器的頂點位置 5 varying vec3 vNormal; //用于傳遞給片元著色器的法向量 6 void main(){ 7 gl_Position = uMVPMatrix * vec4(aPosition,1);//根據總變換矩陣計算此次繪制此頂點位置 8 vPosition = aPosition; //將頂點的位置傳給片元著色器 9 vNormal = aNormal; //將法向量傳給片元著色器 10 }從上述代碼中可以看出,頂點著色器比改動前簡單多了,沒有了計算光照的大量代碼,同時增加了將法向量通過易變變量傳入片元著色器的代碼。
(2)介紹完頂點著色器后,接著就應該介紹改動后的片元著色器了,其具體代碼如下。
讀者應該發現,上述片元著色器中的很多代碼都是本章前面案例中多次出現過的,只不過前面的案例中都是在頂點著色器中出現,而這里挪到了片元著色器中。因此,每片元計算光照與每頂點計算光照算法并沒有本質區別,只是代碼執行的位置不同、效果與效率不同而已。實際開發中讀者應該權衡速度、效果的要求,選用合適的計算策略。
總結
以上是生活随笔為你收集整理的《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》——6.5节光照的每顶点计算与每片元计算...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDOJ-1257 最少拦截系统
- 下一篇: unity 罗技G29开发