第12章 體積散射_第1頁(yè)
第12章 體積散射_第2頁(yè)
第12章 體積散射_第3頁(yè)
第12章 體積散射_第4頁(yè)
第12章 體積散射_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第12章 體積散射到目前為止,我們都假定場(chǎng)景中的所有表面都在真空中,這意味者在表面之間的光線(xiàn)的輻射亮度是恒定的。然而,在許多真實(shí)世界中的情景中,這個(gè)假設(shè)并不精確: 霧和煙對(duì)光產(chǎn)生了衰減和散射作用,大氣中的粒子的散射作用使得藍(lán)天呈藍(lán)色,使得夕陽(yáng)晚景呈紅色。本章介紹相關(guān)的數(shù)學(xué)知識(shí)來(lái)描述參與介質(zhì) (participating media-分布于三維空間區(qū)域中的粒子)對(duì)光的影響。有了對(duì)參與介質(zhì)的效果的模擬,我們就可以渲染場(chǎng)景有霧靄的圖像、穿透云層的光束、子表面的散射 (即光線(xiàn)的出射點(diǎn)跟入射點(diǎn)不同)。本章首先描述了光線(xiàn)的輻射亮度受參與介質(zhì)影響的基本物理過(guò)程。然后,我們介紹VolumeRegion基本類(lèi),

2、它是描述不同介質(zhì)的接口。為了確定光在場(chǎng)景中的分布的整體效果,我們還需要第17章中所介紹的VolumeIntegrator。12.1 體積散射過(guò)程在有參與介質(zhì)的環(huán)境中,有三個(gè)主要過(guò)程可以影響輻射亮度的分布:吸收(Absorption):由于光能轉(zhuǎn)變成其它形式的能量(如熱)而減弱了輻射亮度。放射(Emission):發(fā)光的粒子增強(qiáng)了環(huán)境中的能量。散射(Scattering):由于光跟粒子的碰撞,在一個(gè)方向上傳播的光被散射到其它方向上去。所有這些特性既可以是均質(zhì)的(homogeneous),也可以是非均質(zhì)的(inhomogeneous)。均質(zhì)的特性在給定的一個(gè)空間范圍之內(nèi)是一個(gè)恒 量,而非均質(zhì)的特性

3、在空間內(nèi)是變化的。下圖顯示了一個(gè)體積散射的例子:一個(gè)聚光燈照亮了參與介質(zhì),并投射出一個(gè)體積陰影(volumetric shadow)。12.1.1 吸收考慮一下火產(chǎn)生的濃煙:煙遮擋了后面的物體,因?yàn)闊煹念w粒吸收了從物體到觀(guān)察者的光線(xiàn)。煙越濃,被吸收的光就越多。下圖顯示了煙的這種特效,其體積密度是由一個(gè)模擬煙的精確物理模型生成的。注意地面上的陰影:參與介質(zhì)已經(jīng)吸收了光源和地面之間的光線(xiàn),從而投射出一個(gè)陰影。吸收是通過(guò)介質(zhì)的吸收截面a來(lái)表述的,它是光線(xiàn)在介質(zhì)中單位距離之內(nèi)被吸收的概率密度。通常情況下,吸收截面隨著位置p和方向的變化而變化,雖然嚴(yán)格地講它是關(guān)于位置的函數(shù),但是它通常也是隨光譜變化的量

4、。a的單位是距離的倒數(shù)(m-1)。這意味者a可以取任意正值,并不需要限定在0到1之內(nèi)。下圖顯示了沿著很短一段光線(xiàn)上的吸收效果。在點(diǎn)p上有一定的輻射亮度Li(p, -),我們希望求出在微分體積之內(nèi)被吸收后的出射輻射亮度Lo(p, )。沿光線(xiàn)微分長(zhǎng)度dt的輻射亮度變化值可以通過(guò)下面的微分方程來(lái)表示:    Lo(p, ) Li(p, ) = dLo(p, )= a(p, ) Li(p, ) dt ,也就是說(shuō),沿著光線(xiàn)的輻射亮度的微分減少值跟其初始值呈線(xiàn)性關(guān)系。這個(gè)微分方程的解實(shí)際上是要給出描述光線(xiàn)上被吸收的光的總比率的積分方程。如果我們假定光線(xiàn)以p為起始點(diǎn)在介質(zhì)中沿方向上行進(jìn)了

