寫一個發光材質
來自專欄 360企業安全可視化實驗室
在繪製三維圖形的時候,不論是三維建模軟體還是Three.js都提供了很多現成的材質,可供開發者選擇,如Lambert材質、Phong材質、法向材質等。然鵝在做開發時,這些材質往往不滿足設計需求,比如發光材質就是設計常用的材質,那麼如何寫出一個透明發光材質呢?
分析透明發光材質的特點,它是在三維圖形結構的邊緣處顏色不透明度越高,向內不透明度逐漸降低,其著色跟視角方向強相關。
敲黑板~ 這是一個經典的菲涅爾反射問題。菲尼爾反射描述了一種光學現象,即當光纖照射到物體表面上時,部分光發生反射,部分光發生折射或散射,反射的光和入射的光存在一定比例關係,這個關係可用菲涅爾等式計算。常見的例子如站在湖邊,腳邊的湖面的水是透明的,可以看到水底的石頭,遠處的湖面是看不到水下物體的,只能看到水面反射的結果。
常用的菲涅爾近似等式有:
其中 是一個反射係數,用來控制反射的強度, 是視角方向, 是法線方向。
我們用的是另一個廣泛應用的等式:
其中 、 和 是控制項。
看圖說話:
令歸一化的法線方向為 ,視角方向為 ,那麼有表面的透明度與 成反比。當 接近 0 時,越不透明,接近 1 時,越透明。
簡化後的代碼有:
void main() { float a = pow( bias + scale * abs(dot(vNormal, vPositionNormal)), power ); gl_FragColor = vec4( glowColor, a ); }
其中bias值決定了顏色最亮值的位置,power決定了透明度變化速度及方向。
下圖為bias取1.0,power取2.0的效果,scale取-1.0。
同理,下圖為bias取 0,power取2.0,scale取1.0。
此處注意,vNormal的normalMatrix為模型矩陣的逆矩陣的轉置。
代碼示例請戳:
https://codepen.io/mysisi/details/xYNWNZ/
參考:
[1] Unity Shader入門精要,馮樂樂.
[2] Everything has Fresnel
請大家持續關注我們的公眾號
我們會不斷地分享更多有趣的乾貨~
筆芯~
推薦閱讀: