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

@ -65,8 +65,24 @@ But instead, we will use this following structure to retrieve the information of
nvvk::Buffer m_materialBuffer;
nvvk::Buffer m_matrixBuffer;
nvvk::Buffer m_rtPrimLookup;
nvvk::Buffer m_sceneDesc;
~~~~
And a structure to retrieve all buffers of the scene
~~~~ C++
struct SceneDescription
{
uint64_t vertexAddress;
uint64_t normalAddress;
uint64_t uvAddress;
uint64_t indexAddress;
uint64_t materialAddress;
uint64_t matrixAddress;
uint64_t rtPrimAddress;
};
~~~~
## Loading glTF scene
To load the scene, we will be using [TinyGLTF](https://github.com/syoyo/tinygltf) from Syoyo Fujita, then to avoid traversing
@ -98,27 +114,50 @@ Then we will flatten the scene graph and grab the information we will need using
The next part is to allocate the buffers to hold the information, such as the positions, normals, texture coordinates, etc.
~~~~C
m_vertexBuffer =
m_alloc.createBuffer(cmdBuf, m_gltfScene.m_positions,
vkBU::eVertexBuffer | vkBU::eStorageBuffer | vkBU::eShaderDeviceAddress);
m_indexBuffer =
m_alloc.createBuffer(cmdBuf, m_gltfScene.m_indices,
vkBU::eIndexBuffer | vkBU::eStorageBuffer | vkBU::eShaderDeviceAddress);
m_normalBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_normals,
vkBU::eVertexBuffer | vkBU::eStorageBuffer);
m_uvBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_texcoords0,
vkBU::eVertexBuffer | vkBU::eStorageBuffer);
m_materialBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_materials, vkBU::eStorageBuffer);
// Create the buffers on Device and copy vertices, indices and materials
nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex);
VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer();
m_vertexBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_positions,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR);
m_indexBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_indices,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR);
m_normalBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_normals,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
m_uvBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_texcoords0,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
~~~~
We are making a simple material, extracting only a few members from the glTF material.
~~~~ C++
// Copying all materials, only the elements we need
std::vector<GltfShadeMaterial> shadeMaterials;
for(auto& m : m_gltfScene.m_materials)
{
shadeMaterials.emplace_back(GltfShadeMaterial{m.baseColorFactor, m.emissiveFactor, m.baseColorTexture});
}
m_materialBuffer = m_alloc.createBuffer(cmdBuf, shadeMaterials,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
~~~~
We could use `push_constant` to set the matrix of the node, but instead, we will push the index of the
node to draw and fetch the matrix from a buffer.
~~~~C
// Instance Matrices used by rasterizer
std::vector<nvmath::mat4f> nodeMatrices;
for(auto& node : m_gltfScene.m_nodes)
{
nodeMatrices.emplace_back(node.worldMatrix);
m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices, vkBU::eStorageBuffer);
}
m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
~~~~
To find the positions of the triangle hit in the closest hit shader, as well as the other
@ -131,9 +170,47 @@ attributes, we will store the offsets information of that geometry.
{
primLookup.push_back({primMesh.firstIndex, primMesh.vertexOffset, primMesh.materialIndex});
}
m_rtPrimLookup = m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
m_rtPrimLookup =
m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
~~~~
Finally, we are creating a buffer holding the address of all buffers
~~~~ C++
SceneDescription sceneDesc;
sceneDesc.vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer);
sceneDesc.indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer);
sceneDesc.normalAddress = nvvk::getBufferDeviceAddress(m_device, m_normalBuffer.buffer);
sceneDesc.uvAddress = nvvk::getBufferDeviceAddress(m_device, m_uvBuffer.buffer);
sceneDesc.materialAddress = nvvk::getBufferDeviceAddress(m_device, m_materialBuffer.buffer);
sceneDesc.matrixAddress = nvvk::getBufferDeviceAddress(m_device, m_matrixBuffer.buffer);
sceneDesc.rtPrimAddress = nvvk::getBufferDeviceAddress(m_device, m_rtPrimLookup.buffer);
m_sceneDesc = m_alloc.createBuffer(cmdBuf, sizeof(SceneDescription), &sceneDesc,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
~~~~
Before closing the function, we will create textures (none in default scene) and submitting the command buffer.
The finalize and releasing staging is waiting for the copy of all data to the GPU.
~~~~ C
// Creates all textures found
createTextureImages(cmdBuf, tmodel);
cmdBufGet.submitAndWait(cmdBuf);
m_alloc.finalizeAndReleaseStaging();
NAME_VK(m_vertexBuffer.buffer);
NAME_VK(m_indexBuffer.buffer);
NAME_VK(m_normalBuffer.buffer);
NAME_VK(m_uvBuffer.buffer);
NAME_VK(m_materialBuffer.buffer);
NAME_VK(m_matrixBuffer.buffer);
NAME_VK(m_rtPrimLookup.buffer);
NAME_VK(m_sceneDesc.buffer);
}
~~~~
**NOTE**: the macro `NAME_VK` is a convenience to name Vulkan object to easily identify them in Nsight Graphics and to know where it was created.
## Converting geometry to BLAS
@ -147,11 +224,8 @@ The function is similar, only the input is different.
auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim)
{
// BLAS builder requires raw device addresses.
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
info.buffer = m_vertexBuffer.buffer;
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
info.buffer = m_indexBuffer.buffer;
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer);
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer);
uint32_t maxPrimitiveCount = prim.indexCount / 3;

