Can now render 2 scene at once

This commit is contained in:
antopilo
2025-01-29 19:43:21 -05:00
parent e5fc760938
commit ea136b729c
8 changed files with 324 additions and 326 deletions

View File

@@ -2912,6 +2912,11 @@ namespace Nuake {
{
Selection = EditorSelection();
}
for (auto& sceneEditors : sceneEditors)
{
sceneEditors->Update(ts);
}
}
void EditorInterface::BuildFonts()

View File

@@ -29,7 +29,7 @@ ViewportWidget::~ViewportWidget()
void ViewportWidget::Update(float ts)
{
editorContext.GetScene()->Update(ts);
}
void ViewportWidget::Draw()
@@ -45,6 +45,8 @@ void ViewportWidget::Draw()
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
Vector2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
//this->sceneViewport->SetViewportSize(viewportPanelSize);
// This is important for make UI mouse coord relative to viewport
// Nuake::Input::SetViewportDimensions(m_ViewportPos, viewportPanelSize);

View File

@@ -208,8 +208,6 @@ namespace Nuake
//ImGui::ShowDemoWindow();
RenderCommand::Clear();
// Start imgui frame
@@ -225,8 +223,6 @@ namespace Nuake
// Draw scene
Window::Get()->Draw();
}
void Engine::EndDraw()

View File

@@ -9,7 +9,17 @@ Viewport::Viewport(UUID inViewId, const Vector2& inViewportSize) :
viewportSize(inViewportSize),
viewId(inViewId)
{
// Create render target
renderTarget = CreateRef<VulkanImage>(ImageFormat::RGBA16F, viewportSize);
}
bool Viewport::Resize()
{
if (renderTarget->GetSize() != viewportSize)
{
renderTarget = CreateRef<VulkanImage>(ImageFormat::RGBA16F, viewportSize);
return true;
}
return false;
}

View File

@@ -31,7 +31,7 @@ namespace Nuake
viewportSize = size;
}
Ref<VulkanImage> GetRenderTarget() const { return renderTarget; }
bool Resize();
};
}

View File

@@ -221,8 +221,6 @@ void VkRenderer::RecreateSwapchain()
DestroySwapchain();
CreateSwapchain(Window::Get()->GetSize());
UpdateDescriptorSets();
SceneRenderer->SetGBufferSize(Window::Get()->GetSize());
}
void VkRenderer::CreateSwapchain(const Vector2& size)
@@ -392,6 +390,7 @@ void VkRenderer::DrawScenes()
ctx.CameraID = viewport->GetViewID();
ctx.Size = viewport->GetViewportSize();
ctx.ViewportImage = viewport->GetRenderTarget();
SceneRenderer->DrawSceneView(ctx);
}
}
@@ -399,8 +398,8 @@ void VkRenderer::DrawScenes()
void VkRenderer::DrawScene(RenderContext ctx)
{
SceneRenderer->BeginScene(ctx);
SceneRenderer->EndScene();
//SceneRenderer->BeginScene(ctx);
//SceneRenderer->EndScene();
}
void VkRenderer::UpdateDescriptorSets()
@@ -650,7 +649,7 @@ void VkRenderer::InitImgui()
void VkRenderer::BeginScene(const UUID& camera)
{
SceneRenderer->CurrentCamera = camera;
}
bool VkRenderer::Draw()

View File