5、距離d,則總的吸收比率是:    12.1.2 放射在介質(zhì)中,吸收過(guò)程對(duì)沿光線(xiàn)的輻射亮度有減弱作用,而放射過(guò)程卻有增強(qiáng)作用,原因是由于化學(xué)、熱力學(xué)或核作用將能量轉(zhuǎn)換為可見(jiàn)光。我們記在點(diǎn)p處的方向上單位距離上增加的出射輻射亮度為L(zhǎng)ve(p, ),那么有下列微分方程:    dLo(p, ) = Lve(p, ) dt .注意這個(gè)方程基于這樣的假定:即出射光Lve是不依賴(lài)于入射光Li的。在pbrt的線(xiàn)性光學(xué)的前提下這個(gè)假定總是成立的。12.1.3 外散射(out-scattering)和消光 (extinction)在參與介質(zhì)中,第三個(gè)光的基本交互作用是散射

6、。當(dāng)一束光穿過(guò)一種介質(zhì)中,它可以跟介質(zhì)中的粒子碰撞并被反射到不同的方向上。這對(duì)光束的總輻射亮度有兩個(gè)效 果:它減弱了光束出離一個(gè)微分區(qū)域時(shí)的輻射亮度,因?yàn)椴糠止饩€(xiàn)被反射到其它方向上。這個(gè)效果被稱(chēng)為外散射(out-scattering),即本節(jié)要介紹 的主題。然而,其它光線(xiàn)的輻射亮度也會(huì)被加到當(dāng)前的光線(xiàn)的路徑中,這是下一節(jié)要介紹的內(nèi)散射(in-scattering)。單位距離內(nèi)的外散射事件發(fā)生的概率由散射系數(shù)給s給出。跟衰減系數(shù)類(lèi)似,外散射在微分長(zhǎng)度dt上所產(chǎn)生的輻射亮度減少值可以通過(guò)下列方程給出:    dLo(p, )= s(p, ) Li(p, ) dt 由吸收和外散射

7、所引起的總輻射亮度的減少是根據(jù)a + s來(lái)決定的。這個(gè)綜合效果被稱(chēng)為衰減或消光(extinction)。為了方便起見(jiàn),我們用衰減系數(shù)t來(lái)代表兩個(gè)系數(shù)之和:    t(p, ) = a(p, ) + s(p, )有了衰減系數(shù)以后,我們可以得到描述總衰減效果的微分方程:    dLo(p, ) / dt = t(p, ) Li(p, ) 我們通過(guò)解這個(gè)方程可以得到光束透射率(beam transmittance),它給出了一條光線(xiàn)通過(guò)兩個(gè)點(diǎn)所傳輸?shù)妮椛淞炼鹊谋嚷剩?#160;   其中d是點(diǎn)p到點(diǎn)p'的距離,是兩點(diǎn)之間的向量的正規(guī)化向量,T

