mik*_*era 5 algorithm 3d performance raytracing data-structures
我正在编写一个3D光线跟踪器作为个人学习项目(Enlight),并遇到了一个有趣的问题,涉及在光线和物体场景之间进行交叉测试.
情况是:
Transform对象中来对具有任意仿射变换的场景对象进行渲染(重要的是,这将使得相同图元的多个实例能够在场景中的不同位置使用,因为图元是不可变的)Ray用于表示部分光线段的对象(起始矢量,标准化方向矢量,起始距离,结束距离)问题是当光线撞击Transform对象的边界框时,看起来与包含在其中的变换图元进行交叉测试的唯一方法是将变换Ray为坐标变换的坐标空间.这很容易,但是如果光线没有碰到任何变形的物体,我需要回到原始状态Ray继续跟踪.由于Transforms可以嵌套,这意味着我必须Ray为每个完成的交集跟踪维护一整堆s.
这当然是整个应用程序的内部循环和主要性能瓶颈.它将被称为每秒数百万次,所以我渴望最小化复杂性/避免不必要的内存分配.
有一种聪明的方法可以避免分配新Ray的/保持Ray堆栈吗?
或者有一种更聪明的方式完全这样做?
大多数时候,在光线追踪中,您有几个(数百个、数千个)对象和相当多的光线。可能有数百万条光线。在这种情况下,了解可以在对象上花费什么样的计算以使光线与它们交互更快/更容易是有意义的。
正如 boyfarrell 所建议的,缓存将非常有帮助。不仅在对象上创建将它们移入或移出全局框架的正向和反向变换,而且在全局框架中保留对象的副本可能是有意义的。它使得创建对象或移动它们变得更加昂贵(因为变换发生了变化,缓存的全局帧副本也会发生变化),但这可能没问题。
如果你投射 N 条光线并有 M 个物体,并且 N >> M,那么按理说每个物体都会有多条光线击中它。如果我们假设每条光线都击中一个物体,那么每个物体都有 N/M 条光线击中它。这意味着将 N/M 条光线转换到每个物体,进行命中测试,并可能将其反转。或者每个对象至少进行 N/M 次变换。但是,如果我们缓存变换后的对象,我们可以对每个对象执行一次变换以到达全局框架,然后不需要任何额外的操作。至少对于命中测试来说是这样。