@@ -29,8 +29,6 @@ void VkSceneRenderer::Init()
{
LoadShaders();
SetGBufferSize({ 1280, 720 });
shadowRenderPipeline = CreateRef<ShadowRenderPipeline>();
sceneRenderPipeline = CreateRef<SceneRenderPipeline>();
@@ -67,17 +65,20 @@ void VkSceneRenderer::LoadShaders()
shaderMgr.AddShader("tonemap_vert", shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/tonemap.vert"));
}
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();
uint32_t lightCount = 0;
std::array<LightData, MAX_LIGHTS> allLights;
uint32_t currentIndex = 0;
uint32_t currentMaterialIndex = 0;
std::array<Matrix4, MAX_MODEL_MATRIX> allTransforms;
std::array<MaterialBufferStruct, MAX_MATERIAL> allMaterials;
for (auto& scene : scenes)
{
// Prepare scene
@@ -141,10 +142,6 @@ void VkSceneRenderer::PrepareScenes(const std::vector<Ref<Scene>>& scenes, Rende
// Models
{
uint32_t currentIndex = 0;
uint32_t currentMaterialIndex = 0;
std::array<Matrix4, MAX_MODEL_MATRIX> allTransforms;
std::array<MaterialBufferStruct, MAX_MATERIAL> allMaterials;
auto view = scene->m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
for (auto e : view)
{
@@ -208,15 +205,10 @@ void VkSceneRenderer::PrepareScenes(const std::vector<Ref<Scene>>& scenes, Rende
currentIndex++;
}
gpu.ModelTransforms = ModelData{ allTransforms };
gpu.MaterialDataContainer = MaterialData{ allMaterials };
}
// Lights
{
uint32_t lightCount = 0;
std::array<LightData, MAX_LIGHTS> allLights;
auto lightView = scene->m_Registry.view<TransformComponent, LightComponent>();
for (auto e : lightView)
{
@@ -256,15 +248,8 @@ void VkSceneRenderer::PrepareScenes(const std::vector<Ref<Scene>>& scenes, Rende
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>();
@@ -281,38 +266,43 @@ void VkSceneRenderer::PrepareScenes(const std::vector<Ref<Scene>>& scenes, Rende
}
gpu.RecreateBindlessCameras();
}
for (auto& scene : scenes)
gpu.ModelTransforms = ModelData{ allTransforms };
gpu.MaterialDataContainer = MaterialData{ allMaterials };
gpu.LightDataContainerArray = LightDataContainer{ allLights };
gpu.LightCount = lightCount;
gpu.UpdateBuffers();
for (auto& scene : scenes)
{
PassRenderContext passCtx = { };
passCtx.scene = scene;
passCtx.commandBuffer = inContext.CommandBuffer;
passCtx.resolution = inContext.Size;
passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(scene->GetCurrentCamera()->ID);
auto view = scene->m_Registry.view<TransformComponent, LightComponent>();
for (auto e : view)
{
PassRenderContext passCtx = { };
passCtx.scene = scene;
passCtx.commandBuffer = inContext.CommandBuffer;
passCtx.resolution = inContext.Size;
passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID);
auto [transform, light] = view.get<TransformComponent, LightComponent>(e);
auto view = scene->m_Registry.view<TransformComponent, LightComponent>();
for (auto e : view)
if (light.Type != LightType::Directional || !light.CastShadows)
{
auto [transform, light] = view.get<TransformComponent, LightComponent>(e);
continue;
}
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]);
}
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)
@@ -333,265 +323,266 @@ void VkSceneRenderer::DrawSceneView(RenderContext inContext)
}
// This will prepare all the data and upload it to the GPU before rendering the scene.
void VkSceneRenderer::BeginScene(RenderContext inContext)
{
Context.CommandBuffer = inContext.CommandBuffer;
Context.CurrentScene = inContext.CurrentScene;
Context.CameraID = inContext.CameraID;
//void VkSceneRenderer::BeginScene(RenderContext inContext)
//{
// Context.CommandBuffer = inContext.CommandBuffer;
// Context.CurrentScene = inContext.CurrentScene;
// Context.CameraID = inContext.CameraID;
//
// auto& scene = Context.CurrentScene;
// auto& gpu = GPUResources::Get();
//
// uint32_t currentIndex = 0;
// uint32_t currentMaterialIndex = 0;
// std::array<Matrix4, MAX_MODEL_MATRIX> allTransforms;
// std::array<MaterialBufferStruct, MAX_MATERIAL> allMaterials;
//
// // CameraView
// {
// // Clear last frame's cameras
// gpu.ClearCameras();
//
// // Editor camera, maybe strip this out in runtime?
// 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));
//
// // Add scene cameras
// 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));
// }
// }
//
// // CSM Light's view
// {
// 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));
// }
// }
// }
//
// // All transforms & materials
// {
// auto view = scene->m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
// for (auto e : view)
// {
// // Check if we've reached the maximum capacity of the array
// if (currentIndex >= MAX_MODEL_MATRIX)
// {
// assert(false && "Max model matrix reached!");
// break;
// }
//
// auto [transform, mesh, visibility] = view.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
//
// // Get() will load the resource if its not loaded already
// Ref<Model> modelResource = mesh.ModelResource.Get<Model>();
// if (!modelResource || !visibility.Visible)
// {
// continue;
// }
//
// // Upload transforms to GPU resources
// allTransforms[currentIndex] = transform.GetGlobalTransform();
// gpu.ModelMatrixMapping[Entity((entt::entity)e, scene.get()).GetID()] = currentIndex;
//
// // Upload mesh material to GPU resources
// for (auto& m : modelResource->GetMeshes())
// {
// // TODO: Avoid duplicated materials
// Ref<Material> material = m->GetMaterial();
// if (!material)
// {
// // insert missing material.
// static Ref<Material> missingMaterial = CreateRef<Material>();
// missingMaterial->AlbedoImage = TextureManager::Get()->GetTexture2("missing_texture")->GetID();
//
// material = missingMaterial;
// }
//
// MaterialBufferStruct materialBuffer
// {
// .HasAlbedo = material->HasAlbedo(),
// .AlbedoColor = material->data.m_AlbedoColor,
// .HasNormal = material->HasNormal(),
// .HasMetalness = material->HasMetalness(),
// .HasRoughness = material->HasRoughness(),
// .HasAO = material->HasAO(),
// .MetalnessValue = material->data.u_MetalnessValue,
// .RoughnessValue = material->data.u_RoughnessValue,
// .AoValue = material->data.u_AOValue,
// .AlbedoTextureId = material->HasAlbedo() ? gpu.GetBindlessTextureID(material->AlbedoImage) : 0,
// .NormalTextureId = material->HasNormal() ? gpu.GetBindlessTextureID(material->NormalImage) : 0,
// .MetalnessTextureId = material->HasMetalness() ? gpu.GetBindlessTextureID(material->MetalnessImage) : 0,
// .RoughnessTextureId = material->HasRoughness() ? gpu.GetBindlessTextureID(material->RoughnessImage) : 0,
// .AoTextureId = material->HasAO() ? gpu.GetBindlessTextureID(material->AOImage) : 0,
// };
//
// // Save bindless mapping index
// allMaterials[currentMaterialIndex] = std::move(materialBuffer);
// gpu.MeshMaterialMapping[m->GetVkMesh()->GetID()] = currentMaterialIndex;
// currentMaterialIndex++;
// }
//
// currentIndex++;
// }
// }
//
// gpu.ModelTransforms = ModelData{ allTransforms };
// gpu.MaterialDataContainer = MaterialData{ allMaterials };
//
// // All lights
// {
// 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();
//
// // Execute light
// PassRenderContext passCtx = { };
// passCtx.scene = inContext.CurrentScene;
// 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]);
// }
// }
//
// // Set back the camera ID to the actual desired camera.
// passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID);
// passCtx.resolution = Context.Size;
// sceneRenderPipeline->Render(passCtx);
//}
auto& scene = Context.CurrentScene;
auto& gpu = GPUResources::Get();
// CameraView
{
// Clear last frame's cameras
gpu.ClearCameras();
// Editor camera, maybe strip this out in runtime?
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));
// Add scene cameras
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));
}
}
// CSM Light's view
{
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));
}
}
}
// All transforms & materials
{
uint32_t currentIndex = 0;
uint32_t currentMaterialIndex = 0;
std::array<Matrix4, MAX_MODEL_MATRIX> allTransforms;
std::array<MaterialBufferStruct, MAX_MATERIAL> allMaterials;
auto view = scene->m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
for (auto e : view)
{
// Check if we've reached the maximum capacity of the array
if (currentIndex >= MAX_MODEL_MATRIX)
{
assert(false && "Max model matrix reached!");
break;
}
auto [transform, mesh, visibility] = view.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
// Get() will load the resource if its not loaded already
Ref<Model> modelResource = mesh.ModelResource.Get<Model>();
if (!modelResource || !visibility.Visible)
{
continue;
}
// Upload transforms to GPU resources
allTransforms[currentIndex] = transform.GetGlobalTransform();
gpu.ModelMatrixMapping[Entity((entt::entity)e, scene.get()).GetID()] = currentIndex;
// Upload mesh material to GPU resources
for (auto& m : modelResource->GetMeshes())
{
// TODO: Avoid duplicated materials
Ref<Material> material = m->GetMaterial();
if (!material)
{
// insert missing material.
static Ref<Material> missingMaterial = CreateRef<Material>();
missingMaterial->AlbedoImage = TextureManager::Get()->GetTexture2("missing_texture")->GetID();
material = missingMaterial;
}
MaterialBufferStruct materialBuffer
{
.HasAlbedo = material->HasAlbedo(),
.AlbedoColor = material->data.m_AlbedoColor,
.HasNormal = material->HasNormal(),
.HasMetalness = material->HasMetalness(),
.HasRoughness = material->HasRoughness(),
.HasAO = material->HasAO(),
.MetalnessValue = material->data.u_MetalnessValue,
.RoughnessValue = material->data.u_RoughnessValue,
.AoValue = material->data.u_AOValue,
.AlbedoTextureId = material->HasAlbedo() ? gpu.GetBindlessTextureID(material->AlbedoImage) : 0,
.NormalTextureId = material->HasNormal() ? gpu.GetBindlessTextureID(material->NormalImage) : 0,
.MetalnessTextureId = material->HasMetalness() ? gpu.GetBindlessTextureID(material->MetalnessImage) : 0,
.RoughnessTextureId = material->HasRoughness() ? gpu.GetBindlessTextureID(material->RoughnessImage) : 0,
.AoTextureId = material->HasAO() ? gpu.GetBindlessTextureID(material->AOImage) : 0,
};
// Save bindless mapping index
allMaterials[currentMaterialIndex] = std::move(materialBuffer);
gpu.MeshMaterialMapping[m->GetVkMesh()->GetID()] = currentMaterialIndex;
currentMaterialIndex++;
}
currentIndex++;
}
gpu.ModelTransforms = ModelData{ allTransforms };
gpu.MaterialDataContainer = MaterialData{ allMaterials };
}
// All lights
{
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();
// Execute light
PassRenderContext passCtx = { };
passCtx.scene = inContext.CurrentScene;
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]);
}
}
// Set back the camera ID to the actual desired camera.
passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID);
passCtx.resolution = Context.Size;
sceneRenderPipeline->Render(passCtx);
}
void VkSceneRenderer::EndScene()
{
// Copy final output to DrawImage.
Ref<VulkanImage> drawImage = VkRenderer::Get().GetDrawImage();
Ref<VulkanImage> output = sceneRenderPipeline->GetOutput();
Cmd& cmd = Context.CommandBuffer;
cmd.TransitionImageLayout(output, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
cmd.TransitionImageLayout(drawImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
cmd.CopyImageToImage(output, drawImage);
cmd.TransitionImageLayout(drawImage, VK_IMAGE_LAYOUT_GENERAL);
cmd.TransitionImageLayout(output, VK_IMAGE_LAYOUT_GENERAL);
}
//void VkSceneRenderer::EndScene()
//{
// // Copy final output to DrawImage.
// Ref<VulkanImage> drawImage = VkRenderer::Get().GetDrawImage();
// Ref<VulkanImage> output = sceneRenderPipeline->GetOutput();
//
// Cmd& cmd = Context.CommandBuffer;
// cmd.TransitionImageLayout(output, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
// cmd.TransitionImageLayout(drawImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
// cmd.CopyImageToImage(output, drawImage);
// cmd.TransitionImageLayout(drawImage, VK_IMAGE_LAYOUT_GENERAL);
// cmd.TransitionImageLayout(output, VK_IMAGE_LAYOUT_GENERAL);
//}

View File

@@ -27,23 +27,18 @@ namespace Nuake
static Ref<VkMesh> QuadMesh;
public:
RenderContext Context;
//RenderContext Context;
Ref<SceneRenderPipeline> sceneRenderPipeline;
Ref<ShadowRenderPipeline> shadowRenderPipeline;
public:
UUID CurrentCamera;
VkSceneRenderer() = default;
~VkSceneRenderer() = default;
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();
private:
void LoadShaders();