Fixing access to nonuniform elements + SBT alignment
This commit is contained in:
parent
4f46136c08
commit
ccdc90f35c
41 changed files with 388 additions and 279 deletions
|
|
@ -34,7 +34,7 @@ The directory structure should be looking like:
|
||||||
* |
|
* |
|
||||||
* +-- 📂 shared_sources
|
* +-- 📂 shared_sources
|
||||||
* |
|
* |
|
||||||
* +-- 📂 vk_raytracing_tutorial
|
* +-- 📂 vk_raytracing_tutorial_KHR
|
||||||
* | |
|
* | |
|
||||||
* | +-- 📂 ray_tracing__simple (<-- Start here)
|
* | +-- 📂 ray_tracing__simple (<-- Start here)
|
||||||
* | |
|
* | |
|
||||||
|
|
@ -47,7 +47,7 @@ The directory structure should be looking like:
|
||||||
|
|
||||||
|
|
||||||
!!! Warning
|
!!! Warning
|
||||||
**Run CMake** in vk_raytracing_tutorial.
|
**Run CMake** in vk_raytracing_tutorial_KHR.
|
||||||
|
|
||||||
!!! Warning Beta
|
!!! Warning Beta
|
||||||
Modify `VULKAN > VULKAN_HEADERS_OVERRIDE_INCLUDE_DIR` to the path to beta vulkan headers.
|
Modify `VULKAN > VULKAN_HEADERS_OVERRIDE_INCLUDE_DIR` to the path to beta vulkan headers.
|
||||||
|
|
|
||||||
|
|
@ -64,13 +64,13 @@ void main()
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
uint ind = indices[objId].i[3 * gl_PrimitiveID + 0];
|
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
if (mat.illum != 4)
|
if (mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -101,20 +101,26 @@ Go to the `main` function of the `main.cpp` file, and find where we request Vulk
|
||||||
`nvvk::ContextCreateInfo`.
|
`nvvk::ContextCreateInfo`.
|
||||||
To request ray tracing capabilities, we need to explicitly
|
To request ray tracing capabilities, we need to explicitly
|
||||||
add the
|
add the
|
||||||
[VK_KHR_ray_tracing](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VK_KHR_ray_tracing)
|
[VK_KHR_ray_tracing](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_ray_tracing.html)
|
||||||
extension as well as its dependency
|
extension as well as its various dependencies.
|
||||||
[VK_KHR_maintenance3](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VK_KHR_maintenance3.html):
|
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature;
|
vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature;
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature);
|
||||||
|
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
||||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
||||||
|
|
||||||
````
|
````
|
||||||
|
|
||||||
|
Before creating the device, a linked structure of features must past. Not all extensions requires a set of features, but
|
||||||
|
ray tracing features must be enabled before the creation of the device. By providing
|
||||||
|
`raytracingFeature`, the context creation will query the capable features for ray tracing and will use the
|
||||||
|
filled structure to create the device.
|
||||||
|
|
||||||
|
|
||||||
In the `HelloVulkan` class in `hello_vulkan.h`, add an initialization function and a member storing the capabilities of
|
In the `HelloVulkan` class in `hello_vulkan.h`, add an initialization function and a member storing the capabilities of
|
||||||
the GPU for ray tracing:
|
the GPU for ray tracing:
|
||||||
|
|
||||||
|
|
@ -356,6 +362,14 @@ m_debug.setObjectName(blas.as.accel, (std::string("Blas" + std::to_string(idx)).
|
||||||
|
|
||||||
The acceleration structure builder requires some scratch memory to generate the BLAS. Since we generate all the
|
The acceleration structure builder requires some scratch memory to generate the BLAS. Since we generate all the
|
||||||
BLAS's in a batch, we query the scratch memory requirements for each BLAS, and find the maximum such requirement.
|
BLAS's in a batch, we query the scratch memory requirements for each BLAS, and find the maximum such requirement.
|
||||||
|
The amount of memory for the scratch is determined by filling the memory requirement structure, and setting
|
||||||
|
the previous created acceleration structure. At the time to write those lines, only the device can be use
|
||||||
|
for building the acceleration structure. The same scratch buffer is used by each BLAS, which is the reason to
|
||||||
|
allocate the largest size, to avoid any realocation. At the end of building all BLAS, we can dispose the scratch
|
||||||
|
buffer.
|
||||||
|
|
||||||
|
We are querying the size the acceleration structure is taking on the device as well. This has no real use except
|
||||||
|
for statistics and to compare it to the compact size which can happen in a second step.
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Estimate the amount of scratch memory required to build the BLAS, and
|
// Estimate the amount of scratch memory required to build the BLAS, and
|
||||||
|
|
@ -395,7 +409,11 @@ bufferInfo.buffer = scratchBuffer.buffer;
|
||||||
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(m_device, &bufferInfo);
|
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(m_device, &bufferInfo);
|
||||||
````
|
````
|
||||||
|
|
||||||
To know the size that the BLAS is really taking, we use queries.
|
To know the size that the BLAS is really taking, we use queries and setting the type to `VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR`.
|
||||||
|
This is needed if we want to compact the acceleration structure in a second step. By default, the
|
||||||
|
memory allocated by the creation of the acceleration structure has the size of the worst case. After creation,
|
||||||
|
the real space can be smaller, and it is possible to copy the acceleration structure to one that is
|
||||||
|
using exactly what is needed. This could save over 50% of the device memory usage.
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Query size of compact BLAS
|
// Query size of compact BLAS
|
||||||
|
|
@ -406,9 +424,15 @@ VkQueryPool queryPool;
|
||||||
vkCreateQueryPool(m_device, &qpci, nullptr, &queryPool);
|
vkCreateQueryPool(m_device, &qpci, nullptr, &queryPool);
|
||||||
````
|
````
|
||||||
|
|
||||||
We then use a one-time command buffer to launch all the BLAS builds. Note the barrier after each
|
We then use multiple command buffers to launch all the BLAS builds. We are using multiple
|
||||||
|
command buffers instead of one, to allow the driver to allow system interuption and avoid a
|
||||||
|
TDR if the job was to heavy.
|
||||||
|
|
||||||
|
Note the barrier after each
|
||||||
build call: this is required as we reuse the scratch space across builds, and hence need to ensure
|
build call: this is required as we reuse the scratch space across builds, and hence need to ensure
|
||||||
the previous build has completed before starting the next.
|
the previous build has completed before starting the next. We could have used multiple scratch buffers,
|
||||||
|
but it would have been expensive memory wise, and the device can only build one BLAS at a time, so we
|
||||||
|
wouldn't be faster.
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Query size of compact BLAS
|
// Query size of compact BLAS
|
||||||
|
|
@ -421,10 +445,14 @@ vkCreateQueryPool(m_device, &qpci, nullptr, &queryPool);
|
||||||
|
|
||||||
// Create a command buffer containing all the BLAS builds
|
// Create a command buffer containing all the BLAS builds
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_queueIndex);
|
nvvk::CommandPool genCmdBuf(m_device, m_queueIndex);
|
||||||
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
|
||||||
int ctr{0};
|
int ctr{0};
|
||||||
|
std::vector<VkCommandBuffer> allCmdBufs;
|
||||||
|
allCmdBufs.reserve(m_blas.size());
|
||||||
for(auto& blas : m_blas)
|
for(auto& blas : m_blas)
|
||||||
{
|
{
|
||||||
|
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||||
|
allCmdBufs.push_back(cmdBuf);
|
||||||
|
|
||||||
const VkAccelerationStructureGeometryKHR* pGeometry = blas.asGeometry.data();
|
const VkAccelerationStructureGeometryKHR* pGeometry = blas.asGeometry.data();
|
||||||
VkAccelerationStructureBuildGeometryInfoKHR bottomASInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
VkAccelerationStructureBuildGeometryInfoKHR bottomASInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
||||||
bottomASInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
bottomASInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||||
|
|
@ -460,16 +488,16 @@ for(auto& blas : m_blas)
|
||||||
VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryPool, ctr++);
|
VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryPool, ctr++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
genCmdBuf.submitAndWait(allCmdBufs);
|
||||||
|
allCmdBufs.clear();
|
||||||
````
|
````
|
||||||
|
|
||||||
While this approach has the advantage of keeping all BLAS's independent, building many BLAS's efficiently would
|
While this approach has the advantage of keeping all BLAS's independent, building many BLAS's efficiently would
|
||||||
require allocating a larger scratch buffer, and launch several builds simultaneously. This tutorial also
|
require allocating a larger scratch buffer, and launch several builds simultaneously. This current tutorial
|
||||||
does not use compaction, which could reduce significantly the memory footprint of the acceleration structures. Both
|
does not make use of compaction, which could reduce significantly the memory footprint of the acceleration structures. Both
|
||||||
of those aspects will be part of a future advanced tutorial.
|
of those aspects will be part of a future advanced tutorial.
|
||||||
We finally execute the command buffer and clean up the allocator's scratch memory and staging buffer:
|
|
||||||
|
|
||||||
This part, which is optional, will compact the BLAS in the memory that it is really using. It needs to wait that all BLASes
|
The following is when compation flag is enabled. This part, which is optional, will compact the BLAS in the memory that it is really using. It needs to wait that all BLASes
|
||||||
are constructred, to make a copy in the more fitted memory space.
|
are constructred, to make a copy in the more fitted memory space.
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
|
|
@ -490,7 +518,7 @@ if(doCompaction)
|
||||||
uint32_t totOriginalSize{0}, totCompactSize{0};
|
uint32_t totOriginalSize{0}, totCompactSize{0};
|
||||||
for(int i = 0; i < m_blas.size(); i++)
|
for(int i = 0; i < m_blas.size(); i++)
|
||||||
{
|
{
|
||||||
LOGI("Reducing %i, from %d to %d \n", i, originalSizes[i], compactSizes[i]);
|
// LOGI("Reducing %i, from %d to %d \n", i, originalSizes[i], compactSizes[i]);
|
||||||
totOriginalSize += (uint32_t)originalSizes[i];
|
totOriginalSize += (uint32_t)originalSizes[i];
|
||||||
totCompactSize += (uint32_t)compactSizes[i];
|
totCompactSize += (uint32_t)compactSizes[i];
|
||||||
|
|
||||||
|
|
@ -1646,13 +1674,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
````
|
````
|
||||||
|
|
||||||
Using the hit point's barycentric coordinates, we can interpolate the normal:
|
Using the hit point's barycentric coordinates, we can interpolate the normal:
|
||||||
|
|
@ -1745,8 +1773,8 @@ and fetch the material definition instead:
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
````
|
````
|
||||||
|
|
||||||
!!! Note Note
|
!!! Note Note
|
||||||
|
|
@ -1764,7 +1792,7 @@ supports textures to modulate the surface albedo.
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specular
|
// Specular
|
||||||
|
|
|
||||||
|
|
@ -421,23 +421,29 @@ void Raytracer::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc->createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc->createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc->map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc->unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
m_alloc->finalizeAndReleaseStaging();
|
m_alloc->finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
@ -472,7 +478,8 @@ void Raytracer::raytrace(const vk::CommandBuffer& cmdBuf,
|
||||||
| vk::ShaderStageFlagBits::eCallableKHR,
|
| vk::ShaderStageFlagBits::eCallableKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
if(mat.illum != 4)
|
if(mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -45,13 +45,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -101,8 +101,8 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -112,7 +112,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ void main()
|
||||||
{
|
{
|
||||||
// Material of the object
|
// Material of the object
|
||||||
Implicit impl = allImplicits.i[gl_PrimitiveID];
|
Implicit impl = allImplicits.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[gl_InstanceCustomIndexEXT].m[impl.matId];
|
WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId];
|
||||||
|
|
||||||
if(mat.illum != 4)
|
if(mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ void main()
|
||||||
executeCallableEXT(pushC.lightType, 0);
|
executeCallableEXT(pushC.lightType, 0);
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
WaveFrontMaterial mat = materials[gl_InstanceCustomIndexEXT].m[impl.matId];
|
WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -855,24 +855,31 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -897,7 +904,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eMissKHR,
|
| vk::ShaderStageFlagBits::eMissKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,6 @@ int main(int argc, char** argv)
|
||||||
NVPSystem::exePath() + std::string(PROJECT_RELDIRECTORY) + std::string("../"),
|
NVPSystem::exePath() + std::string(PROJECT_RELDIRECTORY) + std::string("../"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enabling the extension feature
|
|
||||||
vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature;
|
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo(true);
|
nvvk::ContextCreateInfo contextInfo(true);
|
||||||
|
|
@ -140,6 +138,7 @@ int main(int argc, char** argv)
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
|
vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature;
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature);
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -77,8 +77,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -88,7 +88,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -851,24 +851,31 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -893,7 +900,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eMissKHR,
|
| vk::ShaderStageFlagBits::eMissKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
@ -939,7 +947,8 @@ void HelloVulkan::animationInstances(float time)
|
||||||
|
|
||||||
// Update the buffer
|
// Update the buffer
|
||||||
vk::DeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance);
|
vk::DeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance);
|
||||||
nvvk::Buffer stagingBuffer = m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc,
|
nvvk::Buffer stagingBuffer =
|
||||||
|
m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::MemoryPropertyFlagBits::eHostVisible);
|
vk::MemoryPropertyFlagBits::eHostVisible);
|
||||||
// Copy data to staging buffer
|
// Copy data to staging buffer
|
||||||
auto* gInst = m_alloc.map(stagingBuffer);
|
auto* gInst = m_alloc.map(stagingBuffer);
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -90,7 +90,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -853,24 +853,31 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -899,7 +906,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eMissKHR,
|
| vk::ShaderStageFlagBits::eMissKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@ void main()
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
uint ind = indices[objId].i[3 * gl_PrimitiveID + 0];
|
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
if(mat.illum != 4)
|
if(mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -90,7 +90,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -871,24 +871,31 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -917,7 +924,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eCallableKHR,
|
| vk::ShaderStageFlagBits::eCallableKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,13 +45,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -101,8 +101,8 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -112,7 +112,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -864,24 +864,31 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -906,7 +913,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eMissKHR,
|
| vk::ShaderStageFlagBits::eMissKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -90,7 +90,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -1001,24 +1001,31 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1043,7 +1050,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eMissKHR,
|
| vk::ShaderStageFlagBits::eMissKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -90,7 +90,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[gl_InstanceID].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(gl_InstanceID)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[gl_InstanceID].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceID)].m[matIdx];
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
|
|
|
||||||
|
|
@ -842,24 +842,31 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -888,7 +895,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eMissKHR,
|
| vk::ShaderStageFlagBits::eMissKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -90,7 +90,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ extern std::vector<std::string> defaultSearchPaths;
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
#include "nvvk/shaders_vk.hpp"
|
#include "nvvk/shaders_vk.hpp"
|
||||||
|
|
||||||
|
#ifndef ROUND_UP
|
||||||
|
#define ROUND_UP(v, powerOf2Alignment) (((v) + (powerOf2Alignment)-1) & ~((powerOf2Alignment)-1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Holding the camera matrices
|
// Holding the camera matrices
|
||||||
struct CameraMatrices
|
struct CameraMatrices
|
||||||
|
|
@ -850,9 +854,10 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t groupAlignSize = m_rtProperties.shaderGroupBaseAlignment;
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * groupAlignSize;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
|
|
@ -866,9 +871,10 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
uint32_t rayGenSize = groupHandleSize;
|
uint32_t rayGenSize = groupAlignSize;
|
||||||
uint32_t missSize = groupHandleSize;
|
uint32_t missSize = groupAlignSize;
|
||||||
uint32_t hitSize = groupHandleSize + sizeof(HitRecordBuffer);
|
uint32_t hitSize =
|
||||||
|
ROUND_UP(groupHandleSize + static_cast<int>(sizeof(HitRecordBuffer)), groupAlignSize);
|
||||||
uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize;
|
uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize;
|
||||||
|
|
||||||
std::vector<uint8_t> sbtBuffer(newSbtSize);
|
std::vector<uint8_t> sbtBuffer(newSbtSize);
|
||||||
|
|
@ -882,19 +888,22 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
memcpy(pBuffer, handles[2], groupHandleSize); // Miss 1
|
memcpy(pBuffer, handles[2], groupHandleSize); // Miss 1
|
||||||
pBuffer += missSize;
|
pBuffer += missSize;
|
||||||
|
|
||||||
memcpy(pBuffer, handles[3], groupHandleSize); // Hit 0
|
uint8_t* pHitBuffer = pBuffer;
|
||||||
pBuffer += groupHandleSize;
|
memcpy(pHitBuffer, handles[3], groupHandleSize); // Hit 0
|
||||||
pBuffer += sizeof(HitRecordBuffer); // No data
|
// No data
|
||||||
|
pBuffer += hitSize;
|
||||||
|
|
||||||
memcpy(pBuffer, handles[4], groupHandleSize); // Hit 1
|
pHitBuffer = pBuffer;
|
||||||
pBuffer += groupHandleSize;
|
memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 1
|
||||||
memcpy(pBuffer, &m_hitShaderRecord[0], sizeof(HitRecordBuffer)); // Hit 1 data
|
pHitBuffer += groupHandleSize;
|
||||||
pBuffer += sizeof(HitRecordBuffer);
|
memcpy(pHitBuffer, &m_hitShaderRecord[0], sizeof(HitRecordBuffer)); // Hit 1 data
|
||||||
|
pBuffer += hitSize;
|
||||||
|
|
||||||
memcpy(pBuffer, handles[4], groupHandleSize); // Hit 2
|
pHitBuffer = pBuffer;
|
||||||
pBuffer += groupHandleSize;
|
memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 2
|
||||||
memcpy(pBuffer, &m_hitShaderRecord[1], sizeof(HitRecordBuffer)); // Hit 2 data
|
pHitBuffer += groupHandleSize;
|
||||||
pBuffer += sizeof(HitRecordBuffer);
|
memcpy(pHitBuffer, &m_hitShaderRecord[1], sizeof(HitRecordBuffer)); // Hit 2 data
|
||||||
|
pBuffer += hitSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
|
|
@ -933,12 +942,14 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize alignSize = m_rtProperties.shaderGroupBaseAlignment;
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
|
||||||
vk::DeviceSize sbtSize = progSize * (vk::DeviceSize)m_rtShaderGroups.size();
|
|
||||||
|
|
||||||
vk::DeviceSize hitGroupStride = progSize + sizeof(HitRecordBuffer);
|
vk::DeviceSize rayGenOffset = 0u * alignSize; // Start at the beginning of m_sbtBuffer
|
||||||
|
vk::DeviceSize missOffset = 1u * alignSize; // Jump over raygen
|
||||||
|
vk::DeviceSize hitGroupOffset = 3u * alignSize; // Jump over the previous shaders
|
||||||
|
vk::DeviceSize sbtSize = alignSize * (vk::DeviceSize)m_rtShaderGroups.size();
|
||||||
|
|
||||||
|
vk::DeviceSize hitGroupStride = ROUND_UP(progSize + sizeof(HitRecordBuffer), alignSize);
|
||||||
|
|
||||||
// m_sbtBuffer holds all the shader handles: raygen, n-miss, hit...
|
// m_sbtBuffer holds all the shader handles: raygen, n-miss, hit...
|
||||||
const vk::StridedBufferRegionKHR raygenShaderBindingTable = {m_rtSBTBuffer.buffer, rayGenOffset,
|
const vk::StridedBufferRegionKHR raygenShaderBindingTable = {m_rtSBTBuffer.buffer, rayGenOffset,
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -90,7 +90,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -842,27 +842,33 @@ void HelloVulkan::createRtShaderBindingTable()
|
||||||
auto groupCount =
|
auto groupCount =
|
||||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||||
|
uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
|
||||||
|
|
||||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||||
uint32_t sbtSize = groupCount * groupHandleSize;
|
uint32_t sbtSize = groupCount * baseAligment;
|
||||||
|
|
||||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||||
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||||
shaderHandleStorage.data());
|
shaderHandleStorage.data());
|
||||||
// Write the handles in the SBT
|
// Write the handles in the SBT
|
||||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
vk::MemoryPropertyFlagBits::eHostVisible
|
||||||
|
| vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||||
|
|
||||||
m_rtSBTBuffer =
|
// Write the handles in the SBT
|
||||||
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
|
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
|
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||||
|
for(uint32_t g = 0; g < groupCount; g++)
|
||||||
|
{
|
||||||
|
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||||
|
pData += baseAligment;
|
||||||
|
}
|
||||||
|
m_alloc.unmap(m_rtSBTBuffer);
|
||||||
|
|
||||||
|
|
||||||
genCmdBuf.submitAndWait(cmdBuf);
|
|
||||||
|
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
// Ray Tracing the scene
|
// Ray Tracing the scene
|
||||||
//
|
//
|
||||||
|
|
@ -884,7 +890,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
||||||
| vk::ShaderStageFlagBits::eMissKHR,
|
| vk::ShaderStageFlagBits::eMissKHR,
|
||||||
0, m_rtPushConstants);
|
0, m_rtPushConstants);
|
||||||
|
|
||||||
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
vk::DeviceSize progSize =
|
||||||
|
m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
|
||||||
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
|
||||||
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
|
||||||
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ void main()
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = scnDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[objId].i[gl_PrimitiveID];
|
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIndex];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ void main()
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ void main()
|
||||||
uint objId = scnDesc.i[gl_InstanceID].objId;
|
uint objId = scnDesc.i[gl_InstanceID].objId;
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 1], //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
||||||
indices[objId].i[3 * gl_PrimitiveID + 2]); //
|
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[objId].v[ind.x];
|
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||||
Vertex v1 = vertices[objId].v[ind.y];
|
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
||||||
Vertex v2 = vertices[objId].v[ind.z];
|
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
||||||
|
|
||||||
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[objId].i[gl_PrimitiveID];
|
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[objId].m[matIdx];
|
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -90,7 +90,7 @@ void main()
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
|
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].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[txtId], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 specular = vec3(0);
|
vec3 specular = vec3(0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue