Using buffer reference instead of un-sized array

This commit is contained in:
mklefrancois 2021-06-11 12:25:06 +02:00
parent e3a57e6d63
commit c8a0122dd6
248 changed files with 2593 additions and 2660 deletions

View file

@ -35,6 +35,7 @@ compile_glsl_directory(
SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders"
DST "${CMAKE_CURRENT_SOURCE_DIR}/spv"
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("Sources" FILES ${SOURCE_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})
#--------------------------------------------------------------------------------------------------

View file

@ -290,6 +290,7 @@ This will move each vertex up and down over time.
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_scalar_block_layout : enable
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
#include "wavefront.glsl"
layout(binding = 0, scalar) buffer Vertices

View file

@ -35,6 +35,7 @@
#include "nvvk/pipeline_vk.hpp"
#include "nvvk/renderpasses_vk.hpp"
#include "nvvk/shaders_vk.hpp"
#include "nvvk/buffers_vk.hpp"
extern std::vector<std::string> defaultSearchPaths;
@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
void HelloVulkan::createDescriptorSetLayout()
{
auto nbTxt = static_cast<uint32_t>(m_textures.size());
auto nbObj = static_cast<uint32_t>(m_objModel.size());
// 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);
// Materials (binding = 1)
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj,
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,
// Scene description (binding = 1)
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);
// 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);
// 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);
@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet()
// Camera matrices and scene description
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
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
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()));
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
// All texture samplers
std::vector<VkDescriptorImageInfo> diit;
@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet()
{
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
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);
}
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;
model.nbIndices = static_cast<uint32_t>(loader.m_indices.size());
model.nbVertices = static_cast<uint32_t>(loader.m_vertices.size());
// Create the buffers on Device and copy vertices, indices and materials
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage);
model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage);
model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures
flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
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);
// Creates all textures found
uint32_t txtOffset = static_cast<uint32_t>(m_textures.size());
createTextureImages(cmdBuf, loader.m_textures);
cmdBufGet.submitAndWait(cmdBuf);
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.indexBuffer.buffer, (std::string("index_" + 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()));
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_objInstance.emplace_back(instance);
}
@ -633,11 +613,8 @@ void HelloVulkan::initRayTracing()
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
{
// BLAS builder requires raw device addresses.
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
info.buffer = model.vertexBuffer.buffer;
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
info.buffer = model.indexBuffer.buffer;
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
uint32_t maxPrimitiveCount = model.nbIndices / 3;

View file

@ -66,10 +66,14 @@ public:
// Instance of the OBJ
struct ObjInstance
{
uint32_t objIndex{0}; // Reference to the `m_objModel`
uint32_t txtOffset{0}; // Offset in `m_textures`
nvmath::mat4f transform{1}; // Position of the instance
nvmath::mat4f transformIT{1}; // Inverse transpose
nvmath::mat4f transform{1}; // Position of the instance
nvmath::mat4f transformIT{1}; // Inverse transpose
uint32_t objIndex{0}; // Reference to the `m_objModel`
uint32_t txtOffset{0}; // Offset in `m_textures`
VkDeviceAddress vertices;
VkDeviceAddress indices;
VkDeviceAddress materials;
VkDeviceAddress materialIndices;
};
// Information pushed at each draw call
@ -94,9 +98,10 @@ public:
VkDescriptorSetLayout m_descSetLayout;
VkDescriptorSet m_descSet;
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
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_cameraMat; // Device-Host of the camera matrices
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures

View file

@ -109,33 +109,26 @@ int main(int argc, char** argv)
std::string(PROJECT_NAME),
};
// Vulkan required extensions
assert(glfwVulkanSupported() == 1);
uint32_t count{0};
auto reqExtensions = glfwGetRequiredInstanceExtensions(&count);
// Requesting Vulkan extensions and layers
nvvk::ContextCreateInfo contextInfo(true);
contextInfo.setVersion(1, 2);
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true);
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true);
contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME);
#ifdef _WIN32
contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#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);
nvvk::ContextCreateInfo contextInfo;
contextInfo.setVersion(1, 2); // Using Vulkan 1.2
for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..)
contextInfo.addInstanceExtension(reqExtensions[ext_id]);
contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar
contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names
contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering
// #VKRay: Activate the ray tracing extension
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};
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_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);
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline
// Creating Vulkan base application
nvvk::Context vkctx{};
@ -171,7 +164,6 @@ int main(int argc, char** argv)
helloVk.m_objInstance.push_back(inst);
helloVk.loadModel(nvh::findFile("media/scenes/sphere.obj", defaultSearchPaths, true));
helloVk.createOffscreenRender();
helloVk.createDescriptorSetLayout();
helloVk.createGraphicsPipeline();

