Drawing multiple scenes, only need to copy to viewport render targets

This commit is contained in:
antopilo
2025-01-28 23:08:35 -05:00
parent 5347fab0ed
commit 4d316fe280
7 changed files with 227 additions and 11 deletions

View File

@@ -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!
};
}

View File

@@ -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<VulkanImage> GetRenderTarget() const { return renderTarget; }
};
}

View File

@@ -32,7 +32,7 @@
#include <array>
bool NKUseValidationLayer = false;
bool NKUseValidationLayer = true;
using namespace Nuake;
@@ -362,6 +362,40 @@ void VkRenderer::InitDescriptors()
}
}
void VkRenderer::PrepareSceneData(RenderContext ctx)
{
std::vector<Ref<Scene>> 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> 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>& scene, const UUID& vi
}
}
void PrepareSceneData(const Ref<Scene>& scene)
{
// Prepare scene data
}
void DrawSceneViewport(const Ref<Scene>& scene, const UUID& viewportId)
{
// Draw scene viewport

View File

@@ -227,7 +227,8 @@ namespace Nuake
void RegisterSceneViewport(const Ref<Scene>& scene, const UUID& viewportId);
void UnRegisterSceneViewport(const Ref<Scene>& scene, const UUID& viewportId);
void PrepareSceneData(const Ref<Scene>& scene);
void PrepareSceneData(RenderContext ctx);
void DrawScenes();
void DrawSceneViewport(const Ref<Scene>& scene, const UUID& viewportId);
void BeginScene(const UUID& camera);

View File

@@ -72,6 +72,184 @@ void VkSceneRenderer::SetGBufferSize(const Vector2& size)
Context.Size = size;
}
void VkSceneRenderer::PrepareScenes(const std::vector<Ref<Scene>>& 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<TransformComponent, CameraComponent>();
for (auto e : view)
{
const auto& [transform, cameraComponent] = view.get<TransformComponent, CameraComponent>(e);
const Ref<Camera> 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<TransformComponent, LightComponent>();
for (auto e : view)
{
auto [transform, light] = view.get<TransformComponent, LightComponent>(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<LightData, MAX_LIGHTS> allLights;
auto lightView = scene->m_Registry.view<TransformComponent, LightComponent>();
for (auto e : lightView)
{
if (lightCount >= MAX_LIGHTS)
{
assert(false && "Max amount of light reached!");
break;
}
auto [transform, lightComp] = lightView.get<TransformComponent, LightComponent>(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<TransformComponent, LightComponent>();
for (auto e : view)
{
auto [transform, light] = view.get<TransformComponent, LightComponent>(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<TransformComponent, LightComponent>();
for (auto e : view)
{
auto [transform, light] = view.get<TransformComponent, LightComponent>(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)
{

View File

@@ -9,7 +9,7 @@
#include <volk/volk.h>
#include <array>
#include <vector>
#include <map>
#include <string>
@@ -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<Ref<Scene>>& scenes, RenderContext inContext);
void DrawSceneView(RenderContext inContext);
void BeginScene(RenderContext inContext);
void EndScene();

View File

@@ -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();