【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自己,具体场景下的画面优化请见下一篇

 

 

感谢您的阅读,生活愉快~

相关文章
相关标签/搜索