軟陰影與抗鋸齒_第1頁
軟陰影與抗鋸齒_第2頁
軟陰影與抗鋸齒_第3頁
軟陰影與抗鋸齒_第4頁
軟陰影與抗鋸齒_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、軟陰影的實現(xiàn)嘗試 軟陰影(Soft - Shadow),并非一種圖形學(xué)算法或技術(shù)的代名詞。怎么說呢,它是圖形學(xué)大師們孜孜不倦地追求的更逼近真實的陰影效果 。ZwqX 在已有的陰影DEMO上作改進(jìn),是當(dāng)時很自然的想法。而選擇了Shadow Map Demo2 ,不知道,算不算是一個失策。Cascaded ShadowMap技術(shù),從本質(zhì)上說,只是分區(qū)間地調(diào)整投影矩陣,根據(jù)視距離使用不同分辨率的陰影圖,促使效率與效果平衡而已。這是Shadow Map改進(jìn)算法的一條路,但并非唯一?;叵隨hadow Map陰影貼圖技術(shù)之探 ,里面我簡單地用乒乓式的采樣,實現(xiàn)了一下3X3的陰影圖模糊PCF。雖然結(jié)果看上去

2、很那個,但這昭示著Shadow Map改進(jìn)算法的另一條路圖形學(xué)中的圖像處理,調(diào)整陰影圖。 在我的上一個陰影DEMO中,主要的shader只有一個,它是在Shadow - Casting階段完成場景陰影圖的分層次貼附。在CPU上完成的是ShadowMap - Generating階段,因為那里沒有涉及像素層面,完全不需要GPU的并行計算能力。但如果要對一張貼圖的內(nèi)容進(jìn)行像素級的處理恩,這是通常的想法。但當(dāng)時腦中另一個突然一閃的想法,讓我決定先行對其進(jìn)行捕獲場景后處理。 一般說的DefferedShading并不等同于這個意義,但就字面來說它們也有那么一點共通。恩,題外話先免了,先暗自打個小算盤:

3、 場景后處理,我是想在最終畫面上動手腳。在OpenGL流水線的尾部,無論是否雙緩沖,必然是把顯存上每個像素格的值傳向顯示器屏幕上的每個“真像素”上,表示成顏色(譬如LCD是用彩色濾光片等結(jié)構(gòu)對此轉(zhuǎn)換的,可以理解為每個像素上又有紅綠藍(lán)三色子像素balabala嘛,其實我也不怎么理解啊這些硬件的- -,呃離題了,回來)。如果把這個覆蓋屏幕的“結(jié)果”當(dāng)作貼在一個Screen-Aligned-Quad(屏幕大矩形)的一張紋理,我們在顯存-屏幕這個過程之前進(jìn)行攔截,獲得并處理這個“紋理”后再讓它傳向屏幕。 有這方面基礎(chǔ)的朋友都知道,F(xiàn)BO又該出來表演了學(xué)一學(xué),F(xiàn)BO 。把Shadow - Casting

4、的結(jié)果寫入FBO綁定的一個紋理中,然后自己畫一個Screen-Aligned-Quad,貼這個紋理對這個過程啟用shader處理。最后雖然屏幕上本質(zhì)只有這么一個矩形,但是眾多本該直接映射在屏幕上的場景元素已經(jīng)完美地“被代表”了??瓷先ソz毫沒有河蟹爬過的痕跡完全沒有。 依然是模糊處理。高斯模糊。01/02uniformintBSceneWidth;03uniformintBSceneHeight;04uniformfloatishoriz;0506uniformintsamplecount;07uniformfloatweights;08uniformfloatsigma;0910uniform

5、 sampler2D BScenemap;1112voidmain()1314gl_FragData0 = BlurFilter(BScenemap, gl_TexCoord0.xy) ;15 其中BlurFilter函數(shù)是對當(dāng)前像素,在水平或垂直方向上采樣(samplecount),采樣值乘以一個高斯分布值而已(公式也就網(wǎng)上常見的,sigma為參數(shù)),跟PCF也就差不多那回事。很明顯,我們需要在水平方向和垂直方向都模糊一次,這里用2個PASS。我們只需要模糊陰影,因此把陰影部分和場景部分分開寫入紋理(MRT),最后再統(tǒng)一。1/ CastingShader, render to two tex

