所以我正在通过光线追踪教程试图伸展我的F#腿。由于本教程是用C ++编写的,因此找出如何以功能方式应用概念是一个相当有趣的挑战。我想以尽可能多的方式编写所有内容,因为我打算最终并行运行光线跟踪器。但这让我遇到了以下情况,我确信其中的核心是光线跟踪以外的主题。
我们有一个Engine
对象(除此之外)存储一个Scene
对象(Primitive
个对象的集合)。目前,其中的Scene
和Primitive
完全不可变。
为了尝试改善渲染时间,我们正在实现一个常规的三维网格。为了以有效的方式遍历网格,教程引用this paper用于遍历算法,并减少跨越网格边界的基元的交叉测试数。以下是后一部分的工作原理:
Ray
分配一个唯一的rayID
Primitive
都有一个lastRayID
字段。Ray
检查与Primitive
的交集时,
rayID
的{{1}}等于Ray
的{{1}},则会跳过相交测试。lastRayID
的{{1}}存储在Primitive
的{{1}}字段中。这是缓存交叉点测试的一种巧妙方法,但它是为顺序光线跟踪器设置的,即使是两条并发光线也无法工作。因此,虽然我可以使用rayID
字段,因此能够实现此算法,但它不能满足我固有的可并行化光线跟踪器的最终目标。
我确实有一个想法。与每个图元一起存储可变状态的问题在于,就渲染算法而言,场景是一个全局实体 - 每个光线都可能触发任何图元。另一方面,每条光线都是完全自包含的。所以在每一条射线中,我想我可以构建一组已经过测试的原语(这个集合将等同于上面描述的Ray
字段)。这个问题是每条光线的寿命都非常短,并且在任何给定时间都可能存在许多光线,因此在每条光线中设置这样的数据结构可能代价高昂((de)分配时间和内存)消费成本可能会迅速增加)
有没有人有处理这类情况的建议?即使将共享的可变状态转换为本地可变状态或类似的东西是一般性的想法,我相信这会帮助我很多。如果有必要,我很乐意澄清任何事情。