最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

[光線追蹤] 05 -- 相機(jī) & 球體 & 啞光材質(zhì)

2022-05-30 18:18 作者:nyasyamorina  | 我要投稿

上一篇專欄里介紹了光追的程序結(jié)果,? 并且實(shí)現(xiàn)了幾個(gè)重要的模板類.? 這篇專欄就對(duì)模板進(jìn)行實(shí)現(xiàn),? 做出第一個(gè)可以跑的光追程序.


針孔相機(jī)

所有相機(jī)實(shí)類都繼承自 Camera 模板類,? 并且主要是實(shí)現(xiàn)其中的 get_ray 虛函數(shù).

在眾多相機(jī)類型里最常見(jiàn)到的就是針孔相機(jī)了.? 針孔相機(jī)的準(zhǔn)確模型如下圖所示

針孔可以看作一個(gè)無(wú)限小的洞,? 而在后方的傳感器上出現(xiàn)了前方景物的倒像.? 而為了方便計(jì)算機(jī)建模,? 利用相似三角形可以把模型轉(zhuǎn)化為

這樣,? 針孔相機(jī)就可以使用一個(gè)視點(diǎn)位置 (針孔位置) 和一個(gè)焦平面 (傳感器位置) 表示.? 視點(diǎn)位置可以使用一個(gè) Vec3 表示,? 而焦平面則需要3個(gè) Vec3 表示,? 如下圖所示

其中,? d 表示焦平面中心與視點(diǎn)的相對(duì)位置,? uv 是焦平面的紋理坐標(biāo)系.? 值得注意的是,? {u, v, d} 構(gòu)成了左手系,? 在光柵化渲染里,? 為了轉(zhuǎn)成右手系習(xí)慣上把 dv 逆轉(zhuǎn) (opengl 或?dx),? 但光追不涉及仿射變換所以其實(shí)也不在意左右手的問(wèn)題了,? 這里就繼續(xù)用上圖所示的 {u, v, d} 進(jìn)行建模了.

為了進(jìn)行 MC 積分,? 光追需要對(duì)單像素進(jìn)行多次采樣,? 也就是說(shuō)相機(jī)類里還要包含 Sampler,? 并且在焦平面上的采樣應(yīng)該是與 figure 互相綁定的,? 所以 Sampler 可以直接寫(xiě)在基類 Camera 里,? 改寫(xiě) Camera 為

另外需要注意圖像的 y 軸正方向是從上到下,? 而不是紋理坐標(biāo)里的從下到上.? 那么最終針孔相機(jī)實(shí)現(xiàn)為:

雖然實(shí)現(xiàn)了針孔相機(jī),? 但是很明顯這種形式不太像是常用的相機(jī).? 在通常相機(jī)參數(shù)里應(yīng)該提供 視點(diǎn)位置,? 視方向,? 視野寬度,? 長(zhǎng)寬比,? 視上方向.? 實(shí)際上,? 這里實(shí)現(xiàn)的相機(jī)是通用的,? 而通常的相機(jī)參數(shù)可以通過(guò)計(jì)算得到相應(yīng)的紋理坐標(biāo) u, v.? 給針孔相機(jī)定義一個(gè)初始化方法:

里面的數(shù)學(xué)就不過(guò)多敘述了,? 都是簡(jiǎn)單的幾何.? 需要注意的是這個(gè) viewup (視上方向),? 表示的是在視野內(nèi)的上方向,? 而不是世界上方向.? 當(dāng)視上方向與世界上方向相等時(shí),? 圖像是這樣的:

但當(dāng)視上方向與世界上方向形成一定角度時(shí)可以產(chǎn)生這樣的圖像:

也就是說(shuō)視上方向可以起到控制傾角的作用,? 不過(guò)一般來(lái)說(shuō)不怎么經(jīng)常調(diào)整傾角,? 所以可以給 viewup 一個(gè)默認(rèn)的世界上方向.? 但特別需要注意的是,? 計(jì)算會(huì)在視方向和視上方向互相平行時(shí)出錯(cuò),? 所以在給出視方向和傾角時(shí),? 應(yīng)該有一個(gè)方法計(jì)算正確的視上方向:

