屏幕泛光效果

談?wù)勛约旱睦斫獍?/p>

第一次聽說HDR是在我的賓得單反相機(jī)上,有個(gè)HDR的拍攝模式,叫做高動(dòng)態(tài)范圍拍攝,其原理是拍攝一張過曝的圖片,拍攝一張曝光不足的圖片,再拍攝一張正常圖片,相機(jī)只需進(jìn)行一次快門釋放,但這個(gè)功能可以拍攝三張并且自動(dòng)合并,其作用是為了亮部區(qū)域和暗部區(qū)域都能有很豐富的細(xì)節(jié)。
后來從事三維影視相關(guān)的工作,HDR大多用來制作環(huán)境球貼圖,在 PBR 的渲染管線中加入了 IBL(Image Based Lighting)使得渲染結(jié)果更加真實(shí),為離線渲染提供了非常真實(shí)的光線。
隨著游戲業(yè)的畫面水準(zhǔn)開始向電影水準(zhǔn)發(fā)展,越來越多的游戲使用HDR,ToneMapping,ExposureAdjustment等等,我們必須好好理解它并把游戲想電影的畫質(zhì)去推進(jìn)。
HDR的存在能存儲超越圖像存儲介質(zhì)的圖片亮度和細(xì)節(jié),顯示器能夠顯示R、G、B分量在[0,255]之間的像素值,而256個(gè)不同的亮度級別顯然不能表示自然界中光線的亮度情況,HDR再有限的亮度范圍內(nèi)顯示更寬廣的亮度范圍
ExposureAdjustment與相機(jī)的曝光類似,不過引擎里應(yīng)該是計(jì)算render target的平均亮度,然后矯正
ToneMapping是把場景中范圍巨大的亮度值放到范圍有限的存儲空間中來,用ps來表達(dá)就像添加了一個(gè)對比度效果,降低亮度,提升暗部,這個(gè)效果的話就因人而異了。
Bloom可以模擬出HDR的效果,但是原理上和HDR相差甚遠(yuǎn)。Bloom僅僅是能夠?qū)⒘恋牡胤礁痢2贿^效果實(shí)現(xiàn)起來簡單,性能消耗也小,效果也可以接收,對于移動(dòng)平臺很友好。

為了搞懂HDR和Bloom的區(qū)別,我轉(zhuǎn)載了下面這段,感謝原作者:[lupeng0330]

【要比較兩者的異同,得先搞清楚HDR特效是什么;HDR,本身是High-Dynamic Range(高動(dòng)態(tài)范圍)的縮寫,這本來是一個(gè)CG概念。HDR的含義,簡單說,就是超越普通的光照的顏色和強(qiáng)度的光照。計(jì)算機(jī)在表示圖象的時(shí)候是用8bit(256)級或16bit(65536)級來區(qū)分圖象的亮度的,但這區(qū)區(qū)幾百或幾萬無法再現(xiàn)真實(shí)自然的光照情況。因此普通情況下,無法同時(shí)顯示亮部和暗部的所有細(xì)節(jié)。
想要實(shí)現(xiàn)HDR特效,首先,游戲開發(fā)者要在游戲開發(fā)過程中,利用開發(fā)工具(就是游戲引擎)將實(shí)際場景用HDRI記錄下來,當(dāng)然開發(fā)技術(shù)強(qiáng)的開發(fā)組會直接用小開發(fā)工具(比如3D MAX的某些特效插件)創(chuàng)造HDRI圖像;其次,我們的顯卡必須支持顯示HDR特效,nVIDIA的顯卡必須是GeForce 6系列或更高,ATI顯卡至少是Radeon 9550或以上。
那么HDR與bloom效果的差別到底在什么地方呢?
  第一,HDR效果就是超亮的光照與超暗的黑暗的某種結(jié)合,這個(gè)效果是光照產(chǎn)生的,強(qiáng)度、顏色等方面是游戲程序可動(dòng)態(tài)控制的,是一種即時(shí)動(dòng)態(tài)光影;bloom效果則是物體本身發(fā)出的光照,僅僅是將光照范圍調(diào)高到過飽和,是游戲程序無法動(dòng)態(tài)控制的,是一種全屏泛光。
  第二,bloom效果無需HDR就可以實(shí)現(xiàn),但是bloom效果是很受限的,它只支持8位RGBA,而HDR最高支持到32位RGBA。
  第三,bloom效果的實(shí)現(xiàn)很簡單,比如《半條命2》的MOD就是一個(gè)很小的很簡單的MOD,而且bloom效果不受顯卡的規(guī)格的限制,你甚至可以在TNT顯卡上實(shí)現(xiàn)bloom效果(當(dāng)然效果很差)!而HDR,必須是6XXX以上的顯卡才能夠?qū)崿F(xiàn),這里的HDR是指nVIDIA的HDR。這時(shí)有必要談nVIDIA和ATI的顯卡所實(shí)現(xiàn)的HDR,兩者還是有區(qū)別的,具體區(qū)別就很專業(yè)了,總之從真實(shí)性表現(xiàn)來看,nVIDIA的顯卡實(shí)現(xiàn)的HDR更好一些。HDR是nVIDIA提出的概念,從技術(shù)上來講,ATI當(dāng)然無法嚴(yán)格克隆nVIDIA的技術(shù),所以ATI的HDR是另一種途徑實(shí)現(xiàn)的盡可能接近的HDR,不能算“真”HDR,據(jù)傳ATI的R520能夠真正實(shí)現(xiàn)FP16 HDR?!?/p>

