【发布时间】:2012-12-05 03:31:57
【问题描述】:
我正在编写一个 3D 光线追踪器作为个人学习项目 (Enlight),并且遇到了一个与在光线和对象场景之间进行交叉测试相关的有趣问题。
情况是:
- 我有许多可以与光线相交的基元(球体、长方体、平面等)及其组。我统称为这些场景对象。
- 我希望能够通过将对象基元包装在
Transform对象中来对具有任意仿射变换的对象基元进行场景化(重要的是,这将使相同基元的多个实例能够在场景中的不同位置使用,因为原语是不可变的) - 场景对象可以存储在边界体层次结构中(即我正在执行空间分区)
- 我的相交测试使用
Ray表示部分射线段的对象(开始向量、归一化方向向量、开始距离、结束距离)
问题在于,当光线击中 Transform 对象的边界框时,看起来与其中包含的已转换图元进行交集测试的唯一方法是将 Ray 转换为转换后的坐标空间.这很容易,但是如果光线没有击中任何变换的对象,我需要回退到原始的Ray 以继续跟踪。由于变换可能是嵌套的,这意味着我必须为完成的每个交叉点跟踪维护一整堆Rays。
这当然是在整个应用程序的内部循环中,也是主要的性能瓶颈。它每秒会被调用数百万次,所以我希望尽量减少复杂性/避免不必要的内存分配。
有没有一种巧妙的方法可以避免分配新的Rays / 保留Ray 堆栈?
或者有没有更聪明的方法来做到这一点?
【问题讨论】:
-
我不确定这是否会比内存分配更快,但您可以尝试提出一种有效的变换反转算法,然后在退出时将当前光线与逆变换相乘当前对象。
-
@Ivan - 有趣的想法。我想它可能会稍微快一点,虽然我会担心复合数值精度问题.....
-
您可以预先计算和缓存每个对象(以及组中的对象)的变换和逆变换(即矩阵对象),这些对象将与全局框架相互转换。这样您就不需要嵌套层次结构,因为您可以直接对每个对象进行命中测试。 IE。将光线变换到物体的框架,然后变换回来得到全局框架中的命中点。我在我的跟踪器中这样做:github.com/danieljfarrell/pvtrace
标签: performance algorithm data-structures 3d raytracing