1`动态模糊
动态模糊在摄影中就是快门的速度慢,捕捉光的时间长,物体运动时进行捕捉成像,拍出来的结果是这个运动过程每一帧的平均值
我们的思路是:
每一条光线都拥有自己存在的一个时间点。随着时间变化随机生成光线,一般来说我们让摄像机和物体同时运动,然后取在那个时间点的精确平均值
首先,我们让每个光线都拥有自己存在的一个时间点
double tm;
现在我们需要让摄像机在time1到time2的时间段中随机生成光线,通过函数设置光线在范围随机时间点
random_double(time0, time1)
我们还需要一个运动中的物体,和普通非运动球体来说,其实就多了center(double time)函数,负责线性插值在time时刻下的球体运动的位置,我们传入r.time()也就是光线自己的时间点
moving_sphere : public hittable
材质在运算光线散射(反射 / 折射)时,填入散射光线的时间
r_in.time()
接着在场景加入运动球体,设置为漫反射材质
2·Bounding Volume Hierarchies 层次包围盒BVH
为了加速求交的过程,我们使用二叉树搜索方法查找,我们首先应该对模型排序,有两种节点分割方式:分割节点:空间分割 / 按物体分割方式(实现起来更简单并且运行速度不错),从而形成一个个包围盒AABB
现在问题包括:
怎样分割物体?
定义BVH加速类,包括数据结构bvh_node节点(二叉树),
怎样和包围盒求交?
我们一直3个轴的xyz坐标,对应每个轴对齐平面,我们有隐式的表示x0, x1,y0,y1,z0,z1
并且我们直到光线的表示,那么x0 = Ax + to * BX,光线从起点A,经过to时间延B方向,到达轴对齐x的某个平面xO,那么我们可以表示to和t1
当3个轴方向t区间发生重叠的情况,则表示这段t区间光线位于包围盒内
并且要注意如下3点:
bool hit(const ray &r, double tmin, double tmax) const
{
for (int a = 0; a < 3; a++)/* 看每个轴 */
{
/* 光线有可能从比如x0->x1方向入射,也有可能反向,因此,to获得的总应是最小值,t1同理 */
auto t0 = ffmin((_min[a] - r.origin()[a]) / r.direction()[a],
(_max[a] - r.origin()[a]) / r.direction()[a]);
auto t1 = ffmax((_min[a] - r.origin()[a]) / r.direction()[a],
(_max[a] - r.origin()[a]) / r.direction()[a]);
/* 那么3个轴都进入了光线才进入包围盒,其中任意一个离开光线就离开包围盒 */
tmin = ffmax(t0, tmin);
tmax = ffmin(t1, tmax);
/* 光线如果和包围盒不相交则: */
if (tmax <= tmin)
return false;
}
return true;
}
对于物体我们建立bounding_box() 纯虚函数,负责定义物体的包围盒,通过两个点