《學一輩子光線追蹤》 四 重要性取樣材料

2021-10-07 05:52:43 字數 3149 閱讀 3417

蒙特卡洛光線追蹤技術系列 見 蒙特卡洛光線追蹤技術

在接下來的兩章中,我們的目標是利用我們的程式向光源傳送一束額外的光線,這樣我們的雜訊就不會太多了。假設我們可以使用pdf plight(direction) 向光源傳送一束光線。假設我們有乙個與s相關的pdf,我們稱之為psu***ce(direction)。pdf 的乙個優點是,可以使用它們的線性混合來形成混合密度,這也是pdf。

例如,最簡單的方法是:

p(direction) = 0.5*plight(direction) + 0.5*psu***ce(direction)

只要權重是正的並且加起來是1,任何這種pdf的混合都是pdf。記住,我們可以使用任何pdf-它不會改變我們的答案!所以,目標是要找出當乘積 s(direction)*color(direction) 更大的時候,如何使pdf更大。對於漫反射曲面,這主要是猜測顏色(方向)高的地方。對於鏡子來說,s()只在乙個方向附近是巨大的,所以它更重要。事實上,大多數渲染器都會將鏡面作為一種特殊情況,而只是將s/p隱式化——我們的**目前就是這樣做的。

讓我們做乙個簡單的重構,暫時刪除所有不是lambertian的材質(不想刪除也得改改裡面繼承的函式)。我們可以再次使用康奈爾盒子場景,還是使用之前的視點:

vec3 lookfrom(278, 278, -800);//

vec3 lookat(278, 278, 0);

框架也是我在上本書的最後實現的每次渲染都輸出結果的框架。

減少噪音是我們的目標。我們將通過構建乙個pdf來實現這一點,它可以向光傳送更多的光線。

首先,讓我們測試**,以便它顯式地對一些 pdf 進行取樣,然後對其進行規範化。記住mc基礎:積分 f(x) 大約等於 f(r)/p(r)。對於朗伯材料,讓我們像現在這樣取樣:p(direction)=cos(theta)/pi。

我們修改材料以啟用此重要性取樣:

class material 

virtual float scattering_pdf(const ray &r_in, const hit_record& rec, const ray& scattered)const

virtual vec3 emitted(float u, float v, const vec3&p)const

};class lambertian :public material

virtual float scattering_pdf(const ray& r_in, const hit_record& rec, ray& scattered)const

virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& alb, ray& scattered, float &pdf)const

texture* albedo;

};

注意修改一些其他**,因為凡是繼承後的類,都需要修改繼承的虛函式。

vec3 color(const ray&r, hitable *world, int depth) 

else

} else

}

結果竟然只顯示乙個燈,物體和牆都沒有了。我們開始除錯,首先修改一下color函式:

vec3 color(const ray&r, hitable *world, int depth) //albedo* rec.mat_ptr->scattering_pdf(r,rec,scattered) *

else

} else

}

得到結果:

隱約能看到物體,說明是 albedo* rec.mat_ptr->scattering_pdf(r,rec,scattered) 出了問題。

深入檢查,發現

virtual float scattering_pdf(const ray& r_in, const hit_record& rec, ray& scattered)const

的最後乙個引數 ray 竟然少了乙個const修飾符。改過來以後就可以了。效果和前面的一樣。

現在,為了體驗,嘗試不同的抽樣策略。讓我們從高於表面的半球中隨機選擇。這就是p(direction) = 1/(2*pi)

virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& alb, ray& scattered, float &pdf)const  while (dot(direction, rec.normal) < 0);

scattered = ray(rec.p, unitvector(direction), r_in.time());

alb = albedo->value(rec.u, rec.v, rec.p);

pdf = 0.5 / m_pi;

return true;

}

得到結果:

相同背景物體和光照條件下的對比:

再說一遍,我應該得到相同的,除了不同的變化幅度,但並沒有。第二張**的長方體非常均勻,這是為什麼呢?

它很接近我們的老**,但有一些差異不是雜訊。這個高盒子的正面顏色要均勻得多。所以我有最難在蒙特卡羅程式中找到的一種錯誤——一種能產生合理外觀影象的錯誤。我不知道這個bug是程式的第乙個版本還是第二個版本,甚至兩者都是!

讓我們建立一些基礎設施來解決這個問題。

《學一輩子光線追蹤》 六 正交基

蒙特卡洛光線追蹤技術系列 見 蒙特卡洛光線追蹤技術 在最後一章中,我們開發了生成與日晷相對的隨機方向的方法。我們要做的是基於任意曲面的法向量。正交正規基 onb 是三個相互正交的單位向量的集合。笛卡爾xyz軸就是這樣的乙個onb,我有時忘記了它必須坐在某個真實的地方,有真實的方向,才能在真實世界中有...

認識網路(一) 幹一輩子革命學一輩子c

網路 網路其實就是跨主機的 程序間 通訊協議分層 分層的意義 網路協議比較複雜,如果不拆分就會很複雜 分層的好處 拆分成多個模組相當於降低了整個系統的耦合程度,根據實際需要,隨時可以替換其中的某一層協議osi七層模型 tcp ip五層 或四層 模型 由圖可見網路層和傳輸層都是由作業系統核心來實現的,...

讓你「有錢一輩子」的四個習慣

美國理財 專家柯特 康寧漢有句名言 不能養成良好的理財習慣,即使擁有博士學位,也難以擺脫貧窮。雖然養成好的理財習慣是個有些痛苦的過程,但這些習慣可以讓你 有錢一輩子 美國學者托馬斯 史丹 利調查過上萬名百萬富翁,其中的84 都是從儲蓄和省錢開始的 大約70 的富翁每週工作55個小時,仍然抽時間進行理...