蒙特卡洛光線追蹤技術系列 見 蒙特卡洛光線追蹤技術
在接下來的兩章中,我們的目標是利用我們的程式向光源傳送一束額外的光線,這樣我們的雜訊就不會太多了。假設我們可以使用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個小時,仍然抽時間進行理...