WebGL - 示例 添加霧化效果

在三維圖形學中, 霧化用來描述遠處的物體看上去較爲模糊的現象。

示例一:霧化效果

實現霧化的方式有很多種,這裏最簡單的一種就是 線性霧化,在線性霧化中,某一點的霧化程度取決於它與視點之間的距離,距離越遠霧化程度越高,線性霧化有起點和終點,起點表示霧化開始之處,終點表示完全霧化之處,兩點之間某一點的霧化程度與該點的距離呈線性關係

比終點更遠的點完全霧化了,即完全看不到東西,某一點的霧化的程度可以定義爲 霧化因子

<霧化因子> = (<終點> - <當前點與視點間的距離>) / (<終點> - <起點>)

這裏

<起點> <= <當前點與視點間的距離> <= <終點>

如果霧化因子爲 1.0,表示該點完全沒有霧化,可以很清晰的看到此處的物體,如果爲 0.0,就表示該點完全霧化了,此處的物體完全看不見

在這裏插入圖片描述

在片元着色器中根據霧化因子,計算片元的顏色

<片元顏色> = <物體表面的顏色> * <霧化因子> + <霧的顏色> * (1 - <霧化因子>)

頂點着色器

attribute vec4 a_Position;
attribute vec4 a_Color;
uniform mat4 u_MvpMatrix;
uniform mat4 u_ModelMatrix;
uniform vec4 u_Eye;
varying vec4 v_Color;
varying float v_Dist;
void main(){
    gl_Position = u_MvpMatrix * a_Position;
    v_Color = a_Color;
    // 計算頂點座標和視點座標的距離
    v_Dist = distance(u_ModelMatrix * a_Position, u_Eye);
}

片元着色器

precision mediump float;
uniform vec3 u_FogColor;
uniform vec2 u_FogDist;
varying vec4 v_Color;
varying float v_Dist;
void main(){
    // 將霧化因子限制在 0.0 - 1.0 之間
    float fogFactor = clamp((u_FogDist.y - v_Dist)/(u_FogDist.y - u_FogDist.x),0.0, 1.0);
    vec3 color = mix(u_FogColor, vec3(v_Color), fogFactor);
    gl_FragColor = vec4(color, v_Color.a);
}

上面的是在頂點着色器中計算頂點與視點的距離,會造成較大的開銷,其實可以使用另一種計算方法,來近似估算出這個距離,那就是使用頂點經過模型視圖投影矩陣變換後的座標 w分量,也就是gl_Positionw分量,實際上,這個w分量的值就是頂點的視圖座標的z分量乘以-1,在視圖座標系中,視點在原點,視線沿着z軸負方向,觀察者看到的物體其視圖座標系值z分量都是負的,而gl_Positionw分量值正好是z分量值乘以-1,所以可以直接使用該值來近似頂點與視點的距離

頂點着色器修改如下

attribute vec4 a_Position;
attribute vec4 a_Color;
uniform mat4 u_MvpMatrix;
varying float v_Dist;
void main(){
    gl_Position = u_MvpMatrix * a_Position;
    v_Color = a_Color;
    // 使用 w 分量來近似表示頂點與視點的距離
    v_Dist = gl_Position.w;
}

片元着色器不變

示例二:使用w分量

具體代碼可在 gitee上獲取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章