新增调试绘制体系:DebugDraw 服务 + 物理调试 pass + 脚本侧力学线
通用图元(线/箭头四翼头/球/胶囊/盒)瞬时+持久双缓冲聚合; 物理 pass 画刚体速度/重力/接触反力;角色 collider 与力学 线归位(引擎只画资产、脚本画行为);线宽按设备上限钳制
This commit is contained in:
@@ -64,9 +64,11 @@ namespace Engine::Passes
|
||||
FrameSceneData& frame,
|
||||
RG::TextureHandle hdrColor,
|
||||
RG::TextureHandle depth,
|
||||
UniformBuffer& lineVB, UniformBuffer& triVB)
|
||||
UniformBuffer& lineVB, UniformBuffer& triVB,
|
||||
UniformBuffer& debugVB)
|
||||
: m_Device(device), m_Descriptors(descriptors), m_Frame(frame),
|
||||
m_HDRColor(hdrColor), m_Depth(depth), m_LineVB(lineVB), m_TriVB(triVB)
|
||||
m_HDRColor(hdrColor), m_Depth(depth), m_LineVB(lineVB), m_TriVB(triVB),
|
||||
m_DebugVB(debugVB)
|
||||
{
|
||||
// 无描述符 set:viewProj 走 push constant(shader 侧声明一致)
|
||||
m_Layout = descriptors.CreatePipelineLayout(
|
||||
@@ -98,7 +100,8 @@ namespace Engine::Passes
|
||||
}
|
||||
|
||||
void PhysicsDebugPass::PrepareFrame(u32 frameSlot,
|
||||
const PhysicsDebugFrame& src)
|
||||
const PhysicsDebugFrame& src,
|
||||
const Debug::DebugFrame* dbg)
|
||||
{
|
||||
// 预算截断:物理调试不应打满(打满说明该收敛可视化了)
|
||||
const u32 lineVerts = std::min<u32>(
|
||||
@@ -115,18 +118,40 @@ namespace Engine::Passes
|
||||
|
||||
// fence 已等(Renderer::Render 的 WaitFence 之后调用),
|
||||
// 写-读竞争关闭——与 UBO/SSBO 上传同一窗口语义
|
||||
m_Spans[frameSlot].clear();
|
||||
if (lineVerts > 0) {
|
||||
m_LineVB.Update(frameSlot, src.lines.data(),
|
||||
static_cast<u64>(lineVerts) *
|
||||
sizeof(PhysicsDebugVertex));
|
||||
m_Spans[frameSlot].push_back({false, 1.0f, true, 0, lineVerts});
|
||||
}
|
||||
if (triVerts > 0) {
|
||||
m_TriVB.Update(frameSlot, src.triangles.data(),
|
||||
static_cast<u64>(triVerts) *
|
||||
sizeof(PhysicsDebugVertex));
|
||||
m_Spans[frameSlot].push_back({true, 1.0f, true, 0, triVerts});
|
||||
}
|
||||
m_LineCounts[frameSlot] = lineVerts;
|
||||
m_TriCounts[frameSlot] = triVerts;
|
||||
|
||||
// 通用调试源(独立 ring VB,与物理源隔离):批次按收集侧的
|
||||
// (拓扑, 线宽, 深度) 原样展开为绘制段;超预算部分截断
|
||||
if (dbg != nullptr && !dbg->Empty() && !dbg->verts.empty()) {
|
||||
const u32 total = static_cast<u32>(dbg->verts.size());
|
||||
const u32 n = std::min<u32>(total, Debug::kMaxVerts);
|
||||
m_DebugVB.Update(frameSlot, dbg->verts.data(),
|
||||
static_cast<u64>(n) * sizeof(Debug::Vertex));
|
||||
u32 consumed = 0;
|
||||
for (const Debug::Batch& b : dbg->batches) {
|
||||
if (consumed >= n) break;
|
||||
const u32 take = std::min<u32>(b.count, n - consumed);
|
||||
if (take > 0) {
|
||||
m_Spans[frameSlot].push_back(
|
||||
{b.tris, b.width, b.depthTest, consumed, take});
|
||||
}
|
||||
consumed += take;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsDebugPass::Register(RG::RenderGraph& rg)
|
||||
@@ -134,7 +159,10 @@ namespace Engine::Passes
|
||||
rg.AddPass("PhysicsDebug", [this](RG::RenderGraphContext& ctx) {
|
||||
const u32 lineCount = m_LineCounts[ctx.frame.frameSlot];
|
||||
const u32 triCount = m_TriCounts[ctx.frame.frameSlot];
|
||||
if (lineCount == 0 && triCount == 0) return; // 空帧零开销
|
||||
const std::vector<Span>& spans = m_Spans[ctx.frame.frameSlot];
|
||||
if (lineCount == 0 && triCount == 0 && spans.empty()) {
|
||||
return; // 空帧零开销
|
||||
}
|
||||
|
||||
ZoneScopedN("PhysicsDebug");
|
||||
const vk::CommandBuffer cmd = ctx.cmd;
|
||||
@@ -236,6 +264,29 @@ namespace Engine::Passes
|
||||
cmd.draw(triCount, 1, 0, 0);
|
||||
}
|
||||
|
||||
// 通用调试源批次:逐批动态状态(拓扑/线宽/深度测试)。
|
||||
// 线宽 >1 需 wideLines 特性,不支持时钳回 1.0(VUID-07937)
|
||||
if (!spans.empty()) {
|
||||
const std::array<vk::Buffer, 1> bufs{m_DebugVB.Get(ctx.frame.frameSlot)};
|
||||
const std::array<vk::DeviceSize, 1> offs{0};
|
||||
cmd.bindVertexBuffers(0, bufs, offs);
|
||||
for (const Span& s : spans) {
|
||||
cmd.setPrimitiveTopology(
|
||||
s.tris ? vk::PrimitiveTopology::eTriangleList
|
||||
: vk::PrimitiveTopology::eLineList);
|
||||
// 线宽单位 = 像素,设备范围 [1.0, lineWidthRange[1]]:
|
||||
// 低于下限的值(如 0.18)是校验错误,驱动按 1px 处
|
||||
// 理——必须钳进范围;wideLines 不支持则恒 1px
|
||||
cmd.setLineWidth(m_Device.IsWideLinesSupported()
|
||||
? std::clamp(s.width, 1.0f,
|
||||
m_Device.MaxLineWidth())
|
||||
: 1.0f);
|
||||
cmd.setDepthTestEnable(s.depthTest ? VK_TRUE : VK_FALSE);
|
||||
cmd.draw(s.count, 1, s.first, 0);
|
||||
}
|
||||
cmd.setLineWidth(1.0f); // 恢复默认,防状态外泄
|
||||
}
|
||||
|
||||
cmd.endRendering();
|
||||
})
|
||||
// Write use(WAW 链):保证排在 Forward/ForwardTrans 之后、
|
||||
|
||||
Reference in New Issue
Block a user