View file

@ -21,9 +21,10 @@
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_scalar_block_layout : enable
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
#include "wavefront.glsl"
layout(binding = 0, scalar) buffer Vertices
layout(binding = 0, scalar) buffer Vertices_
{
Vertex v[];
}

View file

@ -16,13 +16,16 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_nonuniform_qualifier : enable
#extension GL_GOOGLE_include_directive : 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"
@ -37,30 +40,33 @@ pushC;
// clang-format off
// Incoming
//layout(location = 0) flat in int matIndex;
layout(location = 1) in vec2 fragTexCoord;
layout(location = 2) in vec3 fragNormal;
layout(location = 3) in vec3 viewDir;
layout(location = 4) in vec3 worldPos;
// Outgoing
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
void main()
{
// Object of this instance
int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
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);
@ -84,7 +90,7 @@ void main()
vec3 diffuse = computeDiffuse(mat, L, N);
if(mat.textureId >= 0)
{
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt;

View file

@ -16,9 +16,9 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
layout (location = 0) out vec2 outUV;
layout(location = 0) out vec2 outUV;
out gl_PerVertex
@ -29,6 +29,6 @@ out gl_PerVertex
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);
}

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
layout(location = 0) in vec2 outUV;
layout(location = 0) out vec4 fragColor;

View file

@ -16,12 +16,16 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : 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 "raycommon.glsl"
#include "wavefront.glsl"
@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs;
layout(location = 0) rayPayloadInEXT hitPayload prd;
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 = 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(binding = 3, set = 1) uniform sampler2D textureSamplers[];
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
// clang-format on
layout(push_constant) uniform Constants
@ -55,30 +56,33 @@ pushC;
void main()
{
// Object of this instance
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
// Object data
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
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
ivec3 ind = indices.i[gl_PrimitiveID];
// Vertex of the triangle
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
Vertex v0 = vertices.v[ind.x];
Vertex v1 = vertices.v[ind.y];
Vertex v2 = vertices.v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
// Computing the normal at hit position
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
// Transforming the normal to world space
normal = normalize(vec3(scnDesc.i[gl_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
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
// Transforming the position to world space
worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
// Vector toward the light
vec3 L;
@ -98,17 +102,16 @@ void main()
}
// Material of the object
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
int matIdx = matIndices.i[gl_PrimitiveID];
WaveFrontMaterial mat = materials.m[matIdx];
// Diffuse
vec3 diffuse = computeDiffuse(mat, L, normal);
if(mat.textureId >= 0)
{
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
}
@ -122,9 +125,8 @@ void main()
float tMax = lightDistance;
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
vec3 rayDir = L;
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT
| gl_RayFlagsSkipClosestHitShaderEXT;
isShadowed = true;
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT;
isShadowed = true;
traceRayEXT(topLevelAS, // acceleration structure
flags, // rayFlags
0xFF, // cullMask

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require

View file

@ -16,16 +16,18 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_scalar_block_layout : enable
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
#include "wavefront.glsl"
// 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
layout(binding = 0) uniform UniformBufferObject
@ -65,8 +67,8 @@ out gl_PerVertex
void main()
{
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));

View file

@ -39,12 +39,17 @@ struct WaveFrontMaterial
int textureId;
};
struct sceneDesc
struct SceneDesc
{
int objId;
int txtOffset;
mat4 transfo;
mat4 transfoIT;
int objId;
int txtOffset;
uint64_t vertexAddress;
uint64_t indexAddress;
uint64_t materialAddress;
uint64_t materialIndexAddress;
};