【RAY TRACING THE REST OF YOUR LIFE 超詳解】 光線追蹤 3-3 蒙特卡羅 (三)

 

開學人倍忙,趁着第二週週末,咱們繼續圖形相關的博客html

 

 Prefacedom

今天咱們來介紹一些理論方面的東西,爲Monte Carlo 應用到咱們的光線追蹤器作鋪墊函數

咱們今天會介紹兩章的東西,由於有一章內容太過簡單學習

本篇目的原版內容 見相冊spa

這個東西你點上去會有頁數的,不要看混了設計

 

 readycode

看這一篇您須要具有如下知識htm

1. 瞭解重要性採樣blog

2. 二重積分,基礎微分ci

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θ)

Ω = 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:sdirection),這個散射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。(聯立公式三、5可得)

咱們的表達方式和BRDF之間的轉換很容易。而對於參與媒體(卷),咱們的反照率一般被稱爲散射反照率,而咱們的反照片一般被稱爲相位函數。

 

這一篇主要講一些理論相關的東西,可能沒什麼直觀感覺,可是下一篇學習的時候就須要用到這些東西了,沒感受的也不要緊,結合下一篇可能會體會更深入一點

 

感謝您的閱讀,生活愉快~

相關文章
相關標籤/搜索