Using buffer reference instead of un-sized array
This commit is contained in:
parent
e3a57e6d63
commit
c8a0122dd6
248 changed files with 2593 additions and 2660 deletions
|
|
@ -116,14 +116,10 @@ extensions will need to be added.
|
||||||
```` C
|
```` C
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature);
|
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures
|
||||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
||||||
|
|
||||||
````
|
````
|
||||||
|
|
||||||
Behind the scenes, the helper is selecting a physical device supporting the required `VK_KHR_*` extensions,
|
Behind the scenes, the helper is selecting a physical device supporting the required `VK_KHR_*` extensions,
|
||||||
|
|
@ -293,11 +289,8 @@ potential optimization. (More specifically, this disables calls to the anyhit sh
|
||||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||||
{
|
{
|
||||||
// BLAS builder requires raw device addresses.
|
// BLAS builder requires raw device addresses.
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
info.buffer = model.vertexBuffer.buffer;
|
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
info.buffer = model.indexBuffer.buffer;
|
|
||||||
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
||||||
|
|
||||||
|
|
@ -974,61 +967,31 @@ descriptor set as they semantically fit the Scene descriptor set.
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Scene description (binding = 2)
|
// Textures (binding = 2)
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Textures (binding = 3)
|
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing vertices (binding = 5)
|
|
||||||
m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing indices (binding = 6)
|
|
||||||
m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
````
|
|
||||||
|
|
||||||
We set the actual contents of the descriptor set by adding those buffers in `updateDescriptorSet()`:
|
|
||||||
|
|
||||||
```` C
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiVert;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data()));
|
|
||||||
````
|
````
|
||||||
|
|
||||||
Originally the buffers containing the vertices and indices were only used by the rasterization pipeline.
|
Originally the buffers containing the vertices and indices were only used by the rasterization pipeline.
|
||||||
The ray tracing will need to use those buffers as storage buffers, so we add `VK_BUFFER_USAGE_STORAGE_BUFFER_BIT`;
|
The ray tracing will need to use those buffers as storage buffers, so we add `VK_BUFFER_USAGE_STORAGE_BUFFER_BIT`;
|
||||||
additionally, the buffers will be read by the acceleration structure builder, which requires raw device addresses
|
additionally, the buffers will be read by the acceleration structure builder, which requires raw device addresses
|
||||||
(in `VkAccelerationStructureGeometryTrianglesDataKHR`), so the buffer also needs
|
(in `VkAccelerationStructureGeometryTrianglesDataKHR`), so the buffer also needs
|
||||||
the `VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR`
|
`VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR` bits.
|
||||||
and `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT` bits.
|
|
||||||
|
|
||||||
We update the usage of the buffers in `loadModel`:
|
We update the usage of the buffers in `loadModel`:
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
|
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags);
|
||||||
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags);
|
||||||
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
````
|
````
|
||||||
|
|
||||||
!!! Note: Array of Buffers
|
!!! Note: Array of Buffers
|
||||||
|
|
@ -1949,6 +1912,8 @@ We first include the payload definition and the OBJ-Wavefront structures
|
||||||
```` C
|
```` C
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
````
|
````
|
||||||
|
|
@ -1958,9 +1923,12 @@ Then we describe the resources according to the descriptor set layout
|
||||||
```` C
|
```` C
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
|
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||||
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
````
|
````
|
||||||
|
|
||||||
In the Hit shader we need all the members of the push constant block:
|
In the Hit shader we need all the members of the push constant block:
|
||||||
|
|
@ -1976,22 +1944,25 @@ layout(push_constant) uniform Constants
|
||||||
pushC;
|
pushC;
|
||||||
````
|
````
|
||||||
|
|
||||||
In the `main` function, the `gl_PrimitiveID` allows us to find the vertices of the triangle hit by the ray:
|
In the `main` function, the `gl_InstanceCustomIndexEXT` tells which object was hit, and the `gl_PrimitiveID` allows us to find the vertices of the triangle hit by the ray:
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
// Indices of the triangle
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
Indices indices = Indices(objResource.indexAddress);
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
Vertices vertices = Vertices(objResource.vertexAddress);
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
|
||||||
// Vertex of the triangle
|
// Indices of the triangle
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
ivec3 ind = indices.i[gl_PrimitiveID];
|
||||||
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
|
||||||
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
// Vertex of the triangle
|
||||||
|
Vertex v0 = vertices.v[ind.x];
|
||||||
|
Vertex v1 = vertices.v[ind.y];
|
||||||
|
Vertex v2 = vertices.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:
|
||||||
|
|
@ -2060,12 +2031,10 @@ simplified Alias Wavefront material definitions.
|
||||||
|
|
||||||
These materials define their basic reflectance properties using simple color coefficients, and also support texturing.
|
These materials define their basic reflectance properties using simple color coefficients, and also support texturing.
|
||||||
The buffer containing the materials has already been created for rasterization, and has also been added into the ray
|
The buffer containing the materials has already been created for rasterization, and has also been added into the ray
|
||||||
tracing descriptor set. Add the binding of the material buffer and the array of texture samplers:
|
tracing descriptor set. Add the binding of the array of texture samplers:
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||||
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
|
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
|
||||||
````
|
````
|
||||||
|
|
||||||
The declaration of the material is the same as that used for the rasterizer and is defined in
|
The declaration of the material is the same as that used for the rasterizer and is defined in
|
||||||
|
|
@ -2084,8 +2053,8 @@ and fetch the material definition instead:
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
````
|
````
|
||||||
|
|
||||||
!!! Note Note
|
!!! Note Note
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ compile_glsl_directory(
|
||||||
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
||||||
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
||||||
VULKAN_TARGET "vulkan1.2"
|
VULKAN_TARGET "vulkan1.2"
|
||||||
|
DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS})
|
||||||
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
||||||
source_group("Sources" FILES ${SOURCE_FILES})
|
source_group("Sources" FILES ${SOURCE_FILES})
|
||||||
source_group("Headers" FILES ${HEADER_FILES})
|
source_group("Headers" FILES ${HEADER_FILES})
|
||||||
source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
source_group("Shader Sources" FILES ${GLSL_SOURCES})
|
||||||
|
source_group("Shader Headers" FILES ${GLSL_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#include "nvvk/commands_vk.hpp"
|
#include "nvvk/commands_vk.hpp"
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
|
|
||||||
|
#include "nvvk/buffers_vk.hpp"
|
||||||
|
|
||||||
extern std::vector<std::string> defaultSearchPaths;
|
extern std::vector<std::string> defaultSearchPaths;
|
||||||
|
|
||||||
|
|
@ -119,30 +120,19 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
||||||
void HelloVulkan::createDescriptorSetLayout()
|
void HelloVulkan::createDescriptorSetLayout()
|
||||||
{
|
{
|
||||||
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
||||||
auto nbObj = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
|
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj + 1,
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
||||||
// Scene description (binding = 2)
|
// Textures (binding = 2)
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
|
||||||
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
// Textures (binding = 3)
|
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
// Storing implicit obj (binding = 3)
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
// Storing vertices (binding = 5)
|
|
||||||
m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing indices (binding = 6)
|
|
||||||
m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing implicit obj (binding = 7)
|
|
||||||
m_descSetLayoutBind.addBinding(7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
|
||||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
|
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
|
||||||
| VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
| VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
||||||
|
|
||||||
|
|
@ -162,26 +152,9 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
// Camera matrices and scene description
|
// Camera matrices and scene description
|
||||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
||||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc));
|
|
||||||
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiVert;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
dbiMat.push_back({m_implObjects.implMatBuf.buffer, 0, VK_WHOLE_SIZE}); // Adding implicit mat
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data()));
|
|
||||||
|
|
||||||
// All texture samplers
|
// All texture samplers
|
||||||
std::vector<VkDescriptorImageInfo> diit;
|
std::vector<VkDescriptorImageInfo> diit;
|
||||||
|
|
@ -189,10 +162,10 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
{
|
{
|
||||||
diit.emplace_back(texture.descriptor);
|
diit.emplace_back(texture.descriptor);
|
||||||
}
|
}
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data()));
|
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||||
|
|
||||||
VkDescriptorBufferInfo dbiImplDesc{m_implObjects.implBuf.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiImplDesc{m_implObjects.implBuf.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, &dbiImplDesc));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 3, &dbiImplDesc));
|
||||||
|
|
||||||
// Writing the information
|
// Writing the information
|
||||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||||
|
|
@ -250,36 +223,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
||||||
m.specular = nvmath::pow(m.specular, 2.2f);
|
m.specular = nvmath::pow(m.specular, 2.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjInstance instance;
|
|
||||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
instance.transform = transform;
|
|
||||||
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
|
||||||
instance.txtOffset = static_cast<uint32_t>(m_textures.size());
|
|
||||||
|
|
||||||
ObjModel model;
|
ObjModel model;
|
||||||
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
||||||
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
||||||
|
|
||||||
// Create the buffers on Device and copy vertices, indices and materials
|
// Create the buffers on Device and copy vertices, indices and materials
|
||||||
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
||||||
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
||||||
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
|
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
// Creates all textures found
|
// Creates all textures found
|
||||||
|
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
|
||||||
createTextureImages(cmdBuf, loader.m_textures);
|
createTextureImages(cmdBuf, loader.m_textures);
|
||||||
cmdBufGet.submitAndWait(cmdBuf);
|
cmdBufGet.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
|
|
||||||
std::string objNb = std::to_string(instance.objIndex);
|
std::string objNb = std::to_string(m_objModel.size());
|
||||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
||||||
|
|
||||||
|
ObjInstance instance;
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.transform = transform;
|
||||||
|
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
||||||
|
instance.txtOffset = txtOffset;
|
||||||
|
instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
|
instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||||
|
instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||||
|
|
||||||
m_objModel.emplace_back(model);
|
m_objModel.emplace_back(model);
|
||||||
m_objInstance.emplace_back(instance);
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
@ -573,9 +552,16 @@ void HelloVulkan::createImplictBuffers()
|
||||||
m_implObjects.implBuf = m_alloc.createBuffer(cmdBuf, m_implObjects.objImpl,
|
m_implObjects.implBuf = m_alloc.createBuffer(cmdBuf, m_implObjects.objImpl,
|
||||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR
|
||||||
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||||
m_implObjects.implMatBuf = m_alloc.createBuffer(cmdBuf, m_implObjects.implMat, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
m_implObjects.implMatBuf = m_alloc.createBuffer(cmdBuf, m_implObjects.implMat,
|
||||||
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||||
cmdGen.submitAndWait(cmdBuf);
|
cmdGen.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
m_debug.setObjectName(m_implObjects.implBuf.buffer, "implicitObj");
|
m_debug.setObjectName(m_implObjects.implBuf.buffer, "implicitObj");
|
||||||
m_debug.setObjectName(m_implObjects.implMatBuf.buffer, "implicitMat");
|
m_debug.setObjectName(m_implObjects.implMatBuf.buffer, "implicitMat");
|
||||||
|
|
||||||
|
// Adding an instance to hold the buffer address of implicit materials
|
||||||
|
ObjInstance instance{};
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, m_implObjects.implMatBuf.buffer);
|
||||||
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ public:
|
||||||
Offscreen& offscreen() { return m_offscreen; }
|
Offscreen& offscreen() { return m_offscreen; }
|
||||||
Raytracer& raytracer() { return m_raytrace; }
|
Raytracer& raytracer() { return m_raytrace; }
|
||||||
|
|
||||||
|
|
||||||
ObjPushConstants m_pushConstants;
|
ObjPushConstants m_pushConstants;
|
||||||
|
|
||||||
// Array of objects and instances in the scene
|
// Array of objects and instances in the scene
|
||||||
|
|
@ -83,20 +84,21 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// Graphic pipeline
|
// Graphic pipeline
|
||||||
VkPipelineLayout m_pipelineLayout;
|
VkPipelineLayout m_pipelineLayout;
|
||||||
VkPipeline m_graphicsPipeline;
|
VkPipeline m_graphicsPipeline;
|
||||||
nvvk::DescriptorSetBindings m_descSetLayoutBind;
|
nvvk::DescriptorSetBindings m_descSetLayoutBind;
|
||||||
VkDescriptorPool m_descPool;
|
VkDescriptorPool m_descPool;
|
||||||
VkDescriptorSetLayout m_descSetLayout;
|
VkDescriptorSetLayout m_descSetLayout;
|
||||||
VkDescriptorSet m_descSet;
|
VkDescriptorSet m_descSet;
|
||||||
|
|
||||||
int m_maxFrames{10};
|
int m_maxFrames{10};
|
||||||
void resetFrame();
|
void resetFrame();
|
||||||
void updateFrame();
|
void updateFrame();
|
||||||
|
|
||||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
|
||||||
|
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||||
|
|
||||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ void renderUI(HelloVulkan& helloVk)
|
||||||
static int const SAMPLE_WIDTH = 1280;
|
static int const SAMPLE_WIDTH = 1280;
|
||||||
static int const SAMPLE_HEIGHT = 720;
|
static int const SAMPLE_HEIGHT = 720;
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
// Application Entry
|
// Application Entry
|
||||||
//
|
//
|
||||||
|
|
@ -139,34 +140,26 @@ int main(int argc, char** argv)
|
||||||
std::string(PROJECT_NAME),
|
std::string(PROJECT_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan required extensions
|
||||||
|
assert(glfwVulkanSupported() == 1);
|
||||||
|
uint32_t count{0};
|
||||||
|
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo(true);
|
nvvk::ContextCreateInfo contextInfo;
|
||||||
contextInfo.setVersion(1, 2);
|
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
|
||||||
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
|
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
|
||||||
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
|
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
|
||||||
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
|
||||||
#ifdef _WIN32
|
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
|
||||||
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
|
||||||
#else
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature);
|
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures
|
||||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// Creating Vulkan base application
|
// Creating Vulkan base application
|
||||||
nvvk::Context vkctx{};
|
nvvk::Context vkctx{};
|
||||||
|
|
@ -342,7 +335,7 @@ int main(int argc, char** argv)
|
||||||
// Rendering tonemapper
|
// Rendering tonemapper
|
||||||
vkCmdBeginRenderPass(cmdBuf, &postRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(cmdBuf, &postRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
offscreen.draw(cmdBuf, helloVk.getSize());
|
offscreen.draw(cmdBuf, helloVk.getSize());
|
||||||
|
|
||||||
// Rendering UI
|
// Rendering UI
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmdBuf);
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmdBuf);
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,14 @@ struct ObjModel
|
||||||
// Instance of the OBJ
|
// Instance of the OBJ
|
||||||
struct ObjInstance
|
struct ObjInstance
|
||||||
{
|
{
|
||||||
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
nvmath::mat4f transform{1}; // Position of the instance
|
||||||
uint32_t txtOffset{0}; // Offset in `m_textures`
|
nvmath::mat4f transformIT{1}; // Inverse transpose
|
||||||
nvmath::mat4f transform{1}; // Position of the instance
|
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
||||||
nvmath::mat4f transformIT{1}; // Inverse transpose
|
uint32_t txtOffset{0}; // Offset in `m_textures`
|
||||||
|
VkDeviceAddress vertices;
|
||||||
|
VkDeviceAddress indices;
|
||||||
|
VkDeviceAddress materials;
|
||||||
|
VkDeviceAddress materialIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information pushed at each draw call
|
// Information pushed at each draw call
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ void Offscreen::updateDescriptorSet()
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
// Draw a full screen quad with the attached image
|
// Draw a full screen quad with the attached image
|
||||||
//
|
//
|
||||||
void Offscreen::draw(VkCommandBuffer cmdBuf, VkExtent2D& size)
|
void Offscreen::draw(VkCommandBuffer cmdBuf, const VkExtent2D& size)
|
||||||
{
|
{
|
||||||
m_debug.beginLabel(cmdBuf, "Post");
|
m_debug.beginLabel(cmdBuf, "Post");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public:
|
||||||
void createPipeline(VkRenderPass& renderPass);
|
void createPipeline(VkRenderPass& renderPass);
|
||||||
void createDescriptor();
|
void createDescriptor();
|
||||||
void updateDescriptorSet();
|
void updateDescriptorSet();
|
||||||
void draw(VkCommandBuffer cmdBuf, VkExtent2D& size);
|
void draw(VkCommandBuffer cmdBuf, const VkExtent2D& size);
|
||||||
|
|
||||||
const VkRenderPass& renderPass() { return m_renderPass; }
|
const VkRenderPass& renderPass() { return m_renderPass; }
|
||||||
const VkFramebuffer& frameBuffer() { return m_framebuffer; }
|
const VkFramebuffer& frameBuffer() { return m_framebuffer; }
|
||||||
|
|
|
||||||
|
|
@ -157,12 +157,15 @@ void Raytracer::createBottomLevelAS(std::vector<ObjModel>& models, ImplInst& imp
|
||||||
void Raytracer::createTopLevelAS(std::vector<ObjInstance>& instances, ImplInst& implicitObj)
|
void Raytracer::createTopLevelAS(std::vector<ObjInstance>& instances, ImplInst& implicitObj)
|
||||||
{
|
{
|
||||||
std::vector<nvvk::RaytracingBuilderKHR::Instance> tlas;
|
std::vector<nvvk::RaytracingBuilderKHR::Instance> tlas;
|
||||||
|
|
||||||
|
|
||||||
|
auto nbObj = static_cast<uint32_t>(instances.size()) - 1; // minus the implicit (for material)
|
||||||
tlas.reserve(instances.size());
|
tlas.reserve(instances.size());
|
||||||
for(int i = 0; i < static_cast<int>(instances.size()); i++)
|
for(uint32_t i = 0; i < nbObj; i++)
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = instances[i].transform; // Position of the instance
|
rayInst.transform = instances[i].transform; // Position of the instance
|
||||||
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
rayInst.instanceCustomId = instances[i].objIndex; // gl_InstanceCustomIndexEXT
|
||||||
rayInst.blasId = instances[i].objIndex;
|
rayInst.blasId = instances[i].objIndex;
|
||||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
|
|
@ -173,8 +176,8 @@ void Raytracer::createTopLevelAS(std::vector<ObjInstance>& instances, ImplInst&
|
||||||
if(!implicitObj.objImpl.empty())
|
if(!implicitObj.objImpl.empty())
|
||||||
{
|
{
|
||||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||||
rayInst.transform = implicitObj.transform; // Position of the instance
|
rayInst.transform = implicitObj.transform; // Position of the instance
|
||||||
rayInst.instanceCustomId = static_cast<uint32_t>(implicitObj.blasId); // Same for material index
|
rayInst.instanceCustomId = nbObj; // Same for material index
|
||||||
rayInst.blasId = static_cast<uint32_t>(implicitObj.blasId);
|
rayInst.blasId = static_cast<uint32_t>(implicitObj.blasId);
|
||||||
rayInst.hitGroupId = 1; // We will use the same hit group for all objects (the second one)
|
rayInst.hitGroupId = 1; // We will use the same hit group for all objects (the second one)
|
||||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -40,37 +43,38 @@ pushC;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Incoming
|
// Incoming
|
||||||
//layout(location = 0) flat in int matIndex;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
layout(location = 2) in vec3 fragNormal;
|
layout(location = 2) in vec3 fragNormal;
|
||||||
layout(location = 3) in vec3 viewDir;
|
layout(location = 3) in vec3 viewDir;
|
||||||
layout(location = 4) in vec3 worldPos;
|
layout(location = 4) in vec3 worldPos;
|
||||||
// Outgoing
|
// Outgoing
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
// Buffers
|
|
||||||
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 3) uniform sampler2D[] textureSamplers;
|
|
||||||
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
|
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 2) uniform sampler2D[] textureSamplers;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||||
|
WaveFrontMaterial mat = materials.m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
// Vector toward light
|
// Vector toward light
|
||||||
vec3 LightDir;
|
vec3 LightDir;
|
||||||
float lightIntensity;
|
float lightIntensity;
|
||||||
;
|
|
||||||
|
|
||||||
// Point light
|
// Point light
|
||||||
if(pushC.lightType == 0)
|
if(pushC.lightType == 0)
|
||||||
|
|
@ -101,7 +105,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, LightDir, N);
|
vec3 diffuse = computeDiffuse(mat, LightDir, N);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460 core
|
#version 460 core
|
||||||
#extension GL_EXT_ray_tracing : enable
|
#extension GL_EXT_ray_tracing : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460 core
|
#version 460 core
|
||||||
#extension GL_EXT_ray_tracing : enable
|
#extension GL_EXT_ray_tracing : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460 core
|
#version 460 core
|
||||||
#extension GL_EXT_ray_tracing : enable
|
#extension GL_EXT_ray_tracing : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
|
|
@ -29,6 +29,6 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 outUV;
|
layout(location = 0) in vec2 outUV;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Generate a random unsigned int from two unsigned int values, using 16 pairs
|
// Generate a random unsigned int from two unsigned int values, using 16 pairs
|
||||||
// of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis,
|
// of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis,
|
||||||
// "GPU Random Numbers via the Tiny Encryption Algorithm"
|
// "GPU Random Numbers via the Tiny Encryption Algorithm"
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,14 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "random.glsl"
|
#include "random.glsl"
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
|
|
@ -30,19 +32,22 @@
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
|
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
// Material of the object
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
|
||||||
|
|
||||||
if(mat.illum != 4)
|
if(mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs;
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
layout(location = 1) rayPayloadEXT bool isShadowed;
|
layout(location = 1) rayPayloadEXT bool isShadowed;
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||||
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
|
||||||
|
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
|
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(push_constant) uniform Constants
|
layout(push_constant) uniform Constants
|
||||||
|
|
@ -60,30 +61,33 @@ layout(location = 3) callableDataEXT rayLight cLight;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
Indices indices = Indices(objResource.indexAddress);
|
||||||
|
Vertices vertices = Vertices(objResource.vertexAddress);
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = indices.i[gl_PrimitiveID];
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
Vertex v0 = vertices.v[ind.x];
|
||||||
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
Vertex v1 = vertices.v[ind.y];
|
||||||
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
Vertex v2 = vertices.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);
|
||||||
|
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// Transforming the normal to world space
|
||||||
normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
||||||
|
|
||||||
|
|
||||||
// Computing the coordinates of the hit position
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// Transforming the position to world space
|
||||||
worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
||||||
|
|
||||||
cLight.inHitPosition = worldPos;
|
cLight.inHitPosition = worldPos;
|
||||||
//#define DONT_USE_CALLABLE
|
//#define DONT_USE_CALLABLE
|
||||||
|
|
@ -101,12 +105,11 @@ void main()
|
||||||
{
|
{
|
||||||
vec3 lDir = pushC.lightPosition - cLight.inHitPosition;
|
vec3 lDir = pushC.lightPosition - cLight.inHitPosition;
|
||||||
cLight.outLightDistance = length(lDir);
|
cLight.outLightDistance = length(lDir);
|
||||||
cLight.outIntensity =
|
cLight.outIntensity = pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||||
pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
cLight.outLightDir = normalize(lDir);
|
||||||
cLight.outLightDir = normalize(lDir);
|
float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection));
|
||||||
float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection));
|
float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff;
|
||||||
float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff;
|
float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||||
float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
|
||||||
cLight.outIntensity *= spotIntensity;
|
cLight.outIntensity *= spotIntensity;
|
||||||
}
|
}
|
||||||
else // Directional light
|
else // Directional light
|
||||||
|
|
@ -120,17 +123,16 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal);
|
vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
@ -55,9 +55,8 @@ const int NBSAMPLES = 5;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Initialize the random number
|
// Initialize the random number
|
||||||
uint seed =
|
uint seed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pushC.frame * NBSAMPLES);
|
||||||
tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pushC.frame * NBSAMPLES);
|
prd.seed = seed;
|
||||||
prd.seed = seed;
|
|
||||||
|
|
||||||
vec3 hitValues = vec3(0);
|
vec3 hitValues = vec3(0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,21 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
hitAttributeEXT vec3 HitAttribute;
|
hitAttributeEXT vec3 HitAttribute;
|
||||||
|
|
||||||
layout(binding = 7, set = 1, scalar) buffer allImpl_
|
layout(binding = 3, set = 1, scalar) buffer allImpl_
|
||||||
{
|
{
|
||||||
Implicit i[];
|
Implicit i[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,14 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "random.glsl"
|
#include "random.glsl"
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
|
|
@ -30,15 +32,23 @@
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
|
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
layout(binding = 7, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 3, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
void main()
|
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[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId];
|
|
||||||
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
WaveFrontMaterial mat = materials.m[impl.matId];
|
||||||
|
|
||||||
if(mat.illum != 4)
|
if(mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,15 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
@ -33,14 +36,13 @@ layout(location = 1) rayPayloadEXT bool isShadowed;
|
||||||
|
|
||||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||||
|
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
|
||||||
|
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
layout(binding = 7, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 3, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
@ -93,7 +95,9 @@ void main()
|
||||||
executeCallableEXT(pushC.lightType, 3);
|
executeCallableEXT(pushC.lightType, 3);
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId];
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
WaveFrontMaterial mat = materials.m[impl.matId];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject
|
layout(binding = 0) uniform UniformBufferObject
|
||||||
|
|
@ -68,8 +70,8 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
|
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
|
||||||
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
|
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
|
||||||
|
|
||||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,17 @@ struct WaveFrontMaterial
|
||||||
int textureId;
|
int textureId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sceneDesc
|
struct SceneDesc
|
||||||
{
|
{
|
||||||
int objId;
|
|
||||||
int txtOffset;
|
|
||||||
mat4 transfo;
|
mat4 transfo;
|
||||||
mat4 transfoIT;
|
mat4 transfoIT;
|
||||||
|
int objId;
|
||||||
|
int txtOffset;
|
||||||
|
|
||||||
|
uint64_t vertexAddress;
|
||||||
|
uint64_t indexAddress;
|
||||||
|
uint64_t materialAddress;
|
||||||
|
uint64_t materialIndexAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ compile_glsl_directory(
|
||||||
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
||||||
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
||||||
VULKAN_TARGET "vulkan1.2"
|
VULKAN_TARGET "vulkan1.2"
|
||||||
|
DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS})
|
||||||
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
||||||
source_group("Sources" FILES ${SOURCE_FILES})
|
source_group("Sources" FILES ${SOURCE_FILES})
|
||||||
source_group("Headers" FILES ${HEADER_FILES})
|
source_group("Headers" FILES ${HEADER_FILES})
|
||||||
source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
source_group("Shader Sources" FILES ${GLSL_SOURCES})
|
||||||
|
source_group("Shader Headers" FILES ${GLSL_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "nvvk/pipeline_vk.hpp"
|
#include "nvvk/pipeline_vk.hpp"
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
#include "nvvk/shaders_vk.hpp"
|
#include "nvvk/shaders_vk.hpp"
|
||||||
|
#include "nvvk/buffers_vk.hpp"
|
||||||
|
|
||||||
extern std::vector<std::string> defaultSearchPaths;
|
extern std::vector<std::string> defaultSearchPaths;
|
||||||
|
|
||||||
|
|
@ -108,18 +109,13 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
||||||
void HelloVulkan::createDescriptorSetLayout()
|
void HelloVulkan::createDescriptorSetLayout()
|
||||||
{
|
{
|
||||||
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
||||||
auto nbObj = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
|
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
// Scene description (binding = 2)
|
// Textures (binding = 2)
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
// Textures (binding = 3)
|
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
||||||
|
|
||||||
|
|
||||||
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
||||||
|
|
@ -137,19 +133,9 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
// Camera matrices and scene description
|
// Camera matrices and scene description
|
||||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
||||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc));
|
|
||||||
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
|
|
||||||
// All texture samplers
|
// All texture samplers
|
||||||
std::vector<VkDescriptorImageInfo> diit;
|
std::vector<VkDescriptorImageInfo> diit;
|
||||||
|
|
@ -157,7 +143,7 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
{
|
{
|
||||||
diit.emplace_back(texture.descriptor);
|
diit.emplace_back(texture.descriptor);
|
||||||
}
|
}
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data()));
|
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||||
|
|
||||||
// Writing the information
|
// Writing the information
|
||||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||||
|
|
@ -215,34 +201,40 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
||||||
m.specular = nvmath::pow(m.specular, 2.2f);
|
m.specular = nvmath::pow(m.specular, 2.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjInstance instance;
|
|
||||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
instance.transform = transform;
|
|
||||||
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
|
||||||
instance.txtOffset = static_cast<uint32_t>(m_textures.size());
|
|
||||||
|
|
||||||
ObjModel model;
|
ObjModel model;
|
||||||
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
||||||
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
||||||
|
|
||||||
// Create the buffers on Device and copy vertices, indices and materials
|
// Create the buffers on Device and copy vertices, indices and materials
|
||||||
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
||||||
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | flag);
|
||||||
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | flag);
|
||||||
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
// Creates all textures found
|
// Creates all textures found
|
||||||
|
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
|
||||||
createTextureImages(cmdBuf, loader.m_textures);
|
createTextureImages(cmdBuf, loader.m_textures);
|
||||||
cmdBufGet.submitAndWait(cmdBuf);
|
cmdBufGet.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
|
|
||||||
std::string objNb = std::to_string(instance.objIndex);
|
std::string objNb = std::to_string(m_objModel.size());
|
||||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
||||||
|
|
||||||
|
ObjInstance instance;
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.transform = transform;
|
||||||
|
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
||||||
|
instance.txtOffset = txtOffset;
|
||||||
|
instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
|
instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||||
|
instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||||
|
|
||||||
m_objModel.emplace_back(model);
|
m_objModel.emplace_back(model);
|
||||||
m_objInstance.emplace_back(instance);
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,14 @@ public:
|
||||||
// Instance of the OBJ
|
// Instance of the OBJ
|
||||||
struct ObjInstance
|
struct ObjInstance
|
||||||
{
|
{
|
||||||
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
nvmath::mat4f transform{1}; // Position of the instance
|
||||||
uint32_t txtOffset{0}; // Offset in `m_textures`
|
nvmath::mat4f transformIT{1}; // Inverse transpose
|
||||||
nvmath::mat4f transform{1}; // Position of the instance
|
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
||||||
nvmath::mat4f transformIT{1}; // Inverse transpose
|
uint32_t txtOffset{0}; // Offset in `m_textures`
|
||||||
|
VkDeviceAddress vertices;
|
||||||
|
VkDeviceAddress indices;
|
||||||
|
VkDeviceAddress materials;
|
||||||
|
VkDeviceAddress materialIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information pushed at each draw call
|
// Information pushed at each draw call
|
||||||
|
|
@ -90,9 +94,10 @@ public:
|
||||||
VkDescriptorSetLayout m_descSetLayout;
|
VkDescriptorSetLayout m_descSetLayout;
|
||||||
VkDescriptorSet m_descSet;
|
VkDescriptorSet m_descSet;
|
||||||
|
|
||||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
|
||||||
|
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||||
|
|
||||||
|
|
||||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||||
|
|
|
||||||
|
|
@ -110,24 +110,19 @@ int main(int argc, char** argv)
|
||||||
std::string(PROJECT_NAME),
|
std::string(PROJECT_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan required extensions
|
||||||
|
assert(glfwVulkanSupported() == 1);
|
||||||
|
uint32_t count{0};
|
||||||
|
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo;
|
nvvk::ContextCreateInfo contextInfo;
|
||||||
contextInfo.setVersion(1, 2);
|
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
|
||||||
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
|
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
|
||||||
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
|
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
|
||||||
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
|
||||||
#ifdef _WIN32
|
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
|
||||||
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
|
||||||
#else
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// Creating Vulkan base application
|
// Creating Vulkan base application
|
||||||
nvvk::Context vkctx{};
|
nvvk::Context vkctx{};
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,30 +40,35 @@ pushC;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Incoming
|
// Incoming
|
||||||
//layout(location = 0) flat in int matIndex;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
layout(location = 2) in vec3 fragNormal;
|
layout(location = 2) in vec3 fragNormal;
|
||||||
layout(location = 3) in vec3 viewDir;
|
layout(location = 3) in vec3 viewDir;
|
||||||
layout(location = 4) in vec3 worldPos;
|
layout(location = 4) in vec3 worldPos;
|
||||||
// Outgoing
|
// Outgoing
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
// Buffers
|
|
||||||
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 3) uniform sampler2D[] textureSamplers;
|
|
||||||
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
|
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 2) uniform sampler2D[] textureSamplers;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = sceneDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||||
|
WaveFrontMaterial mat = materials.m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -84,7 +92,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, N);
|
vec3 diffuse = computeDiffuse(mat, L, N);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
|
|
@ -29,6 +29,6 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 outUV;
|
layout(location = 0) in vec2 outUV;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject
|
layout(binding = 0) uniform UniformBufferObject
|
||||||
|
|
@ -65,8 +67,8 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
|
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
|
||||||
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
|
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
|
||||||
|
|
||||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,17 @@ struct WaveFrontMaterial
|
||||||
int textureId;
|
int textureId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sceneDesc
|
struct SceneDesc
|
||||||
{
|
{
|
||||||
int objId;
|
|
||||||
int txtOffset;
|
|
||||||
mat4 transfo;
|
mat4 transfo;
|
||||||
mat4 transfoIT;
|
mat4 transfoIT;
|
||||||
|
int objId;
|
||||||
|
int txtOffset;
|
||||||
|
|
||||||
|
uint64_t vertexAddress;
|
||||||
|
uint64_t indexAddress;
|
||||||
|
uint64_t materialAddress;
|
||||||
|
uint64_t materialIndexAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ compile_glsl_directory(
|
||||||
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
||||||
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
||||||
VULKAN_TARGET "vulkan1.2"
|
VULKAN_TARGET "vulkan1.2"
|
||||||
|
DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS})
|
||||||
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
||||||
source_group("Sources" FILES ${SOURCE_FILES})
|
source_group("Sources" FILES ${SOURCE_FILES})
|
||||||
source_group("Headers" FILES ${HEADER_FILES})
|
source_group("Headers" FILES ${HEADER_FILES})
|
||||||
source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
source_group("Shader Sources" FILES ${GLSL_SOURCES})
|
||||||
|
source_group("Shader Headers" FILES ${GLSL_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "nvvk/pipeline_vk.hpp"
|
#include "nvvk/pipeline_vk.hpp"
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
#include "nvvk/shaders_vk.hpp"
|
#include "nvvk/shaders_vk.hpp"
|
||||||
|
#include "nvvk/buffers_vk.hpp"
|
||||||
|
|
||||||
extern std::vector<std::string> defaultSearchPaths;
|
extern std::vector<std::string> defaultSearchPaths;
|
||||||
|
|
||||||
|
|
@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
||||||
void HelloVulkan::createDescriptorSetLayout()
|
void HelloVulkan::createDescriptorSetLayout()
|
||||||
{
|
{
|
||||||
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
||||||
auto nbObj = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
|
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Scene description (binding = 2)
|
// Textures (binding = 2)
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Textures (binding = 3)
|
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing vertices (binding = 5)
|
|
||||||
m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing indices (binding = 6)
|
|
||||||
m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
|
|
||||||
|
|
||||||
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
||||||
|
|
@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
// Camera matrices and scene description
|
// Camera matrices and scene description
|
||||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
||||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc));
|
|
||||||
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiVert;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data()));
|
|
||||||
|
|
||||||
// All texture samplers
|
// All texture samplers
|
||||||
std::vector<VkDescriptorImageInfo> diit;
|
std::vector<VkDescriptorImageInfo> diit;
|
||||||
|
|
@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
{
|
{
|
||||||
diit.emplace_back(texture.descriptor);
|
diit.emplace_back(texture.descriptor);
|
||||||
}
|
}
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data()));
|
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||||
|
|
||||||
// Writing the information
|
// Writing the information
|
||||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||||
|
|
@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
||||||
m.specular = nvmath::pow(m.specular, 2.2f);
|
m.specular = nvmath::pow(m.specular, 2.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjInstance instance;
|
|
||||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
instance.transform = transform;
|
|
||||||
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
|
||||||
instance.txtOffset = static_cast<uint32_t>(m_textures.size());
|
|
||||||
|
|
||||||
ObjModel model;
|
ObjModel model;
|
||||||
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
||||||
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
||||||
|
|
||||||
// Create the buffers on Device and copy vertices, indices and materials
|
// Create the buffers on Device and copy vertices, indices and materials
|
||||||
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
||||||
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
||||||
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
|
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
// Creates all textures found
|
// Creates all textures found
|
||||||
|
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
|
||||||
createTextureImages(cmdBuf, loader.m_textures);
|
createTextureImages(cmdBuf, loader.m_textures);
|
||||||
cmdBufGet.submitAndWait(cmdBuf);
|
cmdBufGet.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
|
|
||||||
std::string objNb = std::to_string(instance.objIndex);
|
std::string objNb = std::to_string(m_objModel.size());
|
||||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
||||||
|
|
||||||
|
ObjInstance instance;
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.transform = transform;
|
||||||
|
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
||||||
|
instance.txtOffset = txtOffset;
|
||||||
|
instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
|
instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||||
|
instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||||
|
|
||||||
m_objModel.emplace_back(model);
|
m_objModel.emplace_back(model);
|
||||||
m_objInstance.emplace_back(instance);
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
@ -625,11 +605,8 @@ void HelloVulkan::initRayTracing()
|
||||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||||
{
|
{
|
||||||
// BLAS builder requires raw device addresses.
|
// BLAS builder requires raw device addresses.
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
info.buffer = model.vertexBuffer.buffer;
|
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
info.buffer = model.indexBuffer.buffer;
|
|
||||||
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
||||||
|
|
||||||
|
|
@ -928,9 +905,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c
|
||||||
uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
||||||
uint32_t groupStride = groupSize;
|
uint32_t groupStride = groupSize;
|
||||||
|
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress sbtAddress = nvvk::getBufferDeviceAddress(m_device, m_rtSBTBuffer.buffer);
|
||||||
info.buffer = m_rtSBTBuffer.buffer;
|
|
||||||
VkDeviceAddress sbtAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
using Stride = VkStridedDeviceAddressRegionKHR;
|
using Stride = VkStridedDeviceAddressRegionKHR;
|
||||||
std::array<Stride, 4> strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen
|
std::array<Stride, 4> strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,14 @@ public:
|
||||||
// Instance of the OBJ
|
// Instance of the OBJ
|
||||||
struct ObjInstance
|
struct ObjInstance
|
||||||
{
|
{
|
||||||
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
nvmath::mat4f transform{1}; // Position of the instance
|
||||||
uint32_t txtOffset{0}; // Offset in `m_textures`
|
nvmath::mat4f transformIT{1}; // Inverse transpose
|
||||||
nvmath::mat4f transform{1}; // Position of the instance
|
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
||||||
nvmath::mat4f transformIT{1}; // Inverse transpose
|
uint32_t txtOffset{0}; // Offset in `m_textures`
|
||||||
|
VkDeviceAddress vertices;
|
||||||
|
VkDeviceAddress indices;
|
||||||
|
VkDeviceAddress materials;
|
||||||
|
VkDeviceAddress materialIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information pushed at each draw call
|
// Information pushed at each draw call
|
||||||
|
|
@ -93,9 +97,10 @@ public:
|
||||||
VkDescriptorSetLayout m_descSetLayout;
|
VkDescriptorSetLayout m_descSetLayout;
|
||||||
VkDescriptorSet m_descSet;
|
VkDescriptorSet m_descSet;
|
||||||
|
|
||||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
|
||||||
|
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||||
|
|
||||||
|
|
||||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ int main(int argc, char** argv)
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr);
|
GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr);
|
||||||
|
|
||||||
|
|
||||||
// Setup camera
|
// Setup camera
|
||||||
CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT);
|
CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT);
|
||||||
CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
||||||
|
|
@ -109,34 +110,26 @@ int main(int argc, char** argv)
|
||||||
std::string(PROJECT_NAME),
|
std::string(PROJECT_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan required extensions
|
||||||
|
assert(glfwVulkanSupported() == 1);
|
||||||
|
uint32_t count{0};
|
||||||
|
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo(true);
|
nvvk::ContextCreateInfo contextInfo;
|
||||||
contextInfo.setVersion(1, 2);
|
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
|
||||||
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
|
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
|
||||||
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
|
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
|
||||||
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
|
||||||
#ifdef _WIN32
|
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
|
||||||
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
|
||||||
#else
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature);
|
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures
|
||||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// Creating Vulkan base application
|
// Creating Vulkan base application
|
||||||
nvvk::Context vkctx{};
|
nvvk::Context vkctx{};
|
||||||
|
|
@ -167,7 +160,6 @@ int main(int argc, char** argv)
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true));
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true));
|
||||||
|
|
||||||
|
|
||||||
helloVk.createOffscreenRender();
|
helloVk.createOffscreenRender();
|
||||||
helloVk.createDescriptorSetLayout();
|
helloVk.createDescriptorSetLayout();
|
||||||
helloVk.createGraphicsPipeline();
|
helloVk.createGraphicsPipeline();
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,30 +40,32 @@ pushC;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Incoming
|
// Incoming
|
||||||
//layout(location = 0) flat in int matIndex;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
layout(location = 2) in vec3 fragNormal;
|
layout(location = 2) in vec3 fragNormal;
|
||||||
layout(location = 3) in vec3 viewDir;
|
layout(location = 3) in vec3 viewDir;
|
||||||
layout(location = 4) in vec3 worldPos;
|
layout(location = 4) in vec3 worldPos;
|
||||||
// Outgoing
|
// Outgoing
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
// Buffers
|
|
||||||
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 3) uniform sampler2D[] textureSamplers;
|
|
||||||
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
|
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 2) uniform sampler2D[] textureSamplers;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||||
|
WaveFrontMaterial mat = materials.m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -84,7 +89,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, N);
|
vec3 diffuse = computeDiffuse(mat, L, N);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
|
|
@ -29,6 +29,6 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 outUV;
|
layout(location = 0) in vec2 outUV;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
@ -31,14 +35,13 @@ hitAttributeEXT vec2 attribs;
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
layout(location = 1) rayPayloadEXT bool isShadowed;
|
layout(location = 1) rayPayloadEXT bool isShadowed;
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||||
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
|
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(push_constant) uniform Constants
|
layout(push_constant) uniform Constants
|
||||||
|
|
@ -53,30 +56,33 @@ pushC;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
Indices indices = Indices(objResource.indexAddress);
|
||||||
|
Vertices vertices = Vertices(objResource.vertexAddress);
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = indices.i[gl_PrimitiveID];
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
Vertex v0 = vertices.v[ind.x];
|
||||||
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
Vertex v1 = vertices.v[ind.y];
|
||||||
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
Vertex v2 = vertices.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);
|
||||||
|
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// Transforming the normal to world space
|
||||||
normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
||||||
|
|
||||||
|
|
||||||
// Computing the coordinates of the hit position
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// Transforming the position to world space
|
||||||
worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
||||||
|
|
||||||
// Vector toward the light
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -96,17 +102,16 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,9 +125,8 @@ void main()
|
||||||
float tMax = lightDistance;
|
float tMax = lightDistance;
|
||||||
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
||||||
vec3 rayDir = L;
|
vec3 rayDir = L;
|
||||||
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT
|
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||||
| gl_RayFlagsSkipClosestHitShaderEXT;
|
isShadowed = true;
|
||||||
isShadowed = true;
|
|
||||||
traceRayEXT(topLevelAS, // acceleration structure
|
traceRayEXT(topLevelAS, // acceleration structure
|
||||||
flags, // rayFlags
|
flags, // rayFlags
|
||||||
0xFF, // cullMask
|
0xFF, // cullMask
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject
|
layout(binding = 0) uniform UniformBufferObject
|
||||||
|
|
@ -65,8 +67,8 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
|
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
|
||||||
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
|
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
|
||||||
|
|
||||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,17 @@ struct WaveFrontMaterial
|
||||||
int textureId;
|
int textureId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sceneDesc
|
struct SceneDesc
|
||||||
{
|
{
|
||||||
int objId;
|
|
||||||
int txtOffset;
|
|
||||||
mat4 transfo;
|
mat4 transfo;
|
||||||
mat4 transfoIT;
|
mat4 transfoIT;
|
||||||
|
int objId;
|
||||||
|
int txtOffset;
|
||||||
|
|
||||||
|
uint64_t vertexAddress;
|
||||||
|
uint64_t indexAddress;
|
||||||
|
uint64_t materialAddress;
|
||||||
|
uint64_t materialIndexAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ compile_glsl_directory(
|
||||||
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
||||||
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
||||||
VULKAN_TARGET "vulkan1.2"
|
VULKAN_TARGET "vulkan1.2"
|
||||||
|
DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS})
|
||||||
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
||||||
source_group("Sources" FILES ${SOURCE_FILES})
|
source_group("Sources" FILES ${SOURCE_FILES})
|
||||||
source_group("Headers" FILES ${HEADER_FILES})
|
source_group("Headers" FILES ${HEADER_FILES})
|
||||||
source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
source_group("Shader Sources" FILES ${GLSL_SOURCES})
|
||||||
|
source_group("Shader Headers" FILES ${GLSL_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,12 @@ Using monolithic pipeline definitions all stages are compiled for each pipeline,
|
||||||
Pipeline libraries are `VkPipeline` objects that cannot be bound directly. Instead, they can be compiled once and linked into as many pipelines as necessary. The Shader Binding Table of the resulting pipeline references the shader groups of the library as if they had been appended to the groups and stages in the main `VkRayTracingPipelineCreateInfo`
|
Pipeline libraries are `VkPipeline` objects that cannot be bound directly. Instead, they can be compiled once and linked into as many pipelines as necessary. The Shader Binding Table of the resulting pipeline references the shader groups of the library as if they had been appended to the groups and stages in the main `VkRayTracingPipelineCreateInfo`
|
||||||

|

|
||||||
|
|
||||||
We start by adding a new member in the `HelloVulkan` class:
|
We start by adding the device extension in main()
|
||||||
|
~~~~ C
|
||||||
|
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
Following by adding a new member in the `HelloVulkan` class:
|
||||||
~~~~ C
|
~~~~ C
|
||||||
// Ray tracing shader library
|
// Ray tracing shader library
|
||||||
VkPipeline m_rtShaderLibrary;
|
VkPipeline m_rtShaderLibrary;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include "nvvk/pipeline_vk.hpp"
|
#include "nvvk/pipeline_vk.hpp"
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
#include "nvvk/shaders_vk.hpp"
|
#include "nvvk/shaders_vk.hpp"
|
||||||
|
#include "nvvk/buffers_vk.hpp"
|
||||||
// Support for C++ multithreading
|
// Support for C++ multithreading
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
|
|
@ -116,26 +117,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
||||||
void HelloVulkan::createDescriptorSetLayout()
|
void HelloVulkan::createDescriptorSetLayout()
|
||||||
{
|
{
|
||||||
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
||||||
auto nbObj = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
|
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Scene description (binding = 2)
|
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Textures (binding = 3)
|
// Textures (binding = 3)
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing vertices (binding = 5)
|
|
||||||
m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing indices (binding = 6)
|
|
||||||
m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
|
|
||||||
|
|
||||||
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
||||||
|
|
@ -153,25 +143,9 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
// Camera matrices and scene description
|
// Camera matrices and scene description
|
||||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
||||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc));
|
|
||||||
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiVert;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data()));
|
|
||||||
|
|
||||||
// All texture samplers
|
// All texture samplers
|
||||||
std::vector<VkDescriptorImageInfo> diit;
|
std::vector<VkDescriptorImageInfo> diit;
|
||||||
|
|
@ -179,7 +153,7 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
{
|
{
|
||||||
diit.emplace_back(texture.descriptor);
|
diit.emplace_back(texture.descriptor);
|
||||||
}
|
}
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data()));
|
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||||
|
|
||||||
// Writing the information
|
// Writing the information
|
||||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||||
|
|
@ -237,36 +211,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
||||||
m.specular = nvmath::pow(m.specular, 2.2f);
|
m.specular = nvmath::pow(m.specular, 2.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjInstance instance;
|
|
||||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
instance.transform = transform;
|
|
||||||
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
|
||||||
instance.txtOffset = static_cast<uint32_t>(m_textures.size());
|
|
||||||
|
|
||||||
ObjModel model;
|
ObjModel model;
|
||||||
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
||||||
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
||||||
|
|
||||||
// Create the buffers on Device and copy vertices, indices and materials
|
// Create the buffers on Device and copy vertices, indices and materials
|
||||||
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
||||||
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
||||||
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
|
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
// Creates all textures found
|
// Creates all textures found
|
||||||
|
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
|
||||||
createTextureImages(cmdBuf, loader.m_textures);
|
createTextureImages(cmdBuf, loader.m_textures);
|
||||||
cmdBufGet.submitAndWait(cmdBuf);
|
cmdBufGet.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
|
|
||||||
std::string objNb = std::to_string(instance.objIndex);
|
std::string objNb = std::to_string(m_objModel.size());
|
||||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
||||||
|
|
||||||
|
ObjInstance instance;
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.transform = transform;
|
||||||
|
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
||||||
|
instance.txtOffset = txtOffset;
|
||||||
|
instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
|
instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||||
|
instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||||
|
|
||||||
m_objModel.emplace_back(model);
|
m_objModel.emplace_back(model);
|
||||||
m_objInstance.emplace_back(instance);
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
@ -631,11 +611,8 @@ void HelloVulkan::initRayTracing()
|
||||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||||
{
|
{
|
||||||
// BLAS builder requires raw device addresses.
|
// BLAS builder requires raw device addresses.
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
info.buffer = model.vertexBuffer.buffer;
|
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
info.buffer = model.indexBuffer.buffer;
|
|
||||||
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
||||||
|
|
||||||
|
|
@ -920,7 +897,7 @@ void HelloVulkan::createRtPipeline()
|
||||||
pipelineLibraryInfo.layout = m_rtPipelineLayout;
|
pipelineLibraryInfo.layout = m_rtPipelineLayout;
|
||||||
// As for the interface the maximum recursion depth must also be consistent across the pipeline
|
// As for the interface the maximum recursion depth must also be consistent across the pipeline
|
||||||
pipelineLibraryInfo.maxPipelineRayRecursionDepth = 2;
|
pipelineLibraryInfo.maxPipelineRayRecursionDepth = 2;
|
||||||
|
|
||||||
// Pipeline libraries need to define an interface, defined by the maximum hit attribute size (typically 2 for
|
// Pipeline libraries need to define an interface, defined by the maximum hit attribute size (typically 2 for
|
||||||
// the built-in triangle intersector) and the maximum payload size (3 floating-point values in this sample).
|
// the built-in triangle intersector) and the maximum payload size (3 floating-point values in this sample).
|
||||||
// Pipeline libraries can be linked into a final pipeline only if their interface matches
|
// Pipeline libraries can be linked into a final pipeline only if their interface matches
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,14 @@ public:
|
||||||
// Instance of the OBJ
|
// Instance of the OBJ
|
||||||
struct ObjInstance
|
struct ObjInstance
|
||||||
{
|
{
|
||||||
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
nvmath::mat4f transform{1}; // Position of the instance
|
||||||
uint32_t txtOffset{0}; // Offset in `m_textures`
|
nvmath::mat4f transformIT{1}; // Inverse transpose
|
||||||
nvmath::mat4f transform{1}; // Position of the instance
|
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
||||||
nvmath::mat4f transformIT{1}; // Inverse transpose
|
uint32_t txtOffset{0}; // Offset in `m_textures`
|
||||||
|
VkDeviceAddress vertices;
|
||||||
|
VkDeviceAddress indices;
|
||||||
|
VkDeviceAddress materials;
|
||||||
|
VkDeviceAddress materialIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information pushed at each draw call
|
// Information pushed at each draw call
|
||||||
|
|
@ -95,9 +99,11 @@ public:
|
||||||
VkDescriptorSetLayout m_descSetLayout;
|
VkDescriptorSetLayout m_descSetLayout;
|
||||||
VkDescriptorSet m_descSet;
|
VkDescriptorSet m_descSet;
|
||||||
|
|
||||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
nvvk::Buffer m_bufReference; // Buffer references of the OBJ
|
||||||
|
|
||||||
|
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||||
|
|
||||||
|
|
||||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||||
|
|
@ -146,7 +152,7 @@ public:
|
||||||
VkPipeline m_rtPipeline;
|
VkPipeline m_rtPipeline;
|
||||||
nvvk::SBTWrapper m_sbtWrapper;
|
nvvk::SBTWrapper m_sbtWrapper;
|
||||||
// Ray tracing shader library
|
// Ray tracing shader library
|
||||||
VkPipeline m_rtShaderLibrary;
|
VkPipeline m_rtShaderLibrary;
|
||||||
|
|
||||||
struct RtPushConstant
|
struct RtPushConstant
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -120,34 +120,27 @@ int main(int argc, char** argv)
|
||||||
std::string(PROJECT_NAME),
|
std::string(PROJECT_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan required extensions
|
||||||
|
assert(glfwVulkanSupported() == 1);
|
||||||
|
uint32_t count{0};
|
||||||
|
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo;
|
nvvk::ContextCreateInfo contextInfo;
|
||||||
contextInfo.setVersion(1, 2);
|
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
|
||||||
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
|
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
|
||||||
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
|
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
|
||||||
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
|
||||||
#ifdef _WIN32
|
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
|
||||||
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
|
||||||
#else
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature);
|
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures
|
||||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
|
||||||
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_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// Creating Vulkan base application
|
// Creating Vulkan base application
|
||||||
nvvk::Context vkctx{};
|
nvvk::Context vkctx{};
|
||||||
|
|
@ -178,7 +171,6 @@ int main(int argc, char** argv)
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true));
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true));
|
||||||
|
|
||||||
|
|
||||||
helloVk.createOffscreenRender();
|
helloVk.createOffscreenRender();
|
||||||
helloVk.createDescriptorSetLayout();
|
helloVk.createDescriptorSetLayout();
|
||||||
helloVk.createGraphicsPipeline();
|
helloVk.createGraphicsPipeline();
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,30 +40,35 @@ pushC;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Incoming
|
// Incoming
|
||||||
//layout(location = 0) flat in int matIndex;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
layout(location = 2) in vec3 fragNormal;
|
layout(location = 2) in vec3 fragNormal;
|
||||||
layout(location = 3) in vec3 viewDir;
|
layout(location = 3) in vec3 viewDir;
|
||||||
layout(location = 4) in vec3 worldPos;
|
layout(location = 4) in vec3 worldPos;
|
||||||
// Outgoing
|
// Outgoing
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
// Buffers
|
|
||||||
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 3) uniform sampler2D[] textureSamplers;
|
|
||||||
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
|
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 2) uniform sampler2D[] textureSamplers;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object of this instance
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
int objId = sceneDesc.i[pushC.instanceId].objId;
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||||
|
WaveFrontMaterial mat = materials.m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -84,7 +92,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, N);
|
vec3 diffuse = computeDiffuse(mat, L, N);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
|
|
@ -29,6 +29,6 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 outUV;
|
layout(location = 0) in vec2 outUV;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
@ -31,15 +35,13 @@ hitAttributeEXT vec2 attribs;
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
layout(location = 1) rayPayloadEXT bool isShadowed;
|
layout(location = 1) rayPayloadEXT bool isShadowed;
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||||
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
|
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
|
||||||
|
|
||||||
|
|
||||||
layout(constant_id = 0) const int USE_DIFFUSE = 1;
|
layout(constant_id = 0) const int USE_DIFFUSE = 1;
|
||||||
layout(constant_id = 1) const int USE_SPECULAR = 1;
|
layout(constant_id = 1) const int USE_SPECULAR = 1;
|
||||||
layout(constant_id = 2) const int TRACE_SHADOW = 1;
|
layout(constant_id = 2) const int TRACE_SHADOW = 1;
|
||||||
|
|
@ -59,30 +61,33 @@ pushC;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
Indices indices = Indices(objResource.indexAddress);
|
||||||
|
Vertices vertices = Vertices(objResource.vertexAddress);
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = indices.i[gl_PrimitiveID];
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
Vertex v0 = vertices.v[ind.x];
|
||||||
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
Vertex v1 = vertices.v[ind.y];
|
||||||
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
Vertex v2 = vertices.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);
|
||||||
|
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// Transforming the normal to world space
|
||||||
normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
||||||
|
|
||||||
|
|
||||||
// Computing the coordinates of the hit position
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// Transforming the position to world space
|
||||||
worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
||||||
|
|
||||||
// Vector toward the light
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -102,8 +107,8 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -113,9 +118,8 @@ void main()
|
||||||
diffuse = computeDiffuse(mat, L, normal);
|
diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y
|
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
+ v2.texCoord * barycentrics.z;
|
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -132,9 +136,8 @@ void main()
|
||||||
float tMax = lightDistance;
|
float tMax = lightDistance;
|
||||||
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
||||||
vec3 rayDir = L;
|
vec3 rayDir = L;
|
||||||
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT
|
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||||
| gl_RayFlagsSkipClosestHitShaderEXT;
|
isShadowed = true;
|
||||||
isShadowed = true;
|
|
||||||
traceRayEXT(topLevelAS, // acceleration structure
|
traceRayEXT(topLevelAS, // acceleration structure
|
||||||
flags, // rayFlags
|
flags, // rayFlags
|
||||||
0xFF, // cullMask
|
0xFF, // cullMask
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject
|
layout(binding = 0) uniform UniformBufferObject
|
||||||
|
|
@ -65,8 +67,8 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
|
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
|
||||||
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
|
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
|
||||||
|
|
||||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,17 @@ struct WaveFrontMaterial
|
||||||
int textureId;
|
int textureId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sceneDesc
|
struct SceneDesc
|
||||||
{
|
{
|
||||||
int objId;
|
|
||||||
int txtOffset;
|
|
||||||
mat4 transfo;
|
mat4 transfo;
|
||||||
mat4 transfoIT;
|
mat4 transfoIT;
|
||||||
|
int objId;
|
||||||
|
int txtOffset;
|
||||||
|
|
||||||
|
uint64_t vertexAddress;
|
||||||
|
uint64_t indexAddress;
|
||||||
|
uint64_t materialAddress;
|
||||||
|
uint64_t materialIndexAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ compile_glsl_directory(
|
||||||
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
||||||
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
||||||
VULKAN_TARGET "vulkan1.2"
|
VULKAN_TARGET "vulkan1.2"
|
||||||
|
DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS})
|
||||||
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
||||||
source_group("Sources" FILES ${SOURCE_FILES})
|
source_group("Sources" FILES ${SOURCE_FILES})
|
||||||
source_group("Headers" FILES ${HEADER_FILES})
|
source_group("Headers" FILES ${HEADER_FILES})
|
||||||
source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
source_group("Shader Sources" FILES ${GLSL_SOURCES})
|
||||||
|
source_group("Shader Headers" FILES ${GLSL_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,7 @@ This will move each vertex up and down over time.
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
layout(binding = 0, scalar) buffer Vertices
|
layout(binding = 0, scalar) buffer Vertices
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "nvvk/pipeline_vk.hpp"
|
#include "nvvk/pipeline_vk.hpp"
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
#include "nvvk/shaders_vk.hpp"
|
#include "nvvk/shaders_vk.hpp"
|
||||||
|
#include "nvvk/buffers_vk.hpp"
|
||||||
|
|
||||||
extern std::vector<std::string> defaultSearchPaths;
|
extern std::vector<std::string> defaultSearchPaths;
|
||||||
|
|
||||||
|
|
@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
||||||
void HelloVulkan::createDescriptorSetLayout()
|
void HelloVulkan::createDescriptorSetLayout()
|
||||||
{
|
{
|
||||||
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
||||||
auto nbObj = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
|
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Scene description (binding = 2)
|
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Textures (binding = 3)
|
// Textures (binding = 3)
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing vertices (binding = 5)
|
|
||||||
m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
// Storing indices (binding = 6)
|
|
||||||
m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
|
||||||
|
|
||||||
|
|
||||||
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
||||||
|
|
@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
// Camera matrices and scene description
|
// Camera matrices and scene description
|
||||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
||||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc));
|
|
||||||
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiVert;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data()));
|
|
||||||
|
|
||||||
// All texture samplers
|
// All texture samplers
|
||||||
std::vector<VkDescriptorImageInfo> diit;
|
std::vector<VkDescriptorImageInfo> diit;
|
||||||
|
|
@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
{
|
{
|
||||||
diit.emplace_back(texture.descriptor);
|
diit.emplace_back(texture.descriptor);
|
||||||
}
|
}
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data()));
|
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||||
|
|
||||||
// Writing the information
|
// Writing the information
|
||||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||||
|
|
@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
||||||
m.specular = nvmath::pow(m.specular, 2.2f);
|
m.specular = nvmath::pow(m.specular, 2.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjInstance instance;
|
|
||||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
instance.transform = transform;
|
|
||||||
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
|
||||||
instance.txtOffset = static_cast<uint32_t>(m_textures.size());
|
|
||||||
|
|
||||||
ObjModel model;
|
ObjModel model;
|
||||||
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
||||||
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
||||||
|
|
||||||
// Create the buffers on Device and copy vertices, indices and materials
|
// Create the buffers on Device and copy vertices, indices and materials
|
||||||
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
||||||
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
||||||
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
|
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
// Creates all textures found
|
// Creates all textures found
|
||||||
|
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
|
||||||
createTextureImages(cmdBuf, loader.m_textures);
|
createTextureImages(cmdBuf, loader.m_textures);
|
||||||
cmdBufGet.submitAndWait(cmdBuf);
|
cmdBufGet.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
|
|
||||||
std::string objNb = std::to_string(instance.objIndex);
|
std::string objNb = std::to_string(m_objModel.size());
|
||||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
||||||
|
|
||||||
|
ObjInstance instance;
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.transform = transform;
|
||||||
|
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
||||||
|
instance.txtOffset = txtOffset;
|
||||||
|
instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
|
instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||||
|
instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||||
|
|
||||||
m_objModel.emplace_back(model);
|
m_objModel.emplace_back(model);
|
||||||
m_objInstance.emplace_back(instance);
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
@ -633,11 +613,8 @@ void HelloVulkan::initRayTracing()
|
||||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||||
{
|
{
|
||||||
// BLAS builder requires raw device addresses.
|
// BLAS builder requires raw device addresses.
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
info.buffer = model.vertexBuffer.buffer;
|
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
info.buffer = model.indexBuffer.buffer;
|
|
||||||
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,14 @@ public:
|
||||||
// Instance of the OBJ
|
// Instance of the OBJ
|
||||||
struct ObjInstance
|
struct ObjInstance
|
||||||
{
|
{
|
||||||
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
nvmath::mat4f transform{1}; // Position of the instance
|
||||||
uint32_t txtOffset{0}; // Offset in `m_textures`
|
nvmath::mat4f transformIT{1}; // Inverse transpose
|
||||||
nvmath::mat4f transform{1}; // Position of the instance
|
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
||||||
nvmath::mat4f transformIT{1}; // Inverse transpose
|
uint32_t txtOffset{0}; // Offset in `m_textures`
|
||||||
|
VkDeviceAddress vertices;
|
||||||
|
VkDeviceAddress indices;
|
||||||
|
VkDeviceAddress materials;
|
||||||
|
VkDeviceAddress materialIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information pushed at each draw call
|
// Information pushed at each draw call
|
||||||
|
|
@ -94,9 +98,10 @@ public:
|
||||||
VkDescriptorSetLayout m_descSetLayout;
|
VkDescriptorSetLayout m_descSetLayout;
|
||||||
VkDescriptorSet m_descSet;
|
VkDescriptorSet m_descSet;
|
||||||
|
|
||||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
|
||||||
|
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||||
|
|
||||||
|
|
||||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||||
|
|
|
||||||
|
|
@ -109,33 +109,26 @@ int main(int argc, char** argv)
|
||||||
std::string(PROJECT_NAME),
|
std::string(PROJECT_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan required extensions
|
||||||
|
assert(glfwVulkanSupported() == 1);
|
||||||
|
uint32_t count{0};
|
||||||
|
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo(true);
|
nvvk::ContextCreateInfo contextInfo;
|
||||||
contextInfo.setVersion(1, 2);
|
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
|
||||||
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
|
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
|
||||||
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
|
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
|
||||||
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
|
||||||
#ifdef _WIN32
|
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
|
||||||
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
|
||||||
#else
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature);
|
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures
|
||||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// Creating Vulkan base application
|
// Creating Vulkan base application
|
||||||
nvvk::Context vkctx{};
|
nvvk::Context vkctx{};
|
||||||
|
|
@ -171,7 +164,6 @@ int main(int argc, char** argv)
|
||||||
helloVk.m_objInstance.push_back(inst);
|
helloVk.m_objInstance.push_back(inst);
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/sphere.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/sphere.obj", defaultSearchPaths, true));
|
||||||
|
|
||||||
|
|
||||||
helloVk.createOffscreenRender();
|
helloVk.createOffscreenRender();
|
||||||
helloVk.createDescriptorSetLayout();
|
helloVk.createDescriptorSetLayout();
|
||||||
helloVk.createGraphicsPipeline();
|
helloVk.createGraphicsPipeline();
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,10 @@
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
layout(binding = 0, scalar) buffer Vertices
|
layout(binding = 0, scalar) buffer Vertices_
|
||||||
{
|
{
|
||||||
Vertex v[];
|
Vertex v[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,30 +40,33 @@ pushC;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Incoming
|
// Incoming
|
||||||
//layout(location = 0) flat in int matIndex;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
layout(location = 2) in vec3 fragNormal;
|
layout(location = 2) in vec3 fragNormal;
|
||||||
layout(location = 3) in vec3 viewDir;
|
layout(location = 3) in vec3 viewDir;
|
||||||
layout(location = 4) in vec3 worldPos;
|
layout(location = 4) in vec3 worldPos;
|
||||||
// Outgoing
|
// Outgoing
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
// Buffers
|
|
||||||
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 3) uniform sampler2D[] textureSamplers;
|
|
||||||
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
|
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 2) uniform sampler2D[] textureSamplers;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||||
|
WaveFrontMaterial mat = materials.m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -84,7 +90,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, N);
|
vec3 diffuse = computeDiffuse(mat, L, N);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
|
|
@ -29,6 +29,6 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 outUV;
|
layout(location = 0) in vec2 outUV;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs;
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
layout(location = 1) rayPayloadEXT bool isShadowed;
|
layout(location = 1) rayPayloadEXT bool isShadowed;
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||||
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
|
||||||
|
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
|
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(push_constant) uniform Constants
|
layout(push_constant) uniform Constants
|
||||||
|
|
@ -55,30 +56,33 @@ pushC;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
Indices indices = Indices(objResource.indexAddress);
|
||||||
|
Vertices vertices = Vertices(objResource.vertexAddress);
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = indices.i[gl_PrimitiveID];
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
Vertex v0 = vertices.v[ind.x];
|
||||||
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
Vertex v1 = vertices.v[ind.y];
|
||||||
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
Vertex v2 = vertices.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);
|
||||||
|
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// Transforming the normal to world space
|
||||||
normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
||||||
|
|
||||||
|
|
||||||
// Computing the coordinates of the hit position
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// Transforming the position to world space
|
||||||
worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
||||||
|
|
||||||
// Vector toward the light
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -98,17 +102,16 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,9 +125,8 @@ void main()
|
||||||
float tMax = lightDistance;
|
float tMax = lightDistance;
|
||||||
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
||||||
vec3 rayDir = L;
|
vec3 rayDir = L;
|
||||||
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT
|
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||||
| gl_RayFlagsSkipClosestHitShaderEXT;
|
isShadowed = true;
|
||||||
isShadowed = true;
|
|
||||||
traceRayEXT(topLevelAS, // acceleration structure
|
traceRayEXT(topLevelAS, // acceleration structure
|
||||||
flags, // rayFlags
|
flags, // rayFlags
|
||||||
0xFF, // cullMask
|
0xFF, // cullMask
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject
|
layout(binding = 0) uniform UniformBufferObject
|
||||||
|
|
@ -65,8 +67,8 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
|
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
|
||||||
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
|
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
|
||||||
|
|
||||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,17 @@ struct WaveFrontMaterial
|
||||||
int textureId;
|
int textureId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sceneDesc
|
struct SceneDesc
|
||||||
{
|
{
|
||||||
int objId;
|
|
||||||
int txtOffset;
|
|
||||||
mat4 transfo;
|
mat4 transfo;
|
||||||
mat4 transfoIT;
|
mat4 transfoIT;
|
||||||
|
int objId;
|
||||||
|
int txtOffset;
|
||||||
|
|
||||||
|
uint64_t vertexAddress;
|
||||||
|
uint64_t indexAddress;
|
||||||
|
uint64_t materialAddress;
|
||||||
|
uint64_t materialIndexAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ compile_glsl_directory(
|
||||||
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
||||||
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
|
||||||
VULKAN_TARGET "vulkan1.2"
|
VULKAN_TARGET "vulkan1.2"
|
||||||
|
DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS})
|
||||||
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
||||||
source_group("Sources" FILES ${SOURCE_FILES})
|
source_group("Sources" FILES ${SOURCE_FILES})
|
||||||
source_group("Headers" FILES ${HEADER_FILES})
|
source_group("Headers" FILES ${HEADER_FILES})
|
||||||
source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
source_group("Shader Sources" FILES ${GLSL_SOURCES})
|
||||||
|
source_group("Shader Headers" FILES ${GLSL_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -34,18 +34,20 @@ This shader starts like `raytrace.chit`, but uses less information.
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "random.glsl"
|
#include "random.glsl"
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
|
|
@ -59,16 +61,14 @@ opaque, we simply return, which means that the hit will be accepted.
|
||||||
~~~~ C++
|
~~~~ C++
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
// Indices of the triangle
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
// Vertex of the triangle
|
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
if (mat.illum != 4)
|
if (mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
@ -136,33 +136,13 @@ add the Any Hit stage index and push back the shader module to the stages.
|
||||||
|
|
||||||
## Give access of the buffers to the Any Hit shader
|
## Give access of the buffers to the Any Hit shader
|
||||||
|
|
||||||
In `createDescriptorSetLayout()`, we need to allow the Any Hit shader to access some buffers.
|
In `createDescriptorSetLayout()`, we need to allow the Any Hit shader to access the scene description buffer
|
||||||
|
|
||||||
This is the case for the material and scene description buffers
|
|
||||||
|
|
||||||
~~~~ C++
|
~~~~ C++
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
||||||
// Scene description (binding = 2)
|
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
|
||||||
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
and also for the vertex, index and material index buffers:
|
|
||||||
|
|
||||||
~~~~ C++
|
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
// Storing vertices (binding = 5)
|
|
||||||
m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
// Storing indices (binding = 6)
|
|
||||||
m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
## Opaque Flag
|
## Opaque Flag
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "nvvk/pipeline_vk.hpp"
|
#include "nvvk/pipeline_vk.hpp"
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
#include "nvvk/shaders_vk.hpp"
|
#include "nvvk/shaders_vk.hpp"
|
||||||
|
#include "nvvk/buffers_vk.hpp"
|
||||||
|
|
||||||
extern std::vector<std::string> defaultSearchPaths;
|
extern std::vector<std::string> defaultSearchPaths;
|
||||||
|
|
||||||
|
|
@ -113,30 +114,16 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
||||||
void HelloVulkan::createDescriptorSetLayout()
|
void HelloVulkan::createDescriptorSetLayout()
|
||||||
{
|
{
|
||||||
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
||||||
auto nbObj = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
|
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
|
||||||
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
// Scene description (binding = 2)
|
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
||||||
// Textures (binding = 3)
|
// Textures (binding = 3)
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
// Storing vertices (binding = 5)
|
|
||||||
m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
// Storing indices (binding = 6)
|
|
||||||
m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
|
|
||||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
|
||||||
|
|
||||||
|
|
||||||
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
||||||
|
|
@ -154,25 +141,9 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
// Camera matrices and scene description
|
// Camera matrices and scene description
|
||||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
||||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc));
|
|
||||||
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiVert;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data()));
|
|
||||||
|
|
||||||
// All texture samplers
|
// All texture samplers
|
||||||
std::vector<VkDescriptorImageInfo> diit;
|
std::vector<VkDescriptorImageInfo> diit;
|
||||||
|
|
@ -180,7 +151,7 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
{
|
{
|
||||||
diit.emplace_back(texture.descriptor);
|
diit.emplace_back(texture.descriptor);
|
||||||
}
|
}
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data()));
|
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||||
|
|
||||||
// Writing the information
|
// Writing the information
|
||||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||||
|
|
@ -238,36 +209,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
||||||
m.specular = nvmath::pow(m.specular, 2.2f);
|
m.specular = nvmath::pow(m.specular, 2.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjInstance instance;
|
|
||||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
instance.transform = transform;
|
|
||||||
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
|
||||||
instance.txtOffset = static_cast<uint32_t>(m_textures.size());
|
|
||||||
|
|
||||||
ObjModel model;
|
ObjModel model;
|
||||||
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
||||||
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
||||||
|
|
||||||
// Create the buffers on Device and copy vertices, indices and materials
|
// Create the buffers on Device and copy vertices, indices and materials
|
||||||
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
||||||
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
||||||
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
|
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
// Creates all textures found
|
// Creates all textures found
|
||||||
|
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
|
||||||
createTextureImages(cmdBuf, loader.m_textures);
|
createTextureImages(cmdBuf, loader.m_textures);
|
||||||
cmdBufGet.submitAndWait(cmdBuf);
|
cmdBufGet.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
|
|
||||||
std::string objNb = std::to_string(instance.objIndex);
|
std::string objNb = std::to_string(m_objModel.size());
|
||||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
||||||
|
|
||||||
|
ObjInstance instance;
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.transform = transform;
|
||||||
|
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
||||||
|
instance.txtOffset = txtOffset;
|
||||||
|
instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
|
instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||||
|
instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||||
|
|
||||||
m_objModel.emplace_back(model);
|
m_objModel.emplace_back(model);
|
||||||
m_objInstance.emplace_back(instance);
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
@ -630,11 +607,8 @@ void HelloVulkan::initRayTracing()
|
||||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||||
{
|
{
|
||||||
// BLAS builder requires raw device addresses.
|
// BLAS builder requires raw device addresses.
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
info.buffer = model.vertexBuffer.buffer;
|
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
info.buffer = model.indexBuffer.buffer;
|
|
||||||
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
||||||
|
|
||||||
|
|
@ -950,9 +924,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c
|
||||||
uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
||||||
uint32_t groupStride = groupSize;
|
uint32_t groupStride = groupSize;
|
||||||
|
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress sbtAddress = nvvk::getBufferDeviceAddress(m_device, m_rtSBTBuffer.buffer);
|
||||||
info.buffer = m_rtSBTBuffer.buffer;
|
|
||||||
VkDeviceAddress sbtAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
using Stride = VkStridedDeviceAddressRegionKHR;
|
using Stride = VkStridedDeviceAddressRegionKHR;
|
||||||
std::array<Stride, 4> strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen
|
std::array<Stride, 4> strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,14 @@ public:
|
||||||
// Instance of the OBJ
|
// Instance of the OBJ
|
||||||
struct ObjInstance
|
struct ObjInstance
|
||||||
{
|
{
|
||||||
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
nvmath::mat4f transform{1}; // Position of the instance
|
||||||
uint32_t txtOffset{0}; // Offset in `m_textures`
|
nvmath::mat4f transformIT{1}; // Inverse transpose
|
||||||
nvmath::mat4f transform{1}; // Position of the instance
|
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
||||||
nvmath::mat4f transformIT{1}; // Inverse transpose
|
uint32_t txtOffset{0}; // Offset in `m_textures`
|
||||||
|
VkDeviceAddress vertices;
|
||||||
|
VkDeviceAddress indices;
|
||||||
|
VkDeviceAddress materials;
|
||||||
|
VkDeviceAddress materialIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information pushed at each draw call
|
// Information pushed at each draw call
|
||||||
|
|
@ -93,9 +97,10 @@ public:
|
||||||
VkDescriptorSetLayout m_descSetLayout;
|
VkDescriptorSetLayout m_descSetLayout;
|
||||||
VkDescriptorSet m_descSet;
|
VkDescriptorSet m_descSet;
|
||||||
|
|
||||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
|
||||||
|
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||||
|
|
||||||
|
|
||||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ int main(int argc, char** argv)
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr);
|
GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr);
|
||||||
|
|
||||||
|
|
||||||
// Setup camera
|
// Setup camera
|
||||||
CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT);
|
CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT);
|
||||||
CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
||||||
|
|
@ -109,34 +110,26 @@ int main(int argc, char** argv)
|
||||||
std::string(PROJECT_NAME),
|
std::string(PROJECT_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan required extensions
|
||||||
|
assert(glfwVulkanSupported() == 1);
|
||||||
|
uint32_t count{0};
|
||||||
|
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo(true);
|
nvvk::ContextCreateInfo contextInfo;
|
||||||
contextInfo.setVersion(1, 2);
|
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
|
||||||
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
|
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
|
||||||
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
|
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
|
||||||
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
|
||||||
#ifdef _WIN32
|
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
|
||||||
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
|
||||||
#else
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature);
|
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures
|
||||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// Creating Vulkan base application
|
// Creating Vulkan base application
|
||||||
nvvk::Context vkctx{};
|
nvvk::Context vkctx{};
|
||||||
|
|
@ -169,7 +162,6 @@ int main(int argc, char** argv)
|
||||||
nvmath::scale_mat4(nvmath::vec3f(1.5f)) * nvmath::translation_mat4(nvmath::vec3f(0.0f, 1.0f, 0.0f)));
|
nvmath::scale_mat4(nvmath::vec3f(1.5f)) * nvmath::translation_mat4(nvmath::vec3f(0.0f, 1.0f, 0.0f)));
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true));
|
||||||
|
|
||||||
|
|
||||||
helloVk.createOffscreenRender();
|
helloVk.createOffscreenRender();
|
||||||
helloVk.createDescriptorSetLayout();
|
helloVk.createDescriptorSetLayout();
|
||||||
helloVk.createGraphicsPipeline();
|
helloVk.createGraphicsPipeline();
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,30 +40,32 @@ pushC;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Incoming
|
// Incoming
|
||||||
//layout(location = 0) flat in int matIndex;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
layout(location = 2) in vec3 fragNormal;
|
layout(location = 2) in vec3 fragNormal;
|
||||||
layout(location = 3) in vec3 viewDir;
|
layout(location = 3) in vec3 viewDir;
|
||||||
layout(location = 4) in vec3 worldPos;
|
layout(location = 4) in vec3 worldPos;
|
||||||
// Outgoing
|
// Outgoing
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
// Buffers
|
|
||||||
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 3) uniform sampler2D[] textureSamplers;
|
|
||||||
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
|
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 2) uniform sampler2D[] textureSamplers;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||||
|
WaveFrontMaterial mat = materials.m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -84,7 +89,7 @@ void main()
|
||||||
vec3 diffuse = computeDiffuse(mat, L, N);
|
vec3 diffuse = computeDiffuse(mat, L, N);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||||
uint txtId = txtOffset + mat.textureId;
|
uint txtId = txtOffset + mat.textureId;
|
||||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
diffuse *= diffuseTxt;
|
diffuse *= diffuseTxt;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
|
|
@ -29,6 +29,6 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 outUV;
|
layout(location = 0) in vec2 outUV;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Generate a random unsigned int from two unsigned int values, using 16 pairs
|
// Generate a random unsigned int from two unsigned int values, using 16 pairs
|
||||||
// of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis,
|
// of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis,
|
||||||
// "GPU Random Numbers via the Tiny Encryption Algorithm"
|
// "GPU Random Numbers via the Tiny Encryption Algorithm"
|
||||||
|
|
|
||||||
|
|
@ -16,39 +16,38 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "random.glsl"
|
#include "random.glsl"
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
// Indices of the triangle
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
// Vertex of the triangle
|
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
if(mat.illum != 4)
|
if(mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,16 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs;
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
layout(location = 1) rayPayloadEXT shadowPayload prdShadow;
|
layout(location = 1) rayPayloadEXT shadowPayload prdShadow;
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||||
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
|
||||||
|
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
|
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(push_constant) uniform Constants
|
layout(push_constant) uniform Constants
|
||||||
|
|
@ -55,30 +56,33 @@ pushC;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
Indices indices = Indices(objResource.indexAddress);
|
||||||
|
Vertices vertices = Vertices(objResource.vertexAddress);
|
||||||
|
|
||||||
// Indices of the triangle
|
// Indices of the triangle
|
||||||
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
|
ivec3 ind = indices.i[gl_PrimitiveID];
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
|
|
||||||
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
|
|
||||||
// Vertex of the triangle
|
// Vertex of the triangle
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
Vertex v0 = vertices.v[ind.x];
|
||||||
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
|
Vertex v1 = vertices.v[ind.y];
|
||||||
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
|
Vertex v2 = vertices.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);
|
||||||
|
|
||||||
// Computing the normal at hit position
|
// Computing the normal at hit position
|
||||||
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
|
||||||
// Transforming the normal to world space
|
// Transforming the normal to world space
|
||||||
normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
||||||
|
|
||||||
|
|
||||||
// Computing the coordinates of the hit position
|
// Computing the coordinates of the hit position
|
||||||
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
|
||||||
// Transforming the position to world space
|
// Transforming the position to world space
|
||||||
worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
||||||
|
|
||||||
// Vector toward the light
|
// Vector toward the light
|
||||||
vec3 L;
|
vec3 L;
|
||||||
|
|
@ -98,17 +102,16 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
vec3 diffuse = computeDiffuse(mat, L, normal);
|
vec3 diffuse = computeDiffuse(mat, L, normal);
|
||||||
if(mat.textureId >= 0)
|
if(mat.textureId >= 0)
|
||||||
{
|
{
|
||||||
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||||
vec2 texCoord =
|
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
||||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
|
|
||||||
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,13 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#version 460
|
//#version 460
|
||||||
#extension GL_EXT_ray_tracing : require
|
#extension GL_EXT_ray_tracing : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
//#extension GL_GOOGLE_include_directive : enable
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "random.glsl"
|
#include "random.glsl"
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
|
|
@ -34,25 +35,23 @@ layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||||
layout(location = 1) rayPayloadInEXT shadowPayload prd;
|
layout(location = 1) rayPayloadInEXT shadowPayload prd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
// Object data
|
||||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||||
// Indices of the triangle
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
// Vertex of the triangle
|
|
||||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
int matIdx = matIndices.i[gl_PrimitiveID];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
WaveFrontMaterial mat = materials.m[matIdx];
|
||||||
|
|
||||||
if(mat.illum != 4)
|
if(mat.illum != 4)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject
|
layout(binding = 0) uniform UniformBufferObject
|
||||||
|
|
@ -65,8 +67,8 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
|
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
|
||||||
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
|
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
|
||||||
|
|
||||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,17 @@ struct WaveFrontMaterial
|
||||||
int textureId;
|
int textureId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sceneDesc
|
struct SceneDesc
|
||||||
{
|
{
|
||||||
int objId;
|
|
||||||
int txtOffset;
|
|
||||||
mat4 transfo;
|
mat4 transfo;
|
||||||
mat4 transfoIT;
|
mat4 transfoIT;
|
||||||
|
int objId;
|
||||||
|
int txtOffset;
|
||||||
|
|
||||||
|
uint64_t vertexAddress;
|
||||||
|
uint64_t indexAddress;
|
||||||
|
uint64_t materialAddress;
|
||||||
|
uint64_t materialIndexAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.9.6 FATAL_ERROR)
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
# Project setting
|
# Project setting
|
||||||
get_filename_component(PROJNAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
get_filename_component(PROJNAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||||
SET(PROJNAME vk_${PROJNAME}_KHR)
|
set(PROJNAME vk_${PROJNAME}_KHR)
|
||||||
project(${PROJNAME} LANGUAGES C CXX)
|
project(${PROJNAME} LANGUAGES C CXX)
|
||||||
message(STATUS "-------------------------------")
|
message(STATUS "-------------------------------")
|
||||||
message(STATUS "Processing Project ${PROJNAME}:")
|
message(STATUS "Processing Project ${PROJNAME}:")
|
||||||
|
|
@ -53,8 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS})
|
||||||
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES})
|
||||||
source_group("Sources" FILES ${SOURCE_FILES})
|
source_group("Sources" FILES ${SOURCE_FILES})
|
||||||
source_group("Headers" FILES ${HEADER_FILES})
|
source_group("Headers" FILES ${HEADER_FILES})
|
||||||
source_group("Shaders Src" FILES ${GLSL_SOURCES})
|
source_group("Shader Sources" FILES ${GLSL_SOURCES})
|
||||||
source_group("Shaders Hdr" FILES ${GLSL_HEADERS})
|
source_group("Shader Headers" FILES ${GLSL_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "nvvk/pipeline_vk.hpp"
|
#include "nvvk/pipeline_vk.hpp"
|
||||||
#include "nvvk/renderpasses_vk.hpp"
|
#include "nvvk/renderpasses_vk.hpp"
|
||||||
#include "nvvk/shaders_vk.hpp"
|
#include "nvvk/shaders_vk.hpp"
|
||||||
|
#include "nvvk/buffers_vk.hpp"
|
||||||
|
|
||||||
extern std::vector<std::string> defaultSearchPaths;
|
extern std::vector<std::string> defaultSearchPaths;
|
||||||
|
|
||||||
|
|
@ -109,18 +110,13 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
||||||
void HelloVulkan::createDescriptorSetLayout()
|
void HelloVulkan::createDescriptorSetLayout()
|
||||||
{
|
{
|
||||||
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
auto nbTxt = static_cast<uint32_t>(m_textures.size());
|
||||||
auto nbObj = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
|
|
||||||
// Camera matrices (binding = 0)
|
// Camera matrices (binding = 0)
|
||||||
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
|
m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
// Materials (binding = 1)
|
// Scene description (binding = 1)
|
||||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT);
|
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
// Scene description (binding = 2)
|
|
||||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
||||||
// Textures (binding = 3)
|
// Textures (binding = 3)
|
||||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT);
|
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
// Materials (binding = 4)
|
|
||||||
m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
||||||
|
|
||||||
|
|
||||||
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
|
||||||
|
|
@ -138,23 +134,9 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
// Camera matrices and scene description
|
// Camera matrices and scene description
|
||||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif));
|
||||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc));
|
|
||||||
|
|
||||||
// All material buffers, 1 buffer per OBJ
|
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMat;
|
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||||
std::vector<VkDescriptorBufferInfo> dbiMatIdx;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiVert;
|
|
||||||
std::vector<VkDescriptorBufferInfo> dbiIdx;
|
|
||||||
for(auto& m : m_objModel)
|
|
||||||
{
|
|
||||||
dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE});
|
|
||||||
}
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data()));
|
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data()));
|
|
||||||
|
|
||||||
// All texture samplers
|
// All texture samplers
|
||||||
std::vector<VkDescriptorImageInfo> diit;
|
std::vector<VkDescriptorImageInfo> diit;
|
||||||
|
|
@ -162,12 +144,13 @@ void HelloVulkan::updateDescriptorSet()
|
||||||
{
|
{
|
||||||
diit.emplace_back(texture.descriptor);
|
diit.emplace_back(texture.descriptor);
|
||||||
}
|
}
|
||||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data()));
|
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||||
|
|
||||||
// Writing the information
|
// Writing the information
|
||||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
// Creating the pipeline layout
|
// Creating the pipeline layout
|
||||||
//
|
//
|
||||||
|
|
@ -224,36 +207,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
||||||
m.specular = nvmath::pow(m.specular, 2.2f);
|
m.specular = nvmath::pow(m.specular, 2.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjInstance instance;
|
|
||||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
|
||||||
instance.transform = transform;
|
|
||||||
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
|
||||||
instance.txtOffset = static_cast<uint32_t>(m_textures.size());
|
|
||||||
|
|
||||||
ObjModel model;
|
ObjModel model;
|
||||||
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
|
||||||
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
|
||||||
|
|
||||||
// Create the buffers on Device and copy vertices, indices and materials
|
// Create the buffers on Device and copy vertices, indices and materials
|
||||||
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
|
||||||
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
|
||||||
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||||
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
|
||||||
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
|
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
|
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags);
|
||||||
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
|
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag);
|
||||||
// Creates all textures found
|
// Creates all textures found
|
||||||
|
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
|
||||||
createTextureImages(cmdBuf, loader.m_textures);
|
createTextureImages(cmdBuf, loader.m_textures);
|
||||||
cmdBufGet.submitAndWait(cmdBuf);
|
cmdBufGet.submitAndWait(cmdBuf);
|
||||||
m_alloc.finalizeAndReleaseStaging();
|
m_alloc.finalizeAndReleaseStaging();
|
||||||
|
|
||||||
std::string objNb = std::to_string(instance.objIndex);
|
std::string objNb = std::to_string(m_objModel.size());
|
||||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str()));
|
||||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str()));
|
||||||
|
|
||||||
|
ObjInstance instance;
|
||||||
|
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||||
|
instance.transform = transform;
|
||||||
|
instance.transformIT = nvmath::transpose(nvmath::invert(transform));
|
||||||
|
instance.txtOffset = txtOffset;
|
||||||
|
instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
|
instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
|
instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||||
|
instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||||
|
|
||||||
m_objModel.emplace_back(model);
|
m_objModel.emplace_back(model);
|
||||||
m_objInstance.emplace_back(instance);
|
m_objInstance.emplace_back(instance);
|
||||||
}
|
}
|
||||||
|
|
@ -653,11 +642,8 @@ void HelloVulkan::initRayTracing()
|
||||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||||
{
|
{
|
||||||
// BLAS builder requires raw device addresses.
|
// BLAS builder requires raw device addresses.
|
||||||
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||||
info.buffer = model.vertexBuffer.buffer;
|
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||||
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
info.buffer = model.indexBuffer.buffer;
|
|
||||||
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
|
|
||||||
|
|
||||||
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
uint32_t maxPrimitiveCount = model.nbIndices / 3;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,14 @@ public:
|
||||||
// Instance of the OBJ
|
// Instance of the OBJ
|
||||||
struct ObjInstance
|
struct ObjInstance
|
||||||
{
|
{
|
||||||
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
nvmath::mat4f transform{1}; // Position of the instance
|
||||||
uint32_t txtOffset{0}; // Offset in `m_textures`
|
nvmath::mat4f transformIT{1}; // Inverse transpose
|
||||||
nvmath::mat4f transform{1}; // Position of the instance
|
uint32_t objIndex{0}; // Reference to the `m_objModel`
|
||||||
nvmath::mat4f transformIT{1}; // Inverse transpose
|
uint32_t txtOffset{0}; // Offset in `m_textures`
|
||||||
|
VkDeviceAddress vertices;
|
||||||
|
VkDeviceAddress indices;
|
||||||
|
VkDeviceAddress materials;
|
||||||
|
VkDeviceAddress materialIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information pushed at each draw call
|
// Information pushed at each draw call
|
||||||
|
|
@ -104,9 +108,10 @@ public:
|
||||||
VkDescriptorSetLayout m_descSetLayout;
|
VkDescriptorSetLayout m_descSetLayout;
|
||||||
VkDescriptorSet m_descSet;
|
VkDescriptorSet m_descSet;
|
||||||
|
|
||||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
|
||||||
|
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||||
|
|
||||||
|
|
||||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||||
|
|
|
||||||
|
|
@ -110,35 +110,26 @@ int main(int argc, char** argv)
|
||||||
std::string(PROJECT_NAME),
|
std::string(PROJECT_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan required extensions
|
||||||
|
assert(glfwVulkanSupported() == 1);
|
||||||
|
uint32_t count{0};
|
||||||
|
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
|
||||||
// Requesting Vulkan extensions and layers
|
// Requesting Vulkan extensions and layers
|
||||||
nvvk::ContextCreateInfo contextInfo(true);
|
nvvk::ContextCreateInfo contextInfo;
|
||||||
contextInfo.setVersion(1, 2);
|
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
|
||||||
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
|
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
|
||||||
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
|
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
|
||||||
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
|
||||||
#ifdef _WIN32
|
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
|
||||||
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
|
||||||
#else
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// #VKRay: Activate the ray tracing extension
|
// #VKRay: Activate the ray tracing extension
|
||||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures
|
||||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
||||||
// #VKRay: Activate the ray tracing extension
|
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
|
||||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeatures);
|
|
||||||
VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR};
|
VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR};
|
||||||
contextInfo.addDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME, false, &rayQueryFeatures);
|
contextInfo.addDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME, false, &rayQueryFeatures); // Ray tracing in compute shader
|
||||||
|
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
|
||||||
|
|
||||||
// Creating Vulkan base application
|
// Creating Vulkan base application
|
||||||
nvvk::Context vkctx{};
|
nvvk::Context vkctx{};
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,20 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 460
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_scalar_block_layout : enable
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
#extension GL_EXT_ray_tracing : enable
|
|
||||||
#extension GL_EXT_ray_query : enable
|
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||||
|
#extension GL_EXT_buffer_reference2 : require
|
||||||
|
|
||||||
#include "raycommon.glsl"
|
#include "raycommon.glsl"
|
||||||
#include "wavefront.glsl"
|
#include "wavefront.glsl"
|
||||||
|
|
||||||
|
|
||||||
layout(push_constant) uniform shaderInformation
|
layout(push_constant) uniform shaderInformation
|
||||||
{
|
{
|
||||||
vec3 lightPosition;
|
vec3 lightPosition;
|
||||||
|
|
@ -39,7 +41,6 @@ pushC;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Incoming
|
// Incoming
|
||||||
//layout(location = 0) flat in int matIndex;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
layout(location = 2) in vec3 fragNormal;
|
layout(location = 2) in vec3 fragNormal;
|
||||||
layout(location = 3) in vec3 viewDir;
|
layout(location = 3) in vec3 viewDir;
|
||||||
|
|
@ -47,24 +48,26 @@ layout(location = 4) in vec3 worldPos;
|
||||||
// Outgoing
|
// Outgoing
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
layout(location = 1) out vec4 outGbuffer;
|
layout(location = 1) out vec4 outGbuffer;
|
||||||
// Buffers
|
|
||||||
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
|
||||||
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
|
||||||
layout(binding = 3) uniform sampler2D[] textureSamplers;
|
|
||||||
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
|
|
||||||
//layout(binding = 7, set = 0) uniform accelerationStructureEXT topLevelAS;
|
|
||||||
|
|
||||||
|
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
|
||||||
|
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||||
|
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||||
|
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||||
|
layout(binding = 2) uniform sampler2D[] textureSamplers;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Object of this instance
|
|
||||||
int objId = scnDesc.i[pushC.instanceId].objId;
|
|
||||||
|
|
||||||
// Material of the object
|
// Material of the object
|
||||||
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
|
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||||
|
Materials materials = Materials(objResource.materialAddress);
|
||||||
|
|
||||||
|
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||||
|
WaveFrontMaterial mat = materials.m[matIndex];
|
||||||
|
|
||||||
vec3 N = normalize(fragNormal);
|
vec3 N = normalize(fragNormal);
|
||||||
|
|
||||||
|
|
@ -92,7 +95,7 @@ void main()
|
||||||
diffuse = vec3(1);
|
diffuse = vec3(1);
|
||||||
// if(mat.textureId >= 0)
|
// if(mat.textureId >= 0)
|
||||||
// {
|
// {
|
||||||
// int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
|
// int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||||
// uint txtId = txtOffset + mat.textureId;
|
// uint txtId = txtOffset + mat.textureId;
|
||||||
// vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
// vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||||
// diffuse *= diffuseTxt;
|
// diffuse *= diffuseTxt;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
|
|
@ -29,6 +29,6 @@ out gl_PerVertex
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 outUV;
|
layout(location = 0) in vec2 outUV;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue