欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

利用包围盒加速的光线追踪实现图形渲染

最编程 2024-08-14 11:23:31
...

欢迎关注公众号:sumsmile, 图像视觉、移动开发~~

接上一篇《图形渲染5-光线追踪》,对求交算法进行优化.

实现效果

下图中兔子模型是由4968个三角形拼接而成

忽略背景。vscode预览3d模型,默认有个背景,去不掉.

sunny mesh

sunny render result

注:bunny是儿语化的“兔子”

BVH加速

光线追踪的渲染中,每一个像素,实际上是光线打到物体表面反射到场景中。(实际还有自发光的情况,本章节简化模型,仅考虑漫反射)

为什么要加速

场景中可能存在很多物体,单个像素的光线需要和这些物体挨个求交,最后比较得出最近的交点,其他交点处于被遮挡的情况,忽略不计。

上图中兔子模型有4968个三角形,一帧图像中一个点就需要求交近5千次,1280 * 720的窗口渲染一次需求交 4968 * (1280 * 480)次,这还是比较简单的模型场景。

包围盒示意图

很容易就想到,使用一个立方体,将单个模型包围起来,先对立方体求交,条件成立之后,再考虑与里面的几何模型求交。当然了,可以将模型进一步拆分成n个三角形,包裹在立方体中。

包围盒

包围盒有多种形式,最常用的包围盒长、宽、高分别与x、y、z平行,方便计算。

什么是BVH

BVH:Bounding Volume Hierarchy。包围盒层级。

将场景中的所有模型做拆分,分成一块一块的,最常见的有基于空间和基于物体拆分两种形式。本篇中基于物体做拆分,持续迭代,拆成一个二叉树,中间节点存放包围盒,子节点存放真实的物体。

第一次拆分

第二次拆分

第三次拆分

基于包围盒的光线求交

BVH的使用

  1. 创建包围盒:遍历场景中的物体,按照一定规则拆分包围盒。可以沿着最长的轴方向切割,另外拆分有个限制,就是拆到什么程度不再拆了,可以自己定义,比如一个包围盒少于5个三角形就不再拆分了。

  2. 光线求交:从上往下,按照树的遍历方式,对每个节点进行遍历,当然了,先判断父节点的包围盒是否和光线相交,满足条件再遍历子节点,如此,很大程度的优化了光线追踪的算法复杂度。

代码核心逻辑

虽然只是个demo,有软渲染器的核心逻辑,有面向对象的封装,有渲染的算法。

  • Scene(场景)
  • Light(光照)
  • Renderer(渲染器)
  • Model(几何模型)
  • 工具类

光线追踪渲染流程

完整代码:

github.com/summer-go/g…

补充

  • 判断光线与包围盒相交的算法
  • 轻量级的3D加载工具OBJ-Loader
  • 模型只有漫反射,用冯氏光照计算颜色,兔子本身没有颜色,写死成(0.0, 0.5, 0.0)绿色

欢迎关注公众号:sumsmile, 图像视觉、移动开发~~

参考资料:

[1] 完整代码: github.com/summer-go/g…

[2] ray-box-intersection: www.scratchapixel.com/lessons/3d-…

[3] OBJ-Loader: github.com/Bly7/OBJ-Lo…