From 4d316fe2809459daecbce32a99094d21358063d2 Mon Sep 17 00:00:00 2001 From: antopilo Date: Tue, 28 Jan 2025 23:08:35 -0500 Subject: [PATCH] Drawing multiple scenes, only need to copy to viewport render targets --- Nuake/src/Rendering/Vulkan/RenderContext.h | 1 - Nuake/src/Rendering/Vulkan/SceneViewport.h | 2 + Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp | 42 ++++- Nuake/src/Rendering/Vulkan/VulkanRenderer.h | 3 +- .../Rendering/Vulkan/VulkanSceneRenderer.cpp | 178 ++++++++++++++++++ .../Rendering/Vulkan/VulkanSceneRenderer.h | 5 +- Nuake/src/Window.cpp | 7 +- 7 files changed, 227 insertions(+), 11 deletions(-) diff --git a/Nuake/src/Rendering/Vulkan/RenderContext.h b/Nuake/src/Rendering/Vulkan/RenderContext.h index 90dc3538..d68e1abf 100644 --- a/Nuake/src/Rendering/Vulkan/RenderContext.h +++ b/Nuake/src/Rendering/Vulkan/RenderContext.h @@ -15,7 +15,6 @@ namespace Nuake Cmd CommandBuffer; // The command buffer we are recording into Vector2 Size; UUID CameraID; - // ... // We might add more to this! }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/SceneViewport.h b/Nuake/src/Rendering/Vulkan/SceneViewport.h index 16541d95..7a6b6060 100644 --- a/Nuake/src/Rendering/Vulkan/SceneViewport.h +++ b/Nuake/src/Rendering/Vulkan/SceneViewport.h @@ -23,6 +23,7 @@ namespace Nuake public: UUID GetID() const { return id; } + UUID GetViewID() const { return viewId; } const Vector2& GetViewportSize() const { return viewportSize; } void SetViewportSize(const Vector2& size) @@ -30,6 +31,7 @@ namespace Nuake viewportSize = size; } + Ref GetRenderTarget() const { return renderTarget; } }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp index 5b820ba3..218401f0 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp @@ -32,7 +32,7 @@ #include -bool NKUseValidationLayer = false; +bool NKUseValidationLayer = true; using namespace Nuake; @@ -362,6 +362,40 @@ void VkRenderer::InitDescriptors() } } +void VkRenderer::PrepareSceneData(RenderContext ctx) +{ + std::vector> scenes; + scenes.reserve(SceneViewports.size()); + + for (auto& [scene, _] : SceneViewports) + { + scenes.push_back(scene); + } + + SceneRenderer->PrepareScenes(scenes, ctx); +} + +void VkRenderer::DrawScenes() +{ + RenderContext ctx; + ctx.CommandBuffer = GetCurrentCmdBuffer(); + + for (auto& [scene, views] : SceneViewports) + { + ctx.CurrentScene = scene; + + for (auto& view : views) + { + Ref viewport = Viewports[view]; + assert(viewport); + + ctx.CameraID = viewport->GetViewID(); + ctx.Size = viewport->GetViewportSize(); + SceneRenderer->DrawSceneView(ctx); + } + } +} + void VkRenderer::DrawScene(RenderContext ctx) { SceneRenderer->BeginScene(ctx); @@ -446,12 +480,6 @@ void VkRenderer::UnRegisterSceneViewport(const Ref& scene, const UUID& vi } } -void PrepareSceneData(const Ref& scene) -{ - // Prepare scene data - -} - void DrawSceneViewport(const Ref& scene, const UUID& viewportId) { // Draw scene viewport diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h index 1e354717..27a45d7d 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h @@ -227,7 +227,8 @@ namespace Nuake void RegisterSceneViewport(const Ref& scene, const UUID& viewportId); void UnRegisterSceneViewport(const Ref& scene, const UUID& viewportId); - void PrepareSceneData(const Ref& scene); + void PrepareSceneData(RenderContext ctx); + void DrawScenes(); void DrawSceneViewport(const Ref& scene, const UUID& viewportId); void BeginScene(const UUID& camera); diff --git a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp index fdb2e063..38587653 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp @@ -72,6 +72,184 @@ void VkSceneRenderer::SetGBufferSize(const Vector2& size) Context.Size = size; } +void VkSceneRenderer::PrepareScenes(const std::vector>& scenes, RenderContext inContext) +{ + // Prepare all scenes + auto& gpu = GPUResources::Get(); + gpu.ClearCameras(); + + for (auto& scene : scenes) + { + // Prepare scene + // Cameras + { + const auto& camera = scene->m_EditorCamera; + CameraView cameraView + { + .View = camera->GetTransform(), + .Projection = camera->GetPerspective(), + .InverseView = glm::inverse(cameraView.View), + .InverseProjection = glm::inverse(cameraView.Projection), + .Position = camera->GetTranslation(), + .Near = camera->Near, + .Far = camera->Far, + }; + gpu.AddCamera(camera->ID, std::move(cameraView)); + + auto view = scene->m_Registry.view(); + for (auto e : view) + { + const auto& [transform, cameraComponent] = view.get(e); + const Ref camera = cameraComponent.CameraInstance; + + CameraView cameraView + { + .View = camera->GetTransform(), + .Projection = camera->GetPerspective(), + .InverseView = glm::inverse(cameraView.View), + .InverseProjection = glm::inverse(cameraView.Projection), + .Position = camera->GetTranslation(), + .Near = camera->Near, + .Far = camera->Far, + }; + gpu.AddCamera(camera->ID, std::move(cameraView)); + } + } + + // Lights + { + auto view = scene->m_Registry.view(); + for (auto e : view) + { + auto [transform, light] = view.get(e); + for (auto& view : light.m_LightViews) + { + CameraView cameraView + { + .View = view.View, + .Projection = view.Proj, + .InverseView = glm::inverse(view.View), + .InverseProjection = glm::inverse(view.Proj), + .Position = transform.GetGlobalTransform()[3], + .Near = 0, + .Far = 0, + }; + gpu.AddCamera(view.CameraID, std::move(cameraView)); + } + } + } + + // Models + { + uint32_t lightCount = 0; + std::array allLights; + auto lightView = scene->m_Registry.view(); + for (auto e : lightView) + { + if (lightCount >= MAX_LIGHTS) + { + assert(false && "Max amount of light reached!"); + break; + } + + auto [transform, lightComp] = lightView.get(e); + + // Update light direction with transform, shouldn't be here! + // TODO: Move to transform system + lightComp.Direction = transform.GetGlobalRotation() * Vector3(0, 0, -1); + + LightData light + { + .Position = Vector3(transform.GetGlobalTransform()[3]), + .Type = lightComp.Type, + .Color = Vector4(lightComp.Color * lightComp.Strength, 1.0), + .Direction = lightComp.Direction, + .OuterConeAngle = glm::cos(Rad(lightComp.OuterCutoff)), + .InnerConeAngle = glm::cos(Rad(lightComp.Cutoff)), + .CastShadow = lightComp.CastShadows, + }; + + if (lightComp.CastShadows && lightComp.Type == LightType::Directional) + { + for (int i = 0; i < CSM_AMOUNT; i++) + { + light.TransformId[i] = gpu.GetBindlessCameraID(lightComp.m_LightViews[i].CameraID); + light.ShadowMapTextureId[i] = gpu.GetBindlessTextureID(lightComp.m_ShadowMaps[i]->GetID()); + } + } + + allLights[lightCount] = std::move(light); + + lightCount++; + } + + gpu.LightDataContainerArray = LightDataContainer{ allLights }; + gpu.LightCount = lightCount; + } + + // Update transforms, materials and lights. + // We need to push lights first to have bindless mapping for CSM + gpu.UpdateBuffers(); + + // Update light CSM + { + auto view = scene->m_Registry.view(); + for (auto e : view) + { + auto [transform, light] = view.get(e); + auto cam = gpu.GetCamera(inContext.CameraID); + + if (light.Type == LightType::Directional) + { + light.CalculateViewProjection(cam.View, cam.Projection); + } + } + } + } + + gpu.RecreateBindlessCameras(); + + for (auto& scene : scenes) + { + + PassRenderContext passCtx = { }; + passCtx.scene = scene; + passCtx.commandBuffer = inContext.CommandBuffer; + passCtx.resolution = Context.Size; + passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID); + + auto view = scene->m_Registry.view(); + for (auto e : view) + { + auto [transform, light] = view.get(e); + + if (light.Type != LightType::Directional || !light.CastShadows) + { + continue; + } + + light.LightMapIDs.clear(); + for (int i = 0; i < CSM_AMOUNT; i++) + { + light.LightMapIDs.push_back(light.m_ShadowMaps[i]->GetID()); + passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(light.m_LightViews[i].CameraID); + passCtx.resolution = Vector2{ 4096, 4096 }; + shadowRenderPipeline->Render(passCtx, light.m_ShadowMaps[i]); + } + } + } +} + +void VkSceneRenderer::DrawSceneView(RenderContext inContext) +{ + PassRenderContext passCtx = { }; + passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID); + passCtx.resolution = Context.Size; + passCtx.commandBuffer = inContext.CommandBuffer; + passCtx.scene = inContext.CurrentScene; + sceneRenderPipeline->Render(passCtx); +} + // This will prepare all the data and upload it to the GPU before rendering the scene. void VkSceneRenderer::BeginScene(RenderContext inContext) { diff --git a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h index 0247b61e..72139f8d 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h @@ -9,7 +9,7 @@ #include -#include +#include #include #include @@ -17,6 +17,7 @@ namespace Nuake { class SceneRenderPipeline; class ShadowRenderPipeline; + class Scene; class VkMesh; @@ -39,6 +40,8 @@ namespace Nuake void Init(); void SetGBufferSize(const Vector2& size); + void PrepareScenes(const std::vector>& scenes, RenderContext inContext); + void DrawSceneView(RenderContext inContext); void BeginScene(RenderContext inContext); void EndScene(); diff --git a/Nuake/src/Window.cpp b/Nuake/src/Window.cpp index f55f8d66..78261cde 100644 --- a/Nuake/src/Window.cpp +++ b/Nuake/src/Window.cpp @@ -213,6 +213,9 @@ void Window::Draw() ZoneScopedN("Non-playmode Draw"); float resolutionScale = glm::clamp(Engine::GetProject()->Settings.ResolutionScale, 0.5f, 2.0f); this->scene->m_EditorCamera->OnWindowResize(size.x * resolutionScale, size.y * resolutionScale); + + auto& vkRenderer = VkRenderer::Get(); + //vkRenderer.PrepareSceneData(); VkRenderer::Get().BeginScene(scene->m_EditorCamera->ID); this->scene->Draw(*this->framebuffer.get(), this->scene->m_EditorCamera->GetPerspective(), this->scene->m_EditorCamera->GetTransform()); } @@ -248,7 +251,9 @@ void Window::EndDraw() scene->GetCurrentCamera()->ID }; - vkRenderer.DrawScene(ctx); + vkRenderer.PrepareSceneData(ctx); + //vkRenderer.DrawScene(ctx); + vkRenderer.DrawScenes(); } } vkRenderer.EndDraw();