View file

@ -41,6 +41,7 @@
#include "nvh/alignment.hpp"
#include "shaders/binding.glsl"
#include "shaders/gltf.glsl"
#include "nvvk/buffers_vk.hpp"
extern std::vector<std::string> defaultSearchPaths;
@ -120,18 +121,14 @@ void HelloVulkan::createDescriptorSetLayout()
auto& bind = m_descSetLayoutBind;
// Camera matrices (binding = 0)
bind.addBinding(B_CAMERA, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
bind.addBinding(B_VERTICES, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
bind.addBinding(B_INDICES, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
bind.addBinding(B_NORMALS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
bind.addBinding(B_TEXCOORDS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
bind.addBinding(B_MATERIALS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
bind.addBinding(B_MATRICES, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
auto nbTextures = static_cast<uint32_t>(m_textures.size());
bind.addBinding(B_TEXTURES, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTextures,
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
bind.addBinding(B_SCENEDESC, 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);
m_descSetLayout = m_descSetLayoutBind.createLayout(m_device);
m_descPool = m_descSetLayoutBind.createPool(m_device, 1);
m_descSet = nvvk::allocateDescriptorSet(m_device, m_descPool, m_descSetLayout);
@ -146,20 +143,10 @@ void HelloVulkan::updateDescriptorSet()
// Camera matrices and scene description
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
VkDescriptorBufferInfo vertexDesc{m_vertexBuffer.buffer, 0, VK_WHOLE_SIZE};
VkDescriptorBufferInfo indexDesc{m_indexBuffer.buffer, 0, VK_WHOLE_SIZE};
VkDescriptorBufferInfo normalDesc{m_normalBuffer.buffer, 0, VK_WHOLE_SIZE};
VkDescriptorBufferInfo uvDesc{m_uvBuffer.buffer, 0, VK_WHOLE_SIZE};
VkDescriptorBufferInfo materialDesc{m_materialBuffer.buffer, 0, VK_WHOLE_SIZE};
VkDescriptorBufferInfo matrixDesc{m_matrixBuffer.buffer, 0, VK_WHOLE_SIZE};
VkDescriptorBufferInfo sceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_CAMERA, &dbiUnif));
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_VERTICES, &vertexDesc));
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_INDICES, &indexDesc));
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_NORMALS, &normalDesc));
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_TEXCOORDS, &uvDesc));
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_MATERIALS, &materialDesc));
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_MATRICES, &matrixDesc));
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_SCENEDESC, &sceneDesc));
// All texture samplers
std::vector<VkDescriptorImageInfo> diit;
@ -237,17 +224,20 @@ void HelloVulkan::loadScene(const std::string& filename)
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
| VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR);
m_normalBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_normals,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
m_uvBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_texcoords0,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
// Copying all materials, only the elements we need
std::vector<GltfShadeMaterial> shadeMaterials;
for(auto& m : m_gltfScene.m_materials)
{
shadeMaterials.emplace_back(GltfShadeMaterial{m.baseColorFactor, m.baseColorTexture, m.emissiveFactor});
shadeMaterials.emplace_back(GltfShadeMaterial{m.baseColorFactor, m.emissiveFactor, m.baseColorTexture});
}
m_materialBuffer = m_alloc.createBuffer(cmdBuf, shadeMaterials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
m_materialBuffer = m_alloc.createBuffer(cmdBuf, shadeMaterials,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
// Instance Matrices used by rasterizer
std::vector<nvmath::mat4f> nodeMatrices;
@ -255,7 +245,8 @@ void HelloVulkan::loadScene(const std::string& filename)
{
nodeMatrices.emplace_back(node.worldMatrix);
}
m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
// The following is used to find the primitive mesh information in the CHIT
std::vector<RtPrimitiveLookup> primLookup;
@ -263,20 +254,35 @@ void HelloVulkan::loadScene(const std::string& filename)
{
primLookup.push_back({primMesh.firstIndex, primMesh.vertexOffset, primMesh.materialIndex});
}
m_rtPrimLookup = m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
m_rtPrimLookup =
m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
SceneDescription sceneDesc;
sceneDesc.vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer);
sceneDesc.indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer);
sceneDesc.normalAddress = nvvk::getBufferDeviceAddress(m_device, m_normalBuffer.buffer);
sceneDesc.uvAddress = nvvk::getBufferDeviceAddress(m_device, m_uvBuffer.buffer);
sceneDesc.materialAddress = nvvk::getBufferDeviceAddress(m_device, m_materialBuffer.buffer);
sceneDesc.matrixAddress = nvvk::getBufferDeviceAddress(m_device, m_matrixBuffer.buffer);
sceneDesc.rtPrimAddress = nvvk::getBufferDeviceAddress(m_device, m_rtPrimLookup.buffer);
m_sceneDesc = m_alloc.createBuffer(cmdBuf, sizeof(SceneDescription), &sceneDesc,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
// Creates all textures found
createTextureImages(cmdBuf, tmodel);
cmdBufGet.submitAndWait(cmdBuf);
m_alloc.finalizeAndReleaseStaging();
m_debug.setObjectName(m_vertexBuffer.buffer, "Vertex");
m_debug.setObjectName(m_indexBuffer.buffer, "Index");
m_debug.setObjectName(m_normalBuffer.buffer, "Normal");
m_debug.setObjectName(m_uvBuffer.buffer, "TexCoord");
m_debug.setObjectName(m_materialBuffer.buffer, "Material");
m_debug.setObjectName(m_matrixBuffer.buffer, "Matrix");
NAME_VK(m_vertexBuffer.buffer);
NAME_VK(m_indexBuffer.buffer);
NAME_VK(m_normalBuffer.buffer);
NAME_VK(m_uvBuffer.buffer);
NAME_VK(m_materialBuffer.buffer);
NAME_VK(m_matrixBuffer.buffer);
NAME_VK(m_rtPrimLookup.buffer);
NAME_VK(m_sceneDesc.buffer);
}
@ -364,6 +370,7 @@ void HelloVulkan::destroyResources()
m_alloc.destroy(m_materialBuffer);
m_alloc.destroy(m_matrixBuffer);
m_alloc.destroy(m_rtPrimLookup);
m_alloc.destroy(m_sceneDesc);
for(auto& t : m_textures)
{
@ -606,11 +613,8 @@ void HelloVulkan::initRayTracing()
auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim)
{
// BLAS builder requires raw device addresses.
VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
info.buffer = m_vertexBuffer.buffer;
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info);
info.buffer = m_indexBuffer.buffer;
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info);
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer);
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer);
uint32_t maxPrimitiveCount = prim.indexCount / 3;

