《再學一周光線追蹤》 學習 一 引子和運動模糊

2021-10-06 18:24:54 字數 3909 閱讀 2578

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

在《一周學完光線跟蹤》書本中,您構建了乙個簡單且蠻力的光線***。在本期中,我們將新增紋理、體(如霧)、矩形、例項、燈光,並支援使用bvh的許多物件。完成後,你會有乙個「真正的」光線***。

許多人(包括我)相信,光線跟蹤中的乙個啟發是,大多數優化會使**複雜化,而不會帶來很大的加速。我將在這本迷你書中做的是在每乙個設計決策中採用最簡單的方法。去 光線追蹤學習**  (該**在國內貌似訪問不了,鑑於翻牆是違法行為您可以等著哪天去日本旅遊的時候再登入這個**學習)可以閱讀和參考更複雜的方法。但是,我強烈建議您不要過早地進行優化;如果它的執行時間在配置檔案中顯示得不高,則在支援所有功能之前,它最好先不進行優化!

這本書最難的兩部分是bvh和perlin紋理。這就是為什麼標題建議你花乙個星期而不是乙個週末來完成這項工作。但如果你想週末做專案的話,你可以把這些留到最後。順序不是在這本書中提出的很重要的概念,沒有bvh和柏林紋理你仍然可以得到cornell 盒!

運動模糊:

當您決定使用光線跟蹤時,您認為視覺質量更值得執行時使用。在模糊反射和散焦模糊中,每個畫素需要多個取樣。一旦你在這條道路上邁出了一步,好訊息是幾乎所有的效果都可以用暴力來實現。運動模糊當然是其中之一。在真正的相機中,快門開啟並保持開啟一段時間間隔,相機和物件可能在這段時間內移動。它實際上是相機在我們想要的時間間隔內所看到的平均值。當快門開啟時,我們可以通過在某個隨機時間傳送每條光線來獲得隨機估計。只要物體在那個時候應該在的地方,我們就可以用一條正好在同一時間的射線得到正確的平均答案。這就是為什麼隨機光線跟蹤往往很簡單的根本原因。

基本思想是在快門開啟時隨機生成光線並在該時間與模型相交。通常的方法是讓攝影機和物件移動,但讓每條光線恰好同時存在。這樣,光線***的「引擎」就可以確保物件位於光線所需的位置,並且交集部分不會有太大變化。

#ifndef ray_h

#define ray_h

#include "vec3.h"

class ray

ray(const vec3& a, const vec3& b,float ti = 0.0)

ray(const ray& r)

vec3 origin() const

vec3 direction() const

float time()const

vec3 pointatparameter(float t) const

vec3 a;

vec3 b;

float _time;

};#endif

現在我們需要修改相機以在時間1和時間2之間的隨機時間生成光線。相機應該跟蹤時間1和時間2,還是應該在建立光線時由相機的使用者決定?當有疑問的時候,我喜歡讓構造器變得複雜,如果它使呼叫變得簡單,那麼我會讓相機保持跟蹤,但這是個人的偏好。相機不需要太多的改動,因為現在不允許移動;它只是在一段時間內發出光線。

#ifndef __camera_h__

#define __camera_h__

#include "ray.h"

#define m_pi 3.14159265

double myrandom();

vec3 random_in_unit_disk() while (dot(p, p) >= 1.0);

return p;

}class camera

ray get_ray(float s, float t)

vec3 origin;

vec3 lower_left_corner;

vec3 horizontal;

vec3 vertical;

vec3 u, v, w;

float time0, time1;

float lens_radius;

};#endif

我們還需要乙個移動的物體。我將建立乙個sphere類,它的中心在時間0從中心0線性移動到時間1的中心1。在這個時間間隔之外,它繼續執行,所以這些時間不需要與相機光圈的開閉相匹配。

class moving_sphere :public hitable 

moving_sphere(vec3 cen0, vec3 cen1, float t0, float t1, float r, material*m) :

center0(cen0), center1(cen1), time0(t0), time1(t1), radius(r), mat_ptr(m) {};

virtual bool hit(const ray&r, float tmin, float tmax, hit_record& rec)const;

vec3 center(float time)const;

vec3 center0, center1;

float time0, time1;

vec3 center0,center1;

float radius;

material* mat_ptr;

};vec3 moving_sphere::center(float time)const

建立乙個新的移動球體類的另一種方法是使它們都移動,並且使靜止的球體具有相同的起點和終點。我對在更少的類和更高效的固定球體之間的權衡持謹慎態度,所以讓你的設計品味來指導你。

交叉口**幾乎不需要更改:中心只需要成為功能中心(時間):

bool moving_sphere::hit(const ray&r, float t_min, float t_max, hit_record&rec)const 

temp = (-b + sqrt(discriminant)) / (2.0*a);

if (temp < t_max && temp > t_min)

} return false;

}

如果我們以上一本書結尾的場景中的漫射球體為例,使它們在time=0時的center移動到time=1時的 center + vec3 (0,0.5*drand48(),0), 同時在該幀上開啟相機光圈。

hitable *random_scene() 

else if (choose_mat < 0.95)

else

}} }/**/

list[i++] = new sphere(vec3(4, 1, 0), 1.0, new metal(vec3(0.7,0.6,0.5),0.0));

list[i++] = new sphere(vec3(0, 1, 0), 1.0, new dielectric(1.5));

list[i++] = new sphere(vec3(-4, 1, 0), 1.0, new lambertian(vec3(0.4,0.2,0.1)));

return new hitable_list(list, i);

}

通過這些觀察引數可以得到:

《再學一周光線追蹤》 學習 七 實物(一)

蒙特卡洛光線追蹤技術系列 見 蒙特卡洛光線追蹤技術 康奈爾盒子裡通常有兩個街區。它們相對於牆旋轉。首先,讓我們製作乙個軸對齊的塊原語,它包含6個矩形 class box public hitable box const vec3 p0,const vec3 p1,material ptr virtu...

再學一周光線追蹤 bvh樹流程

蒙特卡洛光線追蹤技術系列 見 蒙特卡洛光線追蹤技術 這次詳細分析一下 再學一周光線追蹤 裡面bvh樹和包圍盒繫結的流程,為了加入三角麵片來進行優化。在hitable類的派生類sphere中只有乙個返回項bounding box,返回sphere的包圍盒。但是sphere和這個返回的包圍盒並沒有直接聯...

《再學一周光線追蹤》 學習 七 實物(二)旋轉

蒙特卡洛光線追蹤技術系列 見 蒙特卡洛光線追蹤技術 旋轉不是很容易理解或生成公式。一種常見的圖形策略是應用圍繞x y和z軸的所有旋轉。這些旋轉在某種意義上是軸對齊的。首先,讓我們繞z軸旋轉 這只會改變x和y,而不依賴於z。這涉及到一些基本的三角學,使用的公式,我將不在這裡介紹。這給你乙個正確的印象,...