在之前這篇文章,
WebGL 單通道wireframe渲染
我們介紹了webgl如何實現單通道wireframe的效果。
本篇文章就是在此技術原理基礎之上,來實現發光的wireframe效果。
要實現發光的效果
所謂的發光的效果,就是顏色的漸變。 漸變越慢,發光的效果越明顯,漸變越快,發光效果越不明顯。
其實wireframe本身就是在兩種顏色之間進行漸變,從代碼也可以看出:
gl_FragColor.rgb = mix(vec3(.0,.0,.0), vec3(1.0,1.0,1.0),edgeFactor3());
其中edgeFactor3() 就是通過重心坐標的變換計算出來的一個漸變過度的參數。
但是由於這種漸變的效果不夠慢,所以 發光的效果不是很明顯,因此我們可以改進如下效果,把漸變的參數通過pow函數進行處理,代碼如下:
float interopter = edgeFactor3();
interopter = pow(interopter, uPower);
gl_FragColor.rgb = mix(vec3(1.0,.0,.0), vec3(1.0,1.0,1.0),interopter);
其中uPower表示pow函數的次方,此處取值范圍0~1,通過uniform變量傳遞該變量的數值,最終的效果如下:

上面是既有線框部分,也有面的部分。如果想實現只有線框的效果,可以啟用透明的機制,並對顏色的透明度也進行漸變插值運算,透明設置代碼如下:
// 啟用混合功能
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.disable(gl.DEPTH_WRITEMASK);
// 設置混合函數
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
shader代碼增加以下的這行代碼:
gl_FragColor.a = mix(1.0, .0,interopter);
效果如下圖所示:

如果模型替換成球形,效果如下:

加載模型的效果如下:

如果修改shader中的edgeFactor3函數,把計算最小值,改為計算平均值,代碼如下:
float edgeFactor3(){
vec3 d = fwidth(vBarycentric);
vec3 a3 = smoothstep(vec3(0.0), d * 30.0 , vBarycentric);
//return min(min(a3.x, a3.y), a3.z);
return (a3.x + a3.y + a3.z) / 3.0;
}
得到最終的效果如下圖所示(立方體):

替換成模型,效果如下:

如果結合混合模式中的相加混合,加上多個模型的疊加,可以得到更明顯的發光疊加的效果,此種效果經常用於智慧園區,智慧樓宇中樓宇的發光效果呈現。
首先把混合模式改成相加混合,代碼如下:
// 設置混合函數
// gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE); //相加混合模式
然后同時繪制多個模型,代碼如下:
for (var i = 0;i < 10;i ++){
gl.uniform1f(normalProgram.uScale, 1 - i/10)
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
}
最終的效果如下所示:



本文也發表在我的webgl專欄,相關代碼可以在專欄中獲取:
https://xiaozhuanlan.com/topic/0614325798
案例視頻 可以關注視頻號 "ITman彪叔"觀看,也歡迎關注公眾號。