8、r是兩點(diǎn)之間的光束透射率。如果表面上給定方向上的出射輻射亮度是Lo(p, ),那么,通過(guò)消光作用之后,在方向上的入射輻射亮度是:    Tr(p p') Lo(p, )光束透射率有兩個(gè)很有用的性質(zhì):一個(gè)點(diǎn)到它自身的透射率為1,即Tr(p p) = 1;在真空中對(duì)于所有點(diǎn)p'都有Tr(p p') = 1。另外,對(duì)于所有的介質(zhì),在光線(xiàn)上各點(diǎn)上的透射率有相乘的關(guān)系(例如下面p,p',p''三個(gè)點(diǎn)):    Tr(p p'') = Tr(p p') Tr(p' p''

9、)這個(gè)性質(zhì)對(duì)于體積散射的實(shí)現(xiàn)而言非常有用,因?yàn)槲覀兛梢钥坑?jì)算相繼點(diǎn)上透射率的乘積逐步地得到沿光線(xiàn)上的許多點(diǎn)上的透射率。在Tr中取負(fù)值的指數(shù)被稱(chēng)為兩點(diǎn)之間的光學(xué)厚度(optical thickness), 用符號(hào)來(lái)表示:    對(duì)于均勻介質(zhì)而言,t為常量,很容易計(jì)算出的積分,從而得到Beer定律:    Tr(pp') = etd .11.1.4 內(nèi)散射(In-Scattering)外散射由于向不同方向進(jìn)行散射的緣故減弱了光線(xiàn)的輻射亮度;與之相反的是,由于其它方向上被散射的光線(xiàn)加入到當(dāng)前光線(xiàn)的方向,內(nèi)散射加強(qiáng)了光線(xiàn)的輻射亮 度。假定粒子之間的間距是

10、它們半徑的數(shù)倍,這樣我們就可以忽略粒子之間的交互作用。在這個(gè)假定之下,相函數(shù)p(')表示了在某點(diǎn)上的散射輻射 (scattered radiation)的角分布。它相當(dāng)于體積上的BSDF。然而,這個(gè)比擬并不準(zhǔn)確,因?yàn)橄嗪瘮?shù)有一個(gè)歸一化約束,即對(duì)于所有的,滿(mǎn)足下列條件:    這個(gè)約束條件意味著相函數(shù)實(shí)際上定義了在特定方向上散射的概率分布。內(nèi)散射所增加的總輻射亮度可以由源項(xiàng)S給出,即:    dLo(p, ) = S(p, ) dt它包括了體積放射和內(nèi)散射:    源項(xiàng)的內(nèi)散射部分是單位距離內(nèi)的散射概率s和在該點(diǎn)上所增加的輻射亮

11、度的乘積,所增加的輻射亮度可以通過(guò)對(duì)入射輻射亮度和相函數(shù) 的乘積進(jìn)行球面積分得到。注意這個(gè)公式跟第5章的散射方程很相似,主要的不同是這里沒(méi)有cosine項(xiàng),因?yàn)橄嗪瘮?shù)使用的是輻射亮度而不是微分輻射照度 (differential irradiance)。12.2 相函數(shù)人們?yōu)榱嗣枋霰砻嫔仙⑸溲芯苛嗽S多BSDF模型,同樣地,人們也開(kāi)發(fā)了許多相函數(shù)來(lái)描述體積散射。其中包括用少數(shù)參數(shù)來(lái)做擬合函數(shù)的參數(shù)化模型,還有基于粒子形狀和材質(zhì)(如球形水滴)而推導(dǎo)出的散射輻射分布的解析模型,等等。在大多數(shù)的自然產(chǎn)生的介質(zhì)中,相函數(shù)是關(guān)于兩個(gè)方向和'的夾角的一維函數(shù);這樣的介質(zhì)被稱(chēng)為各向同性的(isotro

12、pic),它們的相函數(shù)常常被 寫(xiě)成p(cos)。在比較奇異的介質(zhì)中,例如有水晶結(jié)構(gòu)的介質(zhì),它的相函數(shù)是兩個(gè)方向的4D函數(shù)。除了前面提到的歸一化性質(zhì)以外,自然生成的介質(zhì)還有一 個(gè)重要的性質(zhì),即互反性(reciprocal):兩個(gè)方向相互交換后,相函數(shù)值保持不變。注意各向同性的介質(zhì)的互反性很容易從cos(-) = cos()得到。相函數(shù)本身可以是各向同性的(isotropic),也可以是各向異性的(isotropic)的。因?yàn)楦飨蛲缘南嗪瘮?shù)描述的是在各個(gè)方向上的均勻散射,因此跟兩個(gè)方向都無(wú)關(guān)。因?yàn)橄嗪瘮?shù)是歸一化的,因此只有唯一的各向同性函數(shù),且為常量1/4:    P iso

