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

@@ -839,6 +839,18 @@ namespace XCEngine
Rendering_CameraRenderRequestContext_GetHasDirectionalShadow(
ulong nativeHandle);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void
Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings(
ulong nativeHandle,
out Rendering.DirectionalShadowPlanningSettings settings);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void
Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings(
ulong nativeHandle,
ref Rendering.DirectionalShadowPlanningSettings settings);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void
Rendering_CameraRenderRequestContext_ClearDirectionalShadow(

View File

@@ -58,6 +58,26 @@ namespace XCEngine.Rendering
.Rendering_CameraRenderRequestContext_GetHasDirectionalShadow(
m_nativeHandle);
public DirectionalShadowPlanningSettings
directionalShadowPlanningSettings
{
get
{
InternalCalls
.Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings(
m_nativeHandle,
out DirectionalShadowPlanningSettings settings);
return settings;
}
set
{
InternalCalls
.Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings(
m_nativeHandle,
ref value);
}
}
public void ClearDirectionalShadow()
{
InternalCalls

View File

@@ -0,0 +1,166 @@
using System;
using System.Runtime.InteropServices;
namespace XCEngine.Rendering
{
[StructLayout(LayoutKind.Sequential)]
public struct DirectionalShadowSamplingSettings
: IEquatable<DirectionalShadowSamplingSettings>
{
public float receiverDepthBias;
public float normalBiasScale;
public float shadowStrength;
public static DirectionalShadowSamplingSettings CreateDefault()
{
return new DirectionalShadowSamplingSettings
{
receiverDepthBias = 0.0010f,
normalBiasScale = 2.0f,
shadowStrength = 0.85f
};
}
public bool Equals(
DirectionalShadowSamplingSettings other)
{
return receiverDepthBias == other.receiverDepthBias &&
normalBiasScale == other.normalBiasScale &&
shadowStrength == other.shadowStrength;
}
public override bool Equals(object obj)
{
return obj is DirectionalShadowSamplingSettings other &&
Equals(other);
}
public override int GetHashCode()
{
unchecked
{
int hash = receiverDepthBias.GetHashCode();
hash = (hash * 397) ^ normalBiasScale.GetHashCode();
hash = (hash * 397) ^ shadowStrength.GetHashCode();
return hash;
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct DirectionalShadowCasterBiasSettings
: IEquatable<DirectionalShadowCasterBiasSettings>
{
public float depthBiasFactor;
public int depthBiasUnits;
public static DirectionalShadowCasterBiasSettings CreateDefault()
{
return new DirectionalShadowCasterBiasSettings
{
depthBiasFactor = 2.5f,
depthBiasUnits = 4
};
}
public bool Equals(
DirectionalShadowCasterBiasSettings other)
{
return depthBiasFactor == other.depthBiasFactor &&
depthBiasUnits == other.depthBiasUnits;
}
public override bool Equals(object obj)
{
return obj is DirectionalShadowCasterBiasSettings other &&
Equals(other);
}
public override int GetHashCode()
{
unchecked
{
return (depthBiasFactor.GetHashCode() * 397) ^
depthBiasUnits;
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct DirectionalShadowPlanningSettings
: IEquatable<DirectionalShadowPlanningSettings>
{
public uint mapDimension;
public float minFocusDistance;
public float maxFocusDistance;
public float perspectiveFocusFactor;
public float orthographicFocusFactor;
public float minDepthRange;
public float boundsPadding;
public float minDepthPadding;
public DirectionalShadowSamplingSettings sampling;
public DirectionalShadowCasterBiasSettings casterBias;
public static DirectionalShadowPlanningSettings CreateDefault()
{
return new DirectionalShadowPlanningSettings
{
mapDimension = 2048u,
minFocusDistance = 5.0f,
maxFocusDistance = 32.0f,
perspectiveFocusFactor = 1.0f,
orthographicFocusFactor = 2.0f,
minDepthRange = 20.0f,
boundsPadding = 0.5f,
minDepthPadding = 2.0f,
sampling =
DirectionalShadowSamplingSettings.CreateDefault(),
casterBias =
DirectionalShadowCasterBiasSettings.CreateDefault()
};
}
public bool Equals(
DirectionalShadowPlanningSettings other)
{
return mapDimension == other.mapDimension &&
minFocusDistance == other.minFocusDistance &&
maxFocusDistance == other.maxFocusDistance &&
perspectiveFocusFactor ==
other.perspectiveFocusFactor &&
orthographicFocusFactor ==
other.orthographicFocusFactor &&
minDepthRange == other.minDepthRange &&
boundsPadding == other.boundsPadding &&
minDepthPadding == other.minDepthPadding &&
sampling.Equals(other.sampling) &&
casterBias.Equals(other.casterBias);
}
public override bool Equals(object obj)
{
return obj is DirectionalShadowPlanningSettings other &&
Equals(other);
}
public override int GetHashCode()
{
unchecked
{
int hash = (int)mapDimension;
hash = (hash * 397) ^ minFocusDistance.GetHashCode();
hash = (hash * 397) ^ maxFocusDistance.GetHashCode();
hash = (hash * 397) ^
perspectiveFocusFactor.GetHashCode();
hash = (hash * 397) ^
orthographicFocusFactor.GetHashCode();
hash = (hash * 397) ^ minDepthRange.GetHashCode();
hash = (hash * 397) ^ boundsPadding.GetHashCode();
hash = (hash * 397) ^ minDepthPadding.GetHashCode();
hash = (hash * 397) ^ sampling.GetHashCode();
hash = (hash * 397) ^ casterBias.GetHashCode();
return hash;
}
}
}
}