HIP RT v2.2 介绍

首次发布:
最后更新:
Daniel Meister's avatar
Daniel Meister

在本篇博文中,我们介绍了 HIP RT v2.2。此版本的主要变更是 HIP RT 现在支持多级实例。

多级实例

在某些情况下,将场景组织成两个以上的级别可能是有益的。多级实例可以显著降低内存需求。例如,代表苹果的单一几何体可以实例化为树的一部分,而树可以实例化形成一片森林(请参见下图)。我们还可以语义上组织场景:网格组织成对象,对象组织成场景。此功能对于在内存有限的情况下渲染大型场景至关重要。

Multi-level BVH

为了在 HIP RT 中支持多级实例,我们引入了一个新的结构来表示 HIP RT 中的实例,这样我们不仅可以实例化几何体,还可以实例化场景。

struct hiprtInstance
{
hiprtInstanceType type;
union
{
hiprtGeometry geometry;
hiprtScene scene;
};
};

在构建输入结构中,实例化几何体的数组被实例数组替换。

struct hiprtSceneBuildInput
{
/* A device array of 'hiprtInstance' objects */
hiprtDevicePtr instances;
...
};

要遍历两个以上级别的层次结构,我们需要一个额外的堆栈来回溯到上层(每个额外的实例级别有一个条目)。默认的遍历对象隐式包含这个具有四个条目(最多五个级别)的实例堆栈。对于具有自定义堆栈的遍历对象,我们必须显式指定实例堆栈。

...
hiprtSharedStackBuffer sharedInstanceStackBuffer{};
hiprtGlobalInstanceStack instanceStack(globalInstanceStackBuffer, sharedInstanceStackBuffer);
hiprtSceneTraversalClosestCustomStack<hiprtGlobalStack, hiprtGlobalInstanceStack> tr(scene, ray, stack, instanceStack);

全局实例堆栈缓冲区可以通过 HIP RT API 创建。

hiprtGlobalStackBufferInput instanceStackBufferInput;
instanceStackBufferInput.type = hiprtStackTypeGlobal;
instanceStackBufferInput.entryType = hiprtStackEntryTypeInstance;
instanceStackBufferInput.stackSize = InstanceStackSize;
instanceStackBufferInput.threadCount = MaxThreads;
hiprtGlobalStackBuffer globalInstanceStackBuffer;
hiprtCreateGlobalStackBuffer(context, instanceStackBufferInput, globalInstanceStackBuffer);

实例堆栈管理为遍历循环带来了额外的逻辑,使用了比两级遍历更多的寄存器。由于实例堆栈类型是一个模板参数,通过传递 hiprtEmptyInstanceStack,编译器将实例化不包含多级逻辑的代码。

对于多级实例,我们不再只有单个实例 ID,而是有多个 ID(每个实例级别一个)。第一个 ID 对应顶层,第二个 ID 对应下一层,以此类推。

struct hiprtHit
{
union
{
uint32_t instanceID = hiprtInvalidValue;
uint32_t instanceIDs[hiprtMaxInstanceLevels];
};
uint32_t primID = hiprtInvalidValue;
hiprtFloat2 uv;
hiprtFloat3 normal;
float t = -1.0f;
};

我们还扩展了变换查询函数以处理多个实例 ID。

hiprtFrameSRT hiprtGetObjectToWorldFrameSRT(hiprtScene scene, const uint32_t (&instanceIDs)[hiprtMaxInstanceLevels], float time = 0.0f);
hiprtFrameSRT hiprtGetWorldToObjectFrameSRT(hiprtScene scene, const uint32_t (&instanceIDs)[hiprtMaxInstanceLevels], float time = 0.0f);
hiprtFrameMatrix hiprtGetObjectToWorldFrameMatrix(hiprtScene scene, const uint32_t (&instanceIDs)[hiprtMaxInstanceLevels], float time = 0.0f);
hiprtFrameMatrix hiprtGetWorldToObjectFrameMatrix(hiprtScene scene, const uint32_t (&instanceIDs)[hiprtMaxInstanceLevels], float time = 0.0f);

有一个概念上的变化需要提及。在之前的版本中,命中了结构中返回的法线是世界空间中的。在内部,我们不得不在遍历循环后手动将此法线转换为世界空间。对于多级场景,这要复杂得多,会引入不可忽略的开销。我们还注意到,大多数用户应用程序根本不使用此法线。因此,我们决定返回 **对象空间中的法线**。如果需要,我们引入了以下函数,可用于将法线转换为世界空间:

hiprtFloat3 hiprtNormalObjectToWorld(hiprtFloat3 normal, hiprtScene scene, uint32_t instanceID, float time = 0.0f);
hiprtFloat3 hiprtNormalObjectToWorld(hiprtFloat3 normal, hiprtScene scene, const uint32_t (&instanceIDs)[hiprtMaxInstanceLevels], float time = 0.0f);

在 AMD GPU 上由 PBRT-v4 渲染的 Moana Island Scene

我们的团队还致力于在 AMD GPU 上运行 PBRT-v4。具体来说,它有另一个 GPU 后端,该后端已移植到 HIP 和 HIPRT。我们的 PBRT-v4 分支可以在 此处找到。多级实例是允许在 VRAM 有限的 GPU 上进行渲染的重要功能之一。下图是 Moana Island Scene 在配备 48GB VRAM 的 AMD Radeon™ PRO W7900 上渲染的,场景在内存中。该场景组织成三个级别,包含 156 个独特的图元和 310 亿个实例化图元。

Moana Island Scene

另一个关键特性是 HIPRT v2.1 中引入的批量构造,它加速了大量小几何体的 BVH 构建。这对于由数百万根头发组成、每根头发都表示为单一几何体的发型模型特别有用。

其他更改

除了多级实例,我们还为几何体和场景添加了压缩功能,创建了内存占用更小的结构副本。我们还显著优化了构建速度,特别是对于快速和平衡的构建。

下载

HIP RT v2.2 的下载链接可在 HIP RT 页面上找到。PBRT HIP 移植版本可在 GPUOpen Github 上找到。

如果您正在寻找有关 HIPRT 入门指南,请查看 HIP RT SDK 教程仓库HIP RT 文档页面

免责声明

Moana Island Scene

版权所有 2017-2022 Disney Enterprises, Inc. 保留所有权利。

此场景描述由 Walt Disney Pictures “按原样”提供,并免除任何明示或暗示的保证,包括但不限于适销性和特定用途适用性的暗示保证。在任何情况下,Walt Disney Pictures 均不对因使用此场景描述而产生的任何直接、间接、附带、特殊、惩戒性或后果性损害(包括但不限于采购替代商品或服务;使用、数据或利润损失;或业务中断)承担任何责任,无论其如何引起以及基于任何责任理论,无论是合同、严格责任还是侵权(包括疏忽或其他),即使已告知可能发生此类损害。

Daniel Meister's avatar

Daniel Meister

Daniel Meister 是 AMD 的一名研究员和软件工程师。他的研究兴趣包括实时光线追踪、加速数据结构、全局照明、GPGPU 和用于渲染的机器学习。

相关新闻和技术文章

© . This site is unofficial and not affiliated with AMD.