Refactoring
This commit is contained in:
parent
3e399adf0a
commit
d90ce79135
222 changed files with 9045 additions and 5734 deletions
|
|
@ -42,18 +42,6 @@
|
|||
|
||||
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
|
||||
|
|
@ -76,16 +64,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.
|
||||
|
|
@ -101,7 +90,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};
|
||||
|
|
@ -121,18 +110,19 @@ void HelloVulkan::createDescriptorSetLayout()
|
|||
{
|
||||
auto nbTxt = static_cast<uint32_t>(m_textures.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);
|
||||
// Scene description (binding = 1)
|
||||
m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||
// Camera matrices
|
||||
m_descSetLayoutBind.addBinding(SceneBindings::eGlobals, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1,
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||
// Obj descriptions
|
||||
m_descSetLayoutBind.addBinding(SceneBindings::eObjDescs, 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);
|
||||
// Textures (binding = 2)
|
||||
m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||
// Textures
|
||||
m_descSetLayoutBind.addBinding(SceneBindings::eTextures, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
||||
|
||||
// Storing implicit obj (binding = 3)
|
||||
m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||
m_descSetLayoutBind.addBinding(eImplicits, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
|
||||
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
|
||||
| VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
|
||||
|
||||
|
|
@ -150,11 +140,11 @@ void HelloVulkan::updateDescriptorSet()
|
|||
std::vector<VkWriteDescriptorSet> writes;
|
||||
|
||||
// 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 dbiUnif{m_bGlobals.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, SceneBindings::eGlobals, &dbiUnif));
|
||||
|
||||
VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc));
|
||||
VkDescriptorBufferInfo dbiSceneDesc{m_bObjDesc.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, SceneBindings::eObjDescs, &dbiSceneDesc));
|
||||
|
||||
// All texture samplers
|
||||
std::vector<VkDescriptorImageInfo> diit;
|
||||
|
|
@ -162,7 +152,7 @@ void HelloVulkan::updateDescriptorSet()
|
|||
{
|
||||
diit.emplace_back(texture.descriptor);
|
||||
}
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data()));
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, SceneBindings::eTextures, diit.data()));
|
||||
|
||||
VkDescriptorBufferInfo dbiImplDesc{m_implObjects.implBuf.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 3, &dbiImplDesc));
|
||||
|
|
@ -177,7 +167,7 @@ void HelloVulkan::updateDescriptorSet()
|
|||
//
|
||||
void HelloVulkan::createGraphicsPipeline()
|
||||
{
|
||||
VkPushConstantRange pushConstantRanges = {VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(ObjPushConstants)};
|
||||
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};
|
||||
|
|
@ -237,30 +227,35 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
|||
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());
|
||||
// Creates all textures found and find the offset for this model
|
||||
auto 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(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()));
|
||||
m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb)));
|
||||
m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb)));
|
||||
m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb)));
|
||||
m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb)));
|
||||
|
||||
// Keeping transformation matrix of the instance
|
||||
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);
|
||||
instance.transform = transform;
|
||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||
m_instances.push_back(instance);
|
||||
|
||||
// Creating information for device access
|
||||
ObjDesc desc;
|
||||
desc.txtOffset = txtOffset;
|
||||
desc.vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer);
|
||||
desc.indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||
desc.materialAddress = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer);
|
||||
desc.materialIndexAddress = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer);
|
||||
|
||||
// Keeping the obj host model and device description
|
||||
m_objModel.emplace_back(model);
|
||||
m_objInstance.emplace_back(instance);
|
||||
m_objDesc.emplace_back(desc);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -270,9 +265,9 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform
|
|||
//
|
||||
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");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -281,15 +276,15 @@ void HelloVulkan::createUniformBuffer()
|
|||
// - Transformation
|
||||
// - Offset for texture
|
||||
//
|
||||
void HelloVulkan::createSceneDescriptionBuffer()
|
||||
void HelloVulkan::createObjDescriptionBuffer()
|
||||
{
|
||||
nvvk::CommandPool cmdGen(m_device, m_graphicsQueueIndex);
|
||||
|
||||
auto cmdBuf = cmdGen.createCommandBuffer();
|
||||
m_sceneDesc = m_alloc.createBuffer(cmdBuf, m_objInstance, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
||||
m_bObjDesc = m_alloc.createBuffer(cmdBuf, m_objDesc, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
||||
cmdGen.submitAndWait(cmdBuf);
|
||||
m_alloc.finalizeAndReleaseStaging();
|
||||
m_debug.setObjectName(m_sceneDesc.buffer, "sceneDesc");
|
||||
m_debug.setObjectName(m_bObjDesc.buffer, "ObjDescs");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -375,8 +370,8 @@ void HelloVulkan::destroyResources()
|
|||
vkDestroyDescriptorPool(m_device, m_descPool, nullptr);
|
||||
vkDestroyDescriptorSetLayout(m_device, m_descSetLayout, nullptr);
|
||||
|
||||
m_alloc.destroy(m_cameraMat);
|
||||
m_alloc.destroy(m_sceneDesc);
|
||||
m_alloc.destroy(m_bGlobals);
|
||||
m_alloc.destroy(m_bObjDesc);
|
||||
m_alloc.destroy(m_implObjects.implBuf);
|
||||
m_alloc.destroy(m_implObjects.implMatBuf);
|
||||
|
||||
|
|
@ -418,15 +413,16 @@ void HelloVulkan::rasterize(const VkCommandBuffer& cmdBuf)
|
|||
vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline);
|
||||
vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descSet, 0, nullptr);
|
||||
|
||||
uint32_t nbInst = static_cast<uint32_t>(m_objInstance.size() - 1); // Remove the implicit object
|
||||
auto nbInst = static_cast<uint32_t>(m_instances.size() - 1); // Remove the implicit object
|
||||
for(uint32_t i = 0; i < nbInst; ++i)
|
||||
{
|
||||
auto& inst = m_objInstance[i];
|
||||
auto& model = m_objModel[inst.objIndex];
|
||||
m_pushConstants.instanceId = i; // Telling which instance is drawn
|
||||
auto& inst = m_instances[i];
|
||||
auto& model = m_objModel[inst.objIndex];
|
||||
m_pcRaster.objIndex = inst.objIndex; // Telling which object is drawn
|
||||
m_pcRaster.modelMatrix = inst.transform;
|
||||
|
||||
vkCmdPushConstants(cmdBuf, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
|
||||
sizeof(ObjPushConstants), &m_pushConstants);
|
||||
sizeof(PushConstantRaster), &m_pcRaster);
|
||||
vkCmdBindVertexBuffers(cmdBuf, 0, 1, &model.vertexBuffer.buffer, &offset);
|
||||
vkCmdBindIndexBuffer(cmdBuf, model.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdDrawIndexed(cmdBuf, model.nbIndices, 1, 0, 0, 0);
|
||||
|
|
@ -462,7 +458,7 @@ void HelloVulkan::initOffscreen()
|
|||
void HelloVulkan::initRayTracing()
|
||||
{
|
||||
m_raytrace.createBottomLevelAS(m_objModel, m_implObjects);
|
||||
m_raytrace.createTopLevelAS(m_objInstance, m_implObjects);
|
||||
m_raytrace.createTopLevelAS(m_instances, m_implObjects);
|
||||
m_raytrace.createRtDescriptorSet(m_offscreen.colorTexture().descriptor.imageView);
|
||||
m_raytrace.createRtPipeline(m_descSetLayout);
|
||||
}
|
||||
|
|
@ -473,10 +469,10 @@ void HelloVulkan::initRayTracing()
|
|||
void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& clearColor)
|
||||
{
|
||||
updateFrame();
|
||||
if(m_pushConstants.frame >= m_maxFrames)
|
||||
if(m_pcRaster.frame >= m_maxFrames)
|
||||
return;
|
||||
|
||||
m_raytrace.raytrace(cmdBuf, clearColor, m_descSet, m_size, m_pushConstants);
|
||||
m_raytrace.raytrace(cmdBuf, clearColor, m_descSet, m_size, m_pcRaster);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -497,12 +493,12 @@ void HelloVulkan::updateFrame()
|
|||
refCamMatrix = m;
|
||||
refFov = fov;
|
||||
}
|
||||
m_pushConstants.frame++;
|
||||
m_pcRaster.frame++;
|
||||
}
|
||||
|
||||
void HelloVulkan::resetFrame()
|
||||
{
|
||||
m_pushConstants.frame = -1;
|
||||
m_pcRaster.frame = -1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -560,9 +556,13 @@ void HelloVulkan::createImplictBuffers()
|
|||
m_debug.setObjectName(m_implObjects.implBuf.buffer, "implicitObj");
|
||||
m_debug.setObjectName(m_implObjects.implMatBuf.buffer, "implicitMat");
|
||||
|
||||
// Adding an instance to hold the buffer address of implicit materials
|
||||
|
||||
// Adding an extra instance to get access to the material buffers
|
||||
ObjDesc objDesc{};
|
||||
objDesc.materialAddress = nvvk::getBufferDeviceAddress(m_device, m_implObjects.implMatBuf.buffer);
|
||||
m_objDesc.emplace_back(objDesc);
|
||||
|
||||
ObjInstance instance{};
|
||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||
instance.materials = nvvk::getBufferDeviceAddress(m_device, m_implObjects.implMatBuf.buffer);
|
||||
m_objInstance.emplace_back(instance);
|
||||
instance.objIndex = static_cast<uint32_t>(m_objModel.size());
|
||||
m_instances.emplace_back(instance);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "nvvk/appbase_vk.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
#include "shaders/host_device.h"
|
||||
|
||||
// #VKRay
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
|
|
@ -65,7 +66,7 @@ public:
|
|||
void loadModel(const std::string& filename, nvmath::mat4f transform = nvmath::mat4f(1));
|
||||
void updateDescriptorSet();
|
||||
void createUniformBuffer();
|
||||
void createSceneDescriptionBuffer();
|
||||
void createObjDescriptionBuffer();
|
||||
void createTextureImages(const VkCommandBuffer& cmdBuf, const std::vector<std::string>& textures);
|
||||
void updateUniformBuffer(const VkCommandBuffer& cmdBuf);
|
||||
void onResize(int /*w*/, int /*h*/) override;
|
||||
|
|
@ -76,11 +77,22 @@ public:
|
|||
Raytracer& raytracer() { return m_raytrace; }
|
||||
|
||||
|
||||
ObjPushConstants m_pushConstants;
|
||||
// Information pushed at each draw call
|
||||
PushConstantRaster m_pcRaster{
|
||||
{1}, // Identity matrix
|
||||
{10.f, 15.f, 8.f}, // light position
|
||||
0, // instance Id
|
||||
{1, 0, 0}, // lightDirection;
|
||||
{cos(deg2rad(12.5f))}, // lightSpotCutoff;
|
||||
{cos(deg2rad(17.5f))}, // lightSpotOuterCutoff;
|
||||
100.f, // light intensity
|
||||
0 // light type
|
||||
};
|
||||
|
||||
// Array of objects and instances in the scene
|
||||
std::vector<ObjModel> m_objModel;
|
||||
std::vector<ObjInstance> m_objInstance;
|
||||
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
|
||||
|
||||
|
||||
// Graphic pipeline
|
||||
|
|
@ -91,18 +103,18 @@ public:
|
|||
VkDescriptorSetLayout m_descSetLayout;
|
||||
VkDescriptorSet m_descSet;
|
||||
|
||||
int m_maxFrames{10};
|
||||
int m_maxFrames{500};
|
||||
void resetFrame();
|
||||
void updateFrame();
|
||||
|
||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||
nvvk::Buffer m_bGlobals; // Device-Host of the camera matrices
|
||||
nvvk::Buffer m_bObjDesc; // Device buffer of the OBJ descriptions
|
||||
|
||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
Allocator m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
Allocator m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
// #Post
|
||||
Offscreen m_offscreen;
|
||||
|
|
|
|||
|
|
@ -59,35 +59,37 @@ void renderUI(HelloVulkan& helloVk)
|
|||
changed |= ImGuiH::CameraWidget();
|
||||
if(ImGui::CollapsingHeader("Light"))
|
||||
{
|
||||
changed |= ImGui::RadioButton("Point", &helloVk.m_pushConstants.lightType, 0);
|
||||
auto& pc = helloVk.m_pcRaster;
|
||||
|
||||
changed |= ImGui::RadioButton("Point", &pc.lightType, 0);
|
||||
ImGui::SameLine();
|
||||
changed |= ImGui::RadioButton("Spot", &helloVk.m_pushConstants.lightType, 1);
|
||||
changed |= ImGui::RadioButton("Spot", &pc.lightType, 1);
|
||||
ImGui::SameLine();
|
||||
changed |= ImGui::RadioButton("Infinite", &helloVk.m_pushConstants.lightType, 2);
|
||||
changed |= ImGui::RadioButton("Infinite", &pc.lightType, 2);
|
||||
|
||||
|
||||
if(helloVk.m_pushConstants.lightType < 2)
|
||||
if(pc.lightType < 2)
|
||||
{
|
||||
changed |= ImGui::SliderFloat3("Light Position", &helloVk.m_pushConstants.lightPosition.x, -20.f, 20.f);
|
||||
changed |= ImGui::SliderFloat3("Light Position", &pc.lightPosition.x, -20.f, 20.f);
|
||||
}
|
||||
if(helloVk.m_pushConstants.lightType > 0)
|
||||
if(pc.lightType > 0)
|
||||
{
|
||||
changed |= ImGui::SliderFloat3("Light Direction", &helloVk.m_pushConstants.lightDirection.x, -1.f, 1.f);
|
||||
changed |= ImGui::SliderFloat3("Light Direction", &pc.lightDirection.x, -1.f, 1.f);
|
||||
}
|
||||
if(helloVk.m_pushConstants.lightType < 2)
|
||||
if(pc.lightType < 2)
|
||||
{
|
||||
changed |= ImGui::SliderFloat("Light Intensity", &helloVk.m_pushConstants.lightIntensity, 0.f, 500.f);
|
||||
changed |= ImGui::SliderFloat("Light Intensity", &pc.lightIntensity, 0.f, 500.f);
|
||||
}
|
||||
if(helloVk.m_pushConstants.lightType == 1)
|
||||
if(pc.lightType == 1)
|
||||
{
|
||||
float dCutoff = rad2deg(acos(helloVk.m_pushConstants.lightSpotCutoff));
|
||||
float dOutCutoff = rad2deg(acos(helloVk.m_pushConstants.lightSpotOuterCutoff));
|
||||
float dCutoff = rad2deg(acos(pc.lightSpotCutoff));
|
||||
float dOutCutoff = rad2deg(acos(pc.lightSpotOuterCutoff));
|
||||
changed |= ImGui::SliderFloat("Cutoff", &dCutoff, 0.f, 45.f);
|
||||
changed |= ImGui::SliderFloat("OutCutoff", &dOutCutoff, 0.f, 45.f);
|
||||
dCutoff = dCutoff > dOutCutoff ? dOutCutoff : dCutoff;
|
||||
|
||||
helloVk.m_pushConstants.lightSpotCutoff = cos(deg2rad(dCutoff));
|
||||
helloVk.m_pushConstants.lightSpotOuterCutoff = cos(deg2rad(dOutCutoff));
|
||||
pc.lightSpotCutoff = cos(deg2rad(dCutoff));
|
||||
pc.lightSpotOuterCutoff = cos(deg2rad(dOutCutoff));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,20 +198,19 @@ int main(int argc, char** argv)
|
|||
std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
|
||||
std::normal_distribution<float> dis(2.0f, 2.0f);
|
||||
std::normal_distribution<float> disn(0.5f, 0.2f);
|
||||
int wusonIndex = static_cast<int>(helloVk.m_objModel.size() - 1);
|
||||
auto wusonIndex = static_cast<int>(helloVk.m_objModel.size() - 1);
|
||||
|
||||
for(int n = 0; n < 50; ++n)
|
||||
{
|
||||
ObjInstance inst = helloVk.m_objInstance[wusonIndex];
|
||||
ObjInstance inst;
|
||||
inst.objIndex = wusonIndex;
|
||||
inst.txtOffset = 0;
|
||||
float scale = fabsf(disn(gen));
|
||||
nvmath::mat4f mat = nvmath::translation_mat4(nvmath::vec3f{dis(gen), 0.f, dis(gen) + 6});
|
||||
// mat = mat * nvmath::rotation_mat4_x(dis(gen));
|
||||
mat = mat * nvmath::scale_mat4(nvmath::vec3f(scale));
|
||||
inst.transform = mat;
|
||||
inst.transformIT = nvmath::transpose(nvmath::invert((inst.transform)));
|
||||
helloVk.m_objInstance.push_back(inst);
|
||||
mat = mat * nvmath::scale_mat4(nvmath::vec3f(scale));
|
||||
inst.transform = mat;
|
||||
|
||||
helloVk.m_instances.push_back(inst);
|
||||
}
|
||||
|
||||
// Creation of implicit geometry
|
||||
|
|
@ -238,7 +239,7 @@ int main(int argc, char** argv)
|
|||
helloVk.createDescriptorSetLayout();
|
||||
helloVk.createGraphicsPipeline();
|
||||
helloVk.createUniformBuffer();
|
||||
helloVk.createSceneDescriptionBuffer();
|
||||
helloVk.createObjDescriptionBuffer();
|
||||
helloVk.updateDescriptorSet();
|
||||
|
||||
// #VKRay
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#pragma once
|
||||
#include "obj_loader.h"
|
||||
|
||||
|
||||
// The OBJ model
|
||||
struct ObjModel
|
||||
{
|
||||
|
|
@ -31,31 +32,12 @@ struct ObjModel
|
|||
nvvk::Buffer matIndexBuffer; // Device buffer of array of 'Wavefront material'
|
||||
};
|
||||
|
||||
// Instance of the OBJ
|
||||
struct ObjInstance
|
||||
{
|
||||
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{0};
|
||||
VkDeviceAddress indices{0};
|
||||
VkDeviceAddress materials{0};
|
||||
VkDeviceAddress materialIndices{0};
|
||||
nvmath::mat4f transform; // Matrix of the instance
|
||||
uint32_t objIndex{0}; // Model index reference
|
||||
};
|
||||
|
||||
// Information pushed at each draw call
|
||||
struct ObjPushConstants
|
||||
{
|
||||
nvmath::vec3f lightPosition{10.f, 15.f, 8.f};
|
||||
float lightIntensity{100.f};
|
||||
nvmath::vec3f lightDirection{-1, -1, -1};
|
||||
float lightSpotCutoff{cos(deg2rad(12.5f))};
|
||||
float lightSpotOuterCutoff{cos(deg2rad(17.5f))};
|
||||
int instanceId{0}; // To retrieve the transformation matrix
|
||||
int lightType{0}; // 0: point, 1: infinite
|
||||
int frame{0};
|
||||
};
|
||||
|
||||
enum EObjType
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ auto Raytracer::objectToVkGeometryKHR(const ObjModel& model)
|
|||
VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer);
|
||||
|
||||
VkAccelerationStructureGeometryTrianglesDataKHR triangles{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR};
|
||||
triangles.vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
triangles.vertexData.deviceAddress = vertexAddress;
|
||||
triangles.vertexStride = sizeof(VertexObj);
|
||||
triangles.indexType = VK_INDEX_TYPE_UINT32;
|
||||
|
|
@ -163,26 +163,26 @@ void Raytracer::createTopLevelAS(std::vector<ObjInstance>& instances, ImplInst&
|
|||
tlas.reserve(instances.size());
|
||||
for(uint32_t i = 0; i < nbObj; i++)
|
||||
{
|
||||
VkAccelerationStructureInstanceKHR rayInst;
|
||||
VkAccelerationStructureInstanceKHR rayInst{};
|
||||
rayInst.transform = nvvk::toTransformMatrixKHR(instances[i].transform); // Position of the instance
|
||||
rayInst.instanceCustomIndex = instances[i].objIndex; // gl_InstanceCustomIndexEXT
|
||||
rayInst.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(instances[i].objIndex);
|
||||
rayInst.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||
rayInst.mask = 0xFF;
|
||||
rayInst.mask = 0xFF; // Only be hit if rayMask & instance.mask != 0
|
||||
rayInst.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
||||
tlas.emplace_back(rayInst);
|
||||
}
|
||||
|
||||
// Add the blas containing all implicit
|
||||
if(!implicitObj.objImpl.empty())
|
||||
{
|
||||
VkAccelerationStructureInstanceKHR rayInst;
|
||||
VkAccelerationStructureInstanceKHR rayInst{};
|
||||
rayInst.transform = nvvk::toTransformMatrixKHR(implicitObj.transform); // Position of the instance
|
||||
rayInst.instanceCustomIndex = nbObj; // Same for material index
|
||||
rayInst.instanceCustomIndex = instances[nbObj].objIndex;
|
||||
rayInst.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(static_cast<uint32_t>(implicitObj.blasId));
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||
rayInst.mask = 0xFF; // Only be hit if rayMask & instance.mask != 0
|
||||
rayInst.instanceShaderBindingTableRecordOffset = 1; // We will use the same hit group for all objects (the second one)
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||
rayInst.mask = 0xFF;
|
||||
tlas.emplace_back(rayInst);
|
||||
}
|
||||
|
||||
|
|
@ -196,9 +196,9 @@ void Raytracer::createRtDescriptorSet(const VkImageView& outputImage)
|
|||
{
|
||||
using vkDSLB = VkDescriptorSetLayoutBinding;
|
||||
|
||||
m_rtDescSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1,
|
||||
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, VK_SHADER_STAGE_RAYGEN_BIT_KHR); // Output image
|
||||
m_rtDescSetLayoutBind.addBinding(RtxBindings::eOutImage, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR); // Output image
|
||||
|
||||
m_rtDescPool = m_rtDescSetLayoutBind.createPool(m_device);
|
||||
m_rtDescSetLayout = m_rtDescSetLayoutBind.createLayout(m_device);
|
||||
|
|
@ -217,8 +217,8 @@ void Raytracer::createRtDescriptorSet(const VkImageView& outputImage)
|
|||
|
||||
|
||||
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, RtxBindings::eTlas, &descASInfo));
|
||||
writes.emplace_back(m_rtDescSetLayoutBind.makeWrite(m_rtDescSet, RtxBindings::eOutImage, &imageInfo));
|
||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ void Raytracer::createRtDescriptorSet(const VkImageView& outputImage)
|
|||
void Raytracer::updateRtDescriptorSet(const VkImageView& outputImage)
|
||||
{
|
||||
VkDescriptorImageInfo imageInfo{{}, outputImage, 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);
|
||||
}
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ void Raytracer::createRtPipeline(VkDescriptorSetLayout& sceneDescLayout)
|
|||
// 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 | VK_SHADER_STAGE_CALLABLE_BIT_KHR,
|
||||
0, sizeof(RtPushConstants)};
|
||||
0, sizeof(PushConstantRay)};
|
||||
|
||||
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
|
||||
|
|
@ -408,18 +408,18 @@ void Raytracer::raytrace(const VkCommandBuffer& cmdBuf,
|
|||
const nvmath::vec4f& clearColor,
|
||||
VkDescriptorSet& sceneDescSet,
|
||||
VkExtent2D& size,
|
||||
ObjPushConstants& sceneConstants)
|
||||
PushConstantRaster& sceneConstants)
|
||||
{
|
||||
m_debug.beginLabel(cmdBuf, "Ray trace");
|
||||
// Initializing push constant values
|
||||
m_rtPushConstants.clearColor = clearColor;
|
||||
m_rtPushConstants.lightPosition = sceneConstants.lightPosition;
|
||||
m_rtPushConstants.lightIntensity = sceneConstants.lightIntensity;
|
||||
m_rtPushConstants.lightDirection = sceneConstants.lightDirection;
|
||||
m_rtPushConstants.lightSpotCutoff = sceneConstants.lightSpotCutoff;
|
||||
m_rtPushConstants.lightSpotOuterCutoff = sceneConstants.lightSpotOuterCutoff;
|
||||
m_rtPushConstants.lightType = sceneConstants.lightType;
|
||||
m_rtPushConstants.frame = sceneConstants.frame;
|
||||
m_pcRay.clearColor = clearColor;
|
||||
m_pcRay.lightPosition = sceneConstants.lightPosition;
|
||||
m_pcRay.lightIntensity = sceneConstants.lightIntensity;
|
||||
m_pcRay.lightDirection = sceneConstants.lightDirection;
|
||||
m_pcRay.lightSpotCutoff = sceneConstants.lightSpotCutoff;
|
||||
m_pcRay.lightSpotOuterCutoff = sceneConstants.lightSpotOuterCutoff;
|
||||
m_pcRay.lightType = sceneConstants.lightType;
|
||||
m_pcRay.frame = sceneConstants.frame;
|
||||
|
||||
|
||||
std::vector<VkDescriptorSet> descSets{m_rtDescSet, sceneDescSet};
|
||||
|
|
@ -429,7 +429,7 @@ void Raytracer::raytrace(const VkCommandBuffer& cmdBuf,
|
|||
vkCmdPushConstants(cmdBuf, m_rtPipelineLayout,
|
||||
VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR
|
||||
| VK_SHADER_STAGE_CALLABLE_BIT_KHR,
|
||||
0, sizeof(RtPushConstants), &m_rtPushConstants);
|
||||
0, sizeof(PushConstantRay), &m_pcRay);
|
||||
|
||||
|
||||
auto& regions = m_sbtWrapper.getRegions();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include "nvvk/sbtwrapper_vk.hpp"
|
||||
#include "obj.hpp"
|
||||
|
||||
#include "shaders/host_device.h"
|
||||
|
||||
class Raytracer
|
||||
{
|
||||
public:
|
||||
|
|
@ -41,7 +43,7 @@ public:
|
|||
const nvmath::vec4f& clearColor,
|
||||
VkDescriptorSet& sceneDescSet,
|
||||
VkExtent2D& size,
|
||||
ObjPushConstants& sceneConstants);
|
||||
PushConstantRaster& sceneConstants);
|
||||
|
||||
private:
|
||||
nvvk::ResourceAllocator* m_alloc{nullptr}; // Allocator for buffer, images, acceleration structures
|
||||
|
|
@ -62,15 +64,6 @@ private:
|
|||
VkPipeline m_rtPipeline;
|
||||
nvvk::Buffer m_rtSBTBuffer;
|
||||
|
||||
struct RtPushConstants
|
||||
{
|
||||
nvmath::vec4f clearColor;
|
||||
nvmath::vec3f lightPosition;
|
||||
float lightIntensity{100.0f};
|
||||
nvmath::vec3f lightDirection{-1, -1, -1};
|
||||
float lightSpotCutoff{deg2rad(12.5f)};
|
||||
float lightSpotOuterCutoff{deg2rad(17.5f)};
|
||||
int lightType{0};
|
||||
int frame{0};
|
||||
} m_rtPushConstants;
|
||||
|
||||
PushConstantRay m_pcRay{};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,91 +29,86 @@
|
|||
#include "wavefront.glsl"
|
||||
|
||||
|
||||
layout(push_constant) uniform shaderInformation
|
||||
layout(push_constant) uniform _PushConstantRaster
|
||||
{
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
uint instanceId;
|
||||
int lightType;
|
||||
}
|
||||
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;
|
||||
|
||||
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;
|
||||
layout(binding = eObjDescs, scalar) buffer ObjDesc_ { ObjDesc i[]; } objDesc;
|
||||
layout(binding = eTextures) uniform sampler2D[] textureSamplers;
|
||||
// clang-format on
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
// Material of the object
|
||||
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
|
||||
ObjDesc objResource = objDesc.i[pcRaster.objIndex];
|
||||
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||
Materials materials = Materials(objResource.materialAddress);
|
||||
|
||||
int matIndex = matIndices.i[gl_PrimitiveID];
|
||||
WaveFrontMaterial mat = materials.m[matIndex];
|
||||
|
||||
vec3 N = normalize(fragNormal);
|
||||
vec3 N = normalize(i_worldNrm);
|
||||
|
||||
// Vector toward light
|
||||
vec3 LightDir;
|
||||
float lightIntensity;
|
||||
|
||||
// Point light
|
||||
if(pushC.lightType == 0)
|
||||
if(pcRaster.lightType == 0)
|
||||
{
|
||||
vec3 lDir = pushC.lightPosition - worldPos;
|
||||
vec3 lDir = pcRaster.lightPosition - i_worldPos;
|
||||
float lightDistance = length(lDir);
|
||||
lightIntensity = pushC.lightIntensity / (lightDistance * lightDistance);
|
||||
lightIntensity = pcRaster.lightIntensity / (lightDistance * lightDistance);
|
||||
LightDir = normalize(lDir);
|
||||
}
|
||||
else if(pushC.lightType == 1)
|
||||
else if(pcRaster.lightType == 1)
|
||||
{
|
||||
vec3 lDir = pushC.lightPosition - worldPos;
|
||||
vec3 lDir = pcRaster.lightPosition - i_worldPos;
|
||||
float lightDistance = length(lDir);
|
||||
lightIntensity = pushC.lightIntensity / (lightDistance * lightDistance);
|
||||
lightIntensity = pcRaster.lightIntensity / (lightDistance * lightDistance);
|
||||
LightDir = normalize(lDir);
|
||||
float theta = dot(LightDir, normalize(-pushC.lightDirection));
|
||||
float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff;
|
||||
float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||
float theta = dot(LightDir, normalize(-pcRaster.lightDirection));
|
||||
float epsilon = pcRaster.lightSpotCutoff - pcRaster.lightSpotOuterCutoff;
|
||||
float spotIntensity = clamp((theta - pcRaster.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||
lightIntensity *= spotIntensity;
|
||||
}
|
||||
else // Directional light
|
||||
{
|
||||
LightDir = normalize(-pushC.lightDirection);
|
||||
LightDir = normalize(-pcRaster.lightDirection);
|
||||
lightIntensity = 1.0;
|
||||
}
|
||||
|
||||
// Diffuse
|
||||
vec3 diffuse = computeDiffuse(mat, LightDir, N);
|
||||
|
||||
if(mat.textureId >= 0)
|
||||
{
|
||||
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
|
||||
int txtOffset = objDesc.i[pcRaster.objIndex].txtOffset;
|
||||
uint txtId = txtOffset + mat.textureId;
|
||||
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, LightDir, N);
|
||||
vec3 specular = computeSpecular(mat, i_viewDir, LightDir, N);
|
||||
|
||||
// Result
|
||||
outColor = vec4(lightIntensity * (diffuse + specular), 1);
|
||||
o_color = vec4(lightIntensity * (diffuse + specular), 1);
|
||||
}
|
||||
|
|
|
|||
126
ray_tracing__advance/shaders/host_device.h
Normal file
126
ray_tracing__advance/shaders/host_device.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 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
|
||||
eObjDescs = 1, // Access to the object descriptions
|
||||
eTextures = 2, // Access to textures
|
||||
eImplicits = 3 // Implicit objects
|
||||
END_BINDING();
|
||||
|
||||
START_BINDING(RtxBindings)
|
||||
eTlas = 0, // Top-level acceleration structure
|
||||
eOutImage = 1 // Ray tracer output image
|
||||
END_BINDING();
|
||||
// clang-format on
|
||||
|
||||
// Information of a obj model when referenced in a shader
|
||||
struct ObjDesc
|
||||
{
|
||||
int txtOffset; // Texture index offset in the array of textures
|
||||
uint64_t vertexAddress; // Address of the Vertex buffer
|
||||
uint64_t indexAddress; // Address of the index buffer
|
||||
uint64_t materialAddress; // Address of the material buffer
|
||||
uint64_t materialIndexAddress; // Address of the triangle material index buffer
|
||||
};
|
||||
|
||||
// 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;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int frame;
|
||||
};
|
||||
|
||||
|
||||
// Push constant structure for the ray tracer
|
||||
struct PushConstantRay
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
uint objIndex;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int frame;
|
||||
};
|
||||
|
||||
struct Vertex // See ObjLoader, copy of VertexObj, could be compressed for device
|
||||
{
|
||||
vec3 pos;
|
||||
vec3 nrm;
|
||||
vec3 color;
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
struct WaveFrontMaterial // See ObjLoader, copy of MaterialObj, could be compressed for device
|
||||
{
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
vec3 transmittance;
|
||||
vec3 emission;
|
||||
float shininess;
|
||||
float ior; // index of refraction
|
||||
float dissolve; // 1 == opaque; 0 == fully transparent
|
||||
int illum; // illumination model (see http://www.fileformat.info/format/material/)
|
||||
int textureId;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -20,24 +20,21 @@
|
|||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "raycommon.glsl"
|
||||
#include "host_device.h"
|
||||
|
||||
layout(location = 3) callableDataInEXT rayLight cLight;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
layout(push_constant) uniform _PushConstantRay
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
int lightType;
|
||||
PushConstantRay pcRay;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
cLight.outLightDistance = 10000000;
|
||||
cLight.outIntensity = 1.0;
|
||||
cLight.outLightDir = normalize(-lightDirection);
|
||||
cLight.outLightDir = normalize(-pcRay.lightDirection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,25 +20,23 @@
|
|||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "raycommon.glsl"
|
||||
#include "host_device.h"
|
||||
|
||||
layout(location = 3) callableDataInEXT rayLight cLight;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
layout(push_constant) uniform _PushConstantRay
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
int lightType;
|
||||
PushConstantRay pcRay;
|
||||
};
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 lDir = lightPosition - cLight.inHitPosition;
|
||||
vec3 lDir = pcRay.lightPosition - cLight.inHitPosition;
|
||||
cLight.outLightDistance = length(lDir);
|
||||
cLight.outIntensity = lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||
cLight.outIntensity = pcRay.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||
cLight.outLightDir = normalize(lDir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,29 +20,26 @@
|
|||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "raycommon.glsl"
|
||||
#include "host_device.h"
|
||||
|
||||
layout(location = 3) callableDataInEXT rayLight cLight;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
layout(push_constant) uniform _PushConstantRay
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
int lightType;
|
||||
PushConstantRay pcRay;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 lDir = lightPosition - cLight.inHitPosition;
|
||||
vec3 lDir = pcRay.lightPosition - cLight.inHitPosition;
|
||||
cLight.outLightDistance = length(lDir);
|
||||
cLight.outIntensity = lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||
cLight.outIntensity = pcRay.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||
cLight.outLightDir = normalize(lDir);
|
||||
float theta = dot(cLight.outLightDir, normalize(-lightDirection));
|
||||
float epsilon = lightSpotCutoff - lightSpotOuterCutoff;
|
||||
float spotIntensity = clamp((theta - lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||
float theta = dot(cLight.outLightDir, normalize(-pcRay.lightDirection));
|
||||
float epsilon = pcRay.lightSpotCutoff - pcRay.lightSpotOuterCutoff;
|
||||
float spotIntensity = clamp((theta - pcRay.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||
cLight.outIntensity *= spotIntensity;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of
|
|||
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||
layout(set = 1, binding = eObjDescs, scalar) buffer ObjDesc_ { ObjDesc i[]; } objDesc;
|
||||
// clang-format on
|
||||
|
||||
void main()
|
||||
{
|
||||
// Object of this instance
|
||||
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||
ObjDesc objResource = objDesc.i[gl_InstanceCustomIndexEXT];
|
||||
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||
Materials materials = Materials(objResource.materialAddress);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#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
|
||||
|
||||
|
|
@ -39,22 +38,13 @@ layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of
|
|||
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 = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
|
||||
layout(set = 0, binding = eTlas) uniform accelerationStructureEXT topLevelAS;
|
||||
layout(set = 1, binding = eObjDescs, scalar) buffer ObjDesc_ { ObjDesc i[]; } objDesc;
|
||||
layout(set = 1, binding = eTextures) uniform sampler2D textureSamplers[];
|
||||
|
||||
layout(push_constant) uniform _PushConstantRay { PushConstantRay pcRay; };
|
||||
// clang-format on
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
int lightType;
|
||||
}
|
||||
pushC;
|
||||
|
||||
layout(location = 3) callableDataEXT rayLight cLight;
|
||||
|
||||
|
|
@ -62,7 +52,7 @@ layout(location = 3) callableDataEXT rayLight cLight;
|
|||
void main()
|
||||
{
|
||||
// Object data
|
||||
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||
ObjDesc objResource = objDesc.i[gl_InstanceCustomIndexEXT];
|
||||
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
|
||||
Materials materials = Materials(objResource.materialAddress);
|
||||
Indices indices = Indices(objResource.indexAddress);
|
||||
|
|
@ -81,45 +71,44 @@ void main()
|
|||
// 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(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
|
||||
|
||||
normal = normalize(vec3(normal * gl_WorldToObjectEXT));
|
||||
|
||||
// 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(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
|
||||
worldPos = vec3(gl_ObjectToWorldEXT * vec4(worldPos, 1.0));
|
||||
|
||||
cLight.inHitPosition = worldPos;
|
||||
//#define DONT_USE_CALLABLE
|
||||
#if defined(DONT_USE_CALLABLE)
|
||||
// Point light
|
||||
if(pushC.lightType == 0)
|
||||
if(pcRay.lightType == 0)
|
||||
{
|
||||
vec3 lDir = pushC.lightPosition - cLight.inHitPosition;
|
||||
vec3 lDir = pcRay.lightPosition - cLight.inHitPosition;
|
||||
float lightDistance = length(lDir);
|
||||
cLight.outIntensity = pushC.lightIntensity / (lightDistance * lightDistance);
|
||||
cLight.outIntensity = pcRay.lightIntensity / (lightDistance * lightDistance);
|
||||
cLight.outLightDir = normalize(lDir);
|
||||
cLight.outLightDistance = lightDistance;
|
||||
}
|
||||
else if(pushC.lightType == 1)
|
||||
else if(pcRay.lightType == 1)
|
||||
{
|
||||
vec3 lDir = pushC.lightPosition - cLight.inHitPosition;
|
||||
vec3 lDir = pcRay.lightPosition - cLight.inHitPosition;
|
||||
cLight.outLightDistance = length(lDir);
|
||||
cLight.outIntensity = pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||
cLight.outIntensity = pcRay.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||
cLight.outLightDir = normalize(lDir);
|
||||
float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection));
|
||||
float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff;
|
||||
float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||
float theta = dot(cLight.outLightDir, normalize(-pcRay.lightDirection));
|
||||
float epsilon = pcRay.lightSpotCutoff - pcRay.lightSpotOuterCutoff;
|
||||
float spotIntensity = clamp((theta - pcRay.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||
cLight.outIntensity *= spotIntensity;
|
||||
}
|
||||
else // Directional light
|
||||
{
|
||||
cLight.outLightDir = normalize(-pushC.lightDirection);
|
||||
cLight.outLightDir = normalize(-pcRay.lightDirection);
|
||||
cLight.outIntensity = 1.0;
|
||||
cLight.outLightDistance = 10000000;
|
||||
}
|
||||
#else
|
||||
executeCallableEXT(pushC.lightType, 3);
|
||||
executeCallableEXT(pcRay.lightType, 3);
|
||||
#endif
|
||||
|
||||
// Material of the object
|
||||
|
|
@ -131,7 +120,7 @@ void main()
|
|||
vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal);
|
||||
if(mat.textureId >= 0)
|
||||
{
|
||||
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
|
||||
uint txtId = mat.textureId + objDesc.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;
|
||||
}
|
||||
|
|
@ -183,6 +172,5 @@ void main()
|
|||
prd.rayDir = rayDir;
|
||||
}
|
||||
|
||||
|
||||
prd.hitValue = vec3(cLight.outIntensity * attenuation * (diffuse + specular));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,42 +20,27 @@
|
|||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "random.glsl"
|
||||
#include "raycommon.glsl"
|
||||
#include "wavefront.glsl"
|
||||
|
||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||
layout(binding = 1, set = 0, rgba32f) uniform image2D image;
|
||||
|
||||
// clang-format off
|
||||
layout(location = 0) rayPayloadEXT hitPayload prd;
|
||||
|
||||
layout(binding = 0, set = 1) uniform CameraProperties
|
||||
{
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 viewInverse;
|
||||
mat4 projInverse;
|
||||
}
|
||||
cam;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
int lightType;
|
||||
int frame;
|
||||
}
|
||||
pushC;
|
||||
layout(set = 0, binding = eTlas) uniform accelerationStructureEXT topLevelAS;
|
||||
layout(set = 0, binding = eOutImage, rgba32f) uniform image2D image;
|
||||
layout(set = 1, binding = eGlobals) uniform _GlobalUniforms { GlobalUniforms uni; };
|
||||
layout(push_constant) uniform _PushConstantRay { PushConstantRay pcRay; };
|
||||
// clang-format on
|
||||
|
||||
const int NBSAMPLES = 5;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Initialize the random number
|
||||
uint seed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pushC.frame * NBSAMPLES);
|
||||
uint seed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pcRay.frame * NBSAMPLES);
|
||||
prd.seed = seed;
|
||||
|
||||
vec3 hitValues = vec3(0);
|
||||
|
|
@ -67,7 +52,7 @@ void main()
|
|||
float r2 = rnd(seed);
|
||||
// Subpixel jitter: send the ray through a different position inside the pixel
|
||||
// each time, to provide antialiasing.
|
||||
vec2 subpixel_jitter = pushC.frame == 0 ? vec2(0.5f, 0.5f) : vec2(r1, r2);
|
||||
vec2 subpixel_jitter = pcRay.frame == 0 ? vec2(0.5f, 0.5f) : vec2(r1, r2);
|
||||
|
||||
const vec2 pixelCenter = vec2(gl_LaunchIDEXT.xy) + subpixel_jitter;
|
||||
|
||||
|
|
@ -75,9 +60,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_RayFlagsNoneEXT;
|
||||
float tMin = 0.001;
|
||||
|
|
@ -120,9 +105,9 @@ void main()
|
|||
prd.hitValue = hitValues / NBSAMPLES;
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
hitAttributeEXT vec3 HitAttribute;
|
||||
|
||||
layout(binding = 3, set = 1, scalar) buffer allImpl_
|
||||
layout(set = 1, binding = eImplicits, scalar) buffer allImpl_
|
||||
{
|
||||
Implicit i[];
|
||||
}
|
||||
|
|
@ -77,6 +77,7 @@ float hitAabb(const Aabb aabb, const Ray r)
|
|||
|
||||
void main()
|
||||
{
|
||||
|
||||
Ray ray;
|
||||
ray.origin = gl_WorldRayOriginEXT;
|
||||
ray.direction = gl_WorldRayDirectionEXT;
|
||||
|
|
|
|||
|
|
@ -20,16 +20,19 @@
|
|||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "raycommon.glsl"
|
||||
#include "wavefront.glsl"
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
layout(push_constant) uniform _PushConstantRay
|
||||
{
|
||||
vec4 clearColor;
|
||||
PushConstantRay pcRay;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
prd.hitValue = clearColor.xyz * 0.8;
|
||||
prd.hitValue = pcRay.clearColor.xyz * 0.8;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of
|
|||
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||
layout(binding = 3, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
||||
layout(set = 1, binding = eObjDescs, scalar) buffer ObjDesc_ { ObjDesc i[]; } objDesc;
|
||||
layout(set = 1, binding = eImplicits, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
||||
// clang-format on
|
||||
|
||||
void main()
|
||||
|
|
@ -45,7 +45,7 @@ void main()
|
|||
// Material of the object
|
||||
Implicit impl = allImplicits.i[gl_PrimitiveID];
|
||||
|
||||
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||
ObjDesc objResource = objDesc.i[gl_InstanceCustomIndexEXT];
|
||||
Materials materials = Materials(objResource.materialAddress);
|
||||
|
||||
WaveFrontMaterial mat = materials.m[impl.matId];
|
||||
|
|
|
|||
|
|
@ -41,22 +41,12 @@ layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of
|
|||
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
|
||||
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
|
||||
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
|
||||
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
|
||||
layout(binding = 3, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
||||
layout(set = 1, binding = eObjDescs, scalar) buffer ObjDesc_ { ObjDesc i[]; } objDesc;
|
||||
layout(set = 1, binding = eImplicits, scalar) buffer allImplicits_ {Implicit i[];} allImplicits;
|
||||
|
||||
layout(push_constant) uniform _PushConstantRay { PushConstantRay pcRay; };
|
||||
// clang-format on
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
int lightType;
|
||||
}
|
||||
pushC;
|
||||
|
||||
layout(location = 3) callableDataEXT rayLight cLight;
|
||||
|
||||
|
|
@ -92,10 +82,10 @@ void main()
|
|||
}
|
||||
|
||||
cLight.inHitPosition = worldPos;
|
||||
executeCallableEXT(pushC.lightType, 3);
|
||||
executeCallableEXT(pcRay.lightType, 3);
|
||||
|
||||
// Material of the object
|
||||
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
|
||||
ObjDesc objResource = objDesc.i[gl_InstanceCustomIndexEXT];
|
||||
Materials materials = Materials(objResource.materialAddress);
|
||||
WaveFrontMaterial mat = materials.m[impl.matId];
|
||||
|
||||
|
|
|
|||
|
|
@ -26,41 +26,26 @@
|
|||
|
||||
#include "wavefront.glsl"
|
||||
|
||||
// clang-format off
|
||||
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } 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;
|
||||
float lightIntensity;
|
||||
vec3 lightDirection;
|
||||
float lightSpotCutoff;
|
||||
float lightSpotOuterCutoff;
|
||||
uint instanceId;
|
||||
int lightType;
|
||||
}
|
||||
pushC;
|
||||
PushConstantRaster pcRaster;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec3 inColor;
|
||||
layout(location = 3) in vec2 inTexCoord;
|
||||
layout(location = 0) in vec3 i_position;
|
||||
layout(location = 1) in vec3 i_normal;
|
||||
layout(location = 2) in vec3 i_color;
|
||||
layout(location = 3) 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,16 +55,12 @@ out gl_PerVertex
|
|||
|
||||
void main()
|
||||
{
|
||||
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
|
||||
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
|
||||
vec3 origin = vec3(uni.viewInverse * vec4(0, 0, 0, 1));
|
||||
|
||||
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,41 +17,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
vec3 pos;
|
||||
vec3 nrm;
|
||||
vec3 color;
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
struct WaveFrontMaterial
|
||||
{
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
vec3 transmittance;
|
||||
vec3 emission;
|
||||
float shininess;
|
||||
float ior; // index of refraction
|
||||
float dissolve; // 1 == opaque; 0 == fully transparent
|
||||
int illum; // illumination model (see http://www.fileformat.info/format/material/)
|
||||
int textureId;
|
||||
};
|
||||
|
||||
struct SceneDesc
|
||||
{
|
||||
mat4 transfo;
|
||||
mat4 transfoIT;
|
||||
int objId;
|
||||
int txtOffset;
|
||||
|
||||
uint64_t vertexAddress;
|
||||
uint64_t indexAddress;
|
||||
uint64_t materialAddress;
|
||||
uint64_t materialIndexAddress;
|
||||
};
|
||||
|
||||
#include "host_device.h"
|
||||
|
||||
vec3 computeDiffuse(WaveFrontMaterial mat, vec3 lightDir, vec3 normal)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue