Fixed viewport rendering behavior, no longer a black screen. Was missing models in pipeline

This commit is contained in:
antopilo
2025-01-29 17:57:35 -05:00
parent 4d316fe280
commit e5fc760938
5 changed files with 127 additions and 27 deletions

View File

@@ -48,7 +48,8 @@ void ViewportWidget::Draw()
// This is important for make UI mouse coord relative to viewport
// Nuake::Input::SetViewportDimensions(m_ViewportPos, viewportPanelSize);
VkDescriptorSet textureDesc = VkRenderer::Get().DrawImage->GetImGuiDescriptorSet();
VkDescriptorSet textureDesc = sceneViewport->GetRenderTarget()->GetImGuiDescriptorSet();
//VkDescriptorSet textureDesc = VkRenderer::Get().DrawImage->GetImGuiDescriptorSet();
ImVec2 imagePos = ImGui::GetWindowPos() + ImGui::GetCursorPos();
// Input::SetEditorViewportSize(m_ViewportPos, viewportPanelSize);

View File

@@ -8,6 +8,7 @@
namespace Nuake
{
class Scene;
class VulkanImage;
struct RenderContext
{
@@ -15,6 +16,7 @@ namespace Nuake
Cmd CommandBuffer; // The command buffer we are recording into
Vector2 Size;
UUID CameraID;
Ref<VulkanImage> ViewportImage;
// We might add more to this!
};
}

View File

@@ -10,6 +10,6 @@ Viewport::Viewport(UUID inViewId, const Vector2& inViewportSize) :
viewId(inViewId)
{
// Create render target
renderTarget = CreateRef<VulkanImage>(ImageFormat::RGBA8, viewportSize);
renderTarget = CreateRef<VulkanImage>(ImageFormat::RGBA16F, viewportSize);
}

View File

@@ -391,6 +391,7 @@ void VkRenderer::DrawScenes()
ctx.CameraID = viewport->GetViewID();
ctx.Size = viewport->GetViewportSize();
ctx.ViewportImage = viewport->GetRenderTarget();
SceneRenderer->DrawSceneView(ctx);
}
}
@@ -686,6 +687,11 @@ bool VkRenderer::Draw()
VK_CALL(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
// Transfer rendering image to general layout
for (auto& [_id, viewport] : Viewports)
{
viewport->GetRenderTarget()->TransitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL);
}
DrawImage->TransitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL);
//VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
@@ -717,12 +723,21 @@ void VkRenderer::EndDraw()
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
DrawImage->TransitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
for (auto& [_id, viewport] : Viewports)
{
viewport->GetRenderTarget()->TransitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
// VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
DrawImgui(cmd, SwapchainImageViews[swapchainImageIndex]);
// Transition the swapchain image to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for presentation
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
DrawImage->TransitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL);
for (auto& [_id, viewport] : Viewports)
{
viewport->GetRenderTarget()->TransitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL);
}
VK_CALL(vkEndCommandBuffer(cmd));
VkCommandBufferSubmitInfo cmdinfo = VulkanInit::CommandBufferSubmitInfo(cmd);

View File

@@ -140,6 +140,80 @@ 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)
{
// 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 };
}
// Lights
{
uint32_t lightCount = 0;
std::array<LightData, MAX_LIGHTS> allLights;
@@ -205,49 +279,57 @@ void VkSceneRenderer::PrepareScenes(const std::vector<Ref<Scene>>& scenes, Rende
}
}
}
}
gpu.RecreateBindlessCameras();
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)
for (auto& scene : scenes)
{
auto [transform, light] = view.get<TransformComponent, LightComponent>(e);
PassRenderContext passCtx = { };
passCtx.scene = scene;
passCtx.commandBuffer = inContext.CommandBuffer;
passCtx.resolution = inContext.Size;
passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID);
if (light.Type != LightType::Directional || !light.CastShadows)
auto view = scene->m_Registry.view<TransformComponent, LightComponent>();
for (auto e : view)
{
continue;
}
auto [transform, light] = view.get<TransformComponent, LightComponent>(e);
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]);
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.resolution = inContext.Size;
passCtx.commandBuffer = inContext.CommandBuffer;
passCtx.scene = inContext.CurrentScene;
sceneRenderPipeline->Render(passCtx);
inContext.CommandBuffer.TransitionImageLayout(sceneRenderPipeline->GetOutput(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
inContext.CommandBuffer.TransitionImageLayout(inContext.ViewportImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
inContext.CommandBuffer.CopyImageToImage(sceneRenderPipeline->GetOutput(), inContext.ViewportImage);
inContext.CommandBuffer.TransitionImageLayout(inContext.ViewportImage, VK_IMAGE_LAYOUT_GENERAL);
inContext.CommandBuffer.TransitionImageLayout(sceneRenderPipeline->GetOutput(), VK_IMAGE_LAYOUT_GENERAL);
}
// This will prepare all the data and upload it to the GPU before rendering the scene.