1// Copyright 2022-2023 The Khronos Group Inc.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5include::{generated}/meta/{refprefix}VK_EXT_opacity_micromap.adoc[]
6
7=== Other Extension Metadata
8
9*Last Modified Date*::
10    2022-08-24
11*Interactions and External Dependencies*::
12  - This extension requires
13    {spirv}/EXT/SPV_EXT_opacity_micromap.html[`SPV_EXT_opacity_micromap`]
14  - This extension provides API support for
15    {GLSLregistry}/ext/GLSL_EXT_opacity_micromap.txt[`GLSL_EXT_opacity_micromap`]
16*Contributors*::
17  - Christoph Kubisch, NVIDIA
18  - Eric Werness, NVIDIA
19  - Josh Barczak, Intel
20  - Stu Smith, AMD
21
22=== Description
23
24When adding adding transparency to a ray traced scene, an application can
25choose between further tessellating the geometry or using an any hit shader
26to allow the ray through specific parts of the geometry.
27These options have the downside of either significantly increasing memory
28consumption or adding runtime overhead to run shader code in the middle of
29traversal, respectively.
30
31This extension adds the ability to add an _opacity micromap_ to geometry
32when building an acceleration structure.
33The opacity micromap compactly encodes opacity information which can be read
34by the implementation to mark parts of triangles as opaque or transparent.
35The format is externally visible to allow the application to compress its
36internal geometry and surface representations into the compressed format
37ahead of time.
38The compressed format subdivides each triangle into a set of subtriangles,
39each of which can be assigned either two or four opacity values.
40These opacity values can control if a ray hitting that subtriangle is
41treated as an opaque hit, complete miss, or possible hit, depending on the
42controls described in <<ray-opacity-micromap,Ray Opacity Micromap>>.
43
44This extension provides:
45
46  * a slink:VkMicromapEXT structure to store the micromap,
47  * functions similar to acceleration structure build functions to build the
48    opacity micromap array, and
49  * a structure to extend
50    slink:VkAccelerationStructureGeometryTrianglesDataKHR to attach a
51    micromap to the geometry of the acceleration structure.
52
53include::{generated}/interfaces/VK_EXT_opacity_micromap.adoc[]
54
55=== Reference Code
56
57[source,c++]
58----
59uint32_t BarycentricsToSpaceFillingCurveIndex(float u, float v, uint32_t level)
60{
61    u = clamp(u, 0.0f, 1.0f);
62    v = clamp(v, 0.0f, 1.0f);
63
64    uint32_t iu, iv, iw;
65
66    // Quantize barycentric coordinates
67    float fu = u * (1u << level);
68    float fv = v * (1u << level);
69
70    iu = (uint32_t)fu;
71    iv = (uint32_t)fv;
72
73    float uf = fu - float(iu);
74    float vf = fv - float(iv);
75
76    if (iu >= (1u << level)) iu = (1u << level) - 1u;
77    if (iv >= (1u << level)) iv = (1u << level) - 1u;
78
79    uint32_t iuv = iu + iv;
80
81    if (iuv >= (1u << level))
82        iu -= iuv - (1u << level) + 1u;
83
84    iw = ~(iu + iv);
85
86    if (uf + vf >= 1.0f && iuv < (1u << level) - 1u) --iw;
87
88    uint32_t b0 = ~(iu ^ iw);
89    b0 &= ((1u << level) - 1u);
90    uint32_t t = (iu ^ iv) & b0;
91
92    uint32_t f = t;
93    f ^= f >> 1u;
94    f ^= f >> 2u;
95    f ^= f >> 4u;
96    f ^= f >> 8u;
97    uint32_t b1 = ((f ^ iu) & ~b0) | t;
98
99    // Interleave bits
100    b0 = (b0 | (b0 << 8u)) & 0x00ff00ffu;
101    b0 = (b0 | (b0 << 4u)) & 0x0f0f0f0fu;
102    b0 = (b0 | (b0 << 2u)) & 0x33333333u;
103    b0 = (b0 | (b0 << 1u)) & 0x55555555u;
104    b1 = (b1 | (b1 << 8u)) & 0x00ff00ffu;
105    b1 = (b1 | (b1 << 4u)) & 0x0f0f0f0fu;
106    b1 = (b1 | (b1 << 2u)) & 0x33333333u;
107    b1 = (b1 | (b1 << 1u)) & 0x55555555u;
108
109    return b0 | (b1 << 1u);
110}
111----
112
113=== Issues
114
115(1) Is the build actually similar to an acceleration structure build?
116--
117  * Resolved: The build should be much lighter-weight than an acceleration
118    structure build, but the infrastructure is similar enough that it makes
119    sense to keep the concepts compatible.
120--
121
122(2) Why does VkMicromapUsageEXT not have type/pNext?
123--
124  * Resolved: There can be a very large number of these structures, so
125    doubling the size of these can be significant memory consumption.
126    Also, an application may be loading these directly from a file which is
127    more compatible with it being a flat structure.
128    The including structures are extensible and are probably a more suitable
129    place to add extensibility.
130--
131
132(3) Why is there a SPIR-V extension?
133--
134  * Resolved: There is a ray flag.
135    To be consistent with how the existing ray tracing extensions work that
136    ray flag needs its own extension.
137--
138
139(4) Should there be indirect micromap build?
140--
141  * Resolved: Not for now.
142    There is more in-depth usage metadata required and it seems less likely
143    that something like a GPU culling system would need to change the counts
144    for a micromap.
145--
146
147(5) Should micromaps have a micromap device address?
148--
149  * Resolved: There is no need right now (can just use the handle) but that
150    is a bit different from acceleration structures, though the two are not
151    completely parallel in their usage.
152--
153
154(6) Why are the alignment requirements defined as a mix of hardcoded values
155and caps?
156--
157  * Resolved: This is most parallel with the definition of
158    `apiext:VK_KHR_acceleration_structure` and maintaining commonality makes
159    it easier for applications to share memory.
160--
161
162=== Version History
163
164  * Revision 2, 2022-06-22 (Eric Werness)
165  ** EXTify and clean up for discussion
166  * Revision 1, 2022-01-01 (Eric Werness)
167  ** Initial revision
168