【Ray Tracing The Next Week 超詳解】 光線追蹤2-6 Cornell box

 

Chapter 6:Rectangles and Lightshtml

 

今天,咱們來學習長方形區域光照ide

 

 先看效果函數

 

 light學習

首先咱們須要設計一個發光的材質優化

/// light.hpp

// -----------------------------------------------------
// [author]        lv
// [begin ]        2019.1
// [brief ]        the areaLight-class for the ray-tracing project
//                from the 《ray tracing the next week》
// -----------------------------------------------------

#pragma once



namespace rt
{

//the statement of areaLight class

class areaLight :public material
    {
public:
    areaLight() {  }

    areaLight(texture* mat) :_emit(mat) {  }

    virtual bool scatter(const ray& InRay, const hitInfo& info, rtvec& attenuation, ray& scattered)const { return false; }

    virtual rtvec emitted(rtvar u, rtvar v, const rtvec& p)const { return _emit->value(u, v, p); }

private:
    texture* _emit;
    };

} // rt namespace

 

關於設計方面,咱們須要把發光函數設爲可繼承虛函數,基類也要添加,可是不是全部的材質都須要發光,因此,基類中的發光函數並不須要設置爲純虛spa

/// material.hpp

// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.12
// [brief ]        the material-class for the ray-tracing project
//                from the 《ray tracing in one week》
// -----------------------------------------------------

#pragma once

namespace rt
{

// the statement of material class

class material
    {
public:

    /*
    @brief: produce a scattered ray
    @param: InRay -> Incident light
            info -> the information of intersect-point(hit-point)
            attenuation -> when scattered, how much the ray should be attenuated by tis reflectance R
            scattered -> as we talk, it is a new sight; or
                         it is the scattered ray with the intersect-point
    @retur: the function calculate a scattered ray or not
    */
    virtual bool scatter(const ray& InRay, const hitInfo& info, rtvec& attenuation, ray& scattered)const = 0;


    /*
    @brief: 自發光
    @param: 紋理所需信息
    @retur: 紋理像素值
    */
    virtual rtvec emitted(rtvar u, rtvar v, const rtvec& p)const { return rtvec(); }

    };

}

 

這樣的話,通常的材質繼承以後,發光爲黑色即不發光,較爲合理設計

咱們既然添加了光照,那麼計算插值函數時候也要將它加進去code

 

到此,咱們的發光材質就設置穩當了orm

 

 rectanglehtm

咱們定義的長方形均爲平行於軸的

(引用書上一張圖)

假設長方形位於 z = k 平面,x和y邊界如上,交點爲P(x,y,k)

咱們如何肯定光線參數t?

已知:

光線:p(t) = eye + t * direction

則,z方向的方程爲:z(t) = eye.z + t * direction.z

那麼,若知足z = k,則

t = (k - eye.z) / direction.z

同理可得x和y的等式

 

若是,獲得的x座標或者y座標不在邊界以內,那麼就沒有相交,反之則光線和長方形相交

 

上面的代碼都比較簡單,那個 hit 呢,就是,根據已知的一個份量求出t,而後,把這個解帶入求出對應的其餘兩個份量,若是其餘兩個份量不在邊界內,那麼返回false

反之,咱們求取該點的紋理座標,以及其餘碰撞點信息記錄之

獲取包圍盒嘛,理論上面無厚薄,線無粗細,可是實際中面有厚薄,咱們能夠將厚度設置爲0.0002,以此模擬理論厚度

同理寫出其餘兩個平面類便可。

 

這個沒什麼問題,咱們就往下進行

咱們來作Cornell box

 

相機參數設置:

 

獲得的圖以下:

 

有幾個面是黑色的??也就是根本沒畫出來

咱們細細看一下,發現,長方形的法向量是關鍵

好比畫出來的紅牆,對面與之平行的面的法線是朝左邊的,展示在咱們視線中的是背面

 

因此,咱們有時候須要反轉一下法向量

/// flip_normal.hpp

// -----------------------------------------------------
// [author]        lv
// [begin ]        2019.1
// [brief ]        the flip_normal-class for the ray-tracing project
//                from the 《ray tracing the next week》
// -----------------------------------------------------

#pragma once


namespace rt
{
    
class flip_normal: public intersect
    {
public:
    flip_normal(intersect * p) :_p(p) {  }
    
    virtual bool hit(const ray& sight, rtvar t_min, rtvar t_max, hitInfo& info)const override
        {
        if (_p->hit(sight, t_min, t_max, info))
            {
            info._n = -info._n;
            return true;
            }
        return false;
        }

    virtual aabb getbox()const override
        {
        return _p->getbox();
        }

private:
    intersect* _p;
    };

} // rt namespace 

 

這樣就能夠了,咱們改一下場景

 

以下:

 

 此外,咱們還須要注意的是,light對應的紋理中的數值越大光強越強

咱們能夠試一下

    material * light = new areaLight(new constant_texture(rtvec(20, 20, 20)));

以下:

 

能夠看出來兩張圖對比之下,第二張亮多了

 

可是咱們依舊看着很不舒服,好多黑點點,太難受了

我想啊想,爲何這麼多黑點??多是由於背景是黑色的,畢竟是漫反射,若是隨機反射失敗那就是黑色,因此隨機反射點可能產生好多黑色小點,你千萬別想着換成鏡面材質,那個更無語

因此啊,我想了下,把背景改成白色,那樣更好,畢竟色彩中摻雜一點白色,無傷大雅

如是,我改了下,效果可觀

此法只適用於Cornell box自己,具體場景下的畫面優化請見下一篇

 

 

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

相關文章
相關標籤/搜索