泛光(Bloom)是一種常用的后期處理特效,游戲中更是隨處可見,這里直接上我們的效果圖凰棉。
Cesium內(nèi)置的bloom后期處理膀哲,是對全屏進行處理往产,還不能只針對選中的特定對象添加泛光效果,通過修改shader代碼也可以實現(xiàn)某宪。不過今天我們不做改進捂齐,而是引進three.js的UnrealBloomPass,在Cesium中實現(xiàn)一個新的泛光效果缩抡。
從UnrealBloomPass這個名字看奠宜,大概是說從Unreal Engine那里學來的吧包颁,另外也是在名稱上區(qū)別于輝光特效BloomPass,可以說UnrealBloomPass就是增強的輝光特效压真。感興趣的可以看看UE4關(guān)于泛光的文檔頁面娩嚼。UE4關(guān)于泛光的文檔頁面
實現(xiàn)流程
泛光效果的技術(shù)并不復雜,大體分為三個步驟:
計算亮度滴肿,獲得亮度紋理岳悟;
高斯模糊,對亮度紋理的根據(jù)不同分辨率和高斯核進行模糊處理泼差,得到多個模糊紋理贵少;
合并紋理,將模糊紋理按照不同權(quán)重疊加到原始場景堆缘。
由于上一篇《Cesium實現(xiàn)更實用的3D描邊效果》已經(jīng)詳細介紹了Cesium后期處理技術(shù)并給出了基本示例滔灶,本文就只對Shader代碼進行簡單的注解,不貼出JavaScript部分的代碼了吼肥。
計算亮度
亮度(Luminosity)的概念和計算方法可以參考維基百科录平。
下面針對Cesium進行修改后的片元著色器(fragmentShader)代碼:
計算亮度的核心代碼就是這兩行:
CZM_SELECTED_FEATURE是由Cesium自動定義的命令,指示當前后期處理節(jié)點是否設(shè)置selected屬性缀皱,和czm_selected一起用于判斷是否為選中對象斗这。
這一步的效果圖如下:
luminosityThreshold和smoothWidth兩個參數(shù)可以對亮度計算結(jié)果進行微調(diào)。
高斯模糊
接下來我們需要對亮度紋理進行多次處理啤斗,得到不同平滑程度和尺寸的模糊紋理表箭。每次處理的流程如下:
設(shè)置高斯核半徑KERNEL_RADIUS;
降低目標紋理分辨率(用紋理縮放倍數(shù)表示);
對亮度紋理進行縱向钮莲、橫向兩次高斯模糊處理燃逻。
高斯模糊的原理網(wǎng)上有很多優(yōu)秀文章可以學習,感興趣可以自行搜索臂痕,興許對這部分Shader代碼會有更加深刻的理解伯襟。
下面這段代碼實現(xiàn)一個方向的高斯模糊:
KERNEL_RADIUS是高斯核半徑,單位是像素握童,在創(chuàng)建Cesium.PostProcessStage時在添加姆怪。
本文實現(xiàn)的效果總的進行了5次模糊處理,高斯核半徑分別為:3, 5, 7, 9, 11澡绩;紋理縮放倍數(shù)分別為:1,0.5,0.25,0.125,0.0625稽揭。
合并紋理
最后我們將五次模糊處理的結(jié)果,按不同權(quán)重和顏色進行疊加肥卡,并預留一些參數(shù)供應用時按需進行調(diào)整溪掀。