feat(rendering): add shader-vector fullscreen SRP seam

Generalize the native fullscreen pass and descriptor plumbing so managed SRP can request shader-driven fullscreen stages without being locked to the ColorScale path.

Keep ColorScale as a convenience descriptor mapped to the builtin color-scale shader, and add native fullscreen factory coverage for the new shader-vector path.
This commit is contained in:
2026-04-18 16:08:01 +08:00
parent 2b6d62a127
commit 5fd474d08d
14 changed files with 286 additions and 70 deletions

View File

@@ -12,11 +12,12 @@
#include "Physics/PhysicsWorld.h"
#include "Rendering/Execution/CameraFramePlan.h"
#include "Rendering/Internal/RenderPipelineFactory.h"
#include "Rendering/Passes/BuiltinColorScalePostProcessPass.h"
#include "Rendering/Passes/BuiltinVectorFullscreenPass.h"
#include "Rendering/Planning/FullscreenPassDesc.h"
#include "Rendering/Pipelines/NativeSceneRecorder.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Rendering/RenderPipelineStageGraphContract.h"
#include "Resources/BuiltinResources.h"
#include "Scene/Scene.h"
#include "Scripting/ScriptComponent.h"
#include "Scripting/ScriptEngine.h"
@@ -332,21 +333,30 @@ Rendering::RenderPass* ConfigureManagedFullscreenPass(
}
std::unique_ptr<Rendering::RenderPass>& passSlot = passPool[passIndex];
Rendering::Passes::BuiltinVectorFullscreenPass* fullscreenPass =
dynamic_cast<Rendering::Passes::BuiltinVectorFullscreenPass*>(
passSlot.get());
if (fullscreenPass == nullptr) {
passSlot =
std::make_unique<Rendering::Passes::BuiltinVectorFullscreenPass>();
fullscreenPass =
static_cast<Rendering::Passes::BuiltinVectorFullscreenPass*>(
passSlot.get());
}
switch (passDesc.type) {
case Rendering::FullscreenPassType::ColorScale: {
Rendering::Passes::BuiltinColorScalePostProcessPass* colorScalePass =
dynamic_cast<Rendering::Passes::BuiltinColorScalePostProcessPass*>(
passSlot.get());
if (colorScalePass == nullptr) {
passSlot =
std::make_unique<Rendering::Passes::BuiltinColorScalePostProcessPass>();
colorScalePass =
static_cast<Rendering::Passes::BuiltinColorScalePostProcessPass*>(
passSlot.get());
}
colorScalePass->SetColorScale(passDesc.colorScale.scale);
return colorScalePass;
fullscreenPass->SetShaderPath(
Resources::GetBuiltinColorScalePostProcessShaderPath());
fullscreenPass->SetPreferredPassName("ColorScale");
fullscreenPass->SetVectorPayload(passDesc.colorScale.scale);
return fullscreenPass;
}
case Rendering::FullscreenPassType::ShaderVector: {
fullscreenPass->SetShaderPath(passDesc.shaderVector.shaderPath);
fullscreenPass->SetPreferredPassName(passDesc.shaderVector.passName);
fullscreenPass->SetVectorPayload(passDesc.shaderVector.vectorPayload);
return fullscreenPass;
}
default:
return nullptr;
@@ -2652,6 +2662,8 @@ mono_bool
InternalCall_Rendering_ScriptableRenderContext_RecordFullscreenPass(
uint64_t nativeHandle,
int32_t passType,
MonoString* shaderPath,
MonoString* passName,
XCEngine::Math::Vector4* vectorPayload) {
ManagedScriptableRenderContextState* const state =
FindManagedScriptableRenderContextState(nativeHandle);
@@ -2670,6 +2682,18 @@ InternalCall_Rendering_ScriptableRenderContext_RecordFullscreenPass(
passDesc =
Rendering::FullscreenPassDesc::MakeColorScale(*vectorPayload);
break;
case Rendering::FullscreenPassType::ShaderVector:
if (vectorPayload == nullptr) {
return 0;
}
passDesc = Rendering::FullscreenPassDesc::MakeShaderVector(
Containers::String(MonoStringToUtf8(shaderPath).c_str()),
*vectorPayload,
Containers::String(MonoStringToUtf8(passName).c_str()));
if (!passDesc.IsValid()) {
return 0;
}
break;
default:
return 0;
}