webgl 實現景深效果(二)

2021-09-26 07:33:22 字數 2546 閱讀 5905

上回我們說到,僅僅使用簡單的混合會導致渲染出現兩個問題:

那麼如何解決這兩個問題呢?答案是對前景和後景分開做處理。我們可以先處理後景,再處理前景。

後景混入前景的問題好辦,在計算模糊時,我們對範圍內每乙個畫素做乙個判斷,如果是前景或者對焦區域的點,就將其排除掉。

前景邊緣過於清晰的問題就需要用點小技巧了:首先,我們計算每乙個畫素的coc。如果是對焦範圍內的點或後景,其coc置為零。這樣可以得到一張coc影象,對該影象做模糊,用模糊後的coc影象做混合,這樣就可以讓前景的邊界不那麼清晰。但光是這樣還是會有一點問題,因為模糊之後,前景邊緣本來是1的部分會變得小於1,這樣看起來邊緣還是有點生硬:

注意看酒桶邊緣,看起來還是不太理想。所以我們要對模糊後的coc影象做乙個逐畫素的處理:

d =m

ax(d

0,2d

b−d0

)d = max(d0, 2db-d0)

d=max(

d0,2

db−d

0)這個公式是怎麼來的呢?假設我們的coc影象有兩個區域,兩個區域有明顯的分界線。在分界線一側的coc值為d0, 另一側為d1。那麼我們可以近似認為,對模糊後的coc值,有:

d b=

1/2∗

(d0+

d1)db = 1/2 * (d0 + d1)

db=1/2

∗(d0

+d1)

那麼,d1=

2db−

d0d1 = 2db - d0

d1=2db

−d0我們希望在邊緣部分,取得較大的那個coc值,則有:

d =m

ax(d

0,d1

)=ma

x(d0

,2db

−d0)

d = max(d0, d1) = max(d0,2db-d0)

d=max(

d0,d

1)=m

ax(d

0,2d

b−d0

)為了展示 max(d0,2db-d0)的效果,這裡我把前景部分的rgb設為了coc值。對比一下處理前後:

僅模糊

模糊 + max(d0,2db-d0)處理

可以看到處理之後邊緣得到了明顯的增強、並且邊緣部分變亮了。

再來看看這樣處理之後酒桶的邊緣:

嗯,終於邊緣糊掉了,是想要的效果233

對了,這個思路來自gpu gems

第三遍渲染,對上一步得到的影象的a通道(儲存了coc的值)進行模糊。模糊後對每個畫素應用 d = max(d0,2db-d0) 。最後根據a通道的值,對影象的rgb通道進行模糊處理。

第二遍渲染的fragment shader,這裡只處理後景:

void main() 

else

coc = clamp(coc, 0.0, 1.0);

bool isforegroundorfocus = -depth - (focaldepth + farstart) < 0.0;

// this shader only handle background.

// "a" channel stores the coc value.

if(isforegroundorfocus)

else

第三遍渲染的fragment shader,這裡處理前景。

void main() 

coc /= cocblurweighttotal;

float originalcoc = texture2d(tcolor, vuv).a;

// according to

coc = 2.0 * max(originalcoc, coc) - originalcoc;

float bokehblurweighttotal = 0.0;

if (coc > 1e-5)

blurcolor /= bokehblurweighttotal;

gl_fragcolor.rgb = mix(sourcecolor, blurcolor, coc);

}else

gl_fragcolor.a = 1.0;

}

本文的**放在github上,這一部分的**寫在乙個檔案 bokeh.html 中。

傳送門:

gpu gems. chapter 28. practical post-process depth of field.

景深效果 Depth of Field

什麼是景深效果?景深效果,簡稱dof,在人眼跟光學攝像裝置上很常見.如下圖 簡單地來說,就是近處跟遠處的景物模糊,而焦點附近的物體則很清晰.至於為什麼會產生這樣的效果,我就懶得說了 p 那麼怎麼來實現這種效果呢?看圖 從攝像機開始,按距離分成三部分 近距離模糊,焦點範圍 清晰 遠距離模糊 渲染的時候...

webgl 實現物體描邊效果

終於把手頭的事結束了,可以有時間來研究研究技術 作為一名3d開發人員,僅僅使用現有的引擎來開發專案不免有些浮於表面,多研究研究底層的實現更利於對3d開發整體的把控 於是我決定最近開始研究webgl一些特效的實現,希望能在秋招前對底層有更深入的理解。這種方法不用進行法線與視線之間的計算,而是將物體每個...

Shader 實驗02 後處理實現景深效果

景深 depth of field 是指在攝影機鏡頭或其他成像器前沿能夠取得清晰影象的成像所測定的被攝物體前後距離範圍。而景深效果是指在焦距之外的地方都是模糊的,只有焦距的地方清晰。通過取樣攝像機的深度紋理,得到當前螢幕紋理每個點的深度,使用深度值與焦距值得到每個點到焦距的距離,並使用距離來對原影象...