13、tropic(') = 1 / 4 <Volume Scattering Definitions> =    float PhaseIsotropic(const Vector &, const Vector &)         return 1.f / (4.f * M_PI);    本節(jié)下面所介紹的各向異性相函數(shù)描述的是各向同性介質(zhì),因此是用兩個(gè)方向的夾角來(lái)定義的(如圖)。    跟表面上散射的約定(兩個(gè)方向都背離散射點(diǎn))有所不同的

14、是,這里入射方向是指向散射點(diǎn)的,而出射方向是背離散射點(diǎn)的,這跟相函數(shù)的約定一致。pbrt實(shí)現(xiàn)了描述Rayleigh散射和Mie散射的相函數(shù)。Rayleigh模型表示了在地球大氣中極小粒子(如分子)所產(chǎn)生的散射。如果粒子半徑比 光波長(zhǎng)小(r/ <  0.05),Rayleigh模型就可以很精確地描述散射光的分布。跟波長(zhǎng)相關(guān)的Rayleigh散射也是藍(lán)天之所以藍(lán)、晚霞之所以紅的原 因。Mie散射基于更一般性的理論:它是從Maxwell方程推導(dǎo)出來(lái)的,可以描述的粒子半徑范圍更為寬廣。例如,它可以很好地描述水霧中的天氣。<Volume Scattering Declar

15、ations> =    float PhaseRayleigh(const Vector &w, const Vector &wp);    float PhaseMieHazy(const Vector &w, const Vector &wp);    float PhaseMieMurky(const Vector &w, const Vector &wp);在計(jì)算機(jī)圖形學(xué)中得到廣泛應(yīng)用的一個(gè)相函數(shù)是由Henyey和Greenstein開(kāi)發(fā)的。這個(gè)相函數(shù)很容易和測(cè)量出的散射

16、數(shù)據(jù)相擬合。它有一個(gè)單一的參數(shù)g(稱(chēng)為非對(duì)稱(chēng)參數(shù)),用來(lái)控制散射光的分布:    pHG(cos ) = (1/4) (1 g2) / (1+ g2 2g(cos )3/2下圖顯示了HenyeyGreenstein相函數(shù),它具有可變的非對(duì)稱(chēng)參數(shù)g,變化范圍是(-1, 1)。負(fù)的g值對(duì)應(yīng)于向后散射(back-scattering),這時(shí)光大多數(shù)會(huì)在入射方向上散射(圖中的實(shí)線(xiàn)部分對(duì)應(yīng)g = -0.35);正的g值對(duì)應(yīng)于向前散射(forword-scattering) (圖中的虛線(xiàn)部分對(duì)應(yīng)g = 0.67)。g的值越大,散射方向就越靠近- (向后散射)或(向前散射)方向。<

17、Volume Scattering Definitions> +=    float PhaseHG(const Vector &w, const Vector &wp, float g)         float costheta = Dot(w, wp);        return 1.f / (4.f * M_PI) *            (

18、1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f);    非對(duì)稱(chēng)參數(shù)有很?chē)?yán)格的意義。它是相函數(shù)和-'夾角余弦的乘積的平均值。給定一個(gè)任意的相函數(shù),可以用下式計(jì)算g:    這樣,對(duì)于各向同性相函數(shù)來(lái)說(shuō),g=0。滿(mǎn)足這個(gè)方程的相函數(shù)有任意多個(gè),單獨(dú)使用g值不足以唯一地描述一個(gè)散射分布。然而。我們將復(fù)雜的散射分布化簡(jiǎn)為一個(gè)只有一個(gè)參數(shù)的模型,這樣做所帶來(lái)的方便比可能的精度上的缺失更重要。無(wú)法用單一的非對(duì)稱(chēng)參數(shù)描述的更復(fù)雜的相函數(shù)常常用相函數(shù)(如HenyeyGreenstein相函數(shù))的加權(quán)

19、和來(lái)表示,其中每個(gè)相函數(shù)帶有不同的參數(shù)值:    其中所有的wi的和為1以保證正規(guī)性。Blasi, Le Saec, 和Schlick開(kāi)發(fā)出了一個(gè)HenyeyGreenstein相函數(shù)的很高效的近似表示,由于它的高效性而被廣泛地應(yīng)用于計(jì)算機(jī)圖形學(xué)領(lǐng)域中:    pSchlick(cos ) = (1/4)(1 k2)/(1 k cos )2其中參數(shù)k跟HenyeyGreenstein中的g項(xiàng)有類(lèi)似的作用,-1對(duì)應(yīng)于向后散射,0對(duì)應(yīng)于各向同性散射,1對(duì)應(yīng)于向前散射。兩者關(guān)系如下:    k = 1.55g - .55g3<Volu

20、me Scattering Definitions> +=    float PhaseSchlick(const Vector &w, const Vector &wp, float g)         float k = 1.55f * g - .55f * g * g * g;        float kcostheta = k * Dot(w, wp);       

21、60;return 1.f / (4.f * M_PI) *            (1.f - k*k) / (1.f - kcostheta) * (1.f - kcostheta);    12.3 體積區(qū)域接口和均勻介質(zhì)在pbrt中描述體積散射的核心抽象類(lèi)是VolumeRegion,它是描述場(chǎng)景中一個(gè)區(qū)域中的體積散射的接口。在場(chǎng)景中不同的部分,可以使用不同類(lèi)型的VolumeRegion來(lái)描述不同類(lèi)型的散射。<Volume Scattering Declarations> +=

22、    class COREDLL VolumeRegion     public:        <VolumeRegion Interface>    ;所有的VolumeRegion必須可以計(jì)算和軸對(duì)齊的世界空間包圍盒,它可以通過(guò)函數(shù)VolumeRegion:WorldBound()來(lái)得到。跟Shape和Primitive一樣,這個(gè)包圍盒可以用來(lái)將VolumeRegion放入加速結(jié)構(gòu)。<VolumeRegion Interface> = 

