webgl智慧樓宇發(fā)光系列之線性采樣下高斯模糊

前面一篇文章 <webgl智慧樓宇發(fā)光效果算法系列之高斯模糊>, 我們知道了 高斯模糊的本質(zhì)原理贝咙,就是對每個像素此叠,按照正態(tài)分布的權(quán)重去獲取周邊像素的值進行平均,是一種卷積操作。

同時我們可以指定周邊像素的數(shù)量悔雹,比如可以是3X3,或者5X5欣喧,通用的表達就是N X N腌零, 數(shù)字N通常稱之為模糊半徑,這在之前的文章的代碼中有體現(xiàn)(uRadius):

uniform float uRadius;
float gaussianPdf(in float x, in float sigma) {
  return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
}
void main() {
  for( int i = 1; i < MAX_KERNEL_RADIUS; i ++ ) {
    float x = float(i);
    if(x > radius){
      break;
    }
    ...
  }
  vec4 result = vec4(1.0) - exp(-diffuseSum/weightSum * uExposure);
  gl_FragColor = result;
}
`

效率問題

通常唆阿,我們希望模糊的效果越強烈益涧,模糊半徑就會要求越大。所謂的半徑就是上面的數(shù)字N驯鳖。
我們知道闲询,要實現(xiàn)一個NxN大小的高斯模糊久免,在紋理的每個像素點,都需要去獲取周邊N個像素點扭弧。因為1024*1024大小的紋理阎姥,要實現(xiàn)33 * 33 大小的高斯模糊,需要訪問大概1024 * 1024 * 33 * 33≈11.4億個紋理像素鸽捻,才能應用整個圖像的模糊效果呼巴。

為了獲得更有效的算法,我們來看看高斯函數(shù)的一些特性:

  • 二維高斯函數(shù)可以通過將兩個一維高斯函數(shù)相加來計算泊愧。
  • 分布為2σ的高斯函數(shù)等于分布為σ的兩個高斯函數(shù)的乘積伊磺。

高斯函數(shù)的這兩個屬性為我們提供了進行大量優(yōu)化的空間。

基于第一個屬性删咱,我們可以將二維高斯函數(shù)分成兩個一維函數(shù)屑埋。在使用片段著色器的情況下,我們可以將高斯濾鏡分為水平模糊濾鏡和垂直模糊濾鏡痰滋,在渲染后仍可獲得準確的結(jié)果摘能。 這個時候,10241024大小的紋理敲街,要實現(xiàn)33 * 33 大小的高斯模糊团搞,需要訪問大概1024 * 1024 * 332≈6,900萬個紋理提取。這種優(yōu)化明細減少了一個量級多艇。文章 《webgl智慧樓宇發(fā)光效果算法系列之高斯模糊》已經(jīng)實現(xiàn)了這一優(yōu)化逻恐。

第二個屬性可用于繞過平臺上的硬件限制,這些平臺僅在一次pass中僅支持有限數(shù)量的紋理提取峻黍。

線性采樣

到此复隆,我們知道了把一個二維的高斯模糊 分離成兩個一維的高斯模糊。效率上也有了大幅度的提高姆涩。但是實際上挽拂,我們還可以通過線性采樣的特性進一步提高效率。

我們知道骨饿,要獲取一個像素信息亏栈,就要做一次貼圖的讀取。這就意味33個像素信息宏赘,就需要做33次貼圖的讀取操作绒北。 但是由于在GPU上面可以隨意進行雙線線性插值,而沒有額外的性能消耗置鼻。 這就意味著镇饮,如果我們不再像素的中心點讀取貼圖,就可以獲得多個像素的信息。 如下圖所示:


示意圖

假設兩個像素储藐,我們在像素1中心點讀取貼圖就是獲取像素1的顏色俱济,在像素2中心點讀取貼圖就是獲取像素2的顏色;而在像素1中心點和像素2中心點的某個位置讀取貼圖钙勃,則會獲取像素1和像素2的顏色的加權(quán)平均的效果蛛碌。

因為我們做高斯模糊的時候,本身就是獲取周邊相鄰元素的加權(quán)平均值辖源,因此利用線性采樣的這個特性蔚携,可以把原本2個像素的采樣,減少為一次采樣克饶。 如果原本33次采樣酝蜒,則可以減少到17次。

對于兩個紋素的采樣矾湃,需要調(diào)整坐標使其與紋素#1中心的距離等于紋素#2的權(quán)重除以兩個權(quán)重之和亡脑。同樣的,坐標與紋素#2中心的距離應該等于紋素#1的權(quán)重除以兩個權(quán)重之和邀跃。

然后我們就有了計算線性采樣高斯濾波的權(quán)重和位移公式:

公式

代碼講解

  • 首先定義一個uniform變量霉咨,該變量表示是否啟用線性采樣的方法:
uniform bool uUseLinear;
  • 然后如果使用線性采樣,就把原本的采樣次數(shù)減少一半:
 if(uUseLinear){
    radius = uRadius / 2.0;
  }
  • 再然后拍屑,如果使用線性采樣途戒,就使用上述的公式進行像素提取:
if(uUseLinear){
      // http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
      float t1 = 2.0 * x - 1.0,t2 = 2.0 * x ;
      float w1 = gaussianPdf(t1,fSigma);
      float w2 = gaussianPdf(t2,fSigma);
      w = w1 + w2;
      t = (t1 * w1 + t2 * w2) / w;
    }

    vec2 uvOffset = uDirection * invSize * t;
    vec4 sample1 = texture2D( uColorTexture, vUv + uvOffset).rgba;
    vec4 sample2 = texture2D( uColorTexture, vUv - uvOffset).rgba;
    diffuseSum += (sample1 + sample2) * w;
    weightSum += 2.0 * w;

最終的繪制效果如下:


效果

其中左邊的未使用線性采樣的機制,而右邊的使用了線性采樣僵驰,可以看出右邊再減少了一半的采樣的情況下喷斋,效果和左邊的基本沒有差別。

而效率上蒜茴,通過測試继准,右邊比左邊大概提高了40%的渲染效率。

總結(jié)

通過線性采樣的機制矮男,我們可以看到效率提高了近一倍。這在一些對性能要求高得場景或者移動終端是很有意義室谚。

其實要做出一個好的發(fā)光效果毡鉴,涉及到相關(guān)算法是很多了,而且細節(jié)之處都需要關(guān)注秒赤。

先看看我們已經(jīng)做了得一些發(fā)光樓宇得案例吧, 以下都是再簡單模型(立方體) + 貼圖 + 光照 + 發(fā)光 出來得效果猪瞬,如果模型層面在優(yōu)化,應該還可以有更酷效果:


案例0
案例1
案例2

如果對可視化感興趣入篮,可以和我交流陈瘦,微信541002349. 另外關(guān)注公眾號“ITMan彪叔” 可以及時收到更多有價值的文章。

參考文檔

參考文檔:http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
本文部分素材使用了參考文檔中的內(nèi)容潮售。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末痊项,一起剝皮案震驚了整個濱河市锅风,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鞍泉,老刑警劉巖皱埠,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異咖驮,居然都是意外死亡边器,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門托修,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忘巧,“玉大人,你說我怎么就攤上這事睦刃⊙庾欤” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵眯勾,是天一觀的道長枣宫。 經(jīng)常有香客問我,道長吃环,這世上最難降的妖魔是什么也颤? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮郁轻,結(jié)果婚禮上翅娶,老公的妹妹穿的比我還像新娘。我一直安慰自己好唯,他們只是感情好竭沫,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著骑篙,像睡著了一般蜕提。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上靶端,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天谎势,我揣著相機與錄音,去河邊找鬼杨名。 笑死脏榆,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的台谍。 我是一名探鬼主播须喂,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坞生?” 一聲冷哼從身側(cè)響起仔役,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎恨胚,沒想到半個月后骂因,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡赃泡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年寒波,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片升熊。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡俄烁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出级野,到底是詐尸還是另有隱情页屠,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布蓖柔,位于F島的核電站辰企,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏况鸣。R本人自食惡果不足惜牢贸,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望镐捧。 院中可真熱鬧潜索,春花似錦、人聲如沸懂酱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽列牺。三九已至整陌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瞎领,已是汗流浹背蔓榄。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留默刚,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓逃魄,卻偏偏與公主長得像荤西,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容