【RAY TRACING THE REST OF YOUR LIFE 超詳解】 光線追蹤 3-1
今天起,我們就開始學習第三本書了
這本書主要講的是蒙特卡羅渲染,以及相關的數學、術語概念等
我們先來一個簡單的開胃菜
chapter 1:A Simple Monte Carlo Program
蒙特卡羅方法(MC)是一種統計模擬方法,是一類很重要的數值計算方法,它是一種使用隨機數解決好很多實際問題的方法。
先來看一個很簡單的例子:估計π
有很多經典的方法,其中之一是
假設你扔了很多隨機的點到方框中,那麼有一部分在圓內,其中圓內點和方框點的比例應該就是圓的面積和方框面積的比例,由此:
比例 = (π * R * R)/((2R)*(2R)) = π/4
所以上式和R無關,我們任意取R = 1,圓心位於原點,則
#include <iostream> #include <lvgm\randfunc.hpp> #define stds std:: using namespace lvgm; void estimate_π(const size_t points) { int inside = 0; for (int i = 0; i < points; ++i) { double x = 2 * rand01() - 1; double y = 2 * rand01() - 1; if (x*x + y*y < 1) inside++; } stds cout << "Estimate of π by" << points << "test points is " << 4 * double(inside) / points << stds endl; } int main() { estimate_π(1000); estimate_π(10000); estimate_π(100000); estimate_π(1000000); estimate_π(10000000); estimate_π(10000000 / 2); }
模擬結果為
當然我們可以利用下面的程式使結果迅速逼近π
void lawDiminishingReturns() { int inside = 0; int runs = 0; while (true) { runs++; double x = 2 * rand01() - 1; double y = 2 * rand01() - 1; if (x*x + y*y < 1) inside++; if(runs % 10000 == 0) stds cout << "Estimate of π by" << runs << "test points is " << 4 * double(inside) / runs << stds endl; } }
結果:
.
一開始非常快速的逼近π,之後變化就比較緩慢了,這是一個收益遞減法( Law of Diminishing Returns) 的例子
即每一個樣本對結果的收益少於後面一個,這個是MC的一個缺點,我們可以通過對樣本進行分層來減輕這種遞減收益,此法通常稱為抖動
我們進行網格劃分,並在每個網格中選取一個樣本:
我們採用邊長為1e4的方框進行測試
void stratify() { size_t inside{ 0 }; size_t circle_stratified{ 0 }; size_t sqrtAll = 1e4; for (int i = 0; i < sqrtAll; ++i) for (int j = 0; j < sqrtAll; ++j) { double x = 2 * rand01() - 1; double y = 2 * rand01() - 1; if (x*x + y*y < 1) inside++; x = 2 * ((i + rand01()) / sqrtAll) - 1; y = 2 * ((j + rand01()) / sqrtAll) - 1; if (x*x + y*y < 1) circle_stratified++; } stds cout << "Regular Estimate of π by 1e8 test points is " << 4 * double(inside) / 1e8 << stds endl; stds cout << "Stratified Estimate of π by 1e8 test points is " << 4 * double(circle_stratified) / 1e8 << stds endl; }
圖片渲染運算讀寫檔案的時候慢。。如今控制檯運算輸出也整不動了。。。。
有意思~
分層方法能更好地收斂於漸近率。不足之處是,這個優勢隨著問題的維度而降低(例如,對於3D球體積版本,差距會更小)。 這被稱為維度詛咒(=.=)。 我們的工程將是非常高的維度(每個反射增加兩個維度),所以我不會在本書中進行分層。
但是,如果你做的是單反射或陰影或某些嚴格的2D問題,分層是個很好的選擇
感謝您的閱讀,生活愉快~