mirror of
https://github.com/antopilo/Nuake.git
synced 2026-01-03 14:09:46 +03:00
Drawing multiple scenes, only need to copy to viewport render targets
This commit is contained in:
@@ -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!
|
||||
};
|
||||
}
|
||||
@@ -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; }
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user