HomeWork 7:路径追踪
首先按照 pdf 里面的操作,将相关函数迁移过来;
IntersectP 函数最后判断的时候,需要=,不然可能会有问题:
1 2 3 4 5 6
| inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir, const std::array<int, 3>& dirIsNeg) const { ... return t_exit >= 0.0f && t_enter <= t_exit; }
|
然后就是本次作业的内容,本次作业要实现的是路径追踪函数;
这个作业是真的有点难… 主要是知识点都忘了…
建议回去看一遍视频… 然后对照课程中的伪代码一步一步比对实现
castRay 这个函数实现的就是路径追踪
具体细节看代码里面的注释!
知识点参考的是这一节课的内容:
【Games 101】Lec 16:光线追踪 4(蒙特卡罗积分,路径追踪)
Scene.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
Vector3f Scene::castRay(const Ray &ray, int depth) const { Intersection p = intersect(ray);
if(!p.happened) return Vector3f(0,0,0); if(p.m->hasEmission()) { return p.m->getEmission(); }
Vector3f wo = ray.direction; Vector3f L_indir(0); Vector3f L_dir(0);
Intersection inter_l; float pdf_light; sampleLight(inter_l, pdf_light); Vector3f x = inter_l.coords;
float p2lightDist = (x - p.coords).norm(); Vector3f p2lightDir = (x - p.coords).normalized();
Ray wi(p.coords, p2lightDir); Intersection inter_tmp = intersect(wi);
if ((inter_l.coords - inter_tmp.coords).norm() < EPSILON * EPSILON) { Vector3f L_i = inter_l.emit; Vector3f f_r = p.m->eval(wo, wi.direction, p.normal); float cos0 = dotProduct(wi.direction, p.normal); float cos0_ = dotProduct(-wi.direction, inter_l.normal);
L_dir = L_i * f_r * cos0 * cos0_ / (p2lightDist * p2lightDist) / pdf_light; }
float P_RR = RussianRoulette; int seed = rand() % 10; if (seed * 1.0 / 10 > P_RR) return L_dir; Vector3f wi_new = p.m->sample(wo, p.normal);
Ray r(p.coords, wi_new); Intersection q = intersect(r);
if (q.happened && !q.obj->hasEmit()) { Vector3f f_r = p.m->eval(wo, wi_new, p.normal); float cos0 = dotProduct(wi_new, p.normal); float pdf_hemi = p.m->pdf(wo,wi_new,p.normal);
L_indir = castRay(r, depth+1) * f_r * cos0 / pdf_hemi / P_RR; } return L_dir + L_indir; }
|
路径追踪结果:
可能是给虚拟机分配的内存和CPU数量少了… 跑了40分钟,主机的CPU也才跑了20多而已…