refactor(srp): bridge universal shadow planning settings into managed asset

- expose directional shadow planning settings on camera request context\n- let the managed universal asset override planner defaults\n- recompute native directional shadow requests only when settings change
This commit is contained in:
2026-04-21 02:19:30 +08:00
parent 5747968fc4
commit bfc4b90ce6
9 changed files with 380 additions and 5 deletions

View File

@@ -19,9 +19,11 @@
#include "Rendering/Internal/RenderPipelineFactory.h"
#include "Rendering/Passes/BuiltinVectorFullscreenPass.h"
#include "Rendering/Planning/FullscreenPassDesc.h"
#include "Rendering/Planning/SceneRenderRequestPlanner.h"
#include "Rendering/Pipelines/NativeSceneRecorder.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Rendering/RenderPassGraphContract.h"
#include "Rendering/RenderPipelineAsset.h"
#include "Rendering/RenderPipelineStageGraphContract.h"
#include "Resources/BuiltinResources.h"
#include "Core/Asset/ResourceManager.h"
@@ -125,6 +127,10 @@ struct ManagedCameraRenderRequestContextState {
Rendering::CameraRenderRequest* request = nullptr;
size_t renderedBaseCameraCount = 0u;
size_t renderedRequestCount = 0u;
Rendering::DirectionalShadowPlanningSettings
directionalShadowPlanningSettings = {};
bool directionalShadowPlanningSettingsDirty = false;
bool suppressDirectionalShadow = false;
};
struct ManagedScriptableRenderPipelinePlanningContextState {
@@ -930,6 +936,45 @@ static_assert(
sizeof(Rendering::RenderGraphTextureDesc),
"Managed render graph texture desc bridge layout must match native RenderGraphTextureDesc.");
struct ManagedDirectionalShadowSamplingSettingsData {
float receiverDepthBias = 0.0010f;
float normalBiasScale = 2.0f;
float shadowStrength = 0.85f;
};
static_assert(
sizeof(ManagedDirectionalShadowSamplingSettingsData) ==
sizeof(Rendering::DirectionalShadowSamplingSettings),
"Managed directional shadow sampling bridge layout must match native DirectionalShadowSamplingSettings.");
struct ManagedDirectionalShadowCasterBiasSettingsData {
float depthBiasFactor = 2.5f;
int32_t depthBiasUnits = 4;
};
static_assert(
sizeof(ManagedDirectionalShadowCasterBiasSettingsData) ==
sizeof(Rendering::DirectionalShadowCasterBiasSettings),
"Managed directional shadow caster bias bridge layout must match native DirectionalShadowCasterBiasSettings.");
struct ManagedDirectionalShadowPlanningSettingsData {
uint32_t mapDimension = 2048u;
float minFocusDistance = 5.0f;
float maxFocusDistance = 32.0f;
float perspectiveFocusFactor = 1.0f;
float orthographicFocusFactor = 2.0f;
float minDepthRange = 20.0f;
float boundsPadding = 0.5f;
float minDepthPadding = 2.0f;
ManagedDirectionalShadowSamplingSettingsData sampling = {};
ManagedDirectionalShadowCasterBiasSettingsData casterBias = {};
};
static_assert(
sizeof(ManagedDirectionalShadowPlanningSettingsData) ==
sizeof(Rendering::DirectionalShadowPlanningSettings),
"Managed directional shadow planning bridge layout must match native DirectionalShadowPlanningSettings.");
struct ManagedFilteringSettingsData {
int32_t renderQueueMin = std::numeric_limits<int32_t>::lowest();
int32_t renderQueueMax = std::numeric_limits<int32_t>::max();
@@ -1735,7 +1780,8 @@ void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest(
Rendering::CameraRenderRequest& request,
size_t renderedBaseCameraCount,
size_t renderedRequestCount,
const Rendering::DirectionalShadowPlanningSettings&) const {
const Rendering::DirectionalShadowPlanningSettings&
directionalShadowSettings) const {
if (!EnsureManagedAsset()) {
return;
}
@@ -1752,6 +1798,8 @@ void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest(
requestContextState.request = &request;
requestContextState.renderedBaseCameraCount = renderedBaseCameraCount;
requestContextState.renderedRequestCount = renderedRequestCount;
requestContextState.directionalShadowPlanningSettings =
directionalShadowSettings;
const uint64_t requestContextHandle =
RegisterManagedCameraRenderRequestContextState(
requestContextState);
@@ -1770,6 +1818,16 @@ void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest(
method,
args,
nullptr);
if (requestContextState.suppressDirectionalShadow) {
request.directionalShadow = {};
} else if (requestContextState.directionalShadowPlanningSettingsDirty) {
request.directionalShadow = {};
Rendering::ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
request,
renderedBaseCameraCount,
renderedRequestCount,
requestContextState.directionalShadowPlanningSettings);
}
UnregisterManagedCameraRenderRequestContextState(
requestContextHandle);
}
@@ -5090,6 +5148,42 @@ InternalCall_Rendering_CameraRenderRequestContext_GetHasDirectionalShadow(
: 0;
}
void
InternalCall_Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings(
uint64_t nativeHandle,
ManagedDirectionalShadowPlanningSettingsData* outSettings) {
const ManagedCameraRenderRequestContextState* const state =
FindManagedCameraRenderRequestContextState(nativeHandle);
if (outSettings == nullptr) {
return;
}
const Rendering::DirectionalShadowPlanningSettings sourceSettings =
state != nullptr
? state->directionalShadowPlanningSettings
: Rendering::DirectionalShadowPlanningSettings();
*outSettings =
*reinterpret_cast<const ManagedDirectionalShadowPlanningSettingsData*>(
&sourceSettings);
}
void
InternalCall_Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings(
uint64_t nativeHandle,
ManagedDirectionalShadowPlanningSettingsData* settings) {
ManagedCameraRenderRequestContextState* const state =
FindManagedCameraRenderRequestContextState(nativeHandle);
if (state == nullptr ||
settings == nullptr) {
return;
}
state->directionalShadowPlanningSettings =
*reinterpret_cast<const Rendering::DirectionalShadowPlanningSettings*>(
settings);
state->directionalShadowPlanningSettingsDirty = true;
}
void InternalCall_Rendering_CameraRenderRequestContext_ClearDirectionalShadow(
uint64_t nativeHandle) {
ManagedCameraRenderRequestContextState* const state =
@@ -5099,6 +5193,7 @@ void InternalCall_Rendering_CameraRenderRequestContext_ClearDirectionalShadow(
}
state->request->directionalShadow = {};
state->suppressDirectionalShadow = true;
}
int32_t
@@ -5430,6 +5525,8 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetRendererIndex));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_SetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_SetRendererIndex));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetHasDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetHasDirectionalShadow));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_ClearDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_ClearDirectionalShadow));
GetInternalCallRegistrationState() = true;