切換
舊版
前往
大廳
主題

Bokeh(散景)

Lumi | 2017-05-16 23:35:36 | 巴幣 0 | 人氣 488

▲Bokeh特效,也被稱作Depth of Field

最初在GPU Pro上第一次看到Bokeh這個詞,一時還以為是人名,想不到這詞是從日文來的,最後面的"h"似乎是為了不要讓歐美人士念錯。實在令人好奇1996年以前外國人是怎麼稱呼這個拍照效果,還有waifu甚麼時候會編入字典…。

上一篇的CoC公式搭配depthmap可以讓我們計算出每個像素在畫面中的擴散程度,實際運用時公式內的絕對值符號會去掉,並將結果換算成半徑橫跨多少個像素。若CoC值大於0.5像素,代表該像素屬於背景,若小於-0.5則代表前景,在-0.5到0.5之間代表中景。
▲藍色為前景,綠色為中景,紅色為背景

顯然用scatter(擴散)的實作方式最擬真,方法是將無數個sprite放大到CoC大小後blend到畫面上。可是像這種有大量blend的運算都快不起來,最初CryEngine3以沒有任何最佳化實作此法,一張1080p的圖費時100 ms。無可奈何下,只好退而求其次用gather(收集)法來作模糊效果。

雖然真實相片的bokeh效果不會像高斯模糊法那麼平滑,而且CoC的最大值還被限制住,不過為了效能,擬真可以先擺一旁。最初是照著GPU Pro 4實作,將1/4原始畫面對X與Y軸分別做兩次高斯模糊,並且對每個採樣都檢查是否在CoC範圍內。做了一半才發現這個演算法在模糊背景沒辦法平均向四周模糊,問題來自只有顏色模糊,CoC不會也不能被模糊,所以第二次模糊的結果會有些錯誤。背景的瑕疵不放大來看還不太會發現,前景的瑕疵就實在太明顯,而且書中的前景模糊根本就放棄檢查CoC了,導致所有前景的像素都是固定的模糊範圍。

▲本篇所使用的採樣分佈

兩次模糊不行那用一次模糊總可以了吧,但此法缺點在於CoC最大值設定太大時,很容易在畫面上看到採樣的分佈圖形。而且分佈的模式也會影響觀感,剛開始時測試了Hammersley set與Halton sequence就覺得很醜,改成SSAO用的螺旋形分佈更醜。最後讓採樣點盡量平均分佈在一個圓內,採樣點多達41個。不過即使採樣點平均分佈,模糊後還是會看得到分佈圖形。這裡採用了已被手游廠買走的Tri-Ace的方法,替背景與前景製作mipmap,與中景合併時稍微提高LOD的值。
▲LOD值會隨CoC變化,LOD太低會看到分佈圖形,LOD太高會出現鋸齒…

合併階段先合併中景與背景,靠CoC值來判斷該使用哪張圖,之後合併前景時得依靠前景攜帶的alpha值。因為前景被模糊後擴散的部分得蓋住中景與背景,而且前景與中(背)景之間不能出現明顯的交界線,所以在模糊前景時就得計算出覆蓋程度並儲存到alpha中。
▲前景的邊緣會逐漸淡出

▲上圖局部放大

現在設定的CoC最大值還是太小,而且也想讓模糊結果隨著光圈形狀改變,這些問題在scatter法都不存在。可是光是以現在的實作,在GeForce GTX 750 Ti上CoC計算費時0.35 ms,模糊前景與背景1.3 ms,合併0.56 ms,共2.21 ms。實在不能說是便宜的特效,很猶豫到底要不要繼續改善擬真度。

聊勝於無,試著改變採樣分佈…
▲採樣點平均分佈在五角形內

創作回應

更多創作