feat: add gpu object id scene picking

This commit is contained in:
2026-04-01 16:44:11 +08:00
parent 6e2711f9e8
commit 6927b4b380
10 changed files with 1030 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
#include "Rendering/CameraRenderer.h"
#include "Rendering/Passes/BuiltinObjectIdPass.h"
#include "Rendering/Pipelines/BuiltinForwardPipeline.h"
#include "Rendering/RenderPipelineAsset.h"
#include "Rendering/RenderSurface.h"
@@ -58,12 +59,23 @@ CameraRenderer::CameraRenderer()
}
CameraRenderer::CameraRenderer(std::unique_ptr<RenderPipeline> pipeline)
: m_pipelineAsset(nullptr) {
: CameraRenderer(std::move(pipeline), std::make_unique<Passes::BuiltinObjectIdPass>()) {
}
CameraRenderer::CameraRenderer(
std::unique_ptr<RenderPipeline> pipeline,
std::unique_ptr<ObjectIdPass> objectIdPass)
: m_pipelineAsset(nullptr)
, m_objectIdPass(std::move(objectIdPass)) {
if (m_objectIdPass == nullptr) {
m_objectIdPass = std::make_unique<Passes::BuiltinObjectIdPass>();
}
ResetPipeline(std::move(pipeline));
}
CameraRenderer::CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset)
: m_pipelineAsset(std::move(pipelineAsset)) {
: m_pipelineAsset(std::move(pipelineAsset))
, m_objectIdPass(std::make_unique<Passes::BuiltinObjectIdPass>()) {
SetPipelineAsset(m_pipelineAsset);
}
@@ -71,6 +83,9 @@ CameraRenderer::~CameraRenderer() {
if (m_pipeline) {
m_pipeline->Shutdown();
}
if (m_objectIdPass != nullptr) {
m_objectIdPass->Shutdown();
}
}
void CameraRenderer::SetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
@@ -83,6 +98,17 @@ void CameraRenderer::SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset>
ResetPipeline(CreatePipelineFromAsset(m_pipelineAsset));
}
void CameraRenderer::SetObjectIdPass(std::unique_ptr<ObjectIdPass> objectIdPass) {
if (m_objectIdPass != nullptr) {
m_objectIdPass->Shutdown();
}
m_objectIdPass = std::move(objectIdPass);
if (m_objectIdPass == nullptr) {
m_objectIdPass = std::make_unique<Passes::BuiltinObjectIdPass>();
}
}
void CameraRenderer::ResetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
if (m_pipeline != nullptr) {
m_pipeline->Shutdown();
@@ -105,6 +131,10 @@ bool CameraRenderer::Render(
request.surface.GetRenderAreaHeight() == 0) {
return false;
}
if (request.objectId.IsRequested() &&
!request.objectId.IsValid()) {
return false;
}
RenderSceneData sceneData = m_sceneExtractor.ExtractForCamera(
*request.scene,
@@ -140,6 +170,13 @@ bool CameraRenderer::Render(
return false;
}
if (request.objectId.IsRequested() &&
(m_objectIdPass == nullptr ||
!m_objectIdPass->Render(request.context, request.objectId.surface, sceneData))) {
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
return false;
}
bool postScenePassesInitialized = false;
if (!InitializePassSequence(
request.postScenePasses,