其中,? d 是視方向,? alpha 是傾角,? 并且這個(gè)公式是由矩陣變換得出的?(說(shuō)過(guò)這里不會(huì)討論線代).

最后稍微提到一點(diǎn),? 在通常的相機(jī)里,? u, v, d 是互相垂直的,? 但如果 u, v 互相垂直,? 但 d 不都與 u, v 垂直,? 即可以得到移軸相機(jī).? 移軸相機(jī)這里也不實(shí)現(xiàn)了,? 感興趣的可以自己做做.


球體

幾何物體實(shí)類全部都繼承自 Object 模板類,? 并實(shí)現(xiàn) hit 和 hit_record 虛函數(shù) (這里不討論光源,? 其他虛函數(shù)統(tǒng)統(tǒng)返回零值).

在幾何物體里,? 除了平行四邊形,? 最簡(jiǎn)單的物體就是球體了.? 可以給出兩個(gè)參數(shù)確定一個(gè)球體:? 球心位置 p 和球體半徑 r,? 空間上所有符合?%7C%5Cvec%20q-%5Cvec%20p_s%7C%3Dr_s%3B%5C%3B%5Cvec%20q%5Cin%20%5Cmathbb%20R%5E3?的點(diǎn)構(gòu)成一個(gè)球體.

之前說(shuō)過(guò),? 光線上任意一點(diǎn)可以表示為?%5Cvec%20p_r%2Bt%5Cvec%20d_r,? 把光線方程代入球體方程里可以得到 %7C%5Cvec%20p_r%2Bt%5Cvec%20d_r-%5Cvec%20p_s%7C%3Dr_s,? 求解 t 就可以得到:? 光線經(jīng)過(guò)路程?t 后與球體碰撞.? 因?yàn)槟iL(zhǎng)有關(guān)系:?%7C%5Cvec%20v%7C%5E2%3D%5Cvec%20v%5Ccdot%5Cvec%20v,? 所以將上式兩邊平方,? 應(yīng)用關(guān)系,? 開(kāi)括號(hào),? 合并同類項(xiàng),? 可以得到: %5Cvec%20d_r%5Ccdot%5Cvec%20d_rt%5E2%2B2%5Cvec%20d_r%5Ccdot(%5Cvec%20p_r-%5Cvec%20p_s)t%2B(%5Cvec%20p_r-%5Cvec%20p_s)%5E2-r_s%5E2%3D0,? 這樣就變成了普通的一元二次方程,? 解就完事了.? 在解出 t 后,? 在確保值大于 0 的情況下,? 值較小的那個(gè)解就是光線與球體最近的碰撞點(diǎn).? 下面給出 Sphere類和相應(yīng)的 hit 函數(shù)實(shí)現(xiàn):

在 hit 里判別 " a_t 是否大于 0" 的時(shí)候使用了 1e-8 是因?yàn)榇嬖诟↑c(diǎn)數(shù)誤差,? 需要選取比 0 大的數(shù)值避免計(jì)算錯(cuò)誤?如下圖所示,? 盡管這里直接選定 1e-8 作為判別值,? 但實(shí)際上對(duì)于不同大小的球體,? 判別值是不一樣的 (這個(gè)就不是這里的討論范圍了).

左為判別值為 0,? 右為判別值為 1e-8

類似地,? 可以實(shí)現(xiàn) hit_record 方法:

在 hit_record 里,? ray 即是 rec.ray,? tmax 即是 rec.t,? 所以在構(gòu)建 HitRecord 時(shí)說(shuō)到初始化 t 可以起到限制 Ray 最遠(yuǎn)距離的作用,? 這在判斷兩個(gè)不同物體的遠(yuǎn)近時(shí)非常有用.? 另外這里不計(jì)算紋理坐標(biāo)的原因是,? 打算以后專門開(kāi)一篇紋理采樣的專欄,? 到時(shí)候再說(shuō)吧.


啞光材質(zhì)

