Micromap
Micromaps
Acceleration structures store and organize geometry for ray tracing, but in some cases it is beneficial to include some information within the geometry, particularly for triangles. A micromap organizes this data around a map of values corresponding to subdivided microtriangles which can be added to a triangle geometry when building a bottom level acceleration structure.
An opacity micromap is a type of micromap which stores information to control intersection opacity as described in Ray Opacity Micromap.
A displacement micromap is a type of micromap which stores information to displace sub-triangle vertices as described in Displacement Micromap.
A micromap is considered to be constructed if a micromap build command or copy command has been executed with the given acceleration structure as the destination.
Building Micromaps
Copying Micromaps
An additional command exists for copying micromaps without updating their contents. Before copying, an application must query the size of the resulting micromap.
Host Micromap Operations
Implementations are also required to provide host implementations of the
micromap operations if the micromapHostCommands
feature is enabled:
- vkBuildMicromapsEXT corresponding to vkCmdBuildMicromapsEXT
- vkCopyMicromapEXT corresponding to vkCmdCopyMicromapEXT
- vkCopyMicromapToMemoryEXT corresponding to vkCmdCopyMicromapToMemoryEXT
- vkCopyMemoryToMicromapEXT corresponding to vkCmdCopyMemoryToMicromapEXT
- vkWriteMicromapsPropertiesEXT corresponding to vkCmdWriteMicromapsPropertiesEXT
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 micromaps used by the host commands must be bound to host-visible memory, and all input data for micromap builds must be referenced using host addresses instead of device addresses. Applications are not required to map micromap memory when using the host commands.
The vkBuildMicromapsEXT and vkCmdBuildMicromapsEXT may use different algorithms, and thus are not required to produce identical structures.
Apart from these details, the host and device operations are interchangeable.
For efficient execution, micromaps 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.
Displacement Micromap
A displacement micromap in an acceleration structure includes information in the VkAccelerationStructureTrianglesDisplacementMicromapNV to define a base triangle and displacement directions then uses displacement information encoded in the micromap to apply to those values to generate the final position.
Displacement Base Triangle
If displacementBiasAndScaleBuffer
is provided the bias and scale are
fetched from that buffer.
If displacementBiasAndScaleBuffer
is zero the bias and scale are
assumed to be 0.0 and 1.0, respectively.
Given an input position from the geometry, the base position and displacement vector used by the displacement are computed by:
basePosition = inputPosition + displacementVector × bias
baseDisplacementVector = displacementVector × scale
The parameters of each micro-vertex are derived from a combination of the base triangle parameters extracted from the bottom-level acceleration structure, the barycentrics of that micro-vertex, and the displacement value fetched from the displacement micromap corresponding to that micro-vertex.
microVertexBasePosition = lerp(basePositions, microVertexBarycentrics)
microVertexDisplacementVector = lerp(displacementVectors, microVertexBarycentrics)
microVertexDisplacedPosition = microVertexBasePosition + microVertexDisplacementVector × micromapDisplacementValue
Displacement Micromap Encoding
Displacement amounts are stored in displacement blocks, each covering a triangular region of microvertices. Depending on the subdivision level and encoding format, one or more displacement blocks combine to store all displacement values for a given displacement micromap.
Displacement blocks are organized along a space filling curve within a displacement micromap if more than one block is required, then micro-vertices are organized along the same space filling curve within a displacement micromap.
The space-filling curve is purely hierarchical with recursive splitting, similar to that for opacity micromaps but operating on vertices instead of triangles. To maintain that the hierarchical ordering is contiguous while keeping continuous winding, some triangles are flipped and wound differently.
The VK_DISPLACEMENT_MICROMAP_FORMAT_64_TRIANGLES_64_BYTES_NV
format is
an uncompressed, packed format which covers 64 microtriangles (subdivision
level 3) in a block.
The block contains 45 displacement values encoded as 11 bit unorm values and
stored tightly packed in the vertex order described above, occupying 495
bits.
This is followed by 15 unused bits then 2 reserved bits which must be 0.
If this block is used to store displacement for a subdivision level below 3
the later unused values are ignored.
Section | Field | Entries | Bits per entry | Starting bit offset |
---|---|---|---|---|
Displacement amounts | Vertex 0 - 44 | 45 | 11 | 0 |
Unused | 1 | 15 | 495 | |
Reserved | Must be 0 | 1 | 2 | 510 |
The VK_DISPLACEMENT_MICROMAP_FORMAT_256_TRIANGLES_128_BYTES_NV
and
VK_DISPLACEMENT_MICROMAP_FORMAT_1024_TRIANGLES_128_BYTES_NV
formats
store displacements in a compressed form to save space.
Both formats use the same compression algorithm, differing in the number of
bits used in the different fields.
The compression algorithm works by starting with fully specified anchor vertices, then for each level, predicting the value for the displacement and encoding the correction for that value, using fewer bits for each level of subdivision.
When adding a vertex in the recursive subdivision process between two adjacent displacement values, the predicted value is given by the rounded average of the two adjacent values as integers:
prediction = (A + B + 1) / 2
The decoded value after applying the correction is given by:
decoded = prediction + ( SignExtend(correction) << shift )
where correction is given by the corrections field for a given level and micro vertex and shift is given by the shifts field indexed from the level then by 4 values, selected from interior or the 3 edges in vertex order in that order.
The bit encoding for
VK_DISPLACEMENT_MICROMAP_FORMAT_256_TRIANGLES_128_BYTES_NV
Section | Field | Entries | Bits per entry | Starting bit offset |
---|---|---|---|---|
Anchors | Vertex 0 - 2 | 3 | 11 | 0 |
Corrections | Level 1 | 3 | 11 | 33 |
Level 2 | 9 | 11 | 66 | |
Level 3 | 30 | 10 | 165 | |
Level 4 | 108 | 5 | 465 | |
Unused | 1 | 1 | 1005 | |
Shifts | Level 4 | 4 | 3 | 1006 |
Level 3 | 4 | 1 | 1018 | |
Reserved | Must be 0 | 1 | 2 | 1022 |
The bit encoding for
VK_DISPLACEMENT_MICROMAP_FORMAT_1024_TRIANGLES_128_BYTES_NV
Section | Field | Entries | Bits per entry | Starting bit offset |
---|---|---|---|---|
Anchors | Vertex 0 - 2 | 3 | 11 | 0 |
Corrections | Level 1 | 3 | 11 | 33 |
Level 2 | 9 | 8 | 66 | |
Level 3 | 30 | 4 | 138 | |
Level 4 | 108 | 2 | 258 | |
Level 5 | 408 | 1 | 474 | |
Unused | 1 | 88 | 882 | |
Shifts | Level 5 | 4 | 4 | 970 |
Level 4 | 4 | 4 | 986 | |
Level 3 | 4 | 3 | 1002 | |
Level 2 | 4 | 2 | 1014 | |
Reserved | Must be 0 | 1 | 2 | 1022 |