Ray tracing in one weekend 疑难点解析与拓展
《Ray tracing in one weekend》(一周末搞定光线追踪), 由Peter Shirley所编写的的软渲光追三部曲第一本, 是一本非常好的入门级书籍, 篇幅不多, 一共只有54页, 适合新手学习。
剩下的两本为:
Ray tracing: The next week(光线追踪: 下一周)
Ray tracing: The rest of your life(光线追踪: 余生)
作者已将本书免费发布到公共领域(cc0协议), 点击这里在线阅读本书
本文将解析书中的一些疑难点, 并对原有的程序稍作修改
有时间的话, 可能会考虑来做个全书翻译翻完啦
1 Overview
2 Output an Image
作者虽然在本书使用PPM格式来输出图片, 但在本章最后他提到自己对stb_image.h
的喜爱, 那我们就顺水推舟, 不妨使用这个常用的图像库把颜色信息储存为更加便于查看的jpg格式。
stb_image.h
, stb_image_write.h
等是由C语言编写的类库文件,遵从MIT协议开源协议(stb是作者Sean T. Barrett名字的缩写)。我们这里使用stb来将数据写入文件,并不需要读取, 所以仅需要导入stb_image_write.h
即可, 点击这里下载
下载完成后将其导入你的项目
1 |
|
为我们的图像分配空间
1 |
|
然后将颜色信息写入
1 |
|
最后写入文件并释放空间
1 |
|
配合github desktop 我们可以很舒服的来观察输出结果的变化
3 The vec3 Class
c++ 重载教学
4 Rays, a Simple Camera, and Background
5 Adding a Sphere
6 Surface Normals and Multiple Objects
c++ 继承教学
7 Antialiasing
这里的抗锯齿做法十分暴力: SSAA, SuperSampling Anti-Aliasing(超级采样抗锯齿), 在每个像素周边发射s条射线然后取颜色的平均值, 本书中s取100
这样程序的运行时间就直接翻了s倍, 十分的慢我们先把程序由Debug
切换到Release
, 实测可以大幅提升运行速度再通过OpenMP来进行多线程的加速首先我们先打开编译器对OpenMP的支持 右键项目属性C/C++ → 语言 → OpenMP支持(是)
1 |
|
这里的num_threads在默认情况下是你cpu的核心数, 开启超过cpu核心数的线程并不会提升程序执行效率。原理很简单, 不优化时程序是在单核跑, 优化后OpenMP将代码块编译, 拆分, 让剩下的3个核心也加入了运算, 这时再开启更多线程也没用了, 一共只有4个核心, 而他们全部都在运算中。
我们可以省略for num_threads()
参数, 直接
1 |
|
当for循环嵌套时,即两个循环之间存在关连时, 复数的优化指令也无法做到加速
1 |
|
#pragma omp parallel for
写在哪个循环前, 就会把该循环的工作拆分, 于是就打乱该循环的次序。使用大括号{}
将目标代码段括起来, 会将内外部循环次序全部打乱
1 |
|
在该项目中加速, 只要在遍历像素前加一句#pragma omp parallel for
即可
1 |
|
现在程序的运行速度就会快上大约你核心数的倍数, 再加上切换到Release
模式,原来渲上好几个小时的图只需渲上几分钟
8 Diffuse Materials
光线打到粗糙不平的物体表面, 会随机的往各个方向散射。在生活中大部分物体都属于这类。
生成一个随机的单位向量来模拟光线的无规则散射
9 Metal
在计算dot(v,n)时, v与n的夹角大于90°, 运算结果为负值, 所以需要补正
10 Dielectrics
求折射光线的方向
全内反射
Fresnel - Schlick approximation近似求借菲涅尔方程
11 Positionable Camera
这里和其他地方的摄像机没有太大的区别fov, depth
12 Defocus Blur
和chapter7的做法一样,将摄像机发出每条射线的位置进行偏移, 然后在SSAA时就会暴力的取平均值
13 Where Next?
Ray tracing in one weekend 疑难点解析与拓展
https://matrix4f.com/Graphic/ray-tracing-in-one-weekend-explanation/