開學人倍忙,趁着第二周周末,我們繼續圖形相關的博客
Preface
今天我們來介紹一些理論方面的東西,為Monte Carlo 應用到我們的光線追蹤器做鋪墊
我們今天會介紹兩章的東西,因為有一章內容太過簡單
本篇目的原版內容 見相冊
這個東西你點上去會有頁數的,不要看混了
ready
看這一篇您需要具備以下知識
1. 了解重要性采樣
2. 二重積分,基礎微分
3. (半)球坐標系
4. 光線追蹤基本原理
5. 立體角(solid angle),現在普及一下
首先類比二維空間的圓,假設我們在二維空間內定義了一個單位圓,我們截取圓上的一段弧AB,它對應的圓心角為∠α
而且我們知道弧長 = α*R,那么整個周長就是C = 2*π*R
那么我們三維空間,仍然有類似的定義
記粉色區域為A
立體角的單位是球面度(sr),1sr定義為球面上一塊面積(A)為R2的區域,從球心看過去的三維角度。
類比於二維圓上的圓弧和圓心角,那塊面積區域為三維弧度,面積區域相對於球心在三維坐標系下的張角即為立體角
立體角計算
Ω = ∫∫A (sinθ)dθdφ
A為三維弧度
其中,θ代表經度,φ代表維度
整個球面的立體角為
Ω = ∫0->2π dφ ∫0->π (sinθ)dθ
Ω = 2π*2 = 4π
content
我們之前的光線追蹤器中有一個過程是獲取一個三維空間的隨機方向,我們利用單位球體內的隨機點來代表該方向,那么我們今天用Monte Carlo 來實現相同的效果
Chapter2 MC Integration on the Sphere of Directions
首先我們需要定義一個2D的pdf函數
我們假定下面這個積分適用於任意方向
∫cos2θdθ
在MC積分下,我們應該做 cos2θ/p(direction) 的采樣
但是這里的direction在我們的環境中如何定義的呢?
我們需要在極坐標系下進行定義,p是關於θ和φ的一個函數
但是,不管你怎么整,一定要記住,
設計一個pdf函數,它的積分必須是1,並且pdf代表着該方向被采樣的相對概率
我們看一下之前我們的隨機函數(模板和異常可忽略)
template<typename T = lvgm::precision> const lvgm::vec3<T> random_unit_sphere() { if (typeid(T) == typeid(int)) { std::cerr << "integer doesn't have a random number from 0 to 1\n"; throw "integer doesn't have a random number from 0 to 1\n"; } lvgm::vec3<T> p; do { p = 2.0*lvgm::vec3<T>(rand01(), rand01(), rand01()) - lvgm::vec3<T>(1, 1, 1); } while (dot(p, p) >= 1.0); return p; }
這得到的是單位球體內部的隨機三維點
如果我們要得到球體表面的三維空間點,那么我們只需要單位化一下即可
也就是return p的單位化向量
那么,能夠代表這些球體表面點的pdf函數應該是什么呢?
作為單位球體表面點的均勻密度,用立體角的方式定義均勻密度
即單位立體角的球面度/整個球體對應的球面度,也就是1/球體面積 或者 1/4π
如果被積函數我們選取上面的cos2θ,θ為隨機方向與z軸的夾角,那么程序如下
void sphereMC() { auto pdf = []() {return 1 / (4 * π); }; size_t n{ 10000000 }; double sum{ 0 }; for (int i = 0; i < n; ++i) { dvec3 d = random_unit_sphere().ret_unitization(); double cosine = d.z()*d.z(); sum += cosine / pdf(); } stds cout << "I = " << sum / n << stds endl; }
答案是 4π/3,絕對沒毛病
Chapter3 Light Scaterring
在上本書中,我們基於表面或者次表面實現散射光線,這是一個普適模型。
但是,更自然的方式是概率,該光線多大概率被吸收了?
設 光線反射概率為A
那么 光線被吸收的概率就為 1-A
這里的A其實代表之前材質中的albedo(latin for whiteness)。
Albedo代表着某些反射形式的反射比例
當我們實現玻璃材質的時候,albedo伴隨着入射光線方向的變化而變化,進而計算相應變化的像素值
在大多數的基於物理的渲染器,我們將用一組波長表示淺色而不是RGB,我們用長中短波長來代表RGB
如果實現光散射,那么我們可以基於立體角設計一個pdf來描述光線散射方向分布。
我將其稱為散射pdf:s(direction),這個散射pdf也會隨着入射方向的變化而變化
所以這個表面色彩就數量(wavelength)而言有如下積分形式
color = ∫A * s(direction) * color(direction) dθ [公式1]
需要注意的是:A 和 s()都是依賴於觀察方向的,當然,color也隨着觀察方向的變化而變化,A 和 s()也可能隨着表面或體內部的位置而變化
如果我們將Monte Carlo應用到上面的積分的話,那么我們得到如下的統計估計公式
Color = (A * s(direction) * color(direction)) / p(direction) [公式2]
這里的p(direction)是方向參數隨機模擬生成的一個pdf函數
對於Lambertian材質表面,我們假定其密度是呈余弦規律的。
so, 一個Lambertian表面的p()是正比於cosθ,而θ是光線方向和表面法線的夾角,還需要注意一點:所有設計的pdf函數在定義域內的積分必須是1
我們還知道,對於磨砂表面來說,入射光線和表面法線的夾角不會超過90°,所以,我們定義
對於 cosθ < 0 的情況,我們設定s(direction) = 0
所以有效區間為半球面,而基於半球的cos積分為π,這個怎么理解呢?
還記得already中的球面度嗎?我們那時候說過那個區域A的微分形式(基於球坐標)為
dA = sinθ dθdφ
所以,半球面積 =
所以,Lambertian表面散射pdf為:
s(direction) = cosθ / π [公式3]
如果我們采樣也使用同樣的pdf函數,
即: p(direction) = cosθ/π [公式4]
那么分子分母可以消去,就得到了
Color = A * color(direction)
這是我們原始的color函數中的設定,但我們現在需要概括一下完整的形式,以便我們可以向重要方向發送額外的光線,例如朝向燈光。
如果你看過其他相關書籍,你可能會看到雙向反射分布函數(BRDF)描述的反射。 它的表示形式非常簡單:
BRDF = A * s(direction) / cosθ [公式5]
例如,對於朗伯表面,BRDF = A / Pi。(聯立公式3、5可得)
我們的表達方式和BRDF之間的轉換很容易。而對於參與媒體(卷),我們的反照率通常被稱為散射反照率,而我們的反照片通常被稱為相位函數。
這一篇主要講一些理論相關的東西,可能沒什么直觀感受,但是下一篇學習的時候就需要用到這些東西了,沒感覺的也沒關系,結合下一篇可能會體會更深刻一點
感謝您的閱讀,生活愉快~