View file

@ -61,6 +61,16 @@ public:
int materialIndex;
};
struct SceneDescription
{
uint64_t vertexAddress;
uint64_t normalAddress;
uint64_t uvAddress;
uint64_t indexAddress;
uint64_t materialAddress;
uint64_t matrixAddress;
uint64_t rtPrimAddress;
};
nvh::GltfScene m_gltfScene;
nvvk::Buffer m_vertexBuffer;
@ -70,6 +80,7 @@ public:
nvvk::Buffer m_materialBuffer;
nvvk::Buffer m_matrixBuffer;
nvvk::Buffer m_rtPrimLookup;
nvvk::Buffer m_sceneDesc;
// Information pushed at each draw call
struct ObjPushConstant

View file

@ -19,10 +19,5 @@
#define B_CAMERA 0
#define B_VERTICES 1
#define B_NORMALS 2
#define B_TEXCOORDS 3
#define B_INDICES 4
#define B_MATERIALS 5
#define B_MATRICES 6
#define B_TEXTURES 7
#define B_SCENEDESC 1
#define B_TEXTURES 2

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 "binding.glsl"
#include "gltf.glsl"
@ -39,7 +42,6 @@ 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;
@ -47,16 +49,19 @@ layout(location = 4) in vec3 worldPos;
// Outgoing
layout(location = 0) out vec4 outColor;
// Buffers
layout(set = 0, binding = B_MATERIALS) buffer _GltfMaterial { GltfShadeMaterial materials[]; };
layout(set = 0, binding = B_TEXTURES) uniform sampler2D[] textureSamplers;
layout(buffer_reference, scalar) buffer Matrices { mat4 m[]; };
layout(buffer_reference, scalar) buffer GltfMaterial { GltfShadeMaterial m[]; };
layout(set = 0, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; } ;
layout(set = 0, binding = B_TEXTURES) uniform sampler2D[] textureSamplers;
// clang-format on
void main()
{
// Material of the object
GltfShadeMaterial mat = materials[nonuniformEXT(pushC.matetrialId)];
GltfMaterial gltfMat = GltfMaterial(sceneDesc.materialAddress);
GltfShadeMaterial mat = gltfMat.m[pushC.matetrialId];
vec3 N = normalize(fragNormal);

View file

@ -20,8 +20,8 @@
struct GltfShadeMaterial
{
vec4 pbrBaseColorFactor;
int pbrBaseColorTexture;
vec3 emissiveFactor;
int pbrBaseColorTexture;
};
#ifndef __cplusplus
@ -32,6 +32,17 @@ struct PrimMeshInfo
int materialIndex;
};
struct SceneDesc
{
uint64_t vertexAddress;
uint64_t normalAddress;
uint64_t uvAddress;
uint64_t indexAddress;
uint64_t materialAddress;
uint64_t matrixAddress;
uint64_t rtPrimAddress;
};
vec3 computeDiffuse(GltfShadeMaterial mat, vec3 lightDir, vec3 normal)
{

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,13 +16,17 @@
* 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 "binding.glsl"
#include "gltf.glsl"
#include "raycommon.glsl"
@ -38,13 +42,15 @@ layout(location = 1) rayPayloadEXT bool isShadowed;
layout(set = 0, binding = 0 ) uniform accelerationStructureEXT topLevelAS;
layout(set = 0, binding = 2) readonly buffer _InstanceInfo {PrimMeshInfo primInfo[];};
layout(set = 1, binding = B_VERTICES) readonly buffer _VertexBuf {float vertices[];};
layout(set = 1, binding = B_INDICES) readonly buffer _Indices {uint indices[];};
layout(set = 1, binding = B_NORMALS) readonly buffer _NormalBuf {float normals[];};
layout(set = 1, binding = B_TEXCOORDS) readonly buffer _TexCoordBuf {float texcoord0[];};
layout(set = 1, binding = B_MATERIALS) readonly buffer _MaterialBuffer {GltfShadeMaterial materials[];};
layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures
layout(buffer_reference, scalar) readonly buffer Vertices { vec3 v[]; };
layout(buffer_reference, scalar) readonly buffer Indices { ivec3 i[]; };
layout(buffer_reference, scalar) readonly buffer Normals { vec3 n[]; };
layout(buffer_reference, scalar) readonly buffer TexCoords { vec2 t[]; };
layout(buffer_reference, scalar) readonly buffer Materials { GltfShadeMaterial m[]; };
layout(set = 1, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; };
layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures
// clang-format on
@ -57,33 +63,6 @@ layout(push_constant) uniform Constants
}
pushC;
// Return the vertex position
vec3 getVertex(uint index)
{
vec3 vp;
vp.x = vertices[3 * index + 0];
vp.y = vertices[3 * index + 1];
vp.z = vertices[3 * index + 2];
return vp;
}
vec3 getNormal(uint index)
{
vec3 vp;
vp.x = normals[3 * index + 0];
vp.y = normals[3 * index + 1];
vp.z = normals[3 * index + 2];
return vp;
}
vec2 getTexCoord(uint index)
{
vec2 vp;
vp.x = texcoord0[2 * index + 0];
vp.y = texcoord0[2 * index + 1];
return vp;
}
void main()
{
@ -91,42 +70,47 @@ void main()
PrimMeshInfo pinfo = primInfo[gl_InstanceCustomIndexEXT];
// Getting the 'first index' for this mesh (offset of the mesh + offset of the triangle)
uint indexOffset = pinfo.indexOffset + (3 * gl_PrimitiveID);
uint indexOffset = (pinfo.indexOffset / 3) + gl_PrimitiveID;
uint vertexOffset = pinfo.vertexOffset; // Vertex offset as defined in glTF
uint matIndex = max(0, pinfo.materialIndex); // material of primitive mesh
Materials gltfMat = Materials(sceneDesc.materialAddress);
Vertices vertices = Vertices(sceneDesc.vertexAddress);
Indices indices = Indices(sceneDesc.indexAddress);
Normals normals = Normals(sceneDesc.normalAddress);
TexCoords texCoords = TexCoords(sceneDesc.uvAddress);
Materials materials = Materials(sceneDesc.materialAddress);
// Getting the 3 indices of the triangle (local)
ivec3 triangleIndex = ivec3(indices[nonuniformEXT(indexOffset + 0)], //
indices[nonuniformEXT(indexOffset + 1)], //
indices[nonuniformEXT(indexOffset + 2)]);
ivec3 triangleIndex = indices.i[indexOffset];
triangleIndex += ivec3(vertexOffset); // (global)
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
// Vertex of the triangle
const vec3 pos0 = getVertex(triangleIndex.x);
const vec3 pos1 = getVertex(triangleIndex.y);
const vec3 pos2 = getVertex(triangleIndex.z);
const vec3 pos0 = vertices.v[triangleIndex.x];
const vec3 pos1 = vertices.v[triangleIndex.y];
const vec3 pos2 = vertices.v[triangleIndex.z];
const vec3 position = pos0 * barycentrics.x + pos1 * barycentrics.y + pos2 * barycentrics.z;
const vec3 world_position = vec3(gl_ObjectToWorldEXT * vec4(position, 1.0));
// Normal
const vec3 nrm0 = getNormal(triangleIndex.x);
const vec3 nrm1 = getNormal(triangleIndex.y);
const vec3 nrm2 = getNormal(triangleIndex.z);
vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z);
const vec3 nrm0 = normals.n[triangleIndex.x];
const vec3 nrm1 = normals.n[triangleIndex.y];
const vec3 nrm2 = normals.n[triangleIndex.z];
vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z);
const vec3 world_normal = normalize(vec3(normal * gl_WorldToObjectEXT));
const vec3 geom_normal = normalize(cross(pos1 - pos0, pos2 - pos0));
// TexCoord
const vec2 uv0 = getTexCoord(triangleIndex.x);
const vec2 uv1 = getTexCoord(triangleIndex.y);
const vec2 uv2 = getTexCoord(triangleIndex.z);
const vec2 uv0 = texCoords.t[triangleIndex.x];
const vec2 uv1 = texCoords.t[triangleIndex.y];
const vec2 uv2 = texCoords.t[triangleIndex.z];
const vec2 texcoord0 = uv0 * barycentrics.x + uv1 * barycentrics.y + uv2 * barycentrics.z;
// https://en.wikipedia.org/wiki/Path_tracing
// Material of the object
GltfShadeMaterial mat = materials[nonuniformEXT(matIndex)];
GltfShadeMaterial mat = materials.m[matIndex];
vec3 emittance = mat.emissiveFactor;
// Pick a random direction from here and keep going.

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 450
layout(location = 0) in vec2 outUV;
layout(location = 0) out vec4 fragColor;