6、tures (MRT)2gl_FragData0 = vec4(gl_Color.rgb * diffuse.rgb * texColor.rgb, 1.0);34gl_FragData1 = shadeFactor;1/PostProcessingShader , as a texture to the screen-aligned quad2uniform sampler2D Scenemap;3uniform sampler2D Shademap;45voidmain()67vec4 shadeFact = texture2D(Shademap, gl_TexCoord1.xy);8gl

7、_FragColor = texture2D(Scenemap, gl_TexCoord0.xy) * shadeFact;9 寫到FBO紋理后,屏幕矩形綁定之: 軟是軟了,就邊界效果而言是很好的(這里圖片壓縮了看上去糟糕而已)但有幾個問題:1.很明顯的邊界問題,陰影與場景分離了,SampleNum越大分離得越明顯;2.隨著SampleNum增加幀率狂降。效果和效率都不行。 首先,這種高采樣帶寬的東西本來就是幀率殺手,更不用說高斯分布權(quán)數(shù)的計算實在夠嗆。其次因為場景和陰影分離,而模糊的只是對于相機(jī)“可見”的那部分陰影,所以圖中間隔線是活生生被當(dāng)作陰影邊界了。 后來也考慮過再加入圖像處理中的“膨

8、脹”運算形態(tài)學(xué)運算小結(jié) ,但是有點吃力不討好的感覺,無論膨脹多少次,還是能依稀見到狹縫,加上效率問題,宣告此法的破產(chǎn)。 左-右,上-下依次 32p4p4pass1, 32p2p2pass1, 32p2p2pass2, 64p2p2pass1(自己猜,我什么都忘記了哈) 還是好好用別的方法吧 軟陰影與反鋸齒有著深刻的關(guān)系,PCF在Graphics上原本就是一種反鋸齒技術(shù),而它在陰影算法上往往作為簡捷的軟陰影達(dá)成途徑。VSM(Variance Shadow Map)同樣旨在解決這一問題,但它并非像以往一樣對陰影圖的后處理,而是重新定義陰影圖。ZwqX1. 鋸齒與反鋸齒 鋸齒感是在Casting的時

9、候產(chǎn)生的。我們確實是相當(dāng)于把一張陰影圖(深度圖)貼在場景上了,但具體的操作依然是一條深度比較指令。譬如,傳統(tǒng)的SM中,根據(jù)場景物體像素在光源視覺下的深度得到的陰影圖,在Casting階段對應(yīng)相機(jī)視覺中的像素判斷是否屬于陰影圖中的像素這本來就是一個TRUE OR FALSE的判斷,若TRUE證明非陰影,像素顏色值不變;若FALSE則涂黑,以表明該處陰影。 NewValue = OldValue * (isShadow? 0 : 1) 即使把0替換成shadowMapValue或是運用距離值判斷,也改變不了這里的根源:把視場景分割成陰影區(qū)和非陰影區(qū)。雙方強(qiáng)烈的撕扯總會造成霹靂的裂痕。我們一般使用的

10、紋理在貼在奇形怪狀的表面上時產(chǎn)生的扭曲同樣會導(dǎo)致鋸齒,可為什么卻不那么難接受呢?原因是filtering。初學(xué)紋理貼圖的時候,一定會接觸到Texture Filtering,尤其在發(fā)生欠采樣和過采樣的時候,紋理映射的策略。在OpenGL 1.x中,GL_LINEAR和GL_NEAREST應(yīng)該是最為熟悉的,尤其是線性插值GL_LINEAR,讓我們貼紋理的時候能得到比較好的性效比:1glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2glTexParameteri(GL_TEXTURE_2D_ARR

11、AY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 貼紋理過程的采樣能通過簡單的線性插值完成,再把插出來的值映射到恰當(dāng)?shù)奈恢萌ハ胂雽τ谏疃葓D這會是什么情況:低分辨率的陰影圖上一個4X4格子,對應(yīng)場景中9X9大小區(qū)域,恰好區(qū)域覆蓋陰影邊界,深度插值后某像素獲得了表示“半影”的灰度數(shù)值。但是要“貼”到場景時,需要經(jīng)過一個TRUE OR FALSE過濾器,這個“半影”像素依然要選擇:自己究竟屬于影子,還是非影子。一旦整個邊界的像素選擇完成,由于陰影判斷式對所有像素等效,它們會發(fā)現(xiàn)自己“整齊”地劃出了一條邊界線,鋸齒邊界線。2. Variance Shadow Map

12、 VSM(Variance Shadow Map)的提出正基于此。其實它本質(zhì)也是一種基于概率的方法,把以上的TRUE OR FALSE過濾器過程改作一個可見性估計過程嘛,你也知道概率學(xué)上的東西有很多微妙的地方讓texture filtering作用于每個像素的方差(Variance)而非其本身的值,于此建立的切比雪夫不等式作為這個可見性估計式。ZwqXin本身概率論學(xué)得不深,為了避免誤人子弟,這許概率數(shù)學(xué)原理我就PASS了。 每個像素經(jīng)過這樣折騰一下,取切比雪夫不等式的上限(UpperBound,即上式pmax(t))為結(jié)果,它大概揭示了當(dāng)前像素屬于“非陰影區(qū)”的程度(當(dāng)這個UpperBoun

13、d越接近0時代表此像素越可能“屬于陰影”)。UpperBound計算式的三個參數(shù),t是像素的實際深度(根據(jù)GPU GEMS3,這里取的是像素距離光源的距離distToLight),是當(dāng)前像素深度的期望E(x)(取的是直接在陰影圖上采樣得到的插值后的深度,好吧,囧),2是方差(2= E(x2)- E(x)2)。 首先查查什么是“切比雪夫不等式”( Chebyshevs inequality )。是的,上過概率課,所以至少聽過這個名詞(聽說,那是因為期末考后潛意識對自身的遺忘魔法):in any data sample or probability distribution, nearly all

14、 the values are close to the mean value the precise statement being that no more than 1/k2of the distributions values can be more than k standard deviationsaway from the mean. WIKI。 上面式子應(yīng)該是另一種表達(dá)形式吧(吧?)。在我看來,切比雪夫不等式的上限是關(guān)于 t的函數(shù)式,描述了一個具體的量t在隨機(jī)集合X上的位置的概率范圍。Casting過程中,一個像素往深度圖Shadow Map上采樣,姑且認(rèn)為這是一個隨機(jī)選擇的過

15、程;像素若是根據(jù)其紋理坐標(biāo)(光源投影矩陣合理所得)進(jìn)行的采樣,紋理上應(yīng)該只有唯一的一個點與之對應(yīng)當(dāng)然,即使取隔壁的點也不是不可,不過它作為準(zhǔn)確值的概率沒有那個“唯一的點”大把可能取的值作為集合X,那X就是一個以“唯一的點”為中心的圓,使該點作為集合的期望值。(期望的計算式子E(X) = x1* p(x1) + x2* p(x2) + ,稍微考慮一下就明白)。問題是t,它作為實際值,在我們的紋理采樣過程中是不可能出現(xiàn)的,甚至我覺得它根本無法得出,為什么取“像素距離光源的距離distToLight”呢?它的計算不存在于紋理采樣過程中,但也不可能就說它就是“真實值”啊哪怕表義如此。對此,可看看GPU GEMS3 8.1中作者的解釋,不過我是沒有太理解而已(盡管沒有更好的)。 于是,既然擺脫的TRUE OR FALSE的抑制,我們完全可以動用texture filtering去取那個“唯一的點”期望值E(x)了。這不,為了計算方差,我們還需要一個E(x2)類似地,我們只需要在ShadowMap Generating階段把像素深度值的平方也保存起來就可以了這就是Variance Shadow Map,需要一張紋理的兩個通道,分別存儲深度和深度平方。CASTING階

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論