From 57564645f26d6a5141bf11f48f8c2b5448d6e766 Mon Sep 17 00:00:00 2001 From: antopilo Date: Mon, 14 Apr 2025 17:29:23 -0400 Subject: [PATCH] better outline + gizmo interaction --- Data/Shaders/Vulkan/gizmo.frag | 22 ++- Data/Shaders/Vulkan/gizmo.vert | 1 + Data/Shaders/Vulkan/outline.frag | 4 +- .../SceneEditor/Widgets/ViewportWidget.cpp | 6 +- .../Rendering/Vulkan/Constant/DebugConstant.h | 1 + .../Nuake/Rendering/Vulkan/DebugCmd.cpp | 3 +- .../Source/Nuake/Rendering/Vulkan/DebugCmd.h | 2 +- .../Rendering/Vulkan/SceneRenderPipeline.cpp | 133 +++++++++--------- 8 files changed, 98 insertions(+), 74 deletions(-) diff --git a/Data/Shaders/Vulkan/gizmo.frag b/Data/Shaders/Vulkan/gizmo.frag index 0f087f4b..20776473 100644 --- a/Data/Shaders/Vulkan/gizmo.frag +++ b/Data/Shaders/Vulkan/gizmo.frag @@ -87,6 +87,7 @@ struct PSInput { struct PSOutput { float4 oColor0 : SV_TARGET; + float4 oEntityID : SV_TARGET1; }; struct DebugConstant @@ -94,6 +95,7 @@ struct DebugConstant float4 Color; float4x4 Transform; int TextureID; + float EntityID; }; [[vk::push_constant]] @@ -102,7 +104,7 @@ DebugConstant pushConstants; PSOutput main(PSInput input) { PSOutput output; - + if(pushConstants.TextureID < 0) { output.oColor0 = float4(input.UV.x, input.UV.y, 0, 1); @@ -115,10 +117,26 @@ PSOutput main(PSInput input) // Alpha scisorring if(textureSample.a < 0.1) { - discard; + //discard; } output.oColor0 = textureSample * pushConstants.Color; + + if(pushConstants.EntityID != 0.0f) + { + float2 center = float2(0.5, 0.5); + float dist = distance(uv, center); + float radius = 0.5; // You can adjust this as needed + + if (dist <= radius) + { + output.oEntityID = float4(pushConstants.EntityID, 0, 0, 1.0f); + } + else + { + output.oEntityID = float4(0, 0, 0, 0); // Or leave it unassigned if default is zero + } + } } return output; diff --git a/Data/Shaders/Vulkan/gizmo.vert b/Data/Shaders/Vulkan/gizmo.vert index e27c227c..ff864460 100644 --- a/Data/Shaders/Vulkan/gizmo.vert +++ b/Data/Shaders/Vulkan/gizmo.vert @@ -85,6 +85,7 @@ struct DebugConstant float4 Color; float4x4 Transform; int TextureID; + float EntityID; }; [[vk::push_constant]] diff --git a/Data/Shaders/Vulkan/outline.frag b/Data/Shaders/Vulkan/outline.frag index 1a1a9729..8c77fb07 100644 --- a/Data/Shaders/Vulkan/outline.frag +++ b/Data/Shaders/Vulkan/outline.frag @@ -122,6 +122,7 @@ PSOutput main(PSInput input) float hasHit = 0.0f; float sampleValue = textures[entityIDTextureID].Sample(mySampler, uv).r; + float depth = textures[pushConstants.DepthTextureID].Sample(mySampler, uv).r; float4 fragColor = float4(0, 0, 0, 0); const float TAU = 6.28318530; @@ -135,7 +136,8 @@ PSOutput main(PSInput input) sampleUV.y = clamp(sampleUV.y, 0.0, 0.999); float sample = textures[entityIDTextureID].Sample(mySampler, sampleUV).r; - if(sample == target) + float sampleDepth = textures[pushConstants.DepthTextureID].Sample(mySampler, sampleUV).r; + if(sample == target && sampleDepth != 1.0f && sampleDepth > depth) { hasHit = 1.0f; } diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp index 1cec933f..d7b21fa9 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp @@ -434,14 +434,14 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd) auto view = cam->GetTransform(); auto proj = cam->GetPerspective(); - static auto drawGizmoIcon = [&](TransformComponent& transform, const std::string& icon, const Color& color) + static auto drawGizmoIcon = [&](TransformComponent& transform, const std::string& icon, const Color& color, int32_t entityId) { Matrix4 initialTransform = transform.GetGlobalTransform(); Matrix4 gizmoTransform = initialTransform; gizmoTransform = glm::inverse(scene->GetCurrentCamera()->GetTransform()); gizmoTransform[3] = initialTransform[3]; gizmoTransform = glm::scale(gizmoTransform, gizmoSize * GetGizmoScale(cameraPosition, initialTransform[3])); - debugCmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2(icon), color); + debugCmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2(icon), color, entityId); }; debugCmd.DrawQuad(proj * view * glm::translate(Matrix4(1.0f), { 0, 4, 0 })); @@ -471,7 +471,7 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd) } // Billboard + scaling logic - drawGizmoIcon(transform, texturePath, isSelected ? Color(1, 1, 0, 1) : Color(1, 1, 1, 1)); + drawGizmoIcon(transform, texturePath, isSelected ? Color(1, 1, 0, 1) : Color(1, 1, 1, 1), (int32_t)e); } DrawIconGizmo(debugCmd, "Resources/Gizmos/Camera.png", editorContext); diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/Constant/DebugConstant.h b/Nuake/Source/Nuake/Rendering/Vulkan/Constant/DebugConstant.h index 6241e17c..15e402a8 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/Constant/DebugConstant.h +++ b/Nuake/Source/Nuake/Rendering/Vulkan/Constant/DebugConstant.h @@ -8,5 +8,6 @@ namespace Nuake Vector4 Color = Vector4(1, 1, 1, 1); Matrix4 Transform; int TextureID; + float EntityID; }; } \ No newline at end of file diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.cpp index ea6fa740..b8790c53 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.cpp @@ -28,11 +28,12 @@ void DebugCmd::DrawQuad(const Matrix4& transform) cmd.DrawIndexed(6); } -void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref texture, const Color& color) +void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref texture, const Color& color, int32_t entityId) { debugConstant.Transform = transform; debugConstant.TextureID = GPUResources::Get().GetBindlessTextureID(texture->GetID()); debugConstant.Color = color; + debugConstant.EntityID = entityId; cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(DebugConstant), &debugConstant); diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.h b/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.h index 2f52a32e..bd707496 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.h +++ b/Nuake/Source/Nuake/Rendering/Vulkan/DebugCmd.h @@ -26,7 +26,7 @@ namespace Nuake Ref GetScene() const; void DrawQuad(const Matrix4& transform); - void DrawTexturedQuad(const Matrix4& transform, Ref texture, const Color& color = Color(1, 1, 1 ,1)); + void DrawTexturedQuad(const Matrix4& transform, Ref texture, const Color& color = Color(1, 1, 1 ,1), int32_t entityId = -1); void DrawSphere(const Vector2& position, float radius, const Color& color) const; void DrawCube(const Vector3& position, const Vector3& size, const Color& color) const; diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/SceneRenderPipeline.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/SceneRenderPipeline.cpp index 15d52864..d481e9e1 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/SceneRenderPipeline.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/SceneRenderPipeline.cpp @@ -265,11 +265,11 @@ void SceneRenderPipeline::Render(PassRenderContext& ctx) { SSAOBlurOutput }, { ShadingOutput }, // Shading { TonemappedOutput }, // Tonemap - { LineOutput, GBufferDepth }, - { LineCombineOutput }, - { GizmoOutput, GBufferDepth }, // Reusing depth from gBuffer + { GizmoOutput, GBufferEntityID, GBufferDepth }, // Reusing depth from gBuffer { GizmoCombineOutput }, - { OutlineOutput } + { OutlineOutput }, + { LineCombineOutput }, + { LineOutput, GBufferDepth }, }; GBufferPipeline.Execute(ctx, pipelineInputs); @@ -545,72 +545,12 @@ void SceneRenderPipeline::RecreatePipeline() cmd.DrawIndexed(6); }); - RenderPass& linePass = GBufferPipeline.AddPass("Line"); - linePass.SetIsLinePass(true); - linePass.SetTopology(PolygonTopology::LINE_LIST); - linePass.SetShaders(shaderMgr.GetShader("line_vert"), shaderMgr.GetShader("line_frag")); - linePass.AddAttachment("LineOutput", LineOutput->GetFormat()); - linePass.AddAttachment("LineDepth", GBufferDepth->GetFormat(), ImageUsage::Depth, false); - linePass.SetPushConstant(lineConstant); - linePass.SetDepthTest(true); - linePass.SetIsLinePass(true); - linePass.SetPreRender([&](PassRenderContext& ctx) - { - Cmd& cmd = ctx.commandBuffer; - auto& layout = ctx.renderPass->PipelineLayout; - auto& res = GPUResources::Get(); - - cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0); - cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2); - cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3); - cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4); - cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5); - cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6); - }); - linePass.SetRender([&](PassRenderContext& ctx) - { - auto& cmd = ctx.commandBuffer; - DebugLineCmd debugCmd = DebugLineCmd(cmd, ctx); - OnLineDraw().Broadcast(debugCmd); - }); - - auto& lineCombinePass = GBufferPipeline.AddPass("LineCombine"); - lineCombinePass.SetPushConstant(copyConstant); - lineCombinePass.SetShaders(shaderMgr.GetShader("copy_vert"), shaderMgr.GetShader("copy_frag")); - lineCombinePass.AddAttachment("LineCombineOutput", LineCombineOutput->GetFormat()); - lineCombinePass.AddInput("lineCombinePassOutput"); - lineCombinePass.SetPreRender([&](PassRenderContext& ctx) - { - Cmd& cmd = ctx.commandBuffer; - auto& layout = ctx.renderPass->PipelineLayout; - auto& res = GPUResources::Get(); - - cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0); - cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2); - cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3); - cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4); - cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5); - cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6); - }); - lineCombinePass.SetRender([&](PassRenderContext& ctx) - { - auto& cmd = ctx.commandBuffer; - - copyConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(LineOutput->GetID()); - copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(TonemappedOutput->GetID()); - cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(copyConstant), ©Constant); - - auto& quadMesh = VkSceneRenderer::QuadMesh; - cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1); - cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer()); - cmd.DrawIndexed(6); - }); - auto& gizmoPass = GBufferPipeline.AddPass("Gizmo"); gizmoPass.SetShaders(shaderMgr.GetShader("gizmo_vert"), shaderMgr.GetShader("gizmo_frag")); gizmoPass.SetPushConstant(debugConstant); gizmoPass.AddInput("Depth"); gizmoPass.AddAttachment("GizmoOutput", GizmoOutput->GetFormat()); + gizmoPass.AddAttachment("GizmoEntityID", GBufferEntityID->GetFormat(), ImageUsage::ColorAttachment, false); gizmoPass.AddAttachment("GizmoDepth", GBufferDepth->GetFormat(), ImageUsage::Depth, false); gizmoPass.SetDepthTest(true); gizmoPass.SetPreRender([&](PassRenderContext& ctx) @@ -656,7 +596,7 @@ void SceneRenderPipeline::RecreatePipeline() auto& cmd = ctx.commandBuffer; copyConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(GizmoOutput->GetID()); - copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(LineCombineOutput->GetID()); + copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(TonemappedOutput->GetID()); cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(copyConstant), ©Constant); auto& quadMesh = VkSceneRenderer::QuadMesh; @@ -705,6 +645,67 @@ void SceneRenderPipeline::RecreatePipeline() cmd.DrawIndexed(6); }); + RenderPass& linePass = GBufferPipeline.AddPass("Line"); + linePass.SetIsLinePass(true); + linePass.SetTopology(PolygonTopology::LINE_LIST); + linePass.SetShaders(shaderMgr.GetShader("line_vert"), shaderMgr.GetShader("line_frag")); + linePass.AddAttachment("LineOutput", LineOutput->GetFormat()); + linePass.AddAttachment("LineDepth", GBufferDepth->GetFormat(), ImageUsage::Depth, false); + linePass.SetPushConstant(lineConstant); + linePass.SetDepthTest(true); + linePass.SetPreRender([&](PassRenderContext& ctx) + { + Cmd& cmd = ctx.commandBuffer; + auto& layout = ctx.renderPass->PipelineLayout; + auto& res = GPUResources::Get(); + + cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0); + cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2); + cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3); + cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4); + cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5); + cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6); + }); + linePass.SetRender([&](PassRenderContext& ctx) + { + auto& cmd = ctx.commandBuffer; + DebugLineCmd debugCmd = DebugLineCmd(cmd, ctx); + OnLineDraw().Broadcast(debugCmd); + }); + + auto& lineCombinePass = GBufferPipeline.AddPass("LineCombine"); + lineCombinePass.SetPushConstant(copyConstant); + lineCombinePass.SetShaders(shaderMgr.GetShader("copy_vert"), shaderMgr.GetShader("copy_frag")); + lineCombinePass.AddAttachment("LineCombineOutput", LineCombineOutput->GetFormat()); + lineCombinePass.AddInput("lineCombinePassOutput"); + lineCombinePass.SetPreRender([&](PassRenderContext& ctx) + { + Cmd& cmd = ctx.commandBuffer; + auto& layout = ctx.renderPass->PipelineLayout; + auto& res = GPUResources::Get(); + + cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0); + cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2); + cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3); + cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4); + cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5); + cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6); + }); + lineCombinePass.SetRender([&](PassRenderContext& ctx) + { + auto& cmd = ctx.commandBuffer; + + copyConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(LineOutput->GetID()); + copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(OutlineOutput->GetID()); + cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(copyConstant), ©Constant); + + auto& quadMesh = VkSceneRenderer::QuadMesh; + cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1); + cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer()); + cmd.DrawIndexed(6); + }); + + GBufferPipeline.Build(); }