材質(zhì)實(shí)類全部都繼承自 Material 模板類,? 并且實(shí)現(xiàn) render 虛函數(shù) (這里不討論光源, 所以不考慮 render_emissive 虛函數(shù)).

當(dāng)光線照射到理想的啞光材質(zhì)上時(shí),? 能量將會(huì)均勻分布在所有出射方向上.? 現(xiàn)實(shí)里是不存在理想的啞光材質(zhì)的,? 最貼近的例子就是啞光紙.? 啞光材質(zhì)對(duì)應(yīng)的 BRDF 模型稱為 Lambertian 反射模型,? 之前說(shuō)過(guò)描述反射的式子為?L_o%3D%5Cint_%7B2%5Cpi%5E%2B%7Df_rL_i%5Ccos%5Ctheta_id%5Comega_i,? 既然啞光材質(zhì)會(huì)均勻地分布能量,? 也就是 f? 與出射方向 ω? 無(wú)關(guān),? 并且由光路可逆條件知道,? f? 也與入射方向 ω? 無(wú)關(guān),? 也就是說(shuō) Lambertian 的?f? 是一個(gè)常數(shù).? 之前說(shuō)過(guò)在測(cè)試函數(shù)空間里,? 反射率定義為?%5Crho_%7B%5Comega_i%7D%3D%5Cint_%7B2%5Cpi%5E%2B%7Df_r(%5Comega_i%2C%5Comega_o)%5Ccos%5Ctheta_od%5Comega_o,? 那么對(duì)于 Lambertian 來(lái)說(shuō)就是: f_%7Br%2CL%7D%5Cint_%7B2%5Cpi%5E%2B%7D%5Ccos%5Ctheta_od%5Comega_o.? 對(duì)于真實(shí)物體來(lái)說(shuō),? 反射率必定小于 1,? 在這里的程序里,? 出射光線的顏色可以由紋理指定,? 所以可以強(qiáng)制指定 BRDF 的反射率等于 1,? 即是 f_%7Br%2CL%7D%5Cint_%7B2%5Cpi%5E%2B%7D%5Ccos%5Ctheta%20d%5Comega%3D1,? 解得 f_%7Br%2CL%7D%3D%5Cfrac%7B1%7D%7B%5Cpi%7D.

于是得到 Lambertian 的半球模型為?L_o%3D%5Cfrac%7B1%7D%7B%5Cpi%7D%5Cint_%7B2%5Cpi%2B%7DL_o%5Ccos%5Ctheta_id%5Comega_i,? 應(yīng)用之前說(shuō)過(guò)的 MC 積分可以得到模型的解為 %5Clangle%20L_o%5Crangle%3D%5Cfrac%7B1%7D%7Bn%7D%5Csum_%7Bi%3D1%7D%5EnL_o%3B%5C%3B%5Comega_i%5Csim%5Ccos%5Ctheta.? 那么啞光材質(zhì)可以實(shí)現(xiàn)為

可能就會(huì)有人好奇說(shuō)好的累加去哪里了,? 忽略 L? 時(shí)的符號(hào)渲染模型為?L_o%3DK%5Ccirc%20L_o,? 迭代一次即為 L_o%3DK%5E2%5Ccirc%20L_o,? 因?yàn)?K 是一個(gè)積分,? 所以 K2 也是一個(gè)積分,? 只不過(guò)需要積分的變量更多了,? 并且 MC 積分是可以用采樣求解高維積分的,? 那么把 K2 看作單個(gè)高維積分,? 那么相應(yīng)的 MC 積分為 L_o%3DK%5E2%5Ccirc%20L_o%3D%5Clim_%7Bn%5Crightarrow%2B%5Cinfty%7D%5Csum_i(%5Ccdots).? 所以累加可以放在積分的最頂層進(jìn)行, 亦即在焦平面上的像素采樣.

或者寫(xiě)成一行也可以:

世界類

世界類 World 含有光追所需所有對(duì)象,? 包括但不限于:? 光追器,? 相機(jī),? 物體s 和 光線迭代的最大深度.? 所以世界類為

當(dāng)然隨著光追程序的完善,? World 里面的東西也會(huì)越來(lái)越多,? 但是在這里的話這樣就足夠了.


渲染部分

到這里為止,? 場(chǎng)景里一個(gè)光源都沒(méi)有,? 所以渲染出來(lái)的場(chǎng)景肯定是漆黑一片.? 但是可以改寫(xiě) RayTracer 類使得部分光線返回不為 0 的顏色值.

在 RayTracer 里有兩部分是直接返回顏色值的:? 迭代過(guò)深 和 光線不與物體碰撞.? 當(dāng)光線不與物體碰撞時(shí),? 可以看作光線與無(wú)限遠(yuǎn)處的天空發(fā)生碰撞,? 并且返回天空的顏色值.? 當(dāng)光線迭代過(guò)深時(shí),? 可以看作光線能量在反射傳播時(shí)耗盡,? 亦即必定返回 0 值.? 那么繼承 RayTracer 類實(shí)現(xiàn)一個(gè)返回天空顏色的光追器:

到此,? 光追所需的類型已經(jīng)全部準(zhǔn)備好了,? 剩下的就是排列組合了 (

渲染過(guò)程也是非常直觀明了的:? 歷遍圖像像素,? 并且每個(gè)像素內(nèi)歷遍采樣集:

到此整個(gè)渲染邏輯已經(jīng)全部實(shí)現(xiàn)了,? 就可以進(jìn)行一個(gè)例子的跑.

這里使用一個(gè)簡(jiǎn)單的場(chǎng)景:? 兩個(gè)球體,? 其中一個(gè)非常大的球體充當(dāng)場(chǎng)景地板:

make_sampler 是自己做的糖,? 可以在 samples.h 里找到定義.

那么在 main 里可以這樣實(shí)現(xiàn)渲染:

輸出的圖像如下:

可以留意到,? Lambertian 的實(shí)現(xiàn)完全只依賴于輸入的采樣集:

當(dāng)采樣集分布不為 cosθ 時(shí)可以做到其他不同的 BRDF.? 比如說(shuō)更改采樣在半球上的集中度:

渲染結(jié)果將會(huì)改變:

可以看到兩球相切的陰影變得更加深色了.? 盡管這里的程序把采樣生成直接暴露在外部,? 從而調(diào)整采樣可以做到不同的效果,? 但必須記住:? 只有集中度為 1 的半球采樣才表示 Lambertian 模型.

另外不得不注意的是,? 在構(gòu)建 world 時(shí)創(chuàng)建了幾個(gè) Sampler,? 為了可以正確地計(jì)算 MC 積分,? 必須要求 Sampler 之間每個(gè)采樣集里的樣本數(shù) samples_per_set?都是一致的.



這里簡(jiǎn)單實(shí)現(xiàn)了第一個(gè)可以運(yùn)行的光追程序,? 但代碼里仍有很多地方還沒(méi)細(xì)化 (特別是 Material).? 在下一篇專欄里將會(huì)實(shí)現(xiàn)幾種不同的簡(jiǎn)單光源以及環(huán)境光.


項(xiàng)目倉(cāng)庫(kù):?https://github.com/nyasyamorina/nyasRT

來(lái)點(diǎn)不正經(jīng)的弔圖扣扣群:?274767696

封面pid:?94213121

[光線追蹤] 05 -- 相機(jī) & 球體 & 啞光材質(zhì)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
上栗县| 蕲春县| 景泰县| 娱乐| 建始县| 铜山县| 邓州市| 云安县| 荥经县| 贵阳市| 余江县| 建水县| 五常市| 晴隆县| 成安县| 济阳县| 双桥区| 隆尧县| 邓州市| 宜春市| 工布江达县| 淮安市| 句容市| 翁源县| 冕宁县| 同仁县| 阿克苏市| 清徐县| 宁安市| 广德县| 南雄市| 米林县| 天水市| 沙河市| 永吉县| 宁国市| 吉安市| 德兴市| 德化县| 翁牛特旗| 大化|