Path Tracing学习笔记
看了Games101中关于Ray Tracing的内容后,自己其实从实现层面还是没理解的,因此找了网上的Path Tracing实现案例再巩固学习下。
代码来源:
smallpt: Global Illumination in 99 lines of C++
页面下方还有其他各种语言的实现,另外还有基于GPU的实现(这个有交互,很适合用来做Ray Tracing的演示)。
PS:这个代码是纯计算密集型的程序,很适合用来做性能测试。
- 使用蒙地卡罗路径追踪(Monte Carlo path-tracing)来产生全局照明效果
- 支持三种双向反射分布函数(bidirectional reflectance distribution function, BRDF): 镜射(specular)、漫射(diffuse)和玻璃(即纯折射的介质)
- 从漫射光源产生柔和阴影(soft shadow)
- 使用2x2超采样(super-sampling)去实现反锯齿
- 使用OpenMP作并行运算,充份利用多核性能
代码兼容性修改
原始代码距今已经10多年了,直接导入VS2019会报错,因此需要先修正一些问题。
导入代码
想要通过VS调试这部分代码,得先生成VS项目。注意不要直接基于当前代码创建项目,而是先创建一个Console类的C++项目,然后将代码复制进去。
这是因为基于当前代码直接在编辑器中创建项目,可能会弄成win类型的项目,导致后面编译报错。
运行按钮显示“附加”而不是“开始”
这是因为打开项目时,从包含它的文件夹中直接双击文件打开了项目,而不是从VS中打开它。
未定义标识符 “erand48”
这个函数应该是已经被移除了,需要自行实现该函数:
https://stackoverflow.com/questions/27198584/erand48x-not-working-in-c-visual-studio-12
注意函数的参数类型,要从int改为unsigned short*:
1 | |
未定义标识符 “M_PI”
https://qa.1r1g.com/sf/ask/1824575161/
1 | |
注意define必须放前面,放后面会报错。
无法解析的外部符号 _WinMain@16,函数 “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ) 中引用了该符号
这就是前面提到的,需要先创建一个console类型的项目,然后手动复制代码进去的原因:
https://blog.csdn.net/xiwan0902/article/details/71515038
‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
https://zhuanlan.zhihu.com/p/386182672
为了简便,我是直接忽略了这个报警,即在文件顶部添加了:
1 | |
0x00007FF6FE5D4D37 处有未经处理的异常(在 smallpt-cpp.exe 中): 0xC00000FD: Stack overflow (参数: 0x0000000000000001, 0x0000004645EE3F90)。
https://www.codenong.com/cs105750005/
(TODO)性能
这段C++代码执行,性能非常差,比JS还慢得多。
运行期间CPU使用率才10-20%,怀疑是没有将多核利用起来。
还有就是可能写法不对。
JS的都比这个快得多。
100采样,JS大约在60s左右。
C++这个,4采样,就花了34.5s。