《用一周学习光线追踪》1.动态模糊

本项目上接《用两天学习光线追踪》,继续学习光线追踪。
项目链接:https://github.com/maijiaquan/ray-tracing-with-imgui

目录:
《用两天学习光线追踪》1.项目介绍和ppm图片输出
《用两天学习光线追踪》2.射线、简单相机和背景输出
《用两天学习光线追踪》3.球体和表面法向量
《用两天学习光线追踪》4.封装成类
《用两天学习光线追踪》5.抗锯齿
《用两天学习光线追踪》6.漫反射材质
《用两天学习光线追踪》7.反射向量和金属材质
《用两天学习光线追踪》8.折射向量和电介质
《用两天学习光线追踪》9.可放置相机
《用两天学习光线追踪》10.散焦模糊

《用一周学习光线追踪》1.动态模糊
《用一周学习光线追踪》2.BVH树、AABB相交检测
《用一周学习光线追踪》3.纯色纹理和棋盘纹理
《用一周学习光线追踪》4.柏林噪声
《用一周学习光线追踪》5.球面纹理贴图
《用一周学习光线追踪》6.光照和轴对齐矩形
《用一周学习光线追踪》7.长方体和平移旋转


上章回顾

上一章《用两天学习光线追踪》中,我们制作了一个简单的光线追踪器,具体渲染流程如下:
1.对一个宽高为nx,ny的屏幕,遍历每个像素
2.每个像素再遍历ns次,以实现多重采样抗锯齿
3.在该位置发射一道射线,并进行递归颜色采样,输出到屏幕


本节内容

增加动态模糊的效果。代码改动:
1.ray增加一个参数t
2.camera生成随机数并赋值给ray的t
3.增加moving_sphere类


动态模糊

如果要实动态模糊的效果,可以将原来的球体,改成球心在某条线段上的球体,例如代码中将sphere修改为moving_sphere,并将原来的center修改成center0, center1。每条射线都会有一个随机的系数t(范围0到1),使用t插值center0, center1,得到这条线段上的某个点作为moving_sphere的球心。

不同的射线会有不同的t,不同的t插值出来的球心位置就会不同。对某个像素随机采样ns次之后,这个像素就会产生ns条t值随机的射线,这ns条射线对应位置不同的球,从而渲染出一个模糊的像素。渲染这条线段附近区域的包含该球体的所有像素,就能看到球在这条线段上运动的模糊效果,从而模拟相机快门的长曝光时间。

ray增加参数:

class ray
{
public:
		...
    float _time;
		...
    ray(const vec3 &a, const vec3 &b, float ti = 0.0)
    {
		...
        _time = ti;
    }
		...
    float time() const { return _time; }
		...
};

camera增加随机产生time赋值给ray:

class camera
{
public:
...
    float time0, time1;

    camera(vec3 lookfrom, vec3 lookat, vec3 vup, float vfov, float aspect, float aperture, float focus_dist, float t0, float t1)
    {
        time0 = t0;
        time1 = t1;
       	...
    }

    ray get_ray(float s, float t)
    {
...
        float time = time0 + random_double() * (time1 - time0);
        return ray(origin + offset, lower_left_corner + s * horizontal + t * vertical - origin - offset, time);
    }
};

moving_sphere类:

class moving_sphere : public hittable
{
public:
    vec3 center0, center1;
    float time0, time1;
    float radius;
		...

    vec3 center(float time) const
    {
        return center0 + ((time - time0) / (time1 - time0)) * (center1 - center0);
    }

    bool hit(const ray &r, float t_min, float t_max, hit_record &rec) const
    {
        vec3 oc = r.origin() - center(r.time());
    	 ...
        if (discriminant > 0)
        {
            ...
            if (temp < t_max && temp > t_min)
            {
              ...
                rec.normal = (rec.p - center(r.time())) / radius;
							...
            }
            ...
            if (temp < t_max && temp > t_min)
            {
               ...
                rec.normal = (rec.p - center(r.time())) / radius;
								...
            }
        }
        ...
    }
};

参考资料:Ray Tracing: The Next Week

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值