代码地址:
目标
- 迁移代码
- Path Tracing:正确实现 Path Tracing 算法
- (附加题)多线程:将多线程应用在 Ray Generation 上
- (附加题)Microfacet:正确实现 Microfacet 材质
迁移代码
Triangle.hpp:
1 | inline Intersection Triangle::getIntersection(Ray ray) |
加了这一条,没有黑点了
if (t_tmp < 0) return inter;
Bounds3.hpp
1 | inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir, |
BVH.cpp
1 | Intersection BVHAccel::getIntersection(BVHBuildNode* node, const Ray& ray) const |
Path Tracing 算法
以下是作业pdf中的伪代码:
1 | shade (p, wo) |
根据作业pdf中的伪代码敲:
1 | Vector3f Scene::castRay(const Ray &ray, int depth) const |
需要注意的是:
- 从p点向x点射出光线,需要对p点进行修正,否则会出现不正确的阴影
- 直接光照的判断条件中,需要将eps调大,否则会出现黑边
下面是spp较小的结果图:
另外,p点要修正,否则会产生以下的错误结果:
随机数问题
随机数构造器优化:https://zhuanlan.zhihu.com/p/606074595
C++的性能分析器:https://blog.csdn.net/u011942101/article/details/123656944
在global.hpp
中将以下三个变量设置为static
,能够加速图像的生成。由于这个函数频繁地被调用,其中的变量经常被反复构建,造成了很大性能开销。将这些变量设置为static,那么这些变量只会初始化一次,避免了重复构建。
1 | inline float get_random_float() |
多线程
C++多线程教程:https://blog.csdn.net/sjc_0910/article/details/118861539
以下是实现多线程需要注意的地方:
- 可以将渲染像素的过程使用lambda表达式写出来,这样能够方便地使用多线程。
UpdateProgress
这个函数可能会造成冲突,需要上锁
1 | void Renderer::Render(const Scene& scene) |
效果提升显著,从18分钟缩减到1分钟。
问题
渲染结果较暗,出现横向黑色条纹的情况,很可能是因为直接光部分由于精度问题,被错误判断为遮挡,请试着通过精度调整放宽相交限制。
解决方法:增大直接光照判断条件中的eps。
渲染结果全黑或几乎全黑,右边完全看不见物体,是因为包围盒AABB的判断错误,天花板和周围的面是没有厚度的,这导致在判断的时候没有纳入相交。
解决方法:需要考虑
t_enter == t_exit
的情况
最终结果如图: