国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

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

[光線追蹤] 06 -- BRDF類 & 光源類

2022-06-01 00:49 作者:nyasyamorina  | 我要投稿

在上一篇專欄里實(shí)現(xiàn)了第一個(gè)可以運(yùn)行的光追例子,? 這篇專欄將會(huì)分離 Material 和 BRDF,? 并且實(shí)現(xiàn)兩種常見的場(chǎng)景光源.


Sphere::hit 的化簡(jiǎn)

上一篇專欄里忘記了一件比較重要的事情,? 這里專門分開一小節(jié)來(lái)講.

求解光線與球體碰撞是求解方程?%5Cleft%7C%5Cvec%20d_r%5Cright%7C%5E2t%5E2%2B2%5Cvec%20d_r%5Ccdot%5Cleft(%5Cvec%20p_r-%5Cvec%20p_s%5Cright)t%2B%5Cleft%7C%5Cvec%20p_r-%5Cvec%20p_s%5Cright%7C%5E2-r_s%5E2%3D0,? 求解一元二次方程的公式是: %5Cfrac%7B-b%5Cpm%5Csqrt%7Bb%5E2-4ac%7D%7D%7B2a%7D,? 上下同除以 2 可以化簡(jiǎn) b 為 half_b,? 并且不需要額外乘 4.? 另外,? 因?yàn)閺?qiáng)制要求 Ray::direction 應(yīng)該是歸一化的,? 那么 a%3D%5Cleft%7C%5Cvec%20d_r%5Cright%7C%5E2%3D1.? 根據(jù)這些信息可以化簡(jiǎn) Sphere::hit 為

同理 Sphere::hit_record 里也一樣.


分離 BRDF

在上一篇專欄里實(shí)現(xiàn)了啞光材質(zhì) Matte 類,? 并在 Matte 里實(shí)現(xiàn)了 Lambertian 模型的半球渲染.? 但是我們需要的渲染模型?L_%7Bo%2C%5Cmathrm%7Bobj%7D%7D%3DK_h%5Ccirc%20L_%7Bo%2C%5Cmathrm%7Bobj%7D%7D%2BK_s%5Ccirc%20L_%7Bo%2C%5Cmathrm%7Blight%7D%7D,? 包含了半球渲染和面積渲染兩項(xiàng),? 并且這兩項(xiàng)應(yīng)該是等價(jià)的.

由之前的討論可以得知,? 一個(gè)?BRDF 應(yīng)該在半球渲染 K??里實(shí)現(xiàn)采樣,? 而在面積渲染 K??里給出 f?.? 那么可以做一個(gè) BRDF 類同時(shí)提供相應(yīng)的采樣和 f?:

函數(shù) f? 需要局部坐標(biāo)系的方向 ω? 和 ω?,? 而 Hitrecord 里包含全局坐標(biāo)的 ω? (-ray.direcion) 和表面法線 normal,? 那么額外輸入全局坐標(biāo)的 ω? 就可以通過(guò)法線計(jì)算出相應(yīng)的局部坐標(biāo)下的 ω? 和 ω?.? 在 Sampler 里返回的采樣是在局部坐標(biāo),? 所以需要法線轉(zhuǎn)換為全局坐標(biāo).

至少這里的程序,? 只需要一個(gè)法線就可以完成局部坐標(biāo)與全局坐標(biāo)的轉(zhuǎn)換.? 當(dāng)只存在法線時(shí),? 立體角里的 θ 是可以求出的,? 但 φ 不能,? 也就是說(shuō)這里的 BRDF 與方向角 φ 無(wú)關(guān),? 這種 BRDF 被稱為各向同性 BRDF.? 為了實(shí)現(xiàn)各向異性?BRDF,? 就必須求出 φ,? 亦即需要碰撞點(diǎn)處的紋理坐標(biāo)系,? 程序修改起來(lái)也是比較簡(jiǎn)單的:? 在 HitRecord 里記錄局部紋理坐標(biāo)系,? 但這個(gè)專欄內(nèi)并沒(méi)有這樣的打算.


實(shí)現(xiàn)了 BRDF 的模板類后,? 就可以把 Lambertian 模型從 Matte 材質(zhì)類里分離出來(lái):

因?yàn)?Lambertian 模型的采樣必須要求是采樣集中度為 1 的半球采樣,? 所以這里選擇輸入 Sampler 的參數(shù)給 Lambertian 的初始化方法,? 而不是直接輸入 Samplerp.

在分離了 BRDF 后,? Matte 類里需要指定 BRDF,? 但 BRDF 是通用的,? 所以如果輸入任意一個(gè) BRDF 的話可能就不是 Matte 了,? 所以這里可以實(shí)現(xiàn)一個(gè)通用的不透明材質(zhì) Opaque:??

光源

在實(shí)現(xiàn)物體光源前,? 先來(lái)介紹兩個(gè)不是物體的光源:? 平行光和點(diǎn)光源.? 平行光可以看作從無(wú)限遠(yuǎn)處的光源,? 這意味著在場(chǎng)景內(nèi)任何地方光線都是從一個(gè)方向射入的.? 點(diǎn)光源可以看作無(wú)限小的球體光源.

因?yàn)楣庠葱枰褂妹娣e模型進(jìn)行渲染,? 而在面積模型里入射光線是從光源處得出的,? 所以只需給出光源照射到物體的位置,? 光源處的 HitRecord 就可以由光源本身給出.? 因?yàn)樽詈?HitRecord 都是被光源本身內(nèi)部消化的,? 所以干脆光源只給出一個(gè)方法?render_light 就足夠了.

看到面積模型:?L_o(%5Cvec%20p%2C%5Cvec%20%5Comega_o)%3D%5Cint_Af_r(%5Cvec%20p%2C%5Cvec%5Comega_i%2C%5Cvec%5Comega_o)L_o(%5Cvec%20q%2C-%5Cvec%5Comega_i)v(%5Cvec%20p%2C%5Cvec%20q)%5Cfrac%7B%5Ccos%5Ctheta_%7Bi%2C%5Cvec%20p%7D%5Ccos%5Ctheta_%7Bo%2C%5Cvec%20q%7D%7D%7B%7C%5Cvec%20q-%5Cvec%20p%7C%5E2%7DdA(%5Cvec%20q),? 僅有?f_r(%5Cvec%20p%2C%5Cvec%5Comega_i%2C%5Cvec%5Comega_o)?和 %5Ccos%5Ctheta_%7Bi%2C%5Cvec%20p%7D 兩項(xiàng)是依靠入射方向 ω? 求出的,? 并且恰好這兩項(xiàng)是發(fā)生在 p 點(diǎn)上的.? 而?L_o(%5Cvec%20q%2C-%5Cvec%5Comega_i)?和?%5Ccos%5Ctheta_%7Bo%2C%5Cvec%20q%7D?兩項(xiàng)是發(fā)生在 q 點(diǎn)上.? v(%5Cvec%20p%2C%5Cvec%20q)?和?%7C%5Cvec%20q-%5Cvec%20p%7C%5E2?兩項(xiàng)則是發(fā)生在從 q 傳播到 p 的路上.? 那么分配計(jì)算時(shí),? 可以把發(fā)生在 p 點(diǎn)上的項(xiàng)放在 Material 里計(jì)算,? 而剩下的項(xiàng)放在光源里計(jì)算,? 也就是說(shuō)光源仍需要提供一個(gè)方法計(jì)算 ω?.? 那么光源類實(shí)現(xiàn)為下:

其中,? 如果當(dāng) has_shadow 為 false 時(shí),? v(p, q) 永遠(yuǎn)返回 1,? 并且這個(gè)值永遠(yuǎn)初始化為 true.

對(duì)于平行光和點(diǎn)光源來(lái)說(shuō),? 它們的面積都為 0,? 所以對(duì)它們進(jìn)行的渲染不應(yīng)該叫做 MC 積分了,? 盡管如此,? 但是代碼邏輯是沒(méi)有變化的.? 在面積模型里的?%7C%5Cvec%20q-%5Cvec%20p%7C%5E%7B-2%7D?可以看作平方反比定律的體現(xiàn),? 但是平行光是不滿足平方反比定律的,? 所以平行光的這一項(xiàng)可以直接刪掉,??那么平行光類實(shí)現(xiàn)如下

可以看到在平行光里 get_direction 沒(méi)用上 Vec3 參數(shù),? 這說(shuō)明平行光對(duì)場(chǎng)景里所有地方都是一致的,??并且?direction 表示光的傳播方向,? 因?yàn)檫@里使用反向光追,? 所以 get_direction 方法返回的是 direction 的反向.

類似地,? 點(diǎn)光源可以實(shí)現(xiàn)如下

至于物體光源就可以留到下一篇專欄里了 (就嗯拖).


渲染部分

因?yàn)?Light 不同于 Object,? 所以在 World 里需要另外一個(gè) vector 存放光源:

并且需要在 Material 里實(shí)現(xiàn)相應(yīng)的面積模型:

至此代碼已經(jīng)完整,? 接下來(lái)又是愉快的排列組合環(huán)節(jié):

渲染結(jié)果如下

在代碼以及渲染結(jié)果里有幾個(gè)值得注意的地方:? 第一個(gè)就是因?yàn)槠叫泄夂忘c(diǎn)光源的面積為無(wú)限小,? 所以是不可見的,? 又所以習(xí)慣在點(diǎn)光源的位置放置一個(gè)渲染方式不太一樣的小球體展示點(diǎn)光源,? 如下圖所示 (相關(guān)代碼是在 render_figure 里被注釋掉的部分,?但這代碼完全沒(méi)考慮被遮擋的情況,?yysy,?也不是不能用):

第二個(gè)需要注意的是,? 看到點(diǎn)光源的顏色值:?45?* RGB(.6, .8, 1),? 說(shuō)明點(diǎn)光源本身亮度是非常高的,? 但盡管如此渲染出來(lái)的場(chǎng)景仍然比較昏暗,? 這是因?yàn)槠椒椒幢软?xiàng)對(duì)亮度起主要作用.? 所以大部分情況下,? 為了美觀會(huì)直接把平方反比項(xiàng)刪掉或改成反比,? 下面是兩種改進(jìn)的渲染圖:

不使用平方反比,? 亮度乘數(shù) = 2.5
使用反比,? 亮度乘數(shù)?=15

可以看到觀感都比使用平方反比的要更好.? 商業(yè)用的光追器提供自定義參數(shù)控制光源隨距離衰減的強(qiáng)度 (當(dāng)然也不難實(shí)現(xiàn)),? 但為了真實(shí)性,? 在這個(gè)程序里還是繼續(xù)使用符合平方反比的光源.

第三個(gè)要注意的是溢色,? 之前說(shuō)過(guò)顏色值是定義在 [0,1] 里,? 而點(diǎn)光源的顏色是大于 1 的,? 那么當(dāng)儲(chǔ)存成圖片時(shí),? 大于 1 的值會(huì)被截?cái)喽槐A粜?shù)部分,? 這會(huì)產(chǎn)生極其嚴(yán)重的顏色錯(cuò)誤,? 比如說(shuō)把點(diǎn)光源的亮度乘數(shù)換成 75 進(jìn)行渲染:

可以看到盡管場(chǎng)景亮度有所增加,? 但光源直接照射的地方出現(xiàn)了錯(cuò)誤的顏色.? 因?yàn)椴淮蛩阋?HDR 渲染 (以及相應(yīng)的 map tonning 技術(shù)),? 所以在 LDR 范圍里有兩種常做的方法: 1) 所有顏色值 clamp 到 [0, 1] 里;? 2) 顏色值除以最大分量值,? 以保證色調(diào)正確.? 下面是兩種方法的實(shí)現(xiàn):

然后改寫 render_figure:

在 main 里指定 RemapColor 的實(shí)類就可以進(jìn)行渲染了,? 下面是兩種不同的渲染結(jié)果

Clamp01
MaxTo01

在觀感上是 Clamp01 比較好,? 但是可以看到展示點(diǎn)光源的球體完全變成了白色;? MaxTo01 保持著色調(diào)正確,? 但在過(guò)曝區(qū)域失去了顏色變化.? 兩種方法可以按照個(gè)人喜好來(lái)使用,? 之后的程序如果沒(méi)有特別說(shuō)明就統(tǒng)一使用 Clamp01 了.


/* 請(qǐng)自行腦部結(jié)語(yǔ)?*/


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

群:?274767696

封面pid: 哦, 這次封面不是澀圖, 那沒(méi)事了

[光線追蹤] 06 -- BRDF類 & 光源類的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
蒙城县| 寿阳县| 紫阳县| 永安市| 白山市| 修武县| 治多县| 宝丰县| 江口县| 都匀市| 呼和浩特市| 绩溪县| 苗栗市| 朝阳区| 台北县| 清涧县| 南安市| 满洲里市| 遂宁市| 广水市| 襄城县| 阿合奇县| 兰州市| 贵定县| 松滋市| 安福县| 乡宁县| 庄浪县| 英德市| 富锦市| 堆龙德庆县| 西畴县| 莒南县| 教育| 崇州市| 长泰县| 喀什市| 泰和县| 湘乡市| 盐山县| 临清市|