Files
HelloVulkan/Engine/include/Engine/Renderer/Passes/HitProxyPass.h
T
atdunbg 1449bea86d feat: HitProxy GPU 拾取 + UE 选中描边 + 编辑器拾取交互
- HitProxy 拾取:RG 管线渲染实体 id → host readback,点击帧
  PickEntity 精确命中;拾取按视觉几何(Model 联合包围球射线求交),
  与 Collider 解耦(UE/Unity 编辑器语义),命中打印实体名+碰撞体参数
- 选中描边(UE 语义):SelectionMask pass(R8Unorm 完整投影轮廓,
  无深度测试透墙可见)→ Outline pass(边缘检测 + alpha 叠加,
  必须注册在 Tonemap 后);edgeCut 贴视口边缘;widthPx=6 可调
- shader object 实证修复:VUID-08879 同程序 set layouts 超集一致、
  VUID-10065 push block 4×float 平铺、新 pass 析构销毁 VkShaderEXT
- RG:SideEffect() 保活"产出无 RG 内消费者"的 pass 链
- Editor:层次面板点击选中、Inspector 姿态编辑、Stats 面板拾取信息
- 相机 Update 改 const(姿态写入 Transform 引用,Camera 本身无状态变更)
2026-10-02 20:09:05 +08:00

75 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// HitProxyPass:UE 式 GPU 拾取(像素级 id pass + 点击 readback)。
//
// 两个 RG pass:
// "HitProxy" —— 拾取请求帧把不透明 + 透明 batch 用 id 管线画进
// R32Uint 目标(片元值 = 实体位模式)。深度自测自写
// (重清主深度):遮挡语义 = 可见表面胜出;运行在
// Forward/ForwardTrans/PhysicsDebug 之后的 WAW 链尾,
// 主链下游无人再读深度,下帧 Forward 照常重新 Clear
// "HitProxyCopy" —— 请求像素 1×1 CopyImageToBuffer 进 host-visible
// 暂存。TransferSrc use 让 RG 自动完成
// eColorAttachmentOptimal → eTransferSrcOptimal 迁移
//
// 无请求帧零绘制零拷贝(barrier 照常插入,GPU 无实际工作)。
// 结果流:Renderer::TakePickResult(waitIdle 保证提交完成)→ 映射暂存。
//
#ifndef HELLOVULKAN_HITPROXYPASS_H
#define HELLOVULKAN_HITPROXYPASS_H
#include <Engine/Core/Types.h>
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/SceneTypes.h>
#include <Engine/Vulkan/Buffer.h>
#include <vulkan/vulkan.hpp>
namespace Engine {
class Device;
class ShaderManager;
class DescriptorManager;
namespace Passes {
class SceneGpu;
class HitProxyPass final : public RenderPass {
public:
HitProxyPass(Device& device, MemoryAllocator& allocator,
ShaderManager& shaders, DescriptorManager& descriptors,
SceneGpu& gpu, FrameSceneData& frame,
RG::TextureHandle idTarget, RG::TextureHandle depth);
~HitProxyPass();
HitProxyPass(const HitProxyPass&) = delete;
HitProxyPass& operator=(const HitProxyPass&) = delete;
void Register(RG::RenderGraph& rg) override;
// 有待取结果(拷贝已录制进当帧命令缓冲)
bool HasPendingResult() const { return m_ResultValid; }
// 取走拷贝结果(一次性)。调用方保证 GPU 已 idle
//(Renderer::TakePickResult 内 waitIdle)
bool TakeResult(u32& outBits);
private:
Device& m_Device;
SceneGpu& m_Gpu;
FrameSceneData& m_Frame;
RG::TextureHandle m_IdTarget;
RG::TextureHandle m_Depth;
vk::PipelineLayout m_Layout; // Set0 = uboSetLayout,无 push
vk::ShaderEXT m_Vert{}, m_Frag{};
// 1×1 像素暂存(host visible,持久映射);拷贝录制时置位
Scope<Buffer> m_Staging;
bool m_ResultValid = false;
};
} // namespace Passes
} // namespace Engine
#endif //HELLOVULKAN_HITPROXYPASS_H