無HDR.jpg
有HDR.jpg

接下來要實(shí)現(xiàn)Bloom
第一步: 先獲取屏幕圖像,然后對每個(gè)像素進(jìn)行亮度檢測,若大于某個(gè)閥值即保留原始顏色值,否則置為黑色;
第二步:對上一步獲取的圖像,做一個(gè)模糊,通常使用高斯模糊。
第三步:將模糊后的圖片和原圖片做一個(gè)加權(quán)和。


20161025011929739.png

核心代碼:

//申請兩塊RT,并且分辨率按照downSameple降低
            RenderTexture temp1 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);
            RenderTexture temp2 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);
 
            //直接將場景圖拷貝到低分辨率的RT上達(dá)到降分辨率的效果
            Graphics.Blit(source, temp1);
         
 
            //根據(jù)閾值提取高亮部分,使用pass0進(jìn)行高亮提取
            _Material.SetVector("_colorThreshold", colorThreshold);
            Graphics.Blit(temp1, temp2, _Material, 0);
 
            //高斯模糊,兩次模糊,橫向縱向,使用pass1進(jìn)行高斯模糊
            _Material.SetVector("_offsets", new Vector4(0, samplerScale, 0, 0));
            Graphics.Blit(temp2, temp1, _Material, 1);
            _Material.SetVector("_offsets", new Vector4(samplerScale, 0, 0, 0));
            Graphics.Blit(temp1, temp2, _Material, 1);
 
            //Bloom,將模糊后的圖作為Material的Blur圖參數(shù)
            _Material.SetTexture("_BlurTex", temp2);
            _Material.SetVector("_bloomColor", bloomColor);
            _Material.SetFloat("_bloomFactor", bloomFactor);
 
            //使用pass2進(jìn)行景深效果計(jì)算,清晰場景圖直接從source輸入到shader的_MainTex中
            Graphics.Blit(source, destination, _Material, 2);
 
            //釋放申請的RT
            RenderTexture.ReleaseTemporary(temp1);
            RenderTexture.ReleaseTemporary(temp2);

Shader:
pass1

//僅當(dāng)color大于設(shè)置的閾值的時(shí)候才輸出
        return saturate(color - _colorThreshold);

pass2

//模糊
o.uv01 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1);
        o.uv23 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 2.0;
        o.uv45 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 3.0;
        
        fixed4 color = fixed4(0,0,0,0);
        color += 0.40 * tex2D(_MainTex, i.uv);
        color += 0.15 * tex2D(_MainTex, i.uv01.xy);
        color += 0.15 * tex2D(_MainTex, i.uv01.zw);
        color += 0.10 * tex2D(_MainTex, i.uv23.xy);
        color += 0.10 * tex2D(_MainTex, i.uv23.zw);
        color += 0.05 * tex2D(_MainTex, i.uv45.xy);
        color += 0.05 * tex2D(_MainTex, i.uv45.zw);
        return color;

pass3

//輸出= 原始圖像,疊加bloom權(quán)值*bloom顏色*泛光顏色
        fixed4 final = _MainTex + _bloomFactor * blur * _bloomColor;

bloom效果.jpg
無bloom.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容