2
3
4
5
10#include "Render/Vulkan/VulkanRayTracing.h"
17 const std::string& rendererName ,
23 :
Renderer(rendererName
, vulkanState
, descriptorPool
, device
, rendererResourcePool
)
27 m_VulkanRayTracing = std::make_shared<VulkanRayTracing>(m_VulkanState);
34 m_VulkanRayTracing =
nullptr;
41 RendererPassBuilder{
"RayTracing",
this }
51 DescriptorSetBuilder{
"RayTracing",
this }
52 .AddPushConstant(
sizeof(RayTracingR::PushConstant))
53 .AddAccelerationStructure(2, 0, VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)
54 .AddStorageTexture(2, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR, {
"RayImage" }, VK_FORMAT_R32G32B32A32_SFLOAT)
55 .AddStorageTexture(2, 2, VK_SHADER_STAGE_RAYGEN_BIT_KHR, {
"RayEntityID",
"RayTriangleID" }, VK_FORMAT_R32_SFLOAT)
56 .AddStorageBuffer(3, 0, SpicesShader::MESH_BUFFER_MAXNUM *
sizeof(uint64_t), VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)
57 .AddStorageBuffer(3, 1,
sizeof(RayTracingR::DirectionalLightBuffer), VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)
58 .AddStorageBuffer(3, 2,
sizeof(RayTracingR::PointLightBuffer), VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)
59 .AddTexture<Texture2D>(4, 0, VK_SHADER_STAGE_MISS_BIT_KHR, {
"skybox/kloofendal_48d_partly_cloudy_puresky_4k.hdr"})
60 .Build(m_VulkanRayTracing->GetAccelerationStructure());
69 AsyncTask(ThreadPoolEnum::Custom, [=]() {
73 std::shared_ptr<VulkanRayTracing> rayTracingInstance = std::make_shared<VulkanRayTracing>(m_VulkanState);
76
77
78 CreateBottomLevelAS(FrameInfo::Get(), view, rayTracingInstance);
79 CreateTopLevelAS (FrameInfo::Get(), view, rayTracingInstance);
82
83
84 CreateDefaultMaterial();
85 CreateRTShaderBindingTable(rayTracingInstance);
88
89
90 AsyncMainTask(ThreadPoolEnum::Main, [=]() {
92 vkQueueWaitIdle(m_VulkanState.m_GraphicQueue);
93 m_RenderCache->PushToCaches(m_VulkanRayTracing);
94 m_VulkanRayTracing = rayTracingInstance;
101 std::shared_ptr<
Material> material ,
102 VkPipelineLayout& layout ,
108 PipelineBuilder{ subPass, material,
this }
110 .NullBindingDescriptions()
111 .NullAttributeDescriptions()
112 .SetPipelineLayout(layout)
113 .BuildRayTracing(*GetHitGroupsCache());
120 if (m_VulkanRayTracing->GetAccelerationStructure() == VK_NULL_HANDLE)
return;
122 UpdateTopLevelAS(frameInfo, m_VulkanRayTracing);
130 builder.BindDescriptorSet(DescriptorSetManager::GetByName(
"PreRenderer"));
132 builder.BindDescriptorSet(DescriptorSetManager::GetByName(
"RayTracing"));
134 builder.BindPipeline(
"RayTracingRenderer.RayTracing.Default");
136 builder.UpdateAccelerationStructure(2, 0, m_VulkanRayTracing->GetAccelerationStructure());
138 builder.UpdateStorageBuffer(3, 0, m_VulkanRayTracing->GetMeshDesc().buffer);
150 push.entityID = entityId;
164 if(!m_VulkanRayTracing)
return nullptr;
166 return m_VulkanRayTracing->GetAccelerationStructure();
176 auto view = GetEntityWithComponent<
MeshComponent>(frameInfo.m_World.get());
177 CreateTopLevelAS(frameInfo, view, rayTracingInstance, update);
184 const auto rayTracingMaterial = ResourcePool<Material>::Load<Material>(
"RayTracingRenderer.RayTracing.Default",
"RayTracingRenderer.RayTracing.Default");
186 const uint32_t rayGenCount =
static_cast<uint32_t>(rayTracingMaterial->GetShaderPath(
"rgen").size());
187 const uint32_t missCount =
static_cast<uint32_t>(rayTracingMaterial->GetShaderPath(
"rmiss").size());
189 rayTracingInstance->CreateRTShaderBindingTable(rayGenCount, missCount, m_Pipelines.Find(
"RayTracingRenderer.RayTracing.Default")->GetPipeline());
196 if (!m_HitGroupsCache)
198 m_HitGroupsCache = std::make_shared<std::unordered_map<std::string, uint32_t>>();
201 return m_HitGroupsCache;
209
210
211 std::vector<VulkanRayTracing::BlasInput> allBlas;
214
215
216 frameInfo.m_World->ViewComponent<MeshComponent>(*view, [&](
auto e,
auto& meshComp){
218 meshComp.GetMesh()->GetPacks().for_each([&](
const uint32_t& k,
const std::shared_ptr<MeshPack>& v) {
220 if (v->HasBlasAccel())
return false;
222 auto blas = v->MeshPackToVkGeometryKHR();
223 allBlas.emplace_back(blas);
232
233
234 if(allBlas.empty())
return;
237
238
239 rayTracingInstance->BuildBLAS(
241 VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR |
242 VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR
251 std::vector<VkAccelerationStructureInstanceKHR> tlas;
252 std::shared_ptr<std::unordered_map<std::string, uint32_t>> hitGroups = std::make_shared<std::unordered_map<std::string, uint32_t>>();
255 auto& desc = rayTracingInstance->GetMeshDesc().attributes;
256 desc->resize(SpicesShader::MESH_BUFFER_MAXNUM, 0);
258 frameInfo.m_World->ViewComponent<MeshComponent>(*view, [&](
auto e,
auto& meshComp){
260 auto& tranComp = frameInfo.m_World->GetComponent<TransformComponent>(
static_cast<entt::entity>(e));
262 meshComp.GetMesh()->AddMaterialToHitGroup(*hitGroups);
263 meshComp.GetMesh()->GetPacks().for_each([&](
const uint32_t& k,
const std::shared_ptr<MeshPack>& v) {
265 VkAccelerationStructureInstanceKHR rayInst{};
266 rayInst.transform = ToVkTransformMatrixKHR(tranComp.GetModelMatrix());
267 rayInst.instanceCustomIndex = index;
268 rayInst.accelerationStructureReference = v->GetAccel().accel->GetACDeviceAddress();
269 rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
271 rayInst.instanceShaderBindingTableRecordOffset = v->GetHitShaderHandle();
273 tlas.push_back(rayInst);
275 (*desc)[index] = v->GetMeshDesc().GetBufferAddress();
284 rayTracingInstance->GetMeshDesc().CreateBuffer(
"MeshDescBuffer", VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
287
288
289 SetHitGroupsCache(hitGroups);
291 rayTracingInstance->SetHitGroups(hitGroups);
294
295
296 rayTracingInstance->BuildTLAS(
298 VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR |
299 VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR |
300 VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR ,
#define SPICES_PROFILE_ZONEN(...)
#define SPICES_PROFILE_ZONE
static FrameInfo & Get()
Get FrameInfo.
RendererType m_RendererType
The renderer type of current world.
FrameInfo Class. This class defines the FrameInfo data.
Material Class. This class contains a branch of parameter and shader, also descriptor.
MeshComponent Class. This class defines the specific behaves of MeshComponent.
virtual void CreateDescriptorSet() override
The interface is inherited from Renderer. Create specific descriptor set for sub pass.
static std::shared_ptr< VulkanRayTracing > m_VulkanRayTracing
In Used VulkanRayTracing.
void CreateTopLevelAS(FrameInfo &frameInfo, std::shared_ptr< std::vector< uint32_t > > view, std::shared_ptr< VulkanRayTracing > rayTracingInstance, bool update=false)
Create TopLevelAS.
virtual void CreatePipeline(std::shared_ptr< Material > material, VkPipelineLayout &layout, std::shared_ptr< RendererSubPass > subPass) override
The interface is inherited from Renderer. Create Material Specific Pipeline.
virtual void Render(TimeStep &ts, FrameInfo &frameInfo) override
The interface is inherited from Renderer.
RayTracingRenderer(const std::string &rendererName, VulkanState &vulkanState, const std::shared_ptr< VulkanDescriptorPool > &descriptorPool, const std::shared_ptr< VulkanDevice > &device, const std::shared_ptr< RendererResourcePool > &rendererResourcePool)
Constructor Function. Init member variables.
virtual void OnMeshAddedWorld() override
virtual ~RayTracingRenderer() override
Destructor Function.
std::shared_ptr< std::unordered_map< std::string, uint32_t > > GetHitGroupsCache()
Get HitGroupsCache.
void CreateRTShaderBindingTable(std::shared_ptr< VulkanRayTracing > rayTracingInstance)
Create Shader Binding Table.
virtual void CreateRendererPass() override
The interface is inherited from Renderer. Create specific render pass.
void CreateBottomLevelAS(FrameInfo &frameInfo, std::shared_ptr< std::vector< uint32_t > > view, std::shared_ptr< VulkanRayTracing > rayTracingInstance)
Create BottomLevelAS with all MeshComponents.
void UpdateTopLevelAS(FrameInfo &frameInfo, std::shared_ptr< VulkanRayTracing > rayTracingInstance, bool update=true)
Update TopLevelAS.
RayTracingRenderer Class. This class defines the ray tracing behaves.
RendererResourcePool Class. This class is a pool of all framebuffer's attachment.
This Class Combines some data relative to sub pass. Usually as a member variable of RendererPass.
virtual void EndRenderPass() override
End this Renderer's RenderPass.
void TraceRays() const
Call vkCmdTraceRaysKHR here.
virtual void BeginRenderPass() override
Begin this Renderer's RenderPass.
This class helps to bind pipeline and bind buffer. Specific for RayTracing Renderer....
RendererPassBuilder & EndSubPass()
End recording a sub pass.
void Build() const
Build the RendererPass.
RendererPassBuilder & AddSubPass(const std::string &subPassName, Querier::StatisticsFlags flags=Querier::ALL)
Add a new SubPass to Renderer Pass.
virtual void OnMeshAddedWorld()
Renderer(const std::string &rendererName, VulkanState &vulkanState, const std::shared_ptr< VulkanDescriptorPool > &DescriptorPool, const std::shared_ptr< VulkanDevice > &device, const std::shared_ptr< RendererResourcePool > &rendererResourcePool, bool isLoadDefaultMaterial=true)
Constructor Function. Init member variables.
void GetDirectionalLight(FrameInfo &frameInfo, std::array< SpicesShader::DirectionalLight, SpicesShader::DIRECTIONALLIGHT_BUFFER_MAXNUM > &dLightBuffer)
Get DirectionalLightComponent's render data in World.
void GetPointLight(FrameInfo &frameInfo, std::array< SpicesShader::PointLight, SpicesShader::POINTLIGHT_BUFFER_MAXNUM > &pLightBuffer)
Get PointLightComponent's render data in World.
Renderer Class. This class defines the basic behaves of renderer. When we add an new Renderer,...
SkyBoxComponent Class. This class defines the specific behaves of SkyBoxComponent.
This Class handles our engine time step during frames. Global Unique.
VulkanDescriptorPool Class. This class is the wrapper of VkDescriptorPool.
VulkanInstance Class. This class defines the VulkanDevice behave. This class is just a wrapper of vkd...
Wrapper of Scene RayTracing (KHR/VK) Features and Data.
World Class. This class defines the basic behaves of World. When we create an new world,...
This struct contains all Vulkan object in used global.