注:文章譯自http://wgld.org/,原做者杉本雅広(doxas),文章中假設有個人額外說明,我會加上[lufy:],另外,鄙人webgl研究還不夠深刻,一些專業詞語,假設翻譯有誤,歡迎你們指正。javascript
本次的demo的執行結果
java
高氏着色從名字上看,是比較難明確詳細是什麼樣的着色的,這個高氏(gouraud)事實上是以研究該着色的Henri Gouraud來命名的。web
lufy:高氏着色又叫高洛德着色或高氏渲染(Gouraud Shading):這是一種光影渲染技術也是眼下較爲流行的着色方法,它可對3D模型各頂點的顏色進行平滑、融合處理,將每個多邊形上的每個點賦以一組色調值,同一時候將多邊形着上較爲順滑的漸變色,使其外觀具備更強烈的實時感和立體動感,只是其着色速度比平面着色慢得多但是效果要好得多。函數
高氏着色可以對多邊形的頂點之間的顏色進行補間,高氏着色的計算負荷並不是過高,但是,可以實現很是美麗的渲染,因此經常被使用。webgl
對頂點間的顏色進行補間是什麼意思呢?ui
簡單的說,用高氏着色計算獲得的終於的顏色情報,適用於全部頂點,並且對頂點和頂點之間的顏色進行補間處理,最後渲染模型。spa
使用高氏着色,想用少許的頂點渲染美麗的光照是很是難的。比方說,一個最簡單的三角形多邊形,三維空間中僅僅有這一個三角形,這個面就直接和光碰撞了。.net
放射性光源的時候(比方說燈泡),應該是三角形的中心就最亮,而頂點的部分要略微暗一些,但是高氏着色僅僅是在頂點之間進行顏色補間,因此沒法凸顯三角形中間的亮點。
另外,因爲是依據每個頂點進行顏色補間,顏色變化的時候會出現鋸齒。這個鋸齒隨着頂點數的增多而逐漸消失,但是這麼作的話,高氏着色計算負荷小的優點就沒有了,因此這是個難處理的地方。翻譯
細心的朋友可能會發現,這個站點中全部的demo,都是用的高氏着色。頂點着色器的光的強度和顏色的進行計算,而後僅僅是將終於算出的顏色傳給了片斷着色器,這樣的依據每個頂點來計算顏色的方法就是高氏着色。
如下是證據,眼下爲止的demo中的顏色之間會存在鋸齒,會有一些不太天然的鏡面反射。code
擴大以後看的話就比較清楚了吧,頂點數越少,這樣的現象就越明顯。
因爲補色着色是在像素之間對顏色進行補間,因此不會發生不天然的鋸齒。如下是和高氏着色的渲染效果作比較。
全然是一樣的頂點數,一樣的光源渲染出的補色着色和高氏着色。左邊是補色着色,無論陰影仍是高亮的部分,都很是的美麗和天然。
attribute vec3 position; attribute vec3 normal; attribute vec4 color; uniform mat4 mvpMatrix; varying vec3 vNormal; varying vec4 vColor; void main(void){ vNormal = normal; vColor = color; gl_Position = mvpMatrix * vec4(position, 1.0); }
precision mediump float; uniform mat4 invMatrix; uniform vec3 lightDirection; uniform vec3 eyeDirection; uniform vec4 ambientColor; varying vec3 vNormal; varying vec4 vColor; void main(void){ vec3 invLight = normalize(invMatrix * vec4(lightDirection, 0.0)).xyz; vec3 invEye = normalize(invMatrix * vec4(eyeDirection, 0.0)).xyz; vec3 halfLE = normalize(invLight + invEye); float diffuse = clamp(dot(vNormal, invLight), 0.0, 1.0); float specular = pow(clamp(dot(vNormal, halfLE), 0.0, 1.0), 50.0); vec4 destColor = vColor * vec4(vec3(diffuse), 1.0) + vec4(vec3(specular), 1.0) + ambientColor; gl_FragColor = destColor; }
另外,補充一點,此次的demo中對圓環體的生成函數作了幾處改動,返回值是以對象的形勢返回的,可以指定圓環體的顏色了。事實上,也並無作什麼其它特別的處理。
用補色着色來渲染的圓環體