在今年的GDC(游戏开发者大会)的Advanced Graphics Summit上,关于Snowdrop引擎中光线追踪技术的讨论引起了广泛关注。
一、光线追踪全局照明的实现细节
-
屏幕空间追踪:
- 屏幕空间追踪从相机出发,对屏幕上的每个像素点生成一条或多条光线。
- 这些光线在屏幕上进行遍历,查找与场景物体相交的点。
- 一旦找到相交点,引擎会计算该点处的光照信息,包括颜色、亮度等。
- 由于屏幕空间追踪只关注屏幕上的像素,因此其计算效率较高,但精度可能受到屏幕分辨率的限制。
-
世界空间追踪:
- 如果屏幕空间追踪未能找到相交点,引擎会转向世界空间进行追踪。
- 在世界空间中,引擎会发出光线,并检查光线是否与场景中的任何物体相交。
- 为加速这一过程,引擎使用BVH(边界体积层次)数据结构。BVH将场景划分为多个层次化的体积,从而可以快速定位到与光线相交的物体。
- 一旦找到相交点,引擎会计算该点处的光照信息,并考虑光线在物体间的传播和交互。
- 世界空间追踪的计算量较大,但可以提供更高的精度和更真实的光照效果。
-
光照缓存:
- 如果世界空间追踪也未能找到相交点,引擎会使用光照缓存作为后备方案。
- 光照缓存是预先计算并存储的光照信息,包括场景中不同位置的光照强度和颜色等。
- 引擎会根据当前场景的几何形状和光源位置,动态地更新光照缓存中的信息。
- 当光线与场景中的物体相交时,引擎会查找光照缓存中对应位置的光照信息,并应用到渲染结果中。
- 光照缓存可以显著提高渲染速度,但可能会占用较大的内存空间。
- 他是探针是利用级联分布的:级联3是最近的一个,每个探针之间的间隔是2米,覆盖64x64x16米的区域。 级联2跟随,探针间隔为8米,覆盖256x256x64米的区域。 然后是级联1,探针之间的间隔为64米,覆盖2048x2048x512米的区域。 最后是远处的级联0,探针之间的间隔为1024米,覆盖32x32x8公里的区域。
二、光线追踪反射的实现细节
-
每像素光线追踪:
- 对于每个像素,引擎都会发出一条或多条光线来模拟反射效果。
- 这些光线从像素位置发出,并根据反射定律进行追踪。
- 根据质量设置,引擎可以使用不同分辨率的光线进行追踪。较低分辨率的光线追踪可以提高性能,但可能会降低反射的清晰度;而较高分辨率的光线追踪则可以生成更精确的反射效果。
-
可变混合分辨率:
- 为了在保持渲染质量的同时降低计算开销,引擎采用了可变混合分辨率技术。
- 这意味着图像的不同部分可以根据需要采用不同的分辨率进行追踪。例如,在细节丰富的区域使用高分辨率,而在平坦的区域使用低分辨率。
- 可变混合分辨率技术可以显著提高渲染效率,同时保持较好的视觉效果。
-
多层反射:
- Snowdrop引擎支持多达两层的反射效果。
- 当光线与物体相交时,引擎会递归地追踪光线的反射路径,并计算每次反射时的光照信息。
- 多层反射可以生成更真实、复杂的反射效果,但也会增加计算量。
三、LOD(层次细节)和材质优化的实现细节
-
LOD(层次细节):
- LOD技术允许引擎根据物体与玩家的距离和重要性选择使用不同的细节层次进行渲染。
- 较远的物体或不太重要的物体可以使用较低的细节层次进行渲染,以减少计算量并提高性能。
- 引擎会根据需要动态加载和卸载不同级别的细节数据,以保持场景的连贯性和一致性。
- LOD技术的关键在于如何平衡渲染质量和性能,以提供最佳的视觉体验。
-
材质优化:
- 为了减少计算量并提高渲染速度,引擎对材质进行了优化。
- 每个网格通常只使用一种简单的材质,并尽量减少纹理的使用。对于需要纹理的对象,引擎会采用专门的纹理压缩和优化技术来减少内存占用并提高渲染速度。
- 引擎还会根据物体的材质属性进行光照计算和优化。例如,对于金属表面,引擎会采用基于物理的渲染(PBR)技术来模拟其真实的光泽和反射效果;而对于漫反射表面,引擎则会使用更简单的光照模型来加速计算。
四、性能优化策略的实现细节
-
BVH(边界体积层次)优化
-
BVH是光线追踪中常用的数据结构,用于加速光线与场景中物体的相交测试。以下是一些BVH优化的策略:
- 减少树的深度与宽度:通过减少BVH树的深度和宽度,可以降低光线追踪时的遍历次数,从而提高性能。这通常需要在构建BVH时仔细选择分割点和分割方式。
- 平衡树的结构:保持BVH树的平衡可以确保光线在树中的遍历路径相对平均,避免出现极端情况导致的性能下降。这需要在构建BVH时考虑节点的体积、表面积等因素。
- 高效的内存布局:优化BVH的内存布局可以减少缓存未命中和内存访问延迟,从而提高性能。例如,可以使用空间填充曲线(如Morton曲线)对BVH节点进行排序和存储。
-
-
着色器间切换开销的减少
-
在光线追踪中,由于需要处理多种类型的着色器(如路径追踪着色器、反射着色器等),着色器间的切换开销可能成为性能瓶颈。以下是一些减少着色器间切换开销的策略:
- 着色器合并:将多个相似的着色器合并为一个更大的着色器,以减少着色器间的切换次数。这需要在着色器编写时仔细考虑代码的复用性和模块化。
- 着色器缓存:利用GPU的着色器缓存机制,缓存已编译的着色器程序,以便在需要时快速访问。这可以减少着色器的编译和加载时间。
- 延迟着色:通过将渲染过程分解为多个阶段,并在每个阶段使用相同的着色器进行处理,可以减少着色器间的切换开销。延迟着色通常用于实现复杂的光照和材质效果。
-
-
纯inline ray tracing
-
纯inline ray tracing是一种将光线追踪逻辑嵌入到渲染管线中的方法,以减少函数调用和状态切换的开销。这种方法通常需要在编写渲染管线时仔细考虑光线追踪的需求,并将其与现有的渲染技术(如延迟渲染、前向渲染等)相结合。通过减少函数调用和状态切换的次数,纯inline ray tracing可以显著提高光线追踪的性能。
-
-
并行化
-
光线追踪是一个高度并行的计算过程,可以通过利用GPU的多核并行处理能力来提高性能。以下是一些并行化的策略:
- 任务并行化:将光线追踪任务划分为多个子任务,并在GPU的不同核心上并行执行这些子任务。这可以通过使用CUDA、OpenCL等并行计算框架来实现。
- 数据并行化:利用GPU的数据并行处理能力,同时对多个像素或光线进行光线追踪计算。这可以通过编写高效的着色器程序来实现。
-
-
其他优化策略
-
除了上述策略外,还有一些其他的性能优化策略可以用于光线追踪中,例如:
- 光线剪裁:通过剪裁掉与场景中的物体不相交的光线,可以减少不必要的计算量。这可以通过使用遮挡剔除、场景深度测试等技术来实现。
- 动态调整光线追踪质量:根据场景中的光照条件和渲染需求,动态调整光线追踪的质量设置(如光线数量、采样率等)。这可以在保持渲染质量的同时降低计算量。
- 使用高效的数据结构和算法:选择适合光线追踪的数据结构和算法可以显著提高性能。例如,使用哈希表来快速查找相交物体、使用KD树来加速光线与物体的相交测试等。
-