View file

@ -16,13 +16,17 @@
* 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 "binding.glsl"
#include "gltf.glsl"
#include "raycommon.glsl"
@ -36,14 +40,18 @@ layout(location = 1) rayPayloadEXT bool isShadowed;
layout(set = 0, binding = 0 ) uniform accelerationStructureEXT topLevelAS;
layout(set = 0, binding = 2) readonly buffer _InstanceInfo {PrimMeshInfo primInfo[];};
layout(set = 1, binding = B_VERTICES) readonly buffer _VertexBuf {float vertices[];};
layout(set = 1, binding = B_INDICES) readonly buffer _Indices {uint indices[];};
layout(set = 1, binding = B_NORMALS) readonly buffer _NormalBuf {float normals[];};
layout(set = 1, binding = B_TEXCOORDS) readonly buffer _TexCoordBuf {float texcoord0[];};
layout(set = 1, binding = B_MATERIALS) readonly buffer _MaterialBuffer {GltfShadeMaterial materials[];};
layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures
//layout(set = 1, binding = B_MATERIALS) readonly buffer _MaterialBuffer {GltfShadeMaterial materials[];};
layout(buffer_reference, scalar) readonly buffer Vertices { vec3 v[]; };
layout(buffer_reference, scalar) readonly buffer Indices { uint i[]; };
layout(buffer_reference, scalar) readonly buffer Normals { vec3 n[]; };
layout(buffer_reference, scalar) readonly buffer TexCoords { vec2 t[]; };
layout(buffer_reference, scalar) readonly buffer Materials { GltfShadeMaterial m[]; };
layout(set = 1, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; };
layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures
// clang-format on
layout(push_constant) uniform Constants
@ -55,33 +63,6 @@ layout(push_constant) uniform Constants
}
pushC;
// Return the vertex position
vec3 getVertex(uint index)
{
vec3 vp;
vp.x = vertices[3 * index + 0];
vp.y = vertices[3 * index + 1];
vp.z = vertices[3 * index + 2];
return vp;
}
vec3 getNormal(uint index)
{
vec3 vp;
vp.x = normals[3 * index + 0];
vp.y = normals[3 * index + 1];
vp.z = normals[3 * index + 2];
return vp;
}
vec2 getTexCoord(uint index)
{
vec2 vp;
vp.x = texcoord0[2 * index + 0];
vp.y = texcoord0[2 * index + 1];
return vp;
}
void main()
{
@ -93,33 +74,39 @@ void main()
uint vertexOffset = pinfo.vertexOffset; // Vertex offset as defined in glTF
uint matIndex = max(0, pinfo.materialIndex); // material of primitive mesh
Materials gltfMat = Materials(sceneDesc.materialAddress);
Vertices vertices = Vertices(sceneDesc.vertexAddress);
Indices indices = Indices(sceneDesc.indexAddress);
Normals normals = Normals(sceneDesc.normalAddress);
TexCoords texCoords = TexCoords(sceneDesc.uvAddress);
Materials materials = Materials(sceneDesc.materialAddress);
// Getting the 3 indices of the triangle (local)
ivec3 triangleIndex = ivec3(indices[nonuniformEXT(indexOffset + 0)], //
indices[nonuniformEXT(indexOffset + 1)], //
indices[nonuniformEXT(indexOffset + 2)]);
ivec3 triangleIndex = ivec3(indices.i[indexOffset + 0], indices.i[indexOffset + 1], indices.i[indexOffset + 2]);
triangleIndex += ivec3(vertexOffset); // (global)
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
// Vertex of the triangle
const vec3 pos0 = getVertex(triangleIndex.x);
const vec3 pos1 = getVertex(triangleIndex.y);
const vec3 pos2 = getVertex(triangleIndex.z);
const vec3 pos0 = vertices.v[triangleIndex.x];
const vec3 pos1 = vertices.v[triangleIndex.y];
const vec3 pos2 = vertices.v[triangleIndex.z];
const vec3 position = pos0 * barycentrics.x + pos1 * barycentrics.y + pos2 * barycentrics.z;
const vec3 world_position = vec3(gl_ObjectToWorldEXT * vec4(position, 1.0));
// Normal
const vec3 nrm0 = getNormal(triangleIndex.x);
const vec3 nrm1 = getNormal(triangleIndex.y);
const vec3 nrm2 = getNormal(triangleIndex.z);
vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z);
const vec3 nrm0 = normals.n[triangleIndex.x];
const vec3 nrm1 = normals.n[triangleIndex.y];
const vec3 nrm2 = normals.n[triangleIndex.z];
vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z);
const vec3 world_normal = normalize(vec3(normal * gl_WorldToObjectEXT));
const vec3 geom_normal = normalize(cross(pos1 - pos0, pos2 - pos0));
// TexCoord
const vec2 uv0 = getTexCoord(triangleIndex.x);
const vec2 uv1 = getTexCoord(triangleIndex.y);
const vec2 uv2 = getTexCoord(triangleIndex.z);
const vec2 uv0 = texCoords.t[triangleIndex.x];
const vec2 uv1 = texCoords.t[triangleIndex.y];
const vec2 uv2 = texCoords.t[triangleIndex.z];
const vec2 texcoord0 = uv0 * barycentrics.x + uv1 * barycentrics.y + uv2 * barycentrics.z;
// Vector toward the light
@ -140,7 +127,7 @@ void main()
}
// Material of the object
GltfShadeMaterial mat = materials[nonuniformEXT(matIndex)];
GltfShadeMaterial mat = materials.m[matIndex];
// Diffuse
vec3 diffuse = computeDiffuse(mat, L, world_normal);
@ -160,9 +147,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

@ -17,7 +17,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,8 +16,8 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* 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,
// "GPU Random Numbers via the Tiny Encryption Algorithm"
uint tea(uint val0, uint val1)

View file

@ -16,16 +16,21 @@
* 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
#extension GL_EXT_buffer_reference2 : require
#include "binding.glsl"
#include "gltf.glsl"
// clang-format off
layout( set = 0, binding = B_MATRICES) readonly buffer _Matrix { mat4 matrices[]; };
layout(buffer_reference, scalar) buffer Matrices { mat4 m[]; };
layout( set = 0, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; };
// clang-format on
layout(binding = 0) uniform UniformBufferObject
@ -42,7 +47,7 @@ layout(push_constant) uniform shaderInformation
uint instanceId;
float lightIntensity;
int lightType;
int materialId;
int materialId;
}
pushC;
@ -65,7 +70,9 @@ out gl_PerVertex
void main()
{
mat4 objMatrix = matrices[pushC.instanceId];
Matrices matrices = Matrices(sceneDesc.matrixAddress);
mat4 objMatrix = matrices.m[pushC.instanceId];
mat4 objMatrixIT = transpose(inverse(objMatrix));
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));