Renaming to instanceCustomId
This commit is contained in:
parent
60b9191069
commit
b1d17dbd2a
35 changed files with 167 additions and 157 deletions
|
|
@ -135,11 +135,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilder::Instance rayInst;
|
nvvk::RaytracingBuilder::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = m_objInstance[i].hitgroup;
|
rayInst.hitGroupId = m_objInstance[i].hitgroup;
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV;
|
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV;
|
||||||
m_tlas.emplace_back(rayInst);
|
m_tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace
|
m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ opaque, we simply return, which means that the hit will be accepted.
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ void HelloVulkan::createBottomLevelAS()
|
||||||
|
|
||||||
### TLAS
|
### 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.
|
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
|
// Add the blas containing all spheres
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilder::Instance rayInst;
|
nvvk::RaytracingBuilder::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[0].transform; // Position of the instance
|
rayInst.transform = m_objInstance[0].transform; // Position of the instance
|
||||||
rayInst.instanceId = static_cast<uint32_t>(tlas.size()); // gl_InstanceID
|
rayInst.instanceCustomId = static_cast<uint32_t>(tlas.size()); // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = static_cast<uint32_t>(m_objModel.size());
|
rayInst.blasId = static_cast<uint32_t>(m_objModel.size());
|
||||||
rayInst.hitGroupId = 1; // We will use the same hit group for all objects
|
rayInst.hitGroupId = 1; // We will use the same hit group for all objects
|
||||||
rayInst.flags = vk::GeometryInstanceFlagBitsKHR::eTriangleCullDisable;
|
rayInst.flags = vk::GeometryInstanceFlagBitsKHR::eTriangleCullDisable;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,9 @@ std::array<Stride, 4> strideAddresses{
|
||||||
|
|
||||||
# Extending Hit
|
# 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.
|
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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
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).
|
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
|
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
|
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.
|
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<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
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
|
As usual in Vulkan, we need to explicitly destroy the objects we created by adding a call at the end of
|
||||||
`HelloVulkan::destroyResources`:
|
`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
|
// the matrix is row-major, we simply copy the first 12 values of the
|
||||||
// original 4x4 matrix
|
// original 4x4 matrix
|
||||||
memcpy(&gInst.transform, &transp, sizeof(gInst.transform));
|
memcpy(&gInst.transform, &transp, sizeof(gInst.transform));
|
||||||
gInst.instanceCustomIndex = instance.instanceId;
|
gInst.instanceCustomIndex = instance.instanceCustomId;
|
||||||
gInst.mask = instance.mask;
|
gInst.mask = instance.mask;
|
||||||
gInst.instanceShaderBindingTableRecordOffset = instance.hitGroupId;
|
gInst.instanceShaderBindingTableRecordOffset = instance.hitGroupId;
|
||||||
gInst.flags = instance.flags;
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
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
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
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);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -171,11 +171,11 @@ void Raytracer::createTopLevelAS(std::vector<ObjInstance>& instances, ImplInst&
|
||||||
for(int i = 0; i < static_cast<int>(instances.size()); i++)
|
for(int i = 0; i < static_cast<int>(instances.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = instances[i].transform; // Position of the instance
|
rayInst.transform = instances[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = instances[i].objIndex;
|
rayInst.blasId = instances[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,8 +183,9 @@ void Raytracer::createTopLevelAS(std::vector<ObjInstance>& instances, ImplInst&
|
||||||
if(!implicitObj.objImpl.empty())
|
if(!implicitObj.objImpl.empty())
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = implicitObj.transform; // Position of the instance
|
rayInst.transform = implicitObj.transform; // Position of the instance
|
||||||
rayInst.instanceId = static_cast<uint32_t>(implicitObj.blasId); // Same for material index
|
rayInst.instanceCustomId =
|
||||||
|
static_cast<uint32_t>(implicitObj.blasId); // Same for material index
|
||||||
rayInst.blasId = static_cast<uint32_t>(implicitObj.blasId);
|
rayInst.blasId = static_cast<uint32_t>(implicitObj.blasId);
|
||||||
rayInst.hitGroupId = 1; // We will use the same hit group for all objects (the second one)
|
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;
|
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMate
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ layout(location = 3) callableDataEXT rayLight cLight;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -58,13 +58,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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;
|
cLight.inHitPosition = worldPos;
|
||||||
//#define DONT_USE_CALLABLE
|
//#define DONT_USE_CALLABLE
|
||||||
|
|
@ -109,7 +109,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal);
|
vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -706,11 +706,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -51,13 +51,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -85,7 +85,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -125,11 +125,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilder::Instance rayInst;
|
nvvk::RaytracingBuilder::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = m_objInstance[i].hitgroup;
|
rayInst.hitGroupId = m_objInstance[i].hitgroup;
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV;
|
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV;
|
||||||
m_tlas.emplace_back(rayInst);
|
m_tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace
|
m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace
|
||||||
|
|
|
||||||
|
|
@ -698,11 +698,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0;
|
rayInst.hitGroupId = 0;
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
m_tlas.emplace_back(rayInst);
|
m_tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -53,13 +53,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -87,7 +87,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ opaque, we simply return, which means that the hit will be accepted.
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
|
|
|
||||||
|
|
@ -696,11 +696,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMate
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -53,13 +53,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -87,7 +87,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
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
|
// Tracing shadow ray only if the light is visible from the surface
|
||||||
if(dot(normal, L) > 0)
|
if(dot(normal, L) > 0)
|
||||||
{
|
{
|
||||||
float tMin = 0.001;
|
float tMin = 0.001;
|
||||||
float tMax = lightDistance;
|
float tMax = lightDistance;
|
||||||
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
||||||
vec3 rayDir = L;
|
vec3 rayDir = L;
|
||||||
uint flags = gl_RayFlagsSkipClosestHitShaderEXT;
|
uint flags = gl_RayFlagsSkipClosestHitShaderEXT;
|
||||||
prdShadow.isHit = true;
|
prdShadow.isHit = true;
|
||||||
prdShadow.seed = prd.seed;
|
prdShadow.seed = prd.seed;
|
||||||
traceRayEXT(topLevelAS, // acceleration structure
|
traceRayEXT(topLevelAS, // acceleration structure
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMate
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
|
|
|
||||||
|
|
@ -695,11 +695,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ layout(location = 0) callableDataEXT rayLight cLight;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -58,13 +58,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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;
|
cLight.inHitPosition = worldPos;
|
||||||
//#define DONT_USE_CALLABLE
|
//#define DONT_USE_CALLABLE
|
||||||
|
|
@ -109,7 +109,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal);
|
vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -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
|
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
|
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
|
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`
|
to the primitive mesh id. This value will be recovered with `gl_InstanceCustomIndexEXT`
|
||||||
in the closest hit shader.
|
in the closest hit shader.
|
||||||
|
|
||||||
|
|
@ -190,11 +190,11 @@ in the closest hit shader.
|
||||||
for(auto& node : m_gltfScene.m_nodes)
|
for(auto& node : m_gltfScene.m_nodes)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = node.worldMatrix;
|
rayInst.transform = node.worldMatrix;
|
||||||
rayInst.instanceId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive
|
rayInst.instanceCustomId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive
|
||||||
rayInst.blasId = node.primMesh;
|
rayInst.blasId = node.primMesh;
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
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.hitGroupId = 0; // We will use the same hit group for all objects
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
|
|
||||||
|
|
@ -670,11 +670,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(auto& node : m_gltfScene.m_nodes)
|
for(auto& node : m_gltfScene.m_nodes)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = node.worldMatrix;
|
rayInst.transform = node.worldMatrix;
|
||||||
rayInst.instanceId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive
|
rayInst.instanceCustomId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive
|
||||||
rayInst.blasId = node.primMesh;
|
rayInst.blasId = node.primMesh;
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
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.hitGroupId = 0; // We will use the same hit group for all objects
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -715,11 +715,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -53,13 +53,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -87,7 +87,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,7 @@ void HelloVulkan::createBottomLevelAS()
|
||||||
|
|
||||||
### TLAS
|
### 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.
|
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
|
// Add the blas containing all spheres
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilder::Instance rayInst;
|
nvvk::RaytracingBuilder::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[0].transform; // Position of the instance
|
rayInst.transform = m_objInstance[0].transform; // Position of the instance
|
||||||
rayInst.instanceId = static_cast<uint32_t>(tlas.size()); // gl_InstanceID
|
rayInst.instanceCustomId = static_cast<uint32_t>(tlas.size()); // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = static_cast<uint32_t>(m_objModel.size());
|
rayInst.blasId = static_cast<uint32_t>(m_objModel.size());
|
||||||
rayInst.hitGroupId = 1; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
|
|
||||||
|
|
@ -811,22 +811,22 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the blas containing all spheres
|
// Add the blas containing all spheres
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[0].transform; // Position of the instance
|
rayInst.transform = m_objInstance[0].transform; // Position of the instance
|
||||||
rayInst.instanceId = static_cast<uint32_t>(tlas.size()); // gl_InstanceID
|
rayInst.instanceCustomId = static_cast<uint32_t>(tlas.size()); // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = static_cast<uint32_t>(m_objModel.size());
|
rayInst.blasId = static_cast<uint32_t>(m_objModel.size());
|
||||||
rayInst.hitGroupId = 1; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -53,13 +53,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -87,7 +87,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -694,11 +694,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -53,13 +53,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -87,7 +87,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ The stride device address will be modified like this:
|
||||||
|
|
||||||
## Extending Hit
|
## 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.
|
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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -692,11 +692,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
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.hitGroupId = m_objInstance[i].hitgroup; // Using the hit group set in main
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -53,13 +53,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -87,7 +87,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
|
|
@ -701,11 +701,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -693,11 +693,11 @@ void HelloVulkan::createTopLevelAS()
|
||||||
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
for(int i = 0; i < static_cast<int>(m_objInstance.size()); i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||||
rayInst.instanceId = i; // gl_InstanceID
|
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = m_objInstance[i].objIndex;
|
rayInst.blasId = m_objInstance[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
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.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
tlas.emplace_back(rayInst);
|
tlas.emplace_back(rayInst);
|
||||||
}
|
}
|
||||||
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ pushC;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
|
|
@ -53,13 +53,13 @@ void main()
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// 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
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// 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
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -87,7 +87,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord =
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue