feat: add gpu object id scene picking
This commit is contained in:
@@ -13,11 +13,29 @@ class Scene;
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct ObjectIdRenderRequest {
|
||||
RenderSurface surface;
|
||||
|
||||
bool IsRequested() const {
|
||||
return !surface.GetColorAttachments().empty();
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
const std::vector<RHI::RHIResourceView*>& colorAttachments = surface.GetColorAttachments();
|
||||
return !colorAttachments.empty() &&
|
||||
colorAttachments[0] != nullptr &&
|
||||
surface.GetDepthAttachment() != nullptr &&
|
||||
surface.GetRenderAreaWidth() > 0 &&
|
||||
surface.GetRenderAreaHeight() > 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct CameraRenderRequest {
|
||||
const Components::Scene* scene = nullptr;
|
||||
Components::CameraComponent* camera = nullptr;
|
||||
RenderContext context;
|
||||
RenderSurface surface;
|
||||
ObjectIdRenderRequest objectId;
|
||||
float cameraDepth = 0.0f;
|
||||
uint8_t cameraStackOrder = 0;
|
||||
RenderClearFlags clearFlags = RenderClearFlags::All;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/CameraRenderRequest.h>
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/RenderPipeline.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -21,12 +22,17 @@ public:
|
||||
CameraRenderer();
|
||||
explicit CameraRenderer(std::unique_ptr<RenderPipeline> pipeline);
|
||||
explicit CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
|
||||
CameraRenderer(
|
||||
std::unique_ptr<RenderPipeline> pipeline,
|
||||
std::unique_ptr<ObjectIdPass> objectIdPass);
|
||||
~CameraRenderer();
|
||||
|
||||
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
|
||||
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
|
||||
void SetObjectIdPass(std::unique_ptr<ObjectIdPass> objectIdPass);
|
||||
RenderPipeline* GetPipeline() const { return m_pipeline.get(); }
|
||||
const RenderPipelineAsset* GetPipelineAsset() const { return m_pipelineAsset.get(); }
|
||||
ObjectIdPass* GetObjectIdPass() const { return m_objectIdPass.get(); }
|
||||
|
||||
bool Render(const CameraRenderRequest& request);
|
||||
|
||||
@@ -36,6 +42,7 @@ private:
|
||||
RenderSceneExtractor m_sceneExtractor;
|
||||
std::shared_ptr<const RenderPipelineAsset> m_pipelineAsset;
|
||||
std::unique_ptr<RenderPipeline> m_pipeline;
|
||||
std::unique_ptr<ObjectIdPass> m_objectIdPass;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
32
engine/include/XCEngine/Rendering/ObjectIdEncoding.h
Normal file
32
engine/include/XCEngine/Rendering/ObjectIdEncoding.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Math/Vector4.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
inline uint32_t EncodeObjectIdToUInt32(uint64_t objectId) {
|
||||
return static_cast<uint32_t>(objectId & 0xFFFFFFFFull);
|
||||
}
|
||||
|
||||
inline Math::Vector4 EncodeObjectIdToColor(uint64_t objectId) {
|
||||
const uint32_t encodedId = EncodeObjectIdToUInt32(objectId);
|
||||
constexpr float kInv255 = 1.0f / 255.0f;
|
||||
return Math::Vector4(
|
||||
static_cast<float>((encodedId >> 0) & 0xFFu) * kInv255,
|
||||
static_cast<float>((encodedId >> 8) & 0xFFu) * kInv255,
|
||||
static_cast<float>((encodedId >> 16) & 0xFFu) * kInv255,
|
||||
static_cast<float>((encodedId >> 24) & 0xFFu) * kInv255);
|
||||
}
|
||||
|
||||
inline uint32_t DecodeObjectIdFromColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
||||
return static_cast<uint32_t>(r) |
|
||||
(static_cast<uint32_t>(g) << 8u) |
|
||||
(static_cast<uint32_t>(b) << 16u) |
|
||||
(static_cast<uint32_t>(a) << 24u);
|
||||
}
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
24
engine/include/XCEngine/Rendering/ObjectIdPass.h
Normal file
24
engine/include/XCEngine/Rendering/ObjectIdPass.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/RenderContext.h>
|
||||
#include <XCEngine/Rendering/RenderSceneExtractor.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
class ObjectIdPass {
|
||||
public:
|
||||
virtual ~ObjectIdPass() = default;
|
||||
|
||||
virtual bool Render(
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const RenderSceneData& sceneData) = 0;
|
||||
|
||||
virtual void Shutdown() {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/ObjectIdEncoding.h>
|
||||
#include <XCEngine/Rendering/RenderResourceCache.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Passes {
|
||||
|
||||
class BuiltinObjectIdPass final : public ObjectIdPass {
|
||||
public:
|
||||
~BuiltinObjectIdPass() override;
|
||||
|
||||
bool Render(
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const RenderSceneData& sceneData) override;
|
||||
|
||||
void Shutdown() override;
|
||||
|
||||
private:
|
||||
struct PerObjectConstants {
|
||||
Math::Matrix4x4 projection = Math::Matrix4x4::Identity();
|
||||
Math::Matrix4x4 view = Math::Matrix4x4::Identity();
|
||||
Math::Matrix4x4 model = Math::Matrix4x4::Identity();
|
||||
Math::Vector4 objectIdColor = Math::Vector4::Zero();
|
||||
};
|
||||
|
||||
struct OwnedDescriptorSet {
|
||||
RHI::RHIDescriptorPool* pool = nullptr;
|
||||
RHI::RHIDescriptorSet* set = nullptr;
|
||||
};
|
||||
|
||||
bool EnsureInitialized(const RenderContext& context);
|
||||
bool CreateResources(const RenderContext& context);
|
||||
void DestroyResources();
|
||||
|
||||
RHI::RHIDescriptorSet* GetOrCreatePerObjectSet(uint64_t objectId);
|
||||
void DestroyOwnedDescriptorSet(OwnedDescriptorSet& descriptorSet);
|
||||
bool DrawVisibleItem(
|
||||
const RenderContext& context,
|
||||
const RenderSceneData& sceneData,
|
||||
const VisibleRenderItem& visibleItem);
|
||||
|
||||
RHI::RHIDevice* m_device = nullptr;
|
||||
RHI::RHIType m_backendType = RHI::RHIType::D3D12;
|
||||
RHI::RHIPipelineLayout* m_pipelineLayout = nullptr;
|
||||
RHI::RHIPipelineState* m_pipelineState = nullptr;
|
||||
RenderResourceCache m_resourceCache;
|
||||
std::unordered_map<uint64_t, OwnedDescriptorSet> m_perObjectSets;
|
||||
};
|
||||
|
||||
} // namespace Passes
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user