better outline + gizmo interaction

This commit is contained in:
antopilo
2025-04-14 17:29:23 -04:00
parent 5ce9fb6093
commit 57564645f2
8 changed files with 98 additions and 74 deletions

View File

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

View File

@@ -85,6 +85,7 @@ struct DebugConstant
float4 Color;
float4x4 Transform;
int TextureID;
float EntityID;
};
[[vk::push_constant]]

View File

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

View File

@@ -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<CameraComponent>(debugCmd, "Resources/Gizmos/Camera.png", editorContext);

View File

@@ -8,5 +8,6 @@ namespace Nuake
Vector4 Color = Vector4(1, 1, 1, 1);
Matrix4 Transform;
int TextureID;
float EntityID;
};
}

View File

@@ -28,11 +28,12 @@ void DebugCmd::DrawQuad(const Matrix4& transform)
cmd.DrawIndexed(6);
}
void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> texture, const Color& color)
void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> 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);

View File

@@ -26,7 +26,7 @@ namespace Nuake
Ref<Scene> GetScene() const;
void DrawQuad(const Matrix4& transform);
void DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> texture, const Color& color = Color(1, 1, 1 ,1));
void DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> 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;

View File

@@ -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), &copyConstant);
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>(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), &copyConstant);
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), &copyConstant);
auto& quadMesh = VkSceneRenderer::QuadMesh;
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
cmd.DrawIndexed(6);
});
GBufferPipeline.Build();
}