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
|
|
@ -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})
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -114,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);
|
||||
|
|
@ -151,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;
|
||||
|
|
@ -177,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);
|
||||
|
|
@ -235,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,10 +76,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
|
||||
|
|
@ -132,9 +136,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
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ int main(int argc, char** argv)
|
|||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr);
|
||||
|
||||
|
||||
// Setup camera
|
||||
CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT);
|
||||
CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
||||
|
|
@ -110,34 +111,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{};
|
||||
|
|
|
|||
|
|
@ -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,32 @@ 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 +89,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;
|
||||
|
|
|
|||
|
|
@ -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_EXT_nonuniform_qualifier : enable
|
||||
|
|
@ -37,6 +37,6 @@ void main()
|
|||
{
|
||||
// Just look up this lantern's color. Self-illuminating, so no lighting calculations.
|
||||
LanternIndirectEntry lantern = lanterns.lanterns[nonuniformEXT(gl_InstanceCustomIndexEXT)];
|
||||
prd.hitValue = vec3(lantern.red, lantern.green, lantern.blue);
|
||||
prd.additiveBlending = false;
|
||||
prd.hitValue = vec3(lantern.red, lantern.green, lantern.blue);
|
||||
prd.additiveBlending = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ layout(push_constant) uniform Constants
|
|||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType; // 0: point, 1: infinite
|
||||
int lanternPassNumber; // -1 if this is the full-screen pass. Otherwise, used to lookup trace indirect parameters.
|
||||
int lightType; // 0: point, 1: infinite
|
||||
int lanternPassNumber; // -1 if this is the full-screen pass. Otherwise, used to lookup trace indirect parameters.
|
||||
int screenX;
|
||||
int screenY;
|
||||
int lanternDebug;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
@ -32,66 +36,65 @@ layout(location = 0) rayPayloadInEXT hitPayload prd;
|
|||
layout(location = 1) rayPayloadEXT bool isShadowed;
|
||||
layout(location = 2) rayPayloadEXT int hitLanternInstance;
|
||||
|
||||
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 = 0) buffer LanternArray { LanternIndirectEntry lanterns[]; } lanterns;
|
||||
|
||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
||||
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(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||
// clang-format on
|
||||
|
||||
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;
|
||||
vec3 colorIntensity = vec3(pushC.lightIntensity);
|
||||
float lightDistance = 100000.0;
|
||||
vec3 colorIntensity = vec3(pushC.lightIntensity);
|
||||
float lightDistance = 100000.0;
|
||||
|
||||
// ray direction is towards lantern, if in lantern pass.
|
||||
if (pushC.lanternPassNumber >= 0)
|
||||
if(pushC.lanternPassNumber >= 0)
|
||||
{
|
||||
LanternIndirectEntry lantern = lanterns.lanterns[pushC.lanternPassNumber];
|
||||
vec3 lDir = vec3(lantern.x, lantern.y, lantern.z) - worldPos;
|
||||
lightDistance = length(lDir);
|
||||
vec3 color = vec3(lantern.red, lantern.green, lantern.blue);
|
||||
vec3 lDir = vec3(lantern.x, lantern.y, lantern.z) - worldPos;
|
||||
lightDistance = length(lDir);
|
||||
vec3 color = vec3(lantern.red, lantern.green, lantern.blue);
|
||||
// Lantern light decreases linearly. Not physically accurate, but looks good
|
||||
// and avoids a hard "edge" at the radius limit. Use a constant value
|
||||
// if lantern debug is enabled to clearly see the covered screen rectangle.
|
||||
float distanceFade =
|
||||
pushC.lanternDebug != 0
|
||||
? 0.3
|
||||
: max(0, (lantern.radius - lightDistance) / lantern.radius);
|
||||
colorIntensity = color * lantern.brightness * distanceFade;
|
||||
L = normalize(lDir);
|
||||
float distanceFade = pushC.lanternDebug != 0 ? 0.3 : max(0, (lantern.radius - lightDistance) / lantern.radius);
|
||||
colorIntensity = color * lantern.brightness * distanceFade;
|
||||
L = normalize(lDir);
|
||||
}
|
||||
// Non-lantern pass may have point light...
|
||||
else if(pushC.lightType == 0)
|
||||
|
|
@ -107,17 +110,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;
|
||||
}
|
||||
|
||||
|
|
@ -133,10 +135,10 @@ void main()
|
|||
vec3 rayDir = L;
|
||||
|
||||
// Ordinary shadow from the simple tutorial.
|
||||
if (pushC.lanternPassNumber < 0) {
|
||||
if(pushC.lanternPassNumber < 0)
|
||||
{
|
||||
isShadowed = true;
|
||||
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT
|
||||
| gl_RayFlagsSkipClosestHitShaderEXT;
|
||||
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||
traceRayEXT(topLevelAS, // acceleration structure
|
||||
flags, // rayFlags
|
||||
0xFF, // cullMask
|
||||
|
|
@ -153,25 +155,28 @@ void main()
|
|||
// Lantern shadow ray. Cast a ray towards the lantern whose lighting is being
|
||||
// added this pass. Only the closest hit shader for lanterns will set
|
||||
// hitLanternInstance (payload 2) to non-negative value.
|
||||
else {
|
||||
else
|
||||
{
|
||||
// Skip ray if no light would be added anyway.
|
||||
if (colorIntensity == vec3(0)) {
|
||||
if(colorIntensity == vec3(0))
|
||||
{
|
||||
isShadowed = true;
|
||||
}
|
||||
else {
|
||||
uint flags = gl_RayFlagsOpaqueEXT;
|
||||
else
|
||||
{
|
||||
uint flags = gl_RayFlagsOpaqueEXT;
|
||||
hitLanternInstance = -1;
|
||||
traceRayEXT(topLevelAS, // acceleration structure
|
||||
flags, // rayFlags
|
||||
0xFF, // cullMask
|
||||
2, // sbtRecordOffset : lantern shadow hit groups start at index 2.
|
||||
0, // sbtRecordStride
|
||||
2, // missIndex : lantern shadow miss shader is number 2.
|
||||
origin, // ray origin
|
||||
tMin, // ray min range
|
||||
rayDir, // ray direction
|
||||
tMax, // ray max range
|
||||
2 // payload (location = 2)
|
||||
traceRayEXT(topLevelAS, // acceleration structure
|
||||
flags, // rayFlags
|
||||
0xFF, // cullMask
|
||||
2, // sbtRecordOffset : lantern shadow hit groups start at index 2.
|
||||
0, // sbtRecordStride
|
||||
2, // missIndex : lantern shadow miss shader is number 2.
|
||||
origin, // ray origin
|
||||
tMin, // ray min range
|
||||
rayDir, // ray direction
|
||||
tMax, // ray max range
|
||||
2 // payload (location = 2)
|
||||
);
|
||||
// Did we hit the lantern we expected?
|
||||
isShadowed = (hitLanternInstance != pushC.lanternPassNumber);
|
||||
|
|
@ -189,6 +194,6 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
prd.hitValue = colorIntensity * (attenuation * (diffuse + specular));
|
||||
prd.hitValue = colorIntensity * (attenuation * (diffuse + specular));
|
||||
prd.additiveBlending = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -36,23 +36,27 @@ layout(binding = 0, set = 1) uniform CameraProperties
|
|||
}
|
||||
cam;
|
||||
|
||||
layout(binding = 2, set = 0) buffer LanternArray { LanternIndirectEntry lanterns[]; } lanterns;
|
||||
layout(binding = 2, set = 0) buffer LanternArray
|
||||
{
|
||||
LanternIndirectEntry lanterns[];
|
||||
}
|
||||
lanterns;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Global light pass is a full screen rectangle (lower corner 0,0), but
|
||||
// lantern passes are only run within rectangles that may be offset.
|
||||
ivec2 pixelOffset = ivec2(0);
|
||||
if (pushC.lanternPassNumber >= 0)
|
||||
if(pushC.lanternPassNumber >= 0)
|
||||
{
|
||||
pixelOffset.x = lanterns.lanterns[pushC.lanternPassNumber].offsetX;
|
||||
pixelOffset.y = lanterns.lanterns[pushC.lanternPassNumber].offsetY;
|
||||
}
|
||||
|
||||
const ivec2 pixelIntCoord = ivec2(gl_LaunchIDEXT.xy) + pixelOffset;
|
||||
const vec2 pixelCenter = vec2(pixelIntCoord) + vec2(0.5);
|
||||
const vec2 inUV = pixelCenter / vec2(pushC.screenX, pushC.screenY);
|
||||
vec2 d = inUV * 2.0 - 1.0;
|
||||
const vec2 pixelCenter = vec2(pixelIntCoord) + vec2(0.5);
|
||||
const vec2 inUV = pixelCenter / vec2(pushC.screenX, pushC.screenY);
|
||||
vec2 d = inUV * 2.0 - 1.0;
|
||||
|
||||
vec4 origin = cam.viewInverse * vec4(0, 0, 0, 1);
|
||||
vec4 target = cam.projInverse * vec4(d.x, d.y, 1, 1);
|
||||
|
|
@ -83,7 +87,8 @@ void main()
|
|||
// Either add to or replace output image color based on prd.additiveBlending.
|
||||
// Global pass always replaces color as it is the first pass.
|
||||
vec3 oldColor = vec3(0);
|
||||
if (prd.additiveBlending && pushC.lanternPassNumber >= 0) {
|
||||
if(prd.additiveBlending && pushC.lanternPassNumber >= 0)
|
||||
{
|
||||
oldColor = imageLoad(image, pixelIntCoord).rgb;
|
||||
}
|
||||
imageStore(image, pixelIntCoord, vec4(prd.hitValue + oldColor, 1.0));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -26,6 +26,6 @@ layout(location = 0) rayPayloadInEXT hitPayload prd;
|
|||
|
||||
void main()
|
||||
{
|
||||
prd.hitValue = pushC.clearColor.xyz * 0.8;
|
||||
prd.hitValue = pushC.clearColor.xyz * 0.8;
|
||||
prd.additiveBlending = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -39,12 +39,16 @@ struct WaveFrontMaterial
|
|||
int textureId;
|
||||
};
|
||||
|
||||
struct sceneDesc
|
||||
struct SceneDesc
|
||||
{
|
||||
int objId;
|
||||
int txtOffset;
|
||||
mat4 transfo;
|
||||
mat4 transfoIT;
|
||||
mat4 transfo;
|
||||
mat4 transfoIT;
|
||||
int objId;
|
||||
int txtOffset;
|
||||
uint64_t vertexAddress;
|
||||
uint64_t indexAddress;
|
||||
uint64_t materialAddress;
|
||||
uint64_t materialIndexAddress;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue