好家伙,閆老師說此程序很慢,算是見識到了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文章中的算法,嗯,我也是先看了一遍。。。最終實現效果如下