23、;   virtual BBox WorldBound() const = 0;因?yàn)閂olumeIntegrator需要知道光線(xiàn)在世界空間中穿過(guò)體積區(qū)域的參數(shù)范圍,而且世界包圍盒并不一定能夠緊包住體積區(qū)域,所以我們提供了一個(gè) 單獨(dú)的函數(shù)VolumeRegion:IntersectP(),用來(lái)返回光線(xiàn)跟該區(qū)域重疊的那部分光線(xiàn)的參數(shù)t值的范圍。<VolumeRegion Interface> +=    virtual bool IntersectP(const Ray &ray, float *t0, float *t1) const = 0;這

24、個(gè)接口有4個(gè)函數(shù),分別對(duì)應(yīng)于前面介紹的散射性質(zhì)。給定了世界空間的一個(gè)點(diǎn)和方 向,VolumeRegion:sigma_a(),VolumeRegion:sigma_s(),VolumeRegion:sigma_Lve() 返回相應(yīng)的吸收、散射和放射性質(zhì)。給定一對(duì)方向后,VolumeRegion:p()函數(shù)返回給定點(diǎn)的相函數(shù)值。<VolumeRegion Interface> +=    virtual Spectrum sigma_a(const Point &, const Vector &,      

25、      float time) const = 0;    virtual Spectrum sigma_s(const Point &, const Vector &,            float time) const = 0;    virtual Spectrum Lve(const Point &, const Vector &,      &#

26、160;     float time) const = 0;    virtual float p(const Point &, const Vector &,            const Vector &, float time) const = 0;為了方便,還有一個(gè)函數(shù)VolumeRegion:sigma_t()用來(lái)返回給定點(diǎn)上的衰減系數(shù)。它的缺省實(shí)現(xiàn)是返回a和s的和,但大多數(shù)的實(shí)現(xiàn)會(huì)重載該函數(shù),直接計(jì)算出t。<Volum

27、e Scattering Definitions> +=    Spectrum VolumeRegion:sigma_t(const Point &p, const Vector &w,            float time) const         return sigma_a(p, w, time) + sigma_s(p, w, time);    最后,VolumeRegio

28、n:tau()函數(shù)根據(jù)點(diǎn)ray(ray.mint)和點(diǎn)ray(ray.maxt)來(lái)計(jì)算體積區(qū)域的光學(xué)厚度。有些實(shí)現(xiàn) 可以之間計(jì)算出這個(gè)值,例如下節(jié)要介紹的HomogeneousVolume,而其它的實(shí)現(xiàn)需要Monte Carlo積分來(lái)計(jì)算。為了方便使用Monte Carlo方法,該函數(shù)使用了兩個(gè)可選的參數(shù),step和offset,對(duì)于使用封閉形式解的實(shí)現(xiàn)而言,可以忽略這兩個(gè)參數(shù)。<VolumeRegion Interface> +=    virtual Spectrum tau(const Ray &ray, float step = 1.f,

29、0;       float offset = 0.5) const = 0;11.3.1 均勻體積區(qū)域最簡(jiǎn)單的體積表示是HomogeneousVolume,它描述了具有均勻散射性質(zhì)的盒形區(qū)域。它的構(gòu)造器使用了a和s,相函數(shù)的g值,還有放射量 Lve。再加上從世界空間到體積區(qū)域的物體空間的變換還有一個(gè)軸對(duì)齊的物體空間的包圍盒,就足夠可以描述該區(qū)域的散射性質(zhì)和空間范圍。<HomogeneousVolumeDensity Declarations> =    class HomogeneousVolumeDensit

30、y : public VolumeRegion     public:        <HomogeneousVolumeDensity Public Methods>    private:        <HomogeneousVolumeDensity Private Data>    ;<HomogeneousVolumeDensity Private Data> =

31、60;   Spectrum sig_a, sig_s, le;    float g;    BBox extent;    Transform WorldToVolume;由于包圍盒是定義在物體空間的,所以在WorldBound()函數(shù)中使用到世界空間的變換。<HomogeneousVolumeDensity Public Methods> =    BBox WorldBound() const         return I

32、nverse(WorldToVolume)(extent);    如果區(qū)域的世界空間-物體空間變換包含了旋轉(zhuǎn)操作,那么該區(qū)域在世界空間里就不是軸對(duì)齊的了,但我們可以將光線(xiàn)變換到區(qū)域的物體空間中,并求得它們的重疊部分,這樣就可以得到更緊密的光線(xiàn)參數(shù)范圍。<HomogeneousVolumeDensity Public Methods> +=    bool IntersectP(const Ray &r, float *t0, float *t1) const         

33、;Ray ray = WorldToVolume(r);        return extent.IntersectP(ray, t0, t1);    剩下的接口函數(shù)都很簡(jiǎn)單。它們都先要驗(yàn)證給定點(diǎn)是否是在區(qū)域中,如果是的話(huà)就返回相應(yīng)的值。這里只列出了sigma_a(),其它的函數(shù)就略去了。<HomogeneousVolumeDensity Public Methods> +=    Spectrum sigma_a(const Point &p, const Vector

34、 &, float) const         return extent.Inside(WorldToVolume(p) ? sig_a : 0.;    由于a和s在整個(gè)區(qū)域中是常量,我們可以通過(guò)Beer法則以封閉解的形式來(lái)計(jì)算光學(xué)厚度:<HomogeneousVolumeDensity Public Methods> +=    Spectrum tau(const Ray &ray, float, float) const    

35、0;    float t0, t1;        if (!IntersectP(ray, &t0, &t1) return 0.;        return Distance(ray(t0), ray(t1) * (sig_a + sig_s);    12.4密度可變的體積區(qū)域本章所介紹的其它的體積區(qū)域基于這樣的一個(gè)假設(shè):介質(zhì)中的粒子有相同的基本散射性質(zhì),但其密度是隨空間位置變化的。這個(gè)假設(shè)所產(chǎn)生的結(jié)

36、論之一就是我們可以 用該點(diǎn)的密度乘以某個(gè)基準(zhǔn)值來(lái)描述體積散射性質(zhì)。例如,我們可以為衰減系數(shù)t設(shè)置基準(zhǔn)值為0.2。對(duì)于粒子密度為1的區(qū)域,t返回0.2。如果粒子密 度為3,則返回0.6。為了減少重復(fù)性代碼,并令不同的表示將重點(diǎn)放在定義粒子密度的方法上,我們定義了一個(gè)DensityRegion類(lèi),它定義了一個(gè)純虛函數(shù)來(lái)獲取一個(gè)點(diǎn)上的粒子密度。體積區(qū)域的表示可以繼承DensityRegion,就無(wú)需實(shí)現(xiàn)相同的邏輯了。<Volume Scattering Declarations> +=    class DensityRegion : public VolumeReg

37、ion     public:        <DensityRegion Public Methods>    protected:        <DensityRegion Protected Data>    ;DensityRegion構(gòu)造器使用了基本散射性質(zhì)的值,并將它們放入相應(yīng)的成員變量中。注意接口聲明了體積區(qū)域-世界空間的變換,但該類(lèi)存放的是世界空間-體積區(qū)域的變換。<D

38、ensityRegion Protected Data> =    Transform WorldToVolume;    Spectrum sig_a, sig_s, le;    float g;    <DensityRegion Public Methods> =    DensityRegion(const Spectrum &sa, const Spectrum &ss, float gg,      

39、0; const Spectrum &emit, const Transform &VolumeToWorld)            : sig_a(sa), sig_s(ss), le(emit), g(gg),    WorldToVolume(Inverse(VolumeToWorld) 所有DensityRegion的繼承類(lèi)必須實(shí)現(xiàn)DensityRegion:Density(),它返回了體積區(qū)域在物體空間中給定點(diǎn)的密度。該密度用來(lái)乘以基本的散射參數(shù),故在任何一

40、點(diǎn)都應(yīng)該是非負(fù)數(shù)。<DensityRegion Public Methods> +=    virtual float Density(const Point &Pobj) const = 0;這里只列出DensityRegion:sigma_a()函數(shù)的實(shí)現(xiàn),其它類(lèi)似,從略:<DensityRegion Public Methods> +=    Spectrum sigma_a(const Point &p, const Vector &) const       

41、;  return Density(WorldToVolume(p) * sig_a;    其中一個(gè)例外是DensityRegion:p()函數(shù),它并不是用局部的密度乘以相函數(shù)值,因?yàn)閺狞c(diǎn)到點(diǎn)的散射變化已經(jīng)由s負(fù)責(zé)處理了。<DensityRegion Public Methods> +=    float p(const Point &p, const Vector &w, const Vector &wp) const         

42、return PhaseHG(w, wp, g);    DensityRegion無(wú)法實(shí)現(xiàn)VolumeRegion:Tau()函數(shù),因?yàn)檫@個(gè)函數(shù)基于對(duì)VolumeRegion形狀的總體的了解,還要知道其中的密度分布。因此這個(gè)方法應(yīng)該由所有的繼承類(lèi)來(lái)實(shí)現(xiàn)。12.4.1 三維網(wǎng)格VolumeGrid類(lèi)將密度存放在一個(gè)普通的三維的位置網(wǎng)格中,這跟用2D采樣網(wǎng)格來(lái)表示圖像的ImageTexture有些類(lèi)似。我們通過(guò)對(duì)這些采樣 值進(jìn)行插值來(lái)計(jì)算采樣點(diǎn)之間的位置上的密度。它的構(gòu)造器使用了用戶(hù)提供的存放著密度的3D數(shù)組,這就可以允許使用很多類(lèi)型的數(shù)據(jù)源(物理仿真,CT掃描, 等等)。因

43、為它是DensityRegion的子類(lèi),所以用戶(hù)也要提供a、s、Lve和g的基準(zhǔn)值。<VolumeGrid Declarations> =    class VolumeGrid: public DensityRegion     public:        <VolumeGridDensity Public Methods>    private:        <VolumeGri

44、dDensity Private Data>    ;構(gòu)造器做基本散射參數(shù)的初始化,存儲(chǔ)區(qū)域的物體空間中的包圍盒,并做密度值的局部拷貝。<VolumeGrid Public Methods> =    VolumeGrid (const Spectrum &sa, const Spectrum &ss, float gg,            const Spectrum &emit, const BBox &e, cons

45、t Transform &v2w,        int x, int y, int z, const float *d)        : DensityRegion(sa, ss, gg, emit, v2w), nx(x), ny(y), nz(z), extent(e)         density = new floatnx*ny*nz;      

46、0; memcpy(density, d, nx*ny*nz*sizeof(float);    <VolumeGridPrivate Data>    float *density;    const int nx, ny, nz;    const BBox extent;WorldBound()函數(shù)跟IntersectP()函數(shù)跟前面所介紹的HomogeneousVolume中的類(lèi)似,從略。VolumeGrid的Density()的任務(wù)是用采樣來(lái)重構(gòu)給定點(diǎn)上的密度。<VolumeG

47、ridMethod Definitions> =    float VolumeGrid:Density(const Point &Pobj) const         if (!extent.Inside(Pobj) return 0;        <Compute voxel coordinates and offsets for Pobj>        <

48、;Trilinearly interpolate density values to compute local density>    有了3D空間中一個(gè)點(diǎn)的8個(gè)采樣值之后,該函數(shù)用三線(xiàn)性插值來(lái)計(jì)算該點(diǎn)的密度函數(shù)值。首先,要找到整數(shù)坐標(biāo)小于該采樣位置的最近的體積區(qū)域采樣,然后用沿每個(gè)軸的麥哈頓距離(Manhattan distance)(dx,dy,dz)來(lái)插值。<Compute voxel coordinates and offsets for Pobj> =    float voxx = (Pobj.x - extent.pMi

49、n.x) /        (extent.pMax.x - extent.pMin.x) * nx - .5f;    float voxy = (Pobj.y - extent.pMin.y) /        (extent.pMax.y - extent.pMin.y) * ny - .5f;    float voxz = (Pobj.z - extent.pMin.z) /      

50、  (extent.pMax.z - extent.pMin.z) * nz - .5f;    int vx = Floor2Int(voxx);    int vy = Floor2Int(voxy);    int vz = Floor2Int(voxz);    float dx = voxx - vx, dy = voxy - vy, dz = voxz - vz;我們用這些距離做一系列的Lerp()調(diào)用來(lái)估算出采樣點(diǎn)的密度:<Trilinearly interpolate de

51、nsity values to compute local density> =    float d00 = Lerp(dx, D(vx, vy, vz), D(vx+1, vy, vz);    float d10 = Lerp(dx, D(vx, vy+1, vz), D(vx+1, vy+1, vz);    float d01 = Lerp(dx, D(vx, vy, vz+1), D(vx+1, vy, vz+1);    float d11 = Lerp(dx, D(vx, vy+1, vz+1

52、), D(vx+1, vy+1, vz+1);    float d0 = Lerp(dy, d00, d10);    float d1 = Lerp(dy, d01, d11);    return Lerp(dz, d0, d1);工具函數(shù)D()返回給定采樣位置上的密度。它的唯一任務(wù)是使用截取(clamping)方式處理越界的情況,并計(jì)算出給定采樣的數(shù)組偏置值。跟MIPMaps不同的是,截取方式幾乎總是我們想要的方式。因?yàn)樗械牟檎尹c(diǎn)都位于包圍盒之內(nèi),只有在邊界的情況會(huì)出現(xiàn)越界。<VolumeGrid Public Met

53、hods> =    float D(int x, int y, int z) const         x = Clamp(x, 0, nx-1);        y = Clamp(y, 0, ny-1);        z = Clamp(z, 0, nz-1);        return densityz*nx*ny +

54、 y*nx + x;    12.4.2 指數(shù)密度另一個(gè)很有用的密度類(lèi)是ExponentialDensity類(lèi),它描述了在給定的3D范圍內(nèi)按照關(guān)于高度h的指數(shù)函數(shù)變化的密度分布:        d(h) = a e-bh其中a,b分別是控制總體密度的參數(shù)以及按高度進(jìn)行衰減的快慢程度的參數(shù)。這個(gè)密度函數(shù)是對(duì)在地球表面上所觀(guān)察到的地球大氣是個(gè)很好的模擬(這里忽略了地球的彎曲)。它也可以用于模擬在地平面上的低沉的霧氣。    <ExponentialDensity Declarations>

55、; =    class ExponentialDensity : public DensityRegion     public:        <ExponentialDensity Public Methods>    private:        <ExponentialDensity Private Data>    ;ExponentialDensity的構(gòu)造

56、器使用所傳入的變量來(lái)初始化成員函數(shù)。除了要傳入DensityRegion構(gòu)造器的體積散射性質(zhì)外,還有體 積的包圍盒,參數(shù)a和b。這個(gè)構(gòu)造器還要用到一個(gè)“向上”的向量對(duì)體積區(qū)域進(jìn)行朝向定位,并用來(lái)計(jì)算點(diǎn)的高度。當(dāng)然,向上向量并非必要(實(shí)際上使用世界 -物體變換也可以做到這一點(diǎn)),但在概念上更容易為用戶(hù)理解。<ExponentialDensity Public Methods> =    ExponentialDensity(const Spectrum &sa, const Spectrum &ss,     

57、0;  float gg, const Spectrum &emit, const BBox &e,        const Transform &v2w, float aa, float bb,        const Vector &up)    : DensityRegion(sa, ss, gg, emit, v2w), extent(e), a(aa), b(bb)    

58、;     upDir = Normalize(up);    <ExponentialDensity Private Data> =    BBox extent;    float a, b;    Vector upDir;WorldBound()函數(shù)跟IntersectP()函數(shù)跟前面所介紹的HomogeneousVolume中的類(lèi)似,從略。在物體空間中,給定點(diǎn)的沿“向上”向量的高度可以這樣求得:將從包圍盒的下角(lower corner)到p的向量投影到

59、“向上”向量的方向上,然后求兩個(gè)向量的點(diǎn)積即得到高度。如圖:<ExponentialDensity Public Methods> +=    float Density(const Point &Pobj) const         if (!extent.Inside(Pobj) return 0;        float height = Dot(Pobj - extent.pMin, upDir);   

60、     return a * expf(-b * height);    12.5 體積聚合體跟可以存放一組Primitive的Aggregate類(lèi)一樣,AggregateVolume可以存放一個(gè)或多個(gè)VolumeRegion。這樣做有兩 個(gè)原因:第一,簡(jiǎn)化場(chǎng)景以及對(duì)VolumeIntegrator的實(shí)現(xiàn),因?yàn)槲覀兛梢灾粚?duì)一個(gè)AggregateVolume進(jìn)行函數(shù)調(diào)用,而無(wú)需對(duì)場(chǎng)景 中所有的區(qū)域進(jìn)行循環(huán);第二,AggeragateVolume的實(shí)現(xiàn)可以有可能利用3D空間數(shù)據(jù)結(jié)構(gòu)來(lái)提升效率,因?yàn)槲覀兛梢蕴蕹衾锾囟ü饩€(xiàn)或查找點(diǎn) 太遠(yuǎn)的

61、區(qū)域。這里我們只實(shí)現(xiàn)一個(gè)簡(jiǎn)單的AggregateVolume,它有一個(gè)存放場(chǎng)景中所有體積區(qū)域的列表,并在具體的函數(shù)實(shí)現(xiàn)中對(duì)這些區(qū)域進(jìn)行循環(huán)。當(dāng)場(chǎng)景中有許多不同的區(qū)域時(shí),這個(gè)實(shí)現(xiàn)不太高效,如何寫(xiě)一個(gè)高效的實(shí)現(xiàn)留做練習(xí)。<Volume Scattering Declarations> +=    class AggregateVolume : public VolumeRegion     public:        <AggregateVolume Public Methods>    private:        <AggregateVolume Private Data>    ;它的構(gòu)造器很簡(jiǎn)單,只是拷

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論