games101 作业7 实现path tracing
好家伙,闫老师说此程序很慢,算是见识到了path tracing有多慢。。。(渲染时间1个小时)
这是3月3号了,主要是2月份过年,然后其他东西,本来我也懒,所以很多时候也荒废掉了,今天算是重新复习了一下渲染管线,然后,果然一段时间不写,框架全部忘光了。。。这个path-tracing也是理解一下了,只能说确实困难。。很久不写代码是这样的,全部gg了。(50行,要写下来真不容易,主要是整个框架一段时间没有碰了)
(先按照要求复制原来的代码,这里注意一个坑,就是在bounds3.hpp中要注意判断相等。。。不判断相等整个图是暗的)
原作业要求如下
Triangle::getIntersection in Triangle.hpp: 将你的光线-三角形相交函数
粘贴到此处,请直接将上次实验中实现的内容粘贴在此。
• IntersectP(const Ray& ray, const Vector3f& invDir,const std::array<int, 3>& dirIsNeg) in the Bounds3.hpp: 这个函数的作用是判断包围盒 BoundingBox 与光线是否相交,请直接将上次实验中实现的内容粘贴在此处,并且注意检查 t_enter = t_exit 的时候的判断是否正确。
1 inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir, 2 const std::array<int, 3>& dirIsNeg) const 3 { 4 float t_Min_x = (pMin.x - ray.origin.x)*invDir[0]; 5 float t_Min_y = (pMin.y - ray.origin.y)*invDir[1]; 6 float t_Min_z = (pMin.z - ray.origin.z)*invDir[2]; 7 float t_Max_x = (pMax.x - ray.origin.x)*invDir[0]; 8 float t_Max_y = (pMax.y - ray.origin.y)*invDir[1]; 9 float t_Max_z = (pMax.z - ray.origin.z)*invDir[2]; 10 if(!dirIsNeg[0]) 11 { 12 float t = t_Min_x; 13 t_Min_x = t_Max_x; 14 t_Max_x = t; 15 } 16 if(!dirIsNeg[1]) 17 { 18 float t = t_Min_y; 19 t_Min_y = t_Max_y; 20 t_Max_y = t; 21 } 22 if(!dirIsNeg[2]) 23 { 24 float t = t_Min_z; 25 t_Min_z = t_Max_z; 26 t_Max_z = t; 27 } 28 29 float t_enter = std::max(t_Min_x,std::max(t_Min_y,t_Min_z)); 30 float t_exit = std::min(t_Max_x,std::min(t_Max_y,t_Max_z)); 31 if(t_enter<=t_exit&&t_exit>=0) 32 return true; 33 else 34 return false; 35 36 // invDir: ray direction(x,y,z), invDir=(1.0/x,1.0/y,1.0/z), use this because Multiply is faster that Division 37 // dirIsNeg: ray direction(x,y,z), dirIsNeg=[int(x>0),int(y>0),int(z>0)], use this to simplify your logic 38 // TODO test if ray bound intersects 39 40 }
• getIntersection(BVHBuildNode* node, const Ray ray)in BVH.cpp: BVH
查找过程,请直接将上次实验中实现的内容粘贴在此处.
Intersection BVHAccel::getIntersection(BVHBuildNode* node, const Ray& ray) const { Intersection intersect; Vector3f invdir(1./ray.direction.x,1./ray.direction.y,1./ray.direction.z); std::array<int, 3> dirIsNeg; dirIsNeg[0] = ray.direction.x>0; dirIsNeg[1] = ray.direction.y>0; dirIsNeg[2] = ray.direction.z>0; if(!node->bounds.IntersectP(ray,invdir,dirIsNeg)) { return intersect; } if(node->left == nullptr && node->right==nullptr) { return node->object->getIntersection(ray); } Intersection h1 = getIntersection(node->left,ray); Intersection h2 = getIntersection(node->right,ray); return h1.distance<h2.distance?h1:h2; return intersect; // TODO Traverse the BVH to find intersection }
最后是要实现的路径追踪算法,还是按照ppt的思路来。
(注意一开始有一个要直接判断是否与光源相交的过程,这个一个是体现直接照射,第二个是在后面的递归中终止递归)
这里首先感谢https://blog.csdn.net/miyu1994/article/details/107016804文章中的算法,嗯,我也是先看了一遍。。。最终实现效果如下