Refactoring
This commit is contained in:
parent
3e399adf0a
commit
d90ce79135
222 changed files with 9045 additions and 5734 deletions
|
|
@ -34,27 +34,48 @@ of the number of elements and offsets.
|
|||
From the source tutorial, we will not need the following and therefore remove it:
|
||||
|
||||
~~~~C
|
||||
struct ObjModel {..};
|
||||
struct ObjInstance {..};
|
||||
std::vector<ObjModel> m_objModel;
|
||||
std::vector<ObjInstance> m_objInstance;
|
||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||
std::vector<ObjModel> m_objModel; // Model on host
|
||||
std::vector<ObjDesc> m_objDesc; // Model description for device access
|
||||
std::vector<ObjInstance> m_instances; // Scene model instances
|
||||
~~~~
|
||||
|
||||
But instead, we will use this following structure to retrieve the information of the primitive that has been hit in the closest hit shader;
|
||||
In `host_device.h` we will add new host/device structures: PrimMeshInfo, SceneDesc and GltfShadeMaterial.
|
||||
|
||||
~~~~C
|
||||
// Structure used for retrieving the primitive information in the closest hit
|
||||
// The gl_InstanceCustomIndexNV
|
||||
struct RtPrimitiveLookup
|
||||
{
|
||||
uint32_t indexOffset;
|
||||
uint32_t vertexOffset;
|
||||
int materialIndex;
|
||||
};
|
||||
~~~~
|
||||
// Structure used for retrieving the primitive information in the closest hit
|
||||
struct PrimMeshInfo
|
||||
{
|
||||
uint indexOffset;
|
||||
uint vertexOffset;
|
||||
int materialIndex;
|
||||
};
|
||||
|
||||
And for holding the information, we will be using a helper class to hold glTF scene and buffers for the data.
|
||||
// Scene buffer addresses
|
||||
struct SceneDesc
|
||||
{
|
||||
uint64_t vertexAddress; // Address of the Vertex buffer
|
||||
uint64_t normalAddress; // Address of the Normal buffer
|
||||
uint64_t uvAddress; // Address of the texture coordinates buffer
|
||||
uint64_t indexAddress; // Address of the triangle indices buffer
|
||||
uint64_t materialAddress; // Address of the Materials buffer (GltfShadeMaterial)
|
||||
uint64_t primInfoAddress; // Address of the mesh primitives buffer (PrimMeshInfo)
|
||||
};
|
||||
~~~~
|
||||
|
||||
And also, our glTF material representation for the shading. This is a stripped down version of the glTF PBR. If you are interested in the
|
||||
correct PBR implementation, check out [vk_raytrace](https://github.com/nvpro-samples/vk_raytrace).
|
||||
|
||||
~~~~ C
|
||||
struct GltfShadeMaterial
|
||||
{
|
||||
vec4 pbrBaseColorFactor;
|
||||
vec3 emissiveFactor;
|
||||
int pbrBaseColorTexture;
|
||||
};
|
||||
~~~~
|
||||
|
||||
|
||||
And for holding the all the buffers allocated for representing the scene, we will store them in the following.
|
||||
|
||||
~~~~C
|
||||
nvh::GltfScene m_gltfScene;
|
||||
|
|
@ -63,26 +84,10 @@ But instead, we will use this following structure to retrieve the information of
|
|||
nvvk::Buffer m_uvBuffer;
|
||||
nvvk::Buffer m_indexBuffer;
|
||||
nvvk::Buffer m_materialBuffer;
|
||||
nvvk::Buffer m_matrixBuffer;
|
||||
nvvk::Buffer m_rtPrimLookup;
|
||||
nvvk::Buffer m_primInfo;
|
||||
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
|
||||
|
|
@ -146,26 +151,12 @@ We are making a simple material, extracting only a few members from the glTF mat
|
|||
~~~~
|
||||
|
||||
|
||||
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,
|
||||
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
|
||||
attributes, we will store the offsets information of that geometry.
|
||||
|
||||
~~~~C
|
||||
// The following is used to find the primitive mesh information in the CHIT
|
||||
std::vector<RtPrimitiveLookup> primLookup;
|
||||
std::vector<PrimMeshInfo> primLookup;
|
||||
for(auto& primMesh : m_gltfScene.m_primMeshes)
|
||||
{
|
||||
primLookup.push_back({primMesh.firstIndex, primMesh.vertexOffset, primMesh.materialIndex});
|
||||
|
|
@ -177,15 +168,14 @@ attributes, we will store the offsets information of that geometry.
|
|||
Finally, we are creating a buffer holding the address of all buffers
|
||||
|
||||
~~~~ C++
|
||||
SceneDescription sceneDesc;
|
||||
SceneDesc 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,
|
||||
sceneDesc.primInfoAddress = nvvk::getBufferDeviceAddress(m_device, m_primInfo.buffer);
|
||||
m_sceneDesc = m_alloc.createBuffer(cmdBuf, sizeof(SceneDesc), &sceneDesc,
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||
~~~~
|
||||
|
||||
|
|
@ -204,18 +194,18 @@ The finalize and releasing staging is waiting for the copy of all data to the GP
|
|||
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_primInfo.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.
|
||||
**:warning: 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
|
||||
|
||||
Instead of `objectToVkGeometryKHR()`, we will be using `primitiveToGeometry(const nvh::GltfPrimMesh& prim)`.
|
||||
The function is similar, only the input is different.
|
||||
Instead of `objectToVkGeometryKHR()`, we will be using `primitiveToVkGeometry(const nvh::GltfPrimMesh& prim)`.
|
||||
The function is similar, only the input is different, except for `VkAccelerationStructureBuildRangeInfoKHR` where
|
||||
we also include the offsets.
|
||||
|
||||
~~~~C
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -231,7 +221,7 @@ auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim)
|
|||
|
||||
// Describe buffer as array of VertexObj.
|
||||
VkAccelerationStructureGeometryTrianglesDataKHR triangles{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR};
|
||||
triangles.vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT; // vec3 vertex position data.
|
||||
triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT; // vec3 vertex position data.
|
||||
triangles.vertexData.deviceAddress = vertexAddress;
|
||||
triangles.vertexStride = sizeof(nvmath::vec3f);
|
||||
// Describe index data (32-bit unsigned int)
|
||||
|
|
@ -264,22 +254,18 @@ auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim)
|
|||
|
||||
## Top Level creation
|
||||
|
||||
There are almost no changes for creating the TLAS but is actually even simpler. Each
|
||||
drawable node has a matrix and an index to the geometry, which in our case, also
|
||||
correspond directly to the BLAS ID. To know which geometry is used, and to find back
|
||||
all the data (see structure `RtPrimitiveLookup`), we will set the `instanceCustomId` member
|
||||
to the primitive mesh id. This value will be recovered with `gl_InstanceCustomIndexEXT`
|
||||
in the closest hit shader.
|
||||
There are almost no differences, besides the fact that the index of the geometry is stored in `primMesh`.
|
||||
|
||||
~~~~C
|
||||
for(auto& node : m_gltfScene.m_nodes)
|
||||
{
|
||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||
rayInst.transform = node.worldMatrix;
|
||||
rayInst.instanceCustomId = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive
|
||||
rayInst.blasId = node.primMesh;
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||
rayInst.hitGroupId = 0; // We will use the same hit group for all objects
|
||||
VkAccelerationStructureInstanceKHR rayInst;
|
||||
rayInst.transform = nvvk::toTransformMatrixKHR(node.worldMatrix);
|
||||
rayInst.instanceCustomIndex = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive
|
||||
rayInst.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(node.primMesh);
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||
rayInst.mask = 0xFF;
|
||||
rayInst.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
||||
tlas.emplace_back(rayInst);
|
||||
}
|
||||
~~~~
|
||||
|
|
@ -288,8 +274,8 @@ in the closest hit shader.
|
|||
## Raster Rendering
|
||||
|
||||
Raster rendering is simple. The shader was changed to use vertex, normal and texture coordinates. For
|
||||
each node, we will be pushing the instance Id (retrieve the matrix) and the material Id. Since we
|
||||
don't have a scene graph, we could loop over all drawable nodes.
|
||||
each node, we will be pushing the material Id this primitive is using. Since we have flatten the scene graph,
|
||||
we can loop over all drawable nodes.
|
||||
|
||||
~~~~C
|
||||
std::vector<VkBuffer> vertexBuffers = {m_vertexBuffer.buffer, m_normalBuffer.buffer, m_uvBuffer.buffer};
|
||||
|
|
@ -301,10 +287,11 @@ don't have a scene graph, we could loop over all drawable nodes.
|
|||
{
|
||||
auto& primitive = m_gltfScene.m_primMeshes[node.primMesh];
|
||||
|
||||
m_pushConstant.instanceId = idxNode++;
|
||||
m_pushConstant.materialId = primitive.materialIndex;
|
||||
m_pcRaster.modelMatrix = node.worldMatrix;
|
||||
m_pcRaster.objIndex = node.primMesh;
|
||||
m_pcRaster.materialId = primitive.materialIndex;
|
||||
vkCmdPushConstants(cmdBuf, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
|
||||
sizeof(ObjPushConstant), &m_pushConstant);
|
||||
sizeof(PushConstantRaster), &m_pcRaster);
|
||||
vkCmdDrawIndexed(cmdBuf, primitive.indexCount, 1, primitive.firstIndex, primitive.vertexOffset, 0);
|
||||
}
|
||||
~~~~
|
||||
|
|
@ -316,12 +303,12 @@ In `createRtDescriptorSet()`, the only change we will add is the primitive info
|
|||
the data when hitting a triangle.
|
||||
|
||||
~~~~C
|
||||
m_rtDescSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||
m_rtDescSetLayoutBind.addBinding(ePrimLookup, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); // Primitive info
|
||||
// ...
|
||||
VkDescriptorBufferInfo primitiveInfoDesc{m_rtPrimLookup.buffer, 0, VK_WHOLE_SIZE};
|
||||
// ...
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, 2, &primitiveInfoDesc));
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, ePrimLookup, &primitiveInfoDesc));
|
||||
~~~~
|
||||
|
||||
|
||||
|
|
@ -393,12 +380,12 @@ void HelloVulkan::updateFrame()
|
|||
refCamMatrix = m;
|
||||
refFov = fov;
|
||||
}
|
||||
m_rtPushConstants.frame++;
|
||||
m_pcRay.frame++;
|
||||
}
|
||||
|
||||
void HelloVulkan::resetFrame()
|
||||
{
|
||||
m_rtPushConstants.frame = -1;
|
||||
m_pcRay.frame = -1;
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
@ -436,16 +423,16 @@ To accumulate the samples, instead of only write to the image, we will also use
|
|||
|
||||
~~~~C
|
||||
// Do accumulation over time
|
||||
if(pushC.frame > 0)
|
||||
if(pcRay.frame > 0)
|
||||
{
|
||||
float a = 1.0f / float(pushC.frame + 1);
|
||||
float a = 1.0f / float(pcRay.frame + 1);
|
||||
vec3 old_color = imageLoad(image, ivec2(gl_LaunchIDEXT.xy)).xyz;
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(mix(old_color, prd.hitValue, a), 1.f));
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(mix(old_color, hitValue, a), 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
// First frame, replace the value in the buffer
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(prd.hitValue, 1.f));
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(hitValue, 1.f));
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -39,23 +39,10 @@
|
|||
#include "nvvk/shaders_vk.hpp"
|
||||
|
||||
#include "nvh/alignment.hpp"
|
||||
#include "shaders/binding.glsl"
|
||||
#include "shaders/gltf.glsl"
|
||||
#include "nvvk/buffers_vk.hpp"
|
||||
|
||||
extern std::vector<std::string> defaultSearchPaths;
|
||||
|
||||
// Holding the camera matrices
|
||||
struct CameraMatrices
|
||||
{
|
||||
nvmath::mat4f view;
|
||||
nvmath::mat4f proj;
|
||||
nvmath::mat4f viewInverse;
|
||||
// #VKRay
|
||||
nvmath::mat4f projInverse;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Keep the handle on the device
|
||||
// Initialize the tool to do all our allocations: buffers, images
|
||||
|
|
@ -75,16 +62,17 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
|||
{
|
||||
// Prepare new UBO contents on host.
|
||||
const float aspectRatio = m_size.width / static_cast<float>(m_size.height);
|
||||
CameraMatrices hostUBO = {};
|
||||
hostUBO.view = CameraManip.getMatrix();
|
||||
hostUBO.proj = nvmath::perspectiveVK(CameraManip.getFov(), aspectRatio, 0.1f, 1000.0f);
|
||||
// hostUBO.proj[1][1] *= -1; // Inverting Y for Vulkan (not needed with perspectiveVK).
|
||||
hostUBO.viewInverse = nvmath::invert(hostUBO.view);
|
||||
// #VKRay
|
||||
hostUBO.projInverse = nvmath::invert(hostUBO.proj);
|
||||
GlobalUniforms hostUBO = {};
|
||||
const auto& view = CameraManip.getMatrix();
|
||||
const auto& proj = nvmath::perspectiveVK(CameraManip.getFov(), aspectRatio, 0.1f, 1000.0f);
|
||||
// proj[1][1] *= -1; // Inverting Y for Vulkan (not needed with perspectiveVK).
|
||||
|
||||
hostUBO.viewProj = proj * view;
|
||||
hostUBO.viewInverse = nvmath::invert(view);
|
||||
hostUBO.projInverse = nvmath::invert(proj);
|
||||
|
||||
// UBO on the device, and what stages access it.
|
||||
VkBuffer deviceUBO = m_cameraMat.buffer;
|
||||
VkBuffer deviceUBO = m_bGlobals.buffer;
|
||||
auto uboUsageStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
|
||||
|
||||
// Ensure that the modified UBO is not visible to previous frames.
|
||||
|
|
@ -100,7 +88,7 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
|||
|
||||
// Schedule the host-to-device upload. (hostUBO is copied into the cmd
|
||||
// buffer so it is okay to deallocate when the function returns).
|
||||
vkCmdUpdateBuffer(cmdBuf, m_cameraMat.buffer, 0, sizeof(CameraMatrices), &hostUBO);
|
||||
vkCmdUpdateBuffer(cmdBuf, m_bGlobals.buffer, 0, sizeof(GlobalUniforms), &hostUBO);
|
||||
|
||||
// Making sure the updated UBO will be visible.
|
||||
VkBufferMemoryBarrier afterBarrier{VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER};
|
||||
|
|
@ -119,13 +107,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf)
|
|||
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);
|
||||
// Camera matrices
|
||||
bind.addBinding(SceneBindings::eGlobals, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1,
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||
// Array of textures
|
||||
auto nbTextures = static_cast<uint32_t>(m_textures.size());
|
||||
bind.addBinding(B_TEXTURES, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTextures,
|
||||
bind.addBinding(SceneBindings::eTextures, 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,
|
||||
// Scene buffers
|
||||
bind.addBinding(eSceneDesc, 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);
|
||||
|
||||
|
|
@ -142,17 +132,17 @@ void HelloVulkan::updateDescriptorSet()
|
|||
std::vector<VkWriteDescriptorSet> writes;
|
||||
|
||||
// Camera matrices and scene description
|
||||
VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE};
|
||||
VkDescriptorBufferInfo dbiUnif{m_bGlobals.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_SCENEDESC, &sceneDesc));
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, SceneBindings::eGlobals, &dbiUnif));
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, eSceneDesc, &sceneDesc));
|
||||
|
||||
// All texture samplers
|
||||
std::vector<VkDescriptorImageInfo> diit;
|
||||
for(auto& texture : m_textures)
|
||||
diit.emplace_back(texture.descriptor);
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, B_TEXTURES, diit.data()));
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, SceneBindings::eTextures, diit.data()));
|
||||
|
||||
// Writing the information
|
||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||
|
|
@ -164,7 +154,7 @@ void HelloVulkan::updateDescriptorSet()
|
|||
//
|
||||
void HelloVulkan::createGraphicsPipeline()
|
||||
{
|
||||
VkPushConstantRange pushConstantRanges = {VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(ObjPushConstant)};
|
||||
VkPushConstantRange pushConstantRanges = {VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstantRaster)};
|
||||
|
||||
// Creating the Pipeline Layout
|
||||
VkPipelineLayoutCreateInfo createInfo{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
|
||||
|
|
@ -181,7 +171,7 @@ void HelloVulkan::createGraphicsPipeline()
|
|||
gpb.depthStencilState.depthTestEnable = true;
|
||||
gpb.addShader(nvh::loadFile("spv/vert_shader.vert.spv", true, paths, true), VK_SHADER_STAGE_VERTEX_BIT);
|
||||
gpb.addShader(nvh::loadFile("spv/frag_shader.frag.spv", true, paths, true), VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
gpb.addBindingDescriptions({{0, sizeof(nvmath::vec3)}, {1, sizeof(nvmath::vec3)}, {2, sizeof(nvmath::vec2)}});
|
||||
gpb.addBindingDescriptions({{0, sizeof(nvmath::vec3f)}, {1, sizeof(nvmath::vec3f)}, {2, sizeof(nvmath::vec2f)}});
|
||||
gpb.addAttributeDescriptions({
|
||||
{0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0}, // Position
|
||||
{1, 1, VK_FORMAT_R32G32B32_SFLOAT, 0}, // Normal
|
||||
|
|
@ -232,41 +222,30 @@ void HelloVulkan::loadScene(const std::string& filename)
|
|||
|
||||
// Copying all materials, only the elements we need
|
||||
std::vector<GltfShadeMaterial> shadeMaterials;
|
||||
for(auto& m : m_gltfScene.m_materials)
|
||||
for(const 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);
|
||||
|
||||
// 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,
|
||||
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;
|
||||
std::vector<PrimMeshInfo> primLookup;
|
||||
for(auto& primMesh : m_gltfScene.m_primMeshes)
|
||||
{
|
||||
primLookup.push_back({primMesh.firstIndex, primMesh.vertexOffset, primMesh.materialIndex});
|
||||
}
|
||||
m_rtPrimLookup =
|
||||
m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||
m_primInfo = m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||
|
||||
|
||||
SceneDescription sceneDesc;
|
||||
SceneDesc 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,
|
||||
sceneDesc.primInfoAddress = nvvk::getBufferDeviceAddress(m_device, m_primInfo.buffer);
|
||||
m_sceneDesc = m_alloc.createBuffer(cmdBuf, sizeof(SceneDesc), &sceneDesc,
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||
|
||||
// Creates all textures found
|
||||
|
|
@ -280,8 +259,7 @@ void HelloVulkan::loadScene(const std::string& filename)
|
|||
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_primInfo.buffer);
|
||||
NAME_VK(m_sceneDesc.buffer);
|
||||
}
|
||||
|
||||
|
|
@ -292,9 +270,9 @@ void HelloVulkan::loadScene(const std::string& filename)
|
|||
//
|
||||
void HelloVulkan::createUniformBuffer()
|
||||
{
|
||||
m_cameraMat = m_alloc.createBuffer(sizeof(CameraMatrices), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
m_debug.setObjectName(m_cameraMat.buffer, "cameraMat");
|
||||
m_bGlobals = m_alloc.createBuffer(sizeof(GlobalUniforms), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
m_debug.setObjectName(m_bGlobals.buffer, "Globals");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -347,7 +325,7 @@ void HelloVulkan::createTextureImages(const VkCommandBuffer& cmdBuf, tinygltf::M
|
|||
VkImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, imageCreateInfo);
|
||||
m_textures.emplace_back(m_alloc.createTexture(image, ivInfo, samplerCreateInfo));
|
||||
|
||||
m_debug.setObjectName(m_textures[i].image, std::string("Txt" + std::to_string(i)).c_str());
|
||||
m_debug.setObjectName(m_textures[i].image, std::string("Txt" + std::to_string(i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -361,15 +339,14 @@ void HelloVulkan::destroyResources()
|
|||
vkDestroyDescriptorPool(m_device, m_descPool, nullptr);
|
||||
vkDestroyDescriptorSetLayout(m_device, m_descSetLayout, nullptr);
|
||||
|
||||
m_alloc.destroy(m_cameraMat);
|
||||
m_alloc.destroy(m_bGlobals);
|
||||
|
||||
m_alloc.destroy(m_vertexBuffer);
|
||||
m_alloc.destroy(m_normalBuffer);
|
||||
m_alloc.destroy(m_uvBuffer);
|
||||
m_alloc.destroy(m_indexBuffer);
|
||||
m_alloc.destroy(m_materialBuffer);
|
||||
m_alloc.destroy(m_matrixBuffer);
|
||||
m_alloc.destroy(m_rtPrimLookup);
|
||||
m_alloc.destroy(m_primInfo);
|
||||
m_alloc.destroy(m_sceneDesc);
|
||||
|
||||
for(auto& t : m_textures)
|
||||
|
|
@ -426,10 +403,11 @@ void HelloVulkan::rasterize(const VkCommandBuffer& cmdBuf)
|
|||
{
|
||||
auto& primitive = m_gltfScene.m_primMeshes[node.primMesh];
|
||||
|
||||
m_pushConstant.instanceId = idxNode++;
|
||||
m_pushConstant.materialId = primitive.materialIndex;
|
||||
m_pcRaster.modelMatrix = node.worldMatrix;
|
||||
m_pcRaster.objIndex = node.primMesh;
|
||||
m_pcRaster.materialId = primitive.materialIndex;
|
||||
vkCmdPushConstants(cmdBuf, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
|
||||
sizeof(ObjPushConstant), &m_pushConstant);
|
||||
sizeof(PushConstantRaster), &m_pcRaster);
|
||||
vkCmdDrawIndexed(cmdBuf, primitive.indexCount, 1, primitive.firstIndex, primitive.vertexOffset, 0);
|
||||
}
|
||||
|
||||
|
|
@ -610,7 +588,7 @@ void HelloVulkan::initRayTracing()
|
|||
//--------------------------------------------------------------------------------------------------
|
||||
// Converting a GLTF primitive in the Raytracing Geometry used for the BLAS
|
||||
//
|
||||
auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim)
|
||||
auto HelloVulkan::primitiveToVkGeometry(const nvh::GltfPrimMesh& prim)
|
||||
{
|
||||
// BLAS builder requires raw device addresses.
|
||||
VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer);
|
||||
|
|
@ -620,7 +598,7 @@ auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim)
|
|||
|
||||
// Describe buffer as array of VertexObj.
|
||||
VkAccelerationStructureGeometryTrianglesDataKHR triangles{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR};
|
||||
triangles.vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT; // vec3 vertex position data.
|
||||
triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT; // vec3 vertex position data.
|
||||
triangles.vertexData.deviceAddress = vertexAddress;
|
||||
triangles.vertexStride = sizeof(nvmath::vec3f);
|
||||
// Describe index data (32-bit unsigned int)
|
||||
|
|
@ -638,7 +616,7 @@ auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim)
|
|||
|
||||
VkAccelerationStructureBuildRangeInfoKHR offset;
|
||||
offset.firstVertex = prim.vertexOffset;
|
||||
offset.primitiveCount = prim.indexCount / 3;
|
||||
offset.primitiveCount = maxPrimitiveCount;
|
||||
offset.primitiveOffset = prim.firstIndex * sizeof(uint32_t);
|
||||
offset.transformOffset = 0;
|
||||
|
||||
|
|
@ -660,25 +638,28 @@ void HelloVulkan::createBottomLevelAS()
|
|||
allBlas.reserve(m_gltfScene.m_primMeshes.size());
|
||||
for(auto& primMesh : m_gltfScene.m_primMeshes)
|
||||
{
|
||||
auto geo = primitiveToGeometry(primMesh);
|
||||
auto geo = primitiveToVkGeometry(primMesh);
|
||||
allBlas.push_back({geo});
|
||||
}
|
||||
m_rtBuilder.buildBlas(allBlas, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
void HelloVulkan::createTopLevelAS()
|
||||
{
|
||||
std::vector<VkAccelerationStructureInstanceKHR> tlas;
|
||||
tlas.reserve(m_gltfScene.m_nodes.size());
|
||||
for(auto& node : m_gltfScene.m_nodes)
|
||||
{
|
||||
VkAccelerationStructureInstanceKHR rayInst;
|
||||
VkAccelerationStructureInstanceKHR rayInst{};
|
||||
rayInst.transform = nvvk::toTransformMatrixKHR(node.worldMatrix);
|
||||
rayInst.instanceCustomIndex = node.primMesh; // gl_InstanceCustomIndexEXT: to find which primitive
|
||||
rayInst.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(node.primMesh);
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||
rayInst.mask = 0xFF;
|
||||
rayInst.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
||||
rayInst.mask = 0xFF;
|
||||
tlas.emplace_back(rayInst);
|
||||
}
|
||||
m_rtBuilder.buildTlas(tlas, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR);
|
||||
|
|
@ -689,13 +670,12 @@ void HelloVulkan::createTopLevelAS()
|
|||
//
|
||||
void HelloVulkan::createRtDescriptorSet()
|
||||
{
|
||||
// Top-level acceleration structure, usable by both the ray generation and the closest hit (to
|
||||
// shoot shadow rays)
|
||||
m_rtDescSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1,
|
||||
// Top-level acceleration structure, usable by both the ray generation and the closest hit (to shoot shadow rays)
|
||||
m_rtDescSetLayoutBind.addBinding(RtxBindings::eTlas, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1,
|
||||
VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); // TLAS
|
||||
m_rtDescSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1,
|
||||
m_rtDescSetLayoutBind.addBinding(RtxBindings::eOutImage, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1,
|
||||
VK_SHADER_STAGE_RAYGEN_BIT_KHR); // Output image
|
||||
m_rtDescSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||
m_rtDescSetLayoutBind.addBinding(RtxBindings::ePrimLookup, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); // Primitive info
|
||||
|
||||
m_rtDescPool = m_rtDescSetLayoutBind.createPool(m_device);
|
||||
|
|
@ -713,12 +693,12 @@ void HelloVulkan::createRtDescriptorSet()
|
|||
descASInfo.accelerationStructureCount = 1;
|
||||
descASInfo.pAccelerationStructures = &tlas;
|
||||
VkDescriptorImageInfo imageInfo{{}, m_offscreenColor.descriptor.imageView, VK_IMAGE_LAYOUT_GENERAL};
|
||||
VkDescriptorBufferInfo primitiveInfoDesc{m_rtPrimLookup.buffer, 0, VK_WHOLE_SIZE};
|
||||
VkDescriptorBufferInfo primitiveInfoDesc{m_primInfo.buffer, 0, VK_WHOLE_SIZE};
|
||||
|
||||
std::vector<VkWriteDescriptorSet> writes;
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, 0, &descASInfo));
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, 1, &imageInfo));
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, 2, &primitiveInfoDesc));
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, RtxBindings::eTlas, &descASInfo));
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, RtxBindings::eOutImage, &imageInfo));
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, RtxBindings::ePrimLookup, &primitiveInfoDesc));
|
||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -731,7 +711,7 @@ void HelloVulkan::updateRtDescriptorSet()
|
|||
{
|
||||
// (1) Output buffer
|
||||
VkDescriptorImageInfo imageInfo{{}, m_offscreenColor.descriptor.imageView, VK_IMAGE_LAYOUT_GENERAL};
|
||||
VkWriteDescriptorSet wds = m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, 1, &imageInfo);
|
||||
VkWriteDescriptorSet wds = m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, RtxBindings::eOutImage, &imageInfo);
|
||||
vkUpdateDescriptorSets(m_device, 1, &wds, 0, nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -804,7 +784,7 @@ void HelloVulkan::createRtPipeline()
|
|||
|
||||
// Push constant: we want to be able to update constants used by the shaders
|
||||
VkPushConstantRange pushConstant{VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR,
|
||||
0, sizeof(RtPushConstant)};
|
||||
0, sizeof(PushConstantRay)};
|
||||
|
||||
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
|
||||
|
|
@ -856,10 +836,10 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c
|
|||
|
||||
m_debug.beginLabel(cmdBuf, "Ray trace");
|
||||
// Initializing push constant values
|
||||
m_rtPushConstants.clearColor = clearColor;
|
||||
m_rtPushConstants.lightPosition = m_pushConstant.lightPosition;
|
||||
m_rtPushConstants.lightIntensity = m_pushConstant.lightIntensity;
|
||||
m_rtPushConstants.lightType = m_pushConstant.lightType;
|
||||
m_pcRay.clearColor = clearColor;
|
||||
m_pcRay.lightPosition = m_pcRaster.lightPosition;
|
||||
m_pcRay.lightIntensity = m_pcRaster.lightIntensity;
|
||||
m_pcRay.lightType = m_pcRaster.lightType;
|
||||
|
||||
|
||||
std::vector<VkDescriptorSet> descSets{m_rtDescSet, m_descSet};
|
||||
|
|
@ -868,7 +848,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c
|
|||
(uint32_t)descSets.size(), descSets.data(), 0, nullptr);
|
||||
vkCmdPushConstants(cmdBuf, m_rtPipelineLayout,
|
||||
VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR,
|
||||
0, sizeof(RtPushConstant), &m_rtPushConstants);
|
||||
0, sizeof(PushConstantRay), &m_pcRay);
|
||||
|
||||
|
||||
auto& regions = m_sbtWrapper.getRegions();
|
||||
|
|
@ -896,10 +876,10 @@ void HelloVulkan::updateFrame()
|
|||
refCamMatrix = m;
|
||||
refFov = fov;
|
||||
}
|
||||
m_rtPushConstants.frame++;
|
||||
m_pcRay.frame++;
|
||||
}
|
||||
|
||||
void HelloVulkan::resetFrame()
|
||||
{
|
||||
m_rtPushConstants.frame = -1;
|
||||
m_pcRay.frame = -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "shaders/host_device.h"
|
||||
|
||||
#include "nvvk/appbase_vk.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
|
|
@ -52,25 +54,6 @@ public:
|
|||
void destroyResources();
|
||||
void rasterize(const VkCommandBuffer& cmdBuff);
|
||||
|
||||
// Structure used for retrieving the primitive information in the closest hit
|
||||
// The gl_InstanceCustomIndexNV
|
||||
struct RtPrimitiveLookup
|
||||
{
|
||||
uint32_t indexOffset;
|
||||
uint32_t vertexOffset;
|
||||
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;
|
||||
|
|
@ -78,20 +61,18 @@ public:
|
|||
nvvk::Buffer m_uvBuffer;
|
||||
nvvk::Buffer m_indexBuffer;
|
||||
nvvk::Buffer m_materialBuffer;
|
||||
nvvk::Buffer m_matrixBuffer;
|
||||
nvvk::Buffer m_rtPrimLookup;
|
||||
nvvk::Buffer m_primInfo;
|
||||
nvvk::Buffer m_sceneDesc;
|
||||
|
||||
// Information pushed at each draw call
|
||||
struct ObjPushConstant
|
||||
{
|
||||
nvmath::vec3f lightPosition{0.f, 4.5f, 0.f};
|
||||
int instanceId{0}; // To retrieve the transformation matrix
|
||||
float lightIntensity{10.f};
|
||||
int lightType{0}; // 0: point, 1: infinite
|
||||
int materialId{0};
|
||||
PushConstantRaster m_pcRaster{
|
||||
{1}, // Identity matrix
|
||||
{0.f, 4.5f, 0.f}, // light position
|
||||
0, // instance Id
|
||||
10.f, // light intensity
|
||||
0, // light type
|
||||
0 // material id
|
||||
};
|
||||
ObjPushConstant m_pushConstant;
|
||||
|
||||
// Graphic pipeline
|
||||
VkPipelineLayout m_pipelineLayout;
|
||||
|
|
@ -101,13 +82,14 @@ public:
|
|||
VkDescriptorSetLayout m_descSetLayout;
|
||||
VkDescriptorSet m_descSet;
|
||||
|
||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
nvvk::Buffer m_bGlobals; // Device-Host of the camera matrices
|
||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
|
||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
// #Post
|
||||
|
||||
// #Post - Draw the rendered image on a quad using a tonemapper
|
||||
void createOffscreenRender();
|
||||
void createPostPipeline();
|
||||
void createPostDescriptor();
|
||||
|
|
@ -128,8 +110,8 @@ public:
|
|||
VkFormat m_offscreenDepthFormat{VK_FORMAT_X8_D24_UNORM_PACK32};
|
||||
|
||||
// #VKRay
|
||||
auto primitiveToGeometry(const nvh::GltfPrimMesh& prim);
|
||||
void initRayTracing();
|
||||
auto primitiveToVkGeometry(const nvh::GltfPrimMesh& prim);
|
||||
void createBottomLevelAS();
|
||||
void createTopLevelAS();
|
||||
void createRtDescriptorSet();
|
||||
|
|
@ -150,12 +132,5 @@ public:
|
|||
VkPipeline m_rtPipeline;
|
||||
nvvk::SBTWrapper m_sbtWrapper;
|
||||
|
||||
struct RtPushConstant
|
||||
{
|
||||
nvmath::vec4f clearColor;
|
||||
nvmath::vec3f lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int frame{0};
|
||||
} m_rtPushConstants;
|
||||
PushConstantRay m_pcRay{};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,14 +54,14 @@ static void onErrorCallback(int error, const char* description)
|
|||
void renderUI(HelloVulkan& helloVk, bool useRaytracer)
|
||||
{
|
||||
ImGuiH::CameraWidget();
|
||||
if( !useRaytracer && ImGui::CollapsingHeader("Light"))
|
||||
if(!useRaytracer && ImGui::CollapsingHeader("Light"))
|
||||
{
|
||||
ImGui::RadioButton("Point", &helloVk.m_pushConstant.lightType, 0);
|
||||
ImGui::RadioButton("Point", &helloVk.m_pcRaster.lightType, 0);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Infinite", &helloVk.m_pushConstant.lightType, 1);
|
||||
ImGui::RadioButton("Infinite", &helloVk.m_pcRaster.lightType, 1);
|
||||
|
||||
ImGui::SliderFloat3("Position", &helloVk.m_pushConstant.lightPosition.x, -20.f, 20.f);
|
||||
ImGui::SliderFloat("Intensity", &helloVk.m_pushConstant.lightIntensity, 0.f, 150.f);
|
||||
ImGui::SliderFloat3("Position", &helloVk.m_pcRaster.lightPosition.x, -20.f, 20.f);
|
||||
ImGui::SliderFloat("Intensity", &helloVk.m_pcRaster.lightIntensity, 0.f, 150.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
ImGuiH::Panel::Begin();
|
||||
ImGui::ColorEdit3("Clear color", reinterpret_cast<float*>(&clearColor));
|
||||
if (ImGui::Checkbox("Ray Tracer mode", &useRaytracer)) // Switch between raster and ray tracing
|
||||
if(ImGui::Checkbox("Ray Tracer mode", &useRaytracer)) // Switch between raster and ray tracing
|
||||
helloVk.resetFrame();
|
||||
renderUI(helloVk, useRaytracer);
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
|
|
|
|||
|
|
@ -26,34 +26,26 @@
|
|||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
#extension GL_EXT_buffer_reference2 : require
|
||||
|
||||
#include "binding.glsl"
|
||||
#include "gltf.glsl"
|
||||
#include "host_device.h"
|
||||
|
||||
|
||||
layout(push_constant) uniform shaderInformation
|
||||
layout(push_constant) uniform _PushConstantRaster
|
||||
{
|
||||
vec3 lightPosition;
|
||||
uint instanceId;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int matetrialId;
|
||||
}
|
||||
pushC;
|
||||
PushConstantRaster pcRaster;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
// Incoming
|
||||
layout(location = 1) in vec2 fragTexCoord;
|
||||
layout(location = 2) in vec3 fragNormal;
|
||||
layout(location = 3) in vec3 viewDir;
|
||||
layout(location = 4) in vec3 worldPos;
|
||||
layout(location = 1) in vec3 i_worldPos;
|
||||
layout(location = 2) in vec3 i_worldNrm;
|
||||
layout(location = 3) in vec3 i_viewDir;
|
||||
layout(location = 4) in vec2 i_texCoord;
|
||||
// Outgoing
|
||||
layout(location = 0) out vec4 outColor;
|
||||
layout(location = 0) out vec4 o_color;
|
||||
// Buffers
|
||||
|
||||
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;
|
||||
layout(set = 0, binding = eSceneDesc ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; } ;
|
||||
layout(set = 0, binding = eTextures) uniform sampler2D[] textureSamplers;
|
||||
// clang-format on
|
||||
|
||||
|
||||
|
|
@ -61,23 +53,23 @@ void main()
|
|||
{
|
||||
// Material of the object
|
||||
GltfMaterial gltfMat = GltfMaterial(sceneDesc.materialAddress);
|
||||
GltfShadeMaterial mat = gltfMat.m[pushC.matetrialId];
|
||||
GltfShadeMaterial mat = gltfMat.m[pcRaster.materialId];
|
||||
|
||||
vec3 N = normalize(fragNormal);
|
||||
vec3 N = normalize(i_worldNrm);
|
||||
|
||||
// Vector toward light
|
||||
vec3 L;
|
||||
float lightIntensity = pushC.lightIntensity;
|
||||
if(pushC.lightType == 0)
|
||||
float lightIntensity = pcRaster.lightIntensity;
|
||||
if(pcRaster.lightType == 0)
|
||||
{
|
||||
vec3 lDir = pushC.lightPosition - worldPos;
|
||||
vec3 lDir = pcRaster.lightPosition - i_worldPos;
|
||||
float d = length(lDir);
|
||||
lightIntensity = pushC.lightIntensity / (d * d);
|
||||
lightIntensity = pcRaster.lightIntensity / (d * d);
|
||||
L = normalize(lDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
L = normalize(pushC.lightPosition - vec3(0));
|
||||
L = normalize(pcRaster.lightPosition);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -86,13 +78,13 @@ void main()
|
|||
if(mat.pbrBaseColorTexture > -1)
|
||||
{
|
||||
uint txtId = mat.pbrBaseColorTexture;
|
||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
|
||||
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], i_texCoord).xyz;
|
||||
diffuse *= diffuseTxt;
|
||||
}
|
||||
|
||||
// Specular
|
||||
vec3 specular = computeSpecular(mat, viewDir, L, N);
|
||||
vec3 specular = computeSpecular(mat, i_viewDir, L, N);
|
||||
|
||||
// Result
|
||||
outColor = vec4(lightIntensity * (diffuse + specular), 1);
|
||||
o_color = vec4(lightIntensity * (diffuse + specular), 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,32 +17,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct GltfShadeMaterial
|
||||
{
|
||||
vec4 pbrBaseColorFactor;
|
||||
vec3 emissiveFactor;
|
||||
int pbrBaseColorTexture;
|
||||
};
|
||||
|
||||
#ifndef __cplusplus
|
||||
struct PrimMeshInfo
|
||||
{
|
||||
uint indexOffset;
|
||||
uint vertexOffset;
|
||||
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;
|
||||
};
|
||||
|
||||
#include "host_device.h"
|
||||
|
||||
vec3 computeDiffuse(GltfShadeMaterial mat, vec3 lightDir, vec3 normal)
|
||||
{
|
||||
|
|
@ -65,4 +41,3 @@ vec3 computeSpecular(GltfShadeMaterial mat, vec3 viewDir, vec3 lightDir, vec3 no
|
|||
|
||||
return vec3(specular);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
112
ray_tracing_gltf/shaders/host_device.h
Normal file
112
ray_tracing_gltf/shaders/host_device.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef COMMON_HOST_DEVICE
|
||||
#define COMMON_HOST_DEVICE
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "nvmath/nvmath.h"
|
||||
// GLSL Type
|
||||
using vec2 = nvmath::vec2f;
|
||||
using vec3 = nvmath::vec3f;
|
||||
using vec4 = nvmath::vec4f;
|
||||
using mat4 = nvmath::mat4f;
|
||||
using uint = unsigned int;
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
#ifdef __cplusplus // Descriptor binding helper for C++ and GLSL
|
||||
#define START_BINDING(a) enum a {
|
||||
#define END_BINDING() }
|
||||
#else
|
||||
#define START_BINDING(a) const uint
|
||||
#define END_BINDING()
|
||||
#endif
|
||||
|
||||
START_BINDING(SceneBindings)
|
||||
eGlobals = 0, // Global uniform containing camera matrices
|
||||
eSceneDesc = 1, // Access to the scene buffers
|
||||
eTextures = 2 // Access to textures
|
||||
END_BINDING();
|
||||
|
||||
START_BINDING(RtxBindings)
|
||||
eTlas = 0, // Top-level acceleration structure
|
||||
eOutImage = 1, // Ray tracer output image
|
||||
ePrimLookup = 2 // Lookup of objects
|
||||
END_BINDING();
|
||||
// clang-format on
|
||||
|
||||
// Scene buffer addresses
|
||||
struct SceneDesc
|
||||
{
|
||||
uint64_t vertexAddress; // Address of the Vertex buffer
|
||||
uint64_t normalAddress; // Address of the Normal buffer
|
||||
uint64_t uvAddress; // Address of the texture coordinates buffer
|
||||
uint64_t indexAddress; // Address of the triangle indices buffer
|
||||
uint64_t materialAddress; // Address of the Materials buffer (GltfShadeMaterial)
|
||||
uint64_t primInfoAddress; // Address of the mesh primitives buffer (PrimMeshInfo)
|
||||
};
|
||||
|
||||
// Uniform buffer set at each frame
|
||||
struct GlobalUniforms
|
||||
{
|
||||
mat4 viewProj; // Camera view * projection
|
||||
mat4 viewInverse; // Camera inverse view matrix
|
||||
mat4 projInverse; // Camera inverse projection matrix
|
||||
};
|
||||
|
||||
// Push constant structure for the raster
|
||||
struct PushConstantRaster
|
||||
{
|
||||
mat4 modelMatrix; // matrix of the instance
|
||||
vec3 lightPosition;
|
||||
uint objIndex;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int materialId;
|
||||
};
|
||||
|
||||
|
||||
// Push constant structure for the ray tracer
|
||||
struct PushConstantRay
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int frame;
|
||||
};
|
||||
|
||||
// Structure used for retrieving the primitive information in the closest hit
|
||||
struct PrimMeshInfo
|
||||
{
|
||||
uint indexOffset;
|
||||
uint vertexOffset;
|
||||
int materialIndex;
|
||||
};
|
||||
|
||||
struct GltfShadeMaterial
|
||||
{
|
||||
vec4 pbrBaseColorFactor;
|
||||
vec3 emissiveFactor;
|
||||
int pbrBaseColorTexture;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -27,11 +27,10 @@
|
|||
#extension GL_EXT_buffer_reference2 : require
|
||||
|
||||
|
||||
#include "binding.glsl"
|
||||
#include "gltf.glsl"
|
||||
#include "raycommon.glsl"
|
||||
#include "sampling.glsl"
|
||||
|
||||
#include "host_device.h"
|
||||
|
||||
hitAttributeEXT vec2 attribs;
|
||||
|
||||
|
|
@ -49,20 +48,12 @@ 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
|
||||
layout(set = 1, binding = eSceneDesc ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; };
|
||||
layout(set = 1, binding = eTextures) uniform sampler2D texturesMap[]; // all textures
|
||||
|
||||
layout(push_constant) uniform _PushConstantRay { PushConstantRay pcRay; };
|
||||
// clang-format on
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
}
|
||||
pushC;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,35 +21,22 @@
|
|||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_ARB_shader_clock : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
|
||||
#include "binding.glsl"
|
||||
#include "raycommon.glsl"
|
||||
#include "sampling.glsl"
|
||||
#include "host_device.h"
|
||||
|
||||
// clang-format off
|
||||
layout(location = 0) rayPayloadEXT hitPayload prd;
|
||||
|
||||
layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;
|
||||
layout(set = 0, binding = 1, rgba32f) uniform image2D image;
|
||||
|
||||
layout(location = 0) rayPayloadEXT hitPayload prd;
|
||||
|
||||
layout(set = 1, binding = B_CAMERA) uniform CameraProperties
|
||||
{
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 viewInverse;
|
||||
mat4 projInverse;
|
||||
}
|
||||
cam;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int frame;
|
||||
}
|
||||
pushC;
|
||||
layout(set = 1, binding = 0) uniform _GlobalUniforms { GlobalUniforms uni; };
|
||||
layout(push_constant) uniform _PushConstantRay { PushConstantRay pcRay; };
|
||||
// clang-format on
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -60,9 +47,9 @@ void main()
|
|||
const vec2 inUV = pixelCenter / vec2(gl_LaunchSizeEXT.xy);
|
||||
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);
|
||||
vec4 direction = cam.viewInverse * vec4(normalize(target.xyz), 0);
|
||||
vec4 origin = uni.viewInverse * vec4(0, 0, 0, 1);
|
||||
vec4 target = uni.projInverse * vec4(d.x, d.y, 1, 1);
|
||||
vec4 direction = uni.viewInverse * vec4(normalize(target.xyz), 0);
|
||||
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT;
|
||||
float tMin = 0.001;
|
||||
|
|
@ -98,9 +85,9 @@ void main()
|
|||
}
|
||||
|
||||
// Do accumulation over time
|
||||
if(pushC.frame > 0)
|
||||
if(pcRay.frame > 0)
|
||||
{
|
||||
float a = 1.0f / float(pushC.frame + 1);
|
||||
float a = 1.0f / float(pcRay.frame + 1);
|
||||
vec3 old_color = imageLoad(image, ivec2(gl_LaunchIDEXT.xy)).xyz;
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(mix(old_color, hitValue, a), 1.f));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
#extension GL_EXT_buffer_reference2 : require
|
||||
|
||||
|
||||
#include "binding.glsl"
|
||||
#include "gltf.glsl"
|
||||
#include "raycommon.glsl"
|
||||
#include "host_device.h"
|
||||
|
||||
hitAttributeEXT vec2 attribs;
|
||||
|
||||
|
|
@ -49,8 +49,8 @@ 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
|
||||
layout(set = 1, binding = eSceneDesc ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; };
|
||||
layout(set = 1, binding = eTextures) uniform sampler2D texturesMap[]; // all textures
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
|
|
|||
|
|
@ -20,22 +20,21 @@
|
|||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#include "binding.glsl"
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "raycommon.glsl"
|
||||
#include "sampling.glsl"
|
||||
#include "host_device.h"
|
||||
|
||||
// clang-format off
|
||||
layout(location = 0) rayPayloadEXT hitPayload prd;
|
||||
|
||||
layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;
|
||||
layout(set = 0, binding = 1, rgba32f) uniform image2D image;
|
||||
|
||||
layout(location = 0) rayPayloadEXT hitPayload prd;
|
||||
|
||||
layout(set = 1, binding = B_CAMERA) uniform CameraProperties
|
||||
{
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 viewInverse;
|
||||
mat4 projInverse;
|
||||
}
|
||||
cam;
|
||||
layout(set = 1, binding = 0) uniform _GlobalUniforms { GlobalUniforms uni; };
|
||||
layout(push_constant) uniform _PushConstantRay { PushConstantRay pcRay; };
|
||||
// clang-format on
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -43,9 +42,9 @@ void main()
|
|||
const vec2 inUV = pixelCenter / vec2(gl_LaunchSizeEXT.xy);
|
||||
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);
|
||||
vec4 direction = cam.viewInverse * vec4(normalize(target.xyz), 0);
|
||||
vec4 origin = uni.viewInverse * vec4(0, 0, 0, 1);
|
||||
vec4 target = uni.projInverse * vec4(d.x, d.y, 1, 1);
|
||||
vec4 direction = uni.viewInverse * vec4(normalize(target.xyz), 0);
|
||||
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT;
|
||||
float tMin = 0.001;
|
||||
|
|
|
|||
|
|
@ -21,46 +21,30 @@
|
|||
#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"
|
||||
#include "host_device.h"
|
||||
|
||||
// clang-format off
|
||||
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
|
||||
layout(binding = 0) uniform _GlobalUniforms
|
||||
{
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 viewI;
|
||||
}
|
||||
ubo;
|
||||
GlobalUniforms uni;
|
||||
};
|
||||
|
||||
layout(push_constant) uniform shaderInformation
|
||||
layout(push_constant) uniform _PushConstantRaster
|
||||
{
|
||||
vec3 lightPosition;
|
||||
uint instanceId;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int materialId;
|
||||
}
|
||||
pushC;
|
||||
PushConstantRaster pcRaster;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec2 inTexCoord;
|
||||
layout(location = 0) in vec3 i_position;
|
||||
layout(location = 1) in vec3 i_normal;
|
||||
layout(location = 2) in vec2 i_texCoord;
|
||||
|
||||
|
||||
//layout(location = 0) flat out int matIndex;
|
||||
layout(location = 1) out vec2 fragTexCoord;
|
||||
layout(location = 2) out vec3 fragNormal;
|
||||
layout(location = 3) out vec3 viewDir;
|
||||
layout(location = 4) out vec3 worldPos;
|
||||
layout(location = 1) out vec3 o_worldPos;
|
||||
layout(location = 2) out vec3 o_worldNrm;
|
||||
layout(location = 3) out vec3 o_viewDir;
|
||||
layout(location = 4) out vec2 o_texCoord;
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
|
|
@ -70,18 +54,12 @@ out gl_PerVertex
|
|||
|
||||
void main()
|
||||
{
|
||||
Matrices matrices = Matrices(sceneDesc.matrixAddress);
|
||||
mat4 objMatrix = matrices.m[pushC.instanceId];
|
||||
vec3 origin = vec3(uni.viewInverse * vec4(0, 0, 0, 1));
|
||||
|
||||
mat4 objMatrixIT = transpose(inverse(objMatrix));
|
||||
o_worldPos = vec3(pcRaster.modelMatrix * vec4(i_position, 1.0));
|
||||
o_viewDir = vec3(o_worldPos - origin);
|
||||
o_texCoord = i_texCoord;
|
||||
o_worldNrm = mat3(pcRaster.modelMatrix) * i_normal;
|
||||
|
||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||
|
||||
worldPos = vec3(objMatrix * vec4(inPosition, 1.0));
|
||||
viewDir = vec3(worldPos - origin);
|
||||
fragTexCoord = inTexCoord;
|
||||
fragNormal = vec3(objMatrixIT * vec4(inNormal, 0.0));
|
||||
// matIndex = inMatID;
|
||||
|
||||
gl_Position = ubo.proj * ubo.view * vec4(worldPos, 1.0);
|
||||
gl_Position = uni.viewProj * vec4(o_worldPos, 1.0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue