上一节中我们实现了光源和矩形物体,并初步创建了一个 Cornell Box 场景,但场景中还缺少两个立方体,并且立方体和墙面之间存在一定的旋转角度,因此这一节我们需要实现一个立方体物体类,并且支持旋转和平移。
1 轴对齐立方体
先使用轴对齐矩形实现一个轴对齐立方体类:
1 |
|
然后将 box 添加到 Cornell Box 场景中:
1 | // Cornell Box场景 |
得到的效果:
2 Instances
接下来我们要实现立方体的旋转,更一般地,我们不止要让立方体旋转,而是要让场景中的所有物体都能够运动,运动包括平移和旋转。在光线追踪器中,这些都是通过 Instances 来实现的,Instances 可以认为是一个几何变换器,可以将传入的物体按照给定的参数和方式进行变换,因此我们要实现这些几何变换的 Instances 类。
2.1 平移
首先是平移变换类,在光线追踪器中实现物体平移不是通过真的把物体移动到某个位置,因为物体一旦被放入场景再去变换位置就需要费很大的功夫,所以实现物体平移是通过向反方向移动光线来实现的,比如:
要把粉色的正方形沿 x 轴向右移动两个单位,我们可以通过把光线沿 x 轴向左移动两个单位来实现。
注意和之前实现的移动的球体做区分,这里的移动不是在一段时间内的运动,而是改变场景中物体的摆放方式。
平移变换类的实现如下:
1 | // 平移变换 |
2.2 旋转
旋转的思路和平移一样,也是先反方向旋转光线,得到交点后对交点再进行正向旋转,不同的是旋转后交点法线也要相应变换,在 Shader 学习中我们知道对法线变换要用变换矩阵的逆转置矩阵,旋转矩阵是正交矩阵,逆转置矩阵就是其本身。
绕 y 轴旋转的实现如下:
1 | // 绕y轴旋转 |
3 完整的 Cornell Box
利用实现的立方体和几何变换类,来得到完整的 Cornell Box 场景:
1 | // Cornell Box场景 |
效果如下: