1、综述
在《Ray Tracing in one weekend》中,我们制作了一个简单的暴力路径追踪器。在这个教程中,我们将增加纹理、体积(比如雾),矩形,实例、灯光,以及对物体使用BVH,我们将得到一个“正真的”光线追踪器。
在光线追踪器中的一个启示就是:许多优化虽然使代码变得复杂,但是没有对程序加速太多。作者强烈建议不要过早地优化代码,如果它在执行时间配置文件中没有那么明显,那么等到所有特性都被支持的时候才进行优化。可以在https://in1weekend.blogspot.com/中阅读和参考更复杂的方法。
书中最难的两个部分分别是BVH和Perlin纹理。你可以不用按顺序阅读章节,可以把他们放到最后阅读,没有BVH和Perlin纹理也可以做出康纳盒。
2 动态模糊
当您决定使用射线跟踪时,您认为视觉质量比运行时更有价值。在模糊反射和散焦模糊中,每个像素需要多个样本(发射多条射线通过该像素)。当你开始做时,有一个好消息:所有的效果都可以暴力实现。动态模糊就是其中之一。在一台真正的相机中,快门打开并保持打开一段时间,在这段时间内相机和物体可能会移动。它实际上是摄像机在我们想要的时间间隔内所看到的平均值。
2.1 时空光线追踪的介绍
我们可以通过在快门打开的某个随机时间发送每条射线来得到一个随机估计。只要物体在那个时候应该在的位置,我们就能得到正确的平均答案,只要射线恰好在同一时间。这就是为什么随机射线跟踪很简单的根本原因。
其基本思想是,当快门打开并与模型相交时,随机产生光线。通常的做法是让摄像机移动,物体移动,但每条光线都在同一时间存在。这样,射线追踪器的“引擎”就可以确保物体在它们需要的位置,并且交叉的部分不会发生太大的变化。
为了实现这个,我们首先需要存储一条光线存在的时间存储在(double)tm中:
// 网页上的代码 [ray.h] Ray with time information
class ray {
public:
ray() {}
ray(const point3& origin, const vec3& direction, double time = 0.0)
: orig(origin), dir(direction), tm(time)
{}
point3 origin() const { return orig; }
vec3 direction() const { return dir; }
double time() const { return tm; }
point3 at(double t) const {
return orig + t*dir;
}
public:
point3 orig;
vec3 dir;
double tm;
};
来自 <https://raytracing.github.io/books/RayTracingTheNextWeek.html>
2.2 升级摄像头模拟运动模糊
现在我们需要修改相机以生成在time1~time2内的随机时间的光线。对于这个时间,有两种考虑:
- 由相机类跟踪time1和tiem2
- 由创建相机的用户跟踪time1和time2