Acceleration Structures
Acceleration Structures
Acceleration structures are data structures used by the implementation to efficiently manage scene geometry as it is traversed during a ray tracing query. The application is responsible for managing acceleration structure objects (see Acceleration Structures), including allocation, destruction, executing builds or updates, and synchronizing resources used during ray tracing queries.
There are two types of acceleration structures, top level acceleration structures and bottom level acceleration structures.
An acceleration structure is considered to be constructed if an acceleration structure build command or copy command has been executed with the given acceleration structure as the destination.
Geometry
Geometries refer to a triangle or axis-aligned bounding box.
Top Level Acceleration Structures
Opaque acceleration structure for an array of instances. The descriptor or device address referencing this is the starting point for traversal.
The top level acceleration structure takes a reference to any bottom level acceleration structure referenced by its instances. Those bottom level acceleration structure objects must be valid when the top level acceleration structure is accessed.
Bottom Level Acceleration Structures
Opaque acceleration structure for an array of geometries.
Acceleration Structure Update Rules
The API defines two types of operations to produce acceleration structures from geometry:
- A build operation is used to construct an acceleration structure.
- An update operation is used to modify an existing acceleration structure.
An update operation imposes certain constraints on the input, in exchange for considerably faster execution. When performing an update, the application is required to provide a full description of the acceleration structure, but is prohibited from changing anything other than instance definitions, transform matrices, and vertex or AABB positions. All other aspects of the description must exactly match the one from the original build.
More precisely, the application must not use an update operation to do any of the following:
- Change primitives or instances from active to inactive, or vice versa (as defined in Inactive Primitives and Instances).
- Change the index or vertex formats of triangle geometry.
- Change triangle geometry transform pointers from null to non-null or vice versa.
- Change the number of geometries or instances in the structure.
- Change the geometry flags for any geometry in the structure.
- Change the number of vertices or primitives for any geometry in the structure.
If the original acceleration structure was built using opacity micromaps and
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT
was set in flags
, the application must provide the corresponding
micromap information to the update operation.
The application is prohibited from changing anything other than the specific
opacity values assigned to the triangles.
More precisely, the application must not use an update operation to do any of the following:
- Remove micromaps or VkOpacityMicromapSpecialIndexEXT values from a geometry which previously had them, or vice versa.
- Change between use of VkOpacityMicromapSpecialIndexEXT values and explicit micro-map triangles.
- Change the subdivision level or format of the micromap triangle associated with any acceleration-structure triangle.
If the original acceleration structure was built using opacity micromaps and
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT
was
set in flags
, the application must provide a micromap to the update
operation.
If the original acceleration structure was built using opacity micromaps and neither opacity micromap update flag is set the application must provide the original micromap to the update operation.
If the original acceleration structure was built using displacement
micromaps and
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV
was set in flags
, the application must provide a displacement
micromap to the update operation.
If the original acceleration structure was built using displacement micromaps and the displacement micromap update flag is not set the application must provide the original micromap to the update operation.
Inactive Primitives and Instances
Acceleration structures allow the use of particular input values to signal inactive primitives or instances.
An inactive triangle is one for which the first (X) component of any vertex is NaN. If any other vertex component is NaN, and the first is not, the behavior is undefined:. If the vertex format does not have a NaN representation, then all triangles are considered active.
An inactive instance is one whose acceleration structure reference is 0
.
An inactive AABB is one for which the minimum X coordinate is NaN. If any other component is NaN, and the first is not, the behavior is undefined:.
In the above definitions, NaN
refers to any type of NaN.
Signaling, non-signaling, quiet, loud, or otherwise.
An inactive object is considered invisible to all rays, and should not be represented in the acceleration structure. Implementations should ensure that the presence of inactive objects does not seriously degrade traversal performance.
Inactive objects are counted in the auto-generated index sequences which are
provided to shaders via InstanceId
and PrimitiveId
SPIR-V
decorations.
This allows objects in the scene to change freely between the active and
inactive states, without affecting the layout of any arrays which are being
indexed using the ID values.
Any transition between the active and inactive states requires a full acceleration structure rebuild. Applications must not perform an acceleration structure update where an object is active in the source acceleration structure but would be inactive in the destination, or vice versa.
Building Acceleration Structures
Copying Acceleration Structures
An additional command exists for copying acceleration structures without updating their contents. The acceleration structure object can be compacted in order to improve performance. Before copying, an application must query the size of the resulting acceleration structure.
Host Acceleration Structure Operations
Implementations are also required to provide host implementations of the
acceleration structure operations if the
accelerationStructureHostCommands
feature is enabled:
- vkBuildAccelerationStructuresKHR corresponding to vkCmdBuildAccelerationStructuresKHR
- vkCopyAccelerationStructureKHR corresponding to vkCmdCopyAccelerationStructureKHR
- vkCopyAccelerationStructureToMemoryKHR corresponding to vkCmdCopyAccelerationStructureToMemoryKHR
- vkCopyMemoryToAccelerationStructureKHR corresponding to vkCmdCopyMemoryToAccelerationStructureKHR
- vkWriteAccelerationStructuresPropertiesKHR corresponding to vkCmdWriteAccelerationStructuresPropertiesKHR
These commands are functionally equivalent to their device counterparts, except that they are executed on the host timeline, rather than being enqueued into command buffers.
All acceleration structures used by the host commands must be bound to host-visible memory, and all input data for acceleration structure builds must be referenced using host addresses instead of device addresses. Applications are not required to map acceleration structure memory when using the host commands.
The vkBuildAccelerationStructuresKHR and vkCmdBuildAccelerationStructuresKHR may use different algorithms, and thus are not required to produce identical structures. The structures produced by these two commands may exhibit different memory footprints or traversal performance, but should strive to be similar where possible.
Apart from these details, the host and device operations are interchangeable. For example, an application can use vkBuildAccelerationStructuresKHR to build a structure, compact it on the device using vkCmdCopyAccelerationStructureKHR, and serialize the result using vkCopyAccelerationStructureToMemoryKHR.
For efficient execution, acceleration structures manipulated using these commands should always be bound to host cached memory, as the implementation may need to repeatedly read and write this memory during the execution of the command.