2026/1/15 8:56:26
网站建设
项目流程
淄博网站制作网络丰富,替人做赌彩网站,国有企业网站建设,营销型网站建设实战》在本地编译前#xff0c;请在 settings.h 中更新 workspace 路径#xff0c;为使用 openmp#xff0c;请使用”-fopenmp“参数进行编译本来这两周计划测试不同 bvh 算法、实现 photonmapping 和 GUI 的#xff0c;但是最近要去实验室#xff0c;所以没空写也就算了。图 1 …在本地编译前请在 settings.h 中更新 workspace 路径为使用 openmp请使用”-fopenmp“参数进行编译本来这两周计划测试不同 bvh 算法、实现 photonmapping 和 GUI 的但是最近要去实验室所以没空写也就算了。图 1 样例系统构架目前没有使用 make/cmake但都留了接口 │ background.h 背景光 │ bound.h 即 AABB用于 hit 时的搜索 │ camera.h 相机模块 │ hitable.h 光线与物体相交模块管理 hitable 文件夹中的各种形状 │ log.txt 运行日志 │ main.cpp CLI 主函数 │ main.exe CLI 编译程序 │ material.h 材质模块管理 material 文件夹各种材质 │ picture.ppm 输出的 ppm 格式图片 │ ray.h 光线 Class │ README.md │ sampler.h 取样模块即 Monte-Carlo管理 sampler 文件夹采样函数 │ scene.h 场景目前全部写在一个文件中 │ geometry/geometry.h 3vector Class │ ├─accelerator 加速模块目前只写了 bvh 加速kd-tree 和基于其上的 photon-mapping 还没来及写 │ │ bvh.h bvh Class │ │ │ └─bvh_method │ bvh_build.h bvh 函数定义 │ bvh_node.h bvh 使用的 struct │ ├─gui GUI 界面使用 Qt5 ├─hitable │ aabb.h 实际上使用的是 bound.h │ cube.h 采用 intersect 方法写的 cube还可以使用三角面片等方法实现 │ cylinder.h 圆柱体 │ hitable_list.h 其实应该叫做 Union是 hitable 集合的并 │ intersect.h Intersect hitable 集合的交 │ plane.h 无穷大平面 │ sphere.h 球 │ triangle.h 三角面片 │ ├─loader 文件加载器 │ │ myobjloader.h 自己写的 c based obj/mtl 模型文件加载 │ │ mypngloader.h 基于 stb_image 的图片加载器理论上不仅支持 png本来尝试使用 pnglib但很笨重最后决定直接用 stb │ │ │ └─external │ stb_image.h │ ├─material │ glass.h 玻璃 │ lambertian.h 余弦体 │ metal.h 金属 │ source.h 光源 │ texture.h 贴图 │ ├─model 模型文件目前仅支持 obj/mtl可以使用开源的 blender 转格式 │ ├─mylib │ common.h 基本所有模块都要用到的基本头 │ mycode.h 我 coding 是的一些习惯性宏或函数 │ mylogo.h Cli 界面 LOGO │ myrand.h 随机数生成器 │ onb.h onb 模块用的不是太多 │ settings.h 编译参数宏利于使用什么算法是否打开色散 etc.可以用 cmake 输入根据需求进行编译 │ ├─notes 笔记 │ bvh.md │ idea.md │ ├─pics 输出各种测试图片 │ ├─png png 格式输出 │ └─ppm ppm 格式输出 │ ├─sampler │ cos_sampler.h 余弦分布采样 │ hit_sampler.h 光源 oriented 采样 │ mix_sampler.h 混合采样 │ └─test 测试模块交互界面GUI 使用 Qt5但是还没来及写好下图是作为替代随便写的 Cli 交互界面图 2 CLIHitable几何体几何体实现都不复杂因为懒只实现了 cube、sphere、plane、cylinder其实使用牛顿下山等方法任意曲面都很好实现。cylinder目前的实现在代码层面上有些暴力可优化cubecube 虽然有多种方法但这里实现的其实更鲁棒一点实际上实现的是平行六面体比 cube 有更高的自由度。逻辑物体hitable_list 和 Intersect 实现的时物体组的交并三角面片很简单解的三元线性方程组即可又很重要不做赘述值得一提的时 obj 文件是右手螺旋顺序以及当下的实现尽可能将计算量预处理在生成三角面片时但是会浪费存储目前跑下来加上贴图和模型内存占用也并不大所以不是什么问题如图二是加载了 02 模型加贴图使用了 bvh 树20000spp8 线程 openmp 的资源占用图 3 任务管理器Material玻璃色散dispersion玻璃的折射与投射都是很基础的内容很容易实现这里额外实现了色散dispersion效果因为只是将光线在第一次发生色散时分为三个通道分别走 rgb 而已和容易看到光线可逆对色散也成立所以可以这样做复杂度增加是常数量级3在 settings.h 种可以设置宏的值开关决定是否编译色散的部分为了节省资源一半会将色散关闭。正常玻璃 rgb 折射率跨度只有约 0.5因此没必要用Sellmeier equation不过为了让效果稍微明显点图 4 使用了 1.5-1.6 的折射率跨度注意物体的边缘有明显的色散效果。全反射显然全反射在球形玻璃中不会出现但图 4 中立方体中可以看到明显的全反射。图 4 dispersion金属和余弦体没什么好说的光源光源目前使用的是球状面光源三角面片的面光源也实现了但并未使用因为在 Monte-Carlo 中为了使用重要性采样需要计算面光源的立体角而三角面片的立体角无法在 O(1)时间内精准计算只能在足够远或三角面片足够小的近似下计算所以有可能造成光源近处物体的失真但是应该看不出来而且只要三角面片够小也可以另外还有 directed source准备和 photon-mapping 一起实现因为可以做出汇聚光的效果TextureTexture 通过计算碰撞点相对贴图的 uv 坐标返回反射率或颜色目前只有 png 和常数贴图即单色其他实现的必要似乎也不大。只实现 png 的主要原因是 png 是无损压缩大部分模型贴图使用的都是 png 格式。下图 5.1 是 02mainbody 贴图5.2 是在室外的渲染效果颜色比较淡的原因是使用了 gamma 修正而图 5.3 则是关闭 gamma 修正的效果都是 100spp。图 5.2 gamma on图 5.2 gamma onCamera目前 Camera 只能设置 FOVLookFromLookAt还不支持焦距之所以不支持原因是现在只是用了纯 Monte-Carlo因此噪音已经很大了如果加上焦距和延迟摄影效果采样自由度又会增加从而造成噪音不可控具体可以参见 sampler 部分。但是只要利用焦平面和透镜组三基点主点、节点、焦点的性质并在 Class ray 中加上时间自由度景深和延迟摄影效果都很好实现。Sampler采用了重要性采样的 Monte-Carlo简单而言就是让更多的光线打到亮的地方例如光源平面镜玻璃之后通过加权得到真实的亮度这样有两点好处shader 更容易打到光源上终止即 shader 深度降低大大提升程序效率因为大部分 sample 光强比较大这样绝对误差就会更小同样较低的采样率使用 monte-carlo 显然会更亮更接近实际情况特别是在黑暗的环境中如果不用重要性采样的 Monte-Carlo场景就会一片黑暗图 6.1 6.2 是同样 sample 数下300spp使用与不使用重要性采样的对比其中图 6.2 中墙上的影子是一个小 bug已经修复了图 6.1 300spp 不使用重要性采样的 Monte Carlo图 6.1 300spp 使用重要性采样的 Monte Carlo但是 Monte-Carlo 这种纯采样机制注定会噪声很大图 7 是 wiki 上的对比每张图都比前一张采样率翻倍可以看到 noise 是 Monte-Carlo 无法避免且致命的缺陷。图 7 Monte Carlo 噪声变化随机数生成随机数生成对图片的噪声显然也有很大影响图 8.1 和 8.2 是同样 spp 同一场景下使用不同随机数生成方法得到的结果因为场景生成也用了随机数所以场景也略有不同图 8.1 随机数生成器 1inline double random_double() { return rand() / (RAND_MAX 1.0); }图 8.2 随机数生成器 2static double random_double() { static std::random_device seed_gen; static std::mt19937 engine(seed_gen()); static std::uniform_real_distribution dist(0.0, 1.0); return dist(engine); }Cos-sampler按余弦分布采样对于有环境光的场景室外以为余弦体就是余弦分布这样采样采样率分布与实际贡献一致误差最小hit-sampler像光源或玻璃采样mix-sampler支持任意数量 sampler 按任意权重加权采样一般采用 coshit 各一半进行采样。Shader目前没有单独出来作为一个模块功能主要是递归的 path tracing。Loader写的时候使用了 C 风格的输入输出后面会替换程 cpp 风格图 9 是没有加载贴图的效果图 9 no texture 02 indoorAccelerator加速模块主要是 bvh、kd-tree、photon mapping不过目前只实现了 bvhbvh之所以使用 bvh 而非 kd-treephoton mapping 会使用 kd-tree原因在于 bvh 虽然是基于物体的分割kd-tree 是基于空间的分割造成无法保证前后遮挡关系不能终止树的遍历从而导致性能不如 kd-tree但是 kd-tree 可以维护以为着可以适用于 RTRT 场景并且通过一些加速算法例如我使用的 ordered bvh可以达到与 bvh 不相上下的效果自然会更 popular可以参考 Stack Exchange 上的回答。本文参考了 Wald et. al.的论文和 PBRT 的实现不过应为还没来及测试各种算法实际跑出来的速率所以具体细节会放到下一次作业这里只简单提一下因为现在渲染的是静态场景所以考虑的是尽可能牺牲 bvh build 的时间和空间换取 shading 的速度。因此采用的是遍历 O(n)种 SAH 取其中最优解的方法共 O()种因为无法避免排序所以bvh build的时间是从图二可以看到02 的 bvh build time 大约 20sec使用 bucket SAH 应该可以有十倍以上加速但不知道 shading 速度会减多少。采用了排序的 bvh这样每次都会先访问中心靠光线更近的 bvh虽然不能立刻终止但可以尽可能减小 t_max光线 hit 的上界从而尽早终止。所有物体都按照 2 种访问顺序重排这样有更大的概率访问内存种连续部分且顺序访问bvh node 使用了 32 位对准