Answers:
如果场景不完全适合内存,则您将进入核心外渲染字段。这里基本上有两种方法:a)按需生成场景b)按需加载场景
前一种方法与大多数动画工作流程非常吻合,其中使用例如Catmull-Clark对模型进行了细分,并且可能占用大量内存,但是基本网格物体本身很容易装入内存。皮克斯(Pixar)对此有几篇论文(例如,用于复杂场景中的分布射线跟踪的射线微分和多分辨率几何缓存),但是要点是,仅当模型被射线照射时才对其进行细分,并且仅对其进行尽可能多的细分。对于这种射线是合理的(例如,漫反射比镜面反射的精度要低)。其余的由几何高速缓存处理,该高速缓存将细分的模型保留在内存中,并希望通过良好的逐出策略提高处理效率。
只要您所有的基础网格都能舒适地适合内存,您就可以轻松地移出核心并以细分级别渲染网格,而这些细分级别永远不会适合内存。几何缓存还可以根据您拥有的内存量很好地扩展,从而可以权衡RAM与渲染时间。我相信这也用在了汽车上。
第二种方法更通用,不依赖大量使用细分。取而代之的是,它依赖于这样一个事实,即您的场景很可能是由艺术家制作的,并且已经被划分为可放入内存的合理的小物体。然后,想法是保留两个层次结构(kD树或边界体积层次结构):顶层层次结构仅存储场景中对象的边界框,而底层层次结构存储实际的几何图形。每个对象都有一个这样的低级层次结构。
通过这种方法,理想情况下,您已经在磁盘上与每个对象一起存储了一个边界框。加载场景时,最初只构建顶层层次结构,这意味着您只需要查看边界框,而不是几何体。然后,您开始跟踪射线并遍历层次结构。每当射线击中顶层层次结构中的叶节点(即它击中对象的边界框)时,该对象就会被加载到内存中并构建其低层层次结构。然后,射线继续向下跟踪该对象。与对象缓存结合使用,该缓存将尽可能多的低级层次结构保留在内存中,因此可以很好地执行。
这种方法的第一个好处是,永远不会加载从未命中的对象,这意味着它会自动适应场景中的可见性。第二个好处是,如果要跟踪很多射线,则不必立即加载对象,因为它会被射线击中。取而代之的是,您可以握住该射线并等待,直到有足够的射线击中该对象,从而分摊多次射线击中的负载。
您也可以将此方法与射线排序算法(例如用于生产路径跟踪的“排序的递延阴影”)结合使用,以避免由于不相干的射线造成的抖动。上面提到的纸张描述了迪士尼的Hyperion渲染器的体系结构,我相信它可用于Big Hero 6,因此它很可能可以处理生产规模的场景。
如果以空间结构组织场景(通常的方法是“ 边界体积层次结构”),则可以使用一种虚拟场景(我指的是虚拟纹理)。
内存管理器一次只能加载有限数量的边界框,并抽象化检索一个边界框的操作。
这样,仅在需要时才加载框:当射线撞击边界框时,将加载该框以解决碰撞。稍后,当需要装入另一个盒子时,未使用的盒子将被删除以为新盒子腾出空间。
随着所有这些盒子的加载和删除,射线相干性将成为速度的主要因素。我想进一步的改进可以是通过重新排序射线以首先处理已经加载的盒子来推迟加载。