一周内实现光线追踪,thenextweek,理解BVH

这一周拜读了雪莉的这个一周内实现光线追踪,收获颇丰,尤其是对于games101的光线追踪框架,我似乎知道他是怎么一步步改过来的了,之前对于那个共享指针到底指到哪儿其实心里还是没有谱的,只是知道进行纹理映射就行了,而这个一周内实现光追特意实现了一些高级的特性(雾效,对焦相机,motion blur)

对于之前101的框架更加认识了一步,尤其是101的框架其实没有教我们最开始的whitted风格,而是直接强上了path-tracing(虽然框架是whitted,但是那时候没有好好研究,而是只是实现bvh之后就放下了)

感谢这个项目,让我见识到了ray tracing的巨大力量,而且对于之前spp数以及ppm格式,这里面的一堆细节,做完之后就有了印象了。

尤其是从第一周,到第二周,一步步的前进,简直是震撼。

特意记录一些东西,作为感想。

首先自然是最重要的bvh的实现,在这里,我更加加深了对于bvh的理解

(步步分治,在最终的时刻进行合并box,牛逼),注意time0和time1 代表(移动物体(比如那个移动的球)的位置移动时间),这里做一个纪念。

而且在此过程中了解了反射,折射,雾效,纹理映射,牛逼,无以言表,强烈建议自己打一遍代码,理解会非常深刻

  1 #ifndef BVH_H
  2 #define BVH_H
  3 
  4 #include "rtweekend.h"
  5 #include "hittable.h"
  6 #include "hittable_list.h"
  7 #include <algorithm>
  8 
  9 class bvh_node : public hittable {
 10 public:
 11     bvh_node() {};
 12     bvh_node(
 13         const std::vector<shared_ptr<hittable>>& src_objects,
 14         size_t start, size_t end, double time0, double time1);
 15 
 16     bvh_node(const hittable_list& list, double time0, double time1)
 17         : bvh_node(list.objects, 0, list.objects.size(), time0, time1)
 18     {}
 19 
 20     
 21 
 22     virtual bool hit(
 23         const ray& r, double t_min, double t_max, hit_record& rec) const override;
 24 
 25     virtual bool bounding_box(double time0, double time1, aabb& output_box) const override;
 26 
 27 public:
 28     shared_ptr<hittable> left;
 29     shared_ptr<hittable> right;
 30     aabb box;
 31 };
 32 
 33 bool bvh_node::bounding_box(double time0, double time1, aabb& output_box) const {
 34     output_box = box;
 35     return true;
 36 }
 37 
 38 inline bool box_compare(const shared_ptr<hittable> a, const shared_ptr<hittable> b, int axis) {
 39     aabb box_a;
 40     aabb box_b;
 41 
 42     if (!a->bounding_box(0, 0, box_a) || !b->bounding_box(0, 0, box_b))
 43         std::cerr << "No bounding box in bvh_node constructor.\n";
 44 
 45     return box_a.min().e[axis] < box_b.min().e[axis];
 46 }
 47 
 48 
 49 bool box_x_compare(const shared_ptr<hittable> a, const shared_ptr<hittable> b) {
 50     return box_compare(a, b, 0);
 51 }
 52 
 53 bool box_y_compare(const shared_ptr<hittable> a, const shared_ptr<hittable> b) {
 54     return box_compare(a, b, 1);
 55 }
 56 
 57 bool box_z_compare(const shared_ptr<hittable> a, const shared_ptr<hittable> b) {
 58     return box_compare(a, b, 2);
 59 }
 60 
 61 bool bvh_node::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
 62     if (!box.hit(r, t_min, t_max))
 63         return false;
 64 
 65     bool hit_left = left->hit(r, t_min, t_max, rec);
 66     bool hit_right = right->hit(r, t_min, hit_left ? rec.t : t_max, rec);
 67 
 68     return hit_left || hit_right;
 69 }
 70 
 71 bvh_node::bvh_node(
 72     const std::vector<shared_ptr<hittable>>& src_objects,
 73     size_t start, size_t end, double time0, double time1)
 74 {
 75     auto objects = src_objects; // Create a modifiable array of the source scene objects
 76 
 77     int axis = random_int(0, 2);
 78     auto comparator = (axis == 0) ? box_x_compare
 79         : (axis == 1) ? box_y_compare
 80         : box_z_compare;
 81 
 82     size_t object_span = end - start;
 83 
 84     if (object_span == 1) {
 85         left = right = objects[start];
 86     }
 87     else if (object_span == 2) {
 88         if (comparator(objects[start], objects[start + 1])) {
 89             left = objects[start];
 90             right = objects[start + 1];
 91         }
 92         else {
 93             left = objects[start + 1];
 94             right = objects[start];
 95         }
 96     }
 97     else {
 98         std::sort(objects.begin() + start, objects.begin() + end, comparator);
 99 
100         auto mid = start + object_span / 2;
101         left = make_shared<bvh_node>(objects, start, mid, time0, time1);
102         right = make_shared<bvh_node>(objects, mid, end, time0, time1);
103     }
104 
105     aabb box_left, box_right;
106 
107     if (!left->bounding_box(time0, time1, box_left)
108         || !right->bounding_box(time0, time1, box_right)
109         )
110         std::cerr << "No bounding box in bvh_node constructor.\n";
111 
112     box = surrounding_box(box_left, box_right);
113 }
114 
115 #endif // !BVH_H
posted @ 2021-04-22 00:03  coolwx  阅读(331)  评论(0编辑  收藏  举报