diff --git a/docs/vkrt_tuto_animation.md.htm b/docs/vkrt_tuto_animation.md.htm index 1ac5e8a..17b2320 100644 --- a/docs/vkrt_tuto_animation.md.htm +++ b/docs/vkrt_tuto_animation.md.htm @@ -135,11 +135,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilder::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = m_objInstance[i].hitgroup; - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = m_objInstance[i].hitgroup; + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV; m_tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace diff --git a/docs/vkrt_tuto_anyhit.md.htm b/docs/vkrt_tuto_anyhit.md.htm index 0bf8b3c..e954013 100644 --- a/docs/vkrt_tuto_anyhit.md.htm +++ b/docs/vkrt_tuto_anyhit.md.htm @@ -62,7 +62,7 @@ opaque, we simply return, which means that the hit will be accepted. void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; // Vertex of the triangle diff --git a/docs/vkrt_tuto_intersection.md.html b/docs/vkrt_tuto_intersection.md.html index 4dfeaa7..ec9e587 100644 --- a/docs/vkrt_tuto_intersection.md.html +++ b/docs/vkrt_tuto_intersection.md.html @@ -239,7 +239,7 @@ void HelloVulkan::createBottomLevelAS() ### TLAS -Similarly in `createTopLevelAS()`, the top level acceleration structure will need to add a reference to the BLAS of the spheres. We are setting the instanceID and blasID to the last element, which is why the sphere BLAS must be added after everything else. +Similarly in `createTopLevelAS()`, the top level acceleration structure will need to add a reference to the BLAS of the spheres. We are setting the instanceCustomId and blasId to the last element, which is why the sphere BLAS must be added after everything else. The hitGroupId will be set to 1 instead of 0. We need to add a new hit group for the implicit primitives, since we will need to compute attributes like the normal, since they are not provide like with triangle primitives. @@ -249,11 +249,11 @@ Just before building the TLAS, we need to add the following // Add the blas containing all spheres { nvvk::RaytracingBuilder::Instance rayInst; - rayInst.transform = m_objInstance[0].transform; // Position of the instance - rayInst.instanceId = static_cast(tlas.size()); // gl_InstanceID - rayInst.blasId = static_cast(m_objModel.size()); - rayInst.hitGroupId = 1; // We will use the same hit group for all objects - rayInst.flags = vk::GeometryInstanceFlagBitsKHR::eTriangleCullDisable; + rayInst.transform = m_objInstance[0].transform; // Position of the instance + rayInst.instanceCustomId = static_cast(tlas.size()); // gl_InstanceCustomIndexEXT + rayInst.blasId = static_cast(m_objModel.size()); + rayInst.hitGroupId = 1; // We will use the same hit group for all objects + rayInst.flags = vk::GeometryInstanceFlagBitsKHR::eTriangleCullDisable; tlas.emplace_back(rayInst); } ~~~~ diff --git a/docs/vkrt_tuto_manyhits.md.htm b/docs/vkrt_tuto_manyhits.md.htm index fc6a638..89da2e8 100644 --- a/docs/vkrt_tuto_manyhits.md.htm +++ b/docs/vkrt_tuto_manyhits.md.htm @@ -284,7 +284,9 @@ std::array strideAddresses{ # Extending Hit -The SBT can be larger than the number of shading models, which could then be used to have one shader per instance with its own data. For some applications, instead of retrieving the material information as in the main tutorial using a storage buffer and indexing into it using the `gl_InstanceID`, it is possible to set all of the material information in the SBT. +The SBT can be larger than the number of shading models, which could then be used to have one shader per instance with its own data. +For some applications, instead of retrieving the material information as in the main tutorial using a storage buffer and indexing +into it using the `gl_InstanceCustomIndexEXT`, it is possible to set all of the material information in the SBT. The following modification will add another entry to the SBT with a different color per instance. The new SBT hit group (2) will use the same CHIT handle (4) as hit group 1. diff --git a/docs/vkrt_tutorial.md.htm b/docs/vkrt_tutorial.md.htm index 639dbe2..51f753d 100644 --- a/docs/vkrt_tutorial.md.htm +++ b/docs/vkrt_tutorial.md.htm @@ -650,6 +650,12 @@ and the index of its corresponding BLAS (`blasId`) in the vector passed to `buil be available during shading as `gl_InstanceCustomIndex`, as well as the index of the hit group that represents the shaders that will be invoked upon hitting the object (`VkAccelerationStructureInstanceKHR::instanceShaderBindingTableRecordOffset`, a.k.a. `hitGroupId` in the helper). +!!! Note gl_InstanceId + We could have ignored to use the custom index, since the Id will be equivalent to + gl_InstanceId. As gl_InstanceId specifies the index of the instance that intersects the + current ray, which is in this case the same value as **i**. In later examples the + value will be different. + This index and the notion of hit group are tied to the definition of the ray tracing pipeline and the Shader Binding Table, described later in this tutorial and used to select determine which shaders are invoked at runtime. For now it suffices to say that we will use only one hit group for the whole scene, and hence the hit group index is always 0. @@ -668,17 +674,18 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); } ```` + As usual in Vulkan, we need to explicitly destroy the objects we created by adding a call at the end of `HelloVulkan::destroyResources`: @@ -753,7 +760,7 @@ For convenience, the implementation of `instanceToVkGeometryInstanceKHR` is copi // the matrix is row-major, we simply copy the first 12 values of the // original 4x4 matrix memcpy(&gInst.transform, &transp, sizeof(gInst.transform)); - gInst.instanceCustomIndex = instance.instanceId; + gInst.instanceCustomIndex = instance.instanceCustomId; gInst.mask = instance.mask; gInst.instanceShaderBindingTableRecordOffset = instance.hitGroupId; gInst.flags = instance.flags; @@ -1889,7 +1896,7 @@ In the `main` function, the `gl_PrimitiveID` allows us to find the vertices of t void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -1909,7 +1916,7 @@ Using the hit point's barycentric coordinates, we can interpolate the normal: // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); ```` The world-space position could be calculated in two ways, the first one being to use the information from the hit @@ -1925,7 +1932,7 @@ Another solution, more precise, consists in computing the position by interpolat // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); ```` The light source specified in the constants can then be used to compute the dot product of the normal with the lighting @@ -2007,7 +2014,7 @@ supports textures to modulate the surface albedo. vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing__advance/raytrace.cpp b/ray_tracing__advance/raytrace.cpp index e590c23..4a69184 100644 --- a/ray_tracing__advance/raytrace.cpp +++ b/ray_tracing__advance/raytrace.cpp @@ -171,11 +171,11 @@ void Raytracer::createTopLevelAS(std::vector& instances, ImplInst& for(int i = 0; i < static_cast(instances.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = instances[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = instances[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = instances[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = instances[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } @@ -183,8 +183,9 @@ void Raytracer::createTopLevelAS(std::vector& instances, ImplInst& if(!implicitObj.objImpl.empty()) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = implicitObj.transform; // Position of the instance - rayInst.instanceId = static_cast(implicitObj.blasId); // Same for material index + rayInst.transform = implicitObj.transform; // Position of the instance + rayInst.instanceCustomId = + static_cast(implicitObj.blasId); // Same for material index rayInst.blasId = static_cast(implicitObj.blasId); rayInst.hitGroupId = 1; // We will use the same hit group for all objects (the second one) rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; diff --git a/ray_tracing__advance/shaders/raytrace.rahit b/ray_tracing__advance/shaders/raytrace.rahit index cf611a5..6a7bfd2 100644 --- a/ray_tracing__advance/shaders/raytrace.rahit +++ b/ray_tracing__advance/shaders/raytrace.rahit @@ -19,7 +19,7 @@ layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMate void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Material of the object int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; diff --git a/ray_tracing__advance/shaders/raytrace.rchit b/ray_tracing__advance/shaders/raytrace.rchit index 5e350fd..43ce518 100644 --- a/ray_tracing__advance/shaders/raytrace.rchit +++ b/ray_tracing__advance/shaders/raytrace.rchit @@ -42,7 +42,7 @@ layout(location = 3) callableDataEXT rayLight cLight; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -58,13 +58,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); cLight.inHitPosition = worldPos; //#define DONT_USE_CALLABLE @@ -109,7 +109,7 @@ void main() vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing__simple/hello_vulkan.cpp b/ray_tracing__simple/hello_vulkan.cpp index b91a743..68e1d32 100644 --- a/ray_tracing__simple/hello_vulkan.cpp +++ b/ray_tracing__simple/hello_vulkan.cpp @@ -706,11 +706,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing__simple/shaders/raytrace.rchit b/ray_tracing__simple/shaders/raytrace.rchit index 7897700..7fea3cc 100644 --- a/ray_tracing__simple/shaders/raytrace.rchit +++ b/ray_tracing__simple/shaders/raytrace.rchit @@ -35,7 +35,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -51,13 +51,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -85,7 +85,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing_animation/README.md b/ray_tracing_animation/README.md index 783bdbe..f2ea91e 100644 --- a/ray_tracing_animation/README.md +++ b/ray_tracing_animation/README.md @@ -125,11 +125,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilder::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = m_objInstance[i].hitgroup; - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = m_objInstance[i].hitgroup; + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV; m_tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace diff --git a/ray_tracing_animation/hello_vulkan.cpp b/ray_tracing_animation/hello_vulkan.cpp index 0a9b75e..8797eec 100644 --- a/ray_tracing_animation/hello_vulkan.cpp +++ b/ray_tracing_animation/hello_vulkan.cpp @@ -698,11 +698,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; m_tlas.emplace_back(rayInst); } diff --git a/ray_tracing_animation/shaders/raytrace.rchit b/ray_tracing_animation/shaders/raytrace.rchit index 130ecd3..e9cc715 100644 --- a/ray_tracing_animation/shaders/raytrace.rchit +++ b/ray_tracing_animation/shaders/raytrace.rchit @@ -37,7 +37,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -53,13 +53,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -87,7 +87,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing_anyhit/README.md b/ray_tracing_anyhit/README.md index 4c7a465..3e0021d 100644 --- a/ray_tracing_anyhit/README.md +++ b/ray_tracing_anyhit/README.md @@ -60,7 +60,7 @@ opaque, we simply return, which means that the hit will be accepted. void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; // Vertex of the triangle diff --git a/ray_tracing_anyhit/hello_vulkan.cpp b/ray_tracing_anyhit/hello_vulkan.cpp index 5ab5852..1160068 100644 --- a/ray_tracing_anyhit/hello_vulkan.cpp +++ b/ray_tracing_anyhit/hello_vulkan.cpp @@ -696,11 +696,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_anyhit/shaders/raytrace.rahit b/ray_tracing_anyhit/shaders/raytrace.rahit index def0fe8..aa629cf 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rahit +++ b/ray_tracing_anyhit/shaders/raytrace.rahit @@ -21,7 +21,7 @@ layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMate void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; // Vertex of the triangle diff --git a/ray_tracing_anyhit/shaders/raytrace.rchit b/ray_tracing_anyhit/shaders/raytrace.rchit index 1e4769a..1ad6dde 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rchit +++ b/ray_tracing_anyhit/shaders/raytrace.rchit @@ -37,7 +37,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -53,13 +53,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -87,7 +87,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; @@ -99,11 +99,11 @@ void main() // Tracing shadow ray only if the light is visible from the surface if(dot(normal, L) > 0) { - float tMin = 0.001; - float tMax = lightDistance; - vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; - vec3 rayDir = L; - uint flags = gl_RayFlagsSkipClosestHitShaderEXT; + float tMin = 0.001; + float tMax = lightDistance; + vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; + vec3 rayDir = L; + uint flags = gl_RayFlagsSkipClosestHitShaderEXT; prdShadow.isHit = true; prdShadow.seed = prd.seed; traceRayEXT(topLevelAS, // acceleration structure diff --git a/ray_tracing_anyhit/shaders/raytrace_rahit.glsl b/ray_tracing_anyhit/shaders/raytrace_rahit.glsl index 12918cd..cf24cc3 100644 --- a/ray_tracing_anyhit/shaders/raytrace_rahit.glsl +++ b/ray_tracing_anyhit/shaders/raytrace_rahit.glsl @@ -25,7 +25,7 @@ layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMate void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; // Vertex of the triangle diff --git a/ray_tracing_callable/hello_vulkan.cpp b/ray_tracing_callable/hello_vulkan.cpp index b287882..8301e47 100644 --- a/ray_tracing_callable/hello_vulkan.cpp +++ b/ray_tracing_callable/hello_vulkan.cpp @@ -695,11 +695,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_callable/shaders/raytrace.rchit b/ray_tracing_callable/shaders/raytrace.rchit index 8207b74..a793d3e 100644 --- a/ray_tracing_callable/shaders/raytrace.rchit +++ b/ray_tracing_callable/shaders/raytrace.rchit @@ -42,7 +42,7 @@ layout(location = 0) callableDataEXT rayLight cLight; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -58,13 +58,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); cLight.inHitPosition = worldPos; //#define DONT_USE_CALLABLE @@ -109,7 +109,7 @@ void main() vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing_gltf/README.md b/ray_tracing_gltf/README.md index de6c23f..fc3bb20 100644 --- a/ray_tracing_gltf/README.md +++ b/ray_tracing_gltf/README.md @@ -182,7 +182,7 @@ nvvk::RaytracingBuilderKHR::Blas HelloVulkan::primitiveToGeometry(const nvh::Glt There are almost no changes for creating the TLAS but is actually even simpler. Each drawable node has a matrix and an index to the geometry, which in our case, also correspond directly to the BLAS ID. To know which geometry is used, and to find back -all the data (see structure `RtPrimitiveLookup`), we will set the `instanceId` member +all the data (see structure `RtPrimitiveLookup`), we will set the `instanceCustomId` member to the primitive mesh id. This value will be recovered with `gl_InstanceCustomIndexEXT` in the closest hit shader. @@ -190,11 +190,11 @@ in the closest hit shader. for(auto& node : m_gltfScene.m_nodes) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = node.worldMatrix; - rayInst.instanceId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive - rayInst.blasId = node.primMesh; - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.transform = node.worldMatrix; + rayInst.instanceCustomId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive + rayInst.blasId = node.primMesh; + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects tlas.emplace_back(rayInst); } ~~~~ diff --git a/ray_tracing_gltf/hello_vulkan.cpp b/ray_tracing_gltf/hello_vulkan.cpp index 152dcf0..a96efaf 100644 --- a/ray_tracing_gltf/hello_vulkan.cpp +++ b/ray_tracing_gltf/hello_vulkan.cpp @@ -670,11 +670,11 @@ void HelloVulkan::createTopLevelAS() for(auto& node : m_gltfScene.m_nodes) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = node.worldMatrix; - rayInst.instanceId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive - rayInst.blasId = node.primMesh; - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.transform = node.worldMatrix; + rayInst.instanceCustomId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive + rayInst.blasId = node.primMesh; + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_instances/hello_vulkan.cpp b/ray_tracing_instances/hello_vulkan.cpp index 4aa4e35..1c890ef 100644 --- a/ray_tracing_instances/hello_vulkan.cpp +++ b/ray_tracing_instances/hello_vulkan.cpp @@ -715,11 +715,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_instances/shaders/raytrace.rchit b/ray_tracing_instances/shaders/raytrace.rchit index 130ecd3..e9cc715 100644 --- a/ray_tracing_instances/shaders/raytrace.rchit +++ b/ray_tracing_instances/shaders/raytrace.rchit @@ -37,7 +37,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -53,13 +53,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -87,7 +87,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing_intersection/README.md b/ray_tracing_intersection/README.md index 8d2344a..b234de3 100644 --- a/ray_tracing_intersection/README.md +++ b/ray_tracing_intersection/README.md @@ -234,7 +234,7 @@ void HelloVulkan::createBottomLevelAS() ### TLAS -Similarly in `createTopLevelAS()`, the top level acceleration structure will need to add a reference to the BLAS of the spheres. We are setting the instanceID and blasID to the last element, which is why the sphere BLAS must be added after everything else. +Similarly in `createTopLevelAS()`, the top level acceleration structure will need to add a reference to the BLAS of the spheres. We are setting the instanceCustomId and blasId to the last element, which is why the sphere BLAS must be added after everything else. The hitGroupId will be set to 1 instead of 0. We need to add a new hit group for the implicit primitives, since we will need to compute attributes like the normal, since they are not provide like with triangle primitives. @@ -244,11 +244,11 @@ Just before building the TLAS, we need to add the following // Add the blas containing all spheres { nvvk::RaytracingBuilder::Instance rayInst; - rayInst.transform = m_objInstance[0].transform; // Position of the instance - rayInst.instanceId = static_cast(tlas.size()); // gl_InstanceID - rayInst.blasId = static_cast(m_objModel.size()); - rayInst.hitGroupId = 1; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[0].transform; // Position of the instance + rayInst.instanceCustomId = static_cast(tlas.size()); // gl_InstanceCustomIndexEXT + rayInst.blasId = static_cast(m_objModel.size()); + rayInst.hitGroupId = 1; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } ~~~~ diff --git a/ray_tracing_intersection/hello_vulkan.cpp b/ray_tracing_intersection/hello_vulkan.cpp index c0120cd..84d86fc 100644 --- a/ray_tracing_intersection/hello_vulkan.cpp +++ b/ray_tracing_intersection/hello_vulkan.cpp @@ -811,22 +811,22 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } // Add the blas containing all spheres { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[0].transform; // Position of the instance - rayInst.instanceId = static_cast(tlas.size()); // gl_InstanceID - rayInst.blasId = static_cast(m_objModel.size()); - rayInst.hitGroupId = 1; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[0].transform; // Position of the instance + rayInst.instanceCustomId = static_cast(tlas.size()); // gl_InstanceCustomIndexEXT + rayInst.blasId = static_cast(m_objModel.size()); + rayInst.hitGroupId = 1; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } diff --git a/ray_tracing_intersection/shaders/raytrace.rchit b/ray_tracing_intersection/shaders/raytrace.rchit index 130ecd3..e9cc715 100644 --- a/ray_tracing_intersection/shaders/raytrace.rchit +++ b/ray_tracing_intersection/shaders/raytrace.rchit @@ -37,7 +37,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -53,13 +53,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -87,7 +87,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing_jitter_cam/hello_vulkan.cpp b/ray_tracing_jitter_cam/hello_vulkan.cpp index bc9502a..5e337b1 100644 --- a/ray_tracing_jitter_cam/hello_vulkan.cpp +++ b/ray_tracing_jitter_cam/hello_vulkan.cpp @@ -694,11 +694,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_jitter_cam/shaders/raytrace.rchit b/ray_tracing_jitter_cam/shaders/raytrace.rchit index 130ecd3..e9cc715 100644 --- a/ray_tracing_jitter_cam/shaders/raytrace.rchit +++ b/ray_tracing_jitter_cam/shaders/raytrace.rchit @@ -37,7 +37,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -53,13 +53,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -87,7 +87,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing_manyhits/README.md b/ray_tracing_manyhits/README.md index 12cc095..72ceb46 100644 --- a/ray_tracing_manyhits/README.md +++ b/ray_tracing_manyhits/README.md @@ -286,7 +286,7 @@ The stride device address will be modified like this: ## Extending Hit -The SBT can be larger than the number of shading models, which could then be used to have one shader per instance with its own data. For some applications, instead of retrieving the material information as in the main tutorial using a storage buffer and indexing into it using the `gl_InstanceID`, it is possible to set all of the material information in the SBT. +The SBT can be larger than the number of shading models, which could then be used to have one shader per instance with its own data. For some applications, instead of retrieving the material information as in the main tutorial using a storage buffer and indexing into it using the `gl_InstanceCustomIndexEXT`, it is possible to set all of the material information in the SBT. The following modification will add another entry to the SBT with a different color per instance. The new SBT hit group (2) will use the same CHIT handle (4) as hit group 1. diff --git a/ray_tracing_manyhits/hello_vulkan.cpp b/ray_tracing_manyhits/hello_vulkan.cpp index fad9433..04c3fbb 100644 --- a/ray_tracing_manyhits/hello_vulkan.cpp +++ b/ray_tracing_manyhits/hello_vulkan.cpp @@ -692,11 +692,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; - rayInst.hitGroupId = m_objInstance[i].hitgroup; // Using the hit group set in main + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.hitGroupId = m_objInstance[i].hitgroup; // Using the hit group set in main tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_manyhits/shaders/raytrace.rchit b/ray_tracing_manyhits/shaders/raytrace.rchit index 130ecd3..e9cc715 100644 --- a/ray_tracing_manyhits/shaders/raytrace.rchit +++ b/ray_tracing_manyhits/shaders/raytrace.rchit @@ -37,7 +37,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -53,13 +53,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -87,7 +87,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; diff --git a/ray_tracing_rayquery/hello_vulkan.cpp b/ray_tracing_rayquery/hello_vulkan.cpp index 17a4498..c735210 100644 --- a/ray_tracing_rayquery/hello_vulkan.cpp +++ b/ray_tracing_rayquery/hello_vulkan.cpp @@ -701,11 +701,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_reflections/hello_vulkan.cpp b/ray_tracing_reflections/hello_vulkan.cpp index 00c888c..ce5b36e 100644 --- a/ray_tracing_reflections/hello_vulkan.cpp +++ b/ray_tracing_reflections/hello_vulkan.cpp @@ -693,11 +693,11 @@ void HelloVulkan::createTopLevelAS() for(int i = 0; i < static_cast(m_objInstance.size()); i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[i].transform; // Position of the instance - rayInst.instanceId = i; // gl_InstanceID - rayInst.blasId = m_objInstance[i].objIndex; - rayInst.hitGroupId = 0; // We will use the same hit group for all objects - rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + rayInst.transform = m_objInstance[i].transform; // Position of the instance + rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.blasId = m_objInstance[i].objIndex; + rayInst.hitGroupId = 0; // We will use the same hit group for all objects + rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; tlas.emplace_back(rayInst); } m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace); diff --git a/ray_tracing_reflections/shaders/raytrace.rchit b/ray_tracing_reflections/shaders/raytrace.rchit index bb7ed55..50ef3ff 100644 --- a/ray_tracing_reflections/shaders/raytrace.rchit +++ b/ray_tracing_reflections/shaders/raytrace.rchit @@ -37,7 +37,7 @@ pushC; void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceID].objId; + uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; // Indices of the triangle ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // @@ -53,13 +53,13 @@ void main() // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceID].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceID].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -87,7 +87,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; + uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;