refactor(srp): move rendering data ownership into universal package

This commit is contained in:
2026-04-19 14:19:57 +08:00
parent a7cda9375a
commit f4d4112e2f
14 changed files with 325 additions and 298 deletions

View File

@@ -0,0 +1,112 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class CameraData
{
internal static readonly CameraData Default =
new CameraData(
Matrix4x4.Identity,
Matrix4x4.Identity,
Matrix4x4.Identity,
new Vector3(0.0f, 0.0f, 0.0f),
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Color(0.0f, 0.0f, 0.0f, 1.0f),
RenderClearFlags.All,
true,
60.0f * 0.017453292519943295f,
5.0f,
1.0f,
0.1f,
1000.0f,
0,
0);
internal CameraData(
Matrix4x4 view,
Matrix4x4 projection,
Matrix4x4 viewProjection,
Vector3 worldPosition,
Vector3 worldRight,
Vector3 worldUp,
Vector3 worldForward,
Color clearColor,
RenderClearFlags clearFlags,
bool perspectiveProjection,
float verticalFovRadians,
float orthographicSize,
float aspectRatio,
float nearClipPlane,
float farClipPlane,
int viewportWidth,
int viewportHeight)
{
this.view = view;
this.projection = projection;
this.viewProjection = viewProjection;
this.worldPosition = worldPosition;
this.worldRight = worldRight;
this.worldUp = worldUp;
this.worldForward = worldForward;
this.clearColor = clearColor;
this.clearFlags = clearFlags;
this.perspectiveProjection = perspectiveProjection;
this.verticalFovRadians = verticalFovRadians;
this.orthographicSize = orthographicSize;
this.aspectRatio = aspectRatio;
this.nearClipPlane = nearClipPlane;
this.farClipPlane = farClipPlane;
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
}
public Matrix4x4 view { get; }
public Matrix4x4 projection { get; }
public Matrix4x4 viewProjection { get; }
public Vector3 worldPosition { get; }
public Vector3 worldRight { get; }
public Vector3 worldUp { get; }
public Vector3 worldForward { get; }
public Color clearColor { get; }
public RenderClearFlags clearFlags { get; }
public bool perspectiveProjection { get; }
public bool isPerspectiveProjection =>
perspectiveProjection;
public bool isOrthographicProjection =>
!perspectiveProjection;
public bool clearsColor =>
(clearFlags & RenderClearFlags.Color) != 0;
public bool clearsDepth =>
(clearFlags & RenderClearFlags.Depth) != 0;
public float verticalFovRadians { get; }
public float orthographicSize { get; }
public float aspectRatio { get; }
public float nearClipPlane { get; }
public float farClipPlane { get; }
public int viewportWidth { get; }
public int viewportHeight { get; }
}
}

View File

@@ -0,0 +1,43 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class DirectionalLightData
{
internal static readonly DirectionalLightData Default =
new DirectionalLightData(
false,
false,
new Vector3(0.0f, 0.0f, -1.0f),
new Color(1.0f, 1.0f, 1.0f, 1.0f),
1.0f);
internal DirectionalLightData(
bool enabled,
bool castsShadows,
Vector3 direction,
Color color,
float intensity)
{
this.enabled = enabled;
this.castsShadows = castsShadows;
this.direction = direction;
this.color = color;
this.intensity = intensity;
}
public bool enabled { get; }
public bool castsShadows { get; }
public Vector3 direction { get; }
public Color color { get; }
public float intensity { get; }
public bool isValid =>
enabled;
}
}

View File

@@ -0,0 +1,86 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class DirectionalShadowData
{
internal static readonly DirectionalShadowData Default =
new DirectionalShadowData(
false,
Matrix4x4.Identity,
0.0f,
0.1f,
0.0f,
0,
0,
0.0f,
0.0f,
0.0f,
0.0f,
0.0f,
0);
internal DirectionalShadowData(
bool enabled,
Matrix4x4 viewProjection,
float orthographicHalfExtent,
float nearClipPlane,
float farClipPlane,
int mapWidth,
int mapHeight,
float worldTexelSize,
float receiverDepthBias,
float normalBiasScale,
float shadowStrength,
float depthBiasFactor,
int depthBiasUnits)
{
this.enabled = enabled;
this.viewProjection = viewProjection;
this.orthographicHalfExtent =
orthographicHalfExtent;
this.nearClipPlane = nearClipPlane;
this.farClipPlane = farClipPlane;
this.mapWidth = mapWidth;
this.mapHeight = mapHeight;
this.worldTexelSize = worldTexelSize;
this.receiverDepthBias = receiverDepthBias;
this.normalBiasScale = normalBiasScale;
this.shadowStrength = shadowStrength;
this.depthBiasFactor = depthBiasFactor;
this.depthBiasUnits = depthBiasUnits;
}
public bool enabled { get; }
public Matrix4x4 viewProjection { get; }
public float orthographicHalfExtent { get; }
public float nearClipPlane { get; }
public float farClipPlane { get; }
public int mapWidth { get; }
public int mapHeight { get; }
public float worldTexelSize { get; }
public float receiverDepthBias { get; }
public float normalBiasScale { get; }
public float shadowStrength { get; }
public float depthBiasFactor { get; }
public int depthBiasUnits { get; }
public bool hasShadowMap =>
enabled &&
mapWidth > 0 &&
mapHeight > 0;
}
}

View File

@@ -0,0 +1,44 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class EnvironmentData
{
internal static readonly EnvironmentData Default =
new EnvironmentData(
RenderEnvironmentMode.None,
new Color(0.18f, 0.36f, 0.74f, 1.0f),
new Color(0.78f, 0.84f, 0.92f, 1.0f),
new Color(0.92f, 0.93f, 0.95f, 1.0f));
internal EnvironmentData(
RenderEnvironmentMode mode,
Color skyboxTopColor,
Color skyboxHorizonColor,
Color skyboxBottomColor)
{
this.mode = mode;
this.skyboxTopColor = skyboxTopColor;
this.skyboxHorizonColor = skyboxHorizonColor;
this.skyboxBottomColor = skyboxBottomColor;
}
public RenderEnvironmentMode mode { get; }
public Color skyboxTopColor { get; }
public Color skyboxHorizonColor { get; }
public Color skyboxBottomColor { get; }
public bool hasProceduralSkybox =>
mode == RenderEnvironmentMode.ProceduralSkybox;
public bool hasMaterialSkybox =>
mode == RenderEnvironmentMode.MaterialSkybox;
public bool hasSkybox =>
hasProceduralSkybox || hasMaterialSkybox;
}
}

View File

@@ -0,0 +1,42 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class FinalColorData
{
internal static readonly FinalColorData Default =
new FinalColorData(
FinalColorSettings.CreateDefault(),
false,
false);
internal FinalColorData(
FinalColorSettings settings,
bool hasPipelineDefaults,
bool hasCameraOverrides)
{
this.settings = settings;
this.hasPipelineDefaults = hasPipelineDefaults;
this.hasCameraOverrides = hasCameraOverrides;
}
public FinalColorSettings settings { get; }
public bool hasPipelineDefaults { get; }
public bool hasCameraOverrides { get; }
public bool requiresProcessing =>
settings.outputTransferMode !=
FinalColorOutputTransferMode.Disabled ||
settings.exposureMode !=
FinalColorExposureMode.Disabled ||
settings.toneMappingMode !=
FinalColorToneMappingMode.Disabled ||
settings.finalColorScale.x != 1.0f ||
settings.finalColorScale.y != 1.0f ||
settings.finalColorScale.z != 1.0f ||
settings.finalColorScale.w != 1.0f;
}
}

View File

@@ -0,0 +1,38 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class LightingData
{
internal static readonly LightingData Default =
new LightingData(
DirectionalLightData.Default,
false,
0);
internal LightingData(
DirectionalLightData mainDirectionalLight,
bool hasMainDirectionalShadow,
int additionalLightCount)
{
this.mainDirectionalLight =
mainDirectionalLight ?? DirectionalLightData.Default;
this.hasMainDirectionalShadow =
hasMainDirectionalShadow;
this.additionalLightCount = additionalLightCount;
}
public DirectionalLightData mainDirectionalLight { get; }
public bool hasMainDirectionalShadow { get; }
public int additionalLightCount { get; }
public bool hasMainDirectionalLight =>
mainDirectionalLight.enabled;
public bool hasAdditionalLights =>
additionalLightCount > 0;
}
}

View File

@@ -0,0 +1,15 @@
using System;
using XCEngine;
namespace XCEngine.Rendering.Universal
{
[Flags]
public enum RenderClearFlags
{
None = 0,
Color = 1 << 0,
Depth = 1 << 1,
All = Color | Depth
}
}

View File

@@ -0,0 +1,12 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public enum RenderEnvironmentMode
{
None = 0,
ProceduralSkybox = 1,
MaterialSkybox = 2
}
}

View File

@@ -23,22 +23,22 @@ namespace XCEngine.Rendering.Universal
? context.stage
: CameraFrameStage.MainScene,
context != null
? context.cameraData
? RenderingDataResolver.ResolveCameraData(context)
: CameraData.Default,
context != null
? context.lightingData
? RenderingDataResolver.ResolveLightingData(context)
: LightingData.Default,
context != null
? context.shadowData
? RenderingDataResolver.ResolveShadowData(context)
: ShadowData.Default,
context != null
? context.environmentData
? RenderingDataResolver.ResolveEnvironmentData(context)
: EnvironmentData.Default,
context != null
? context.finalColorData
? RenderingDataResolver.ResolveFinalColorData(context)
: FinalColorData.Default,
context != null
? context.stageColorData
? RenderingDataResolver.ResolveStageColorData(context)
: StageColorData.Default)
{
}

View File

@@ -0,0 +1,296 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
internal static class RenderingDataResolver
{
public static CameraData ResolveCameraData(
ScriptableRenderContext context)
{
if (context == null)
{
return CameraData.Default;
}
ulong nativeHandle = context.nativeHandle;
Matrix4x4 view;
Matrix4x4 projection;
Matrix4x4 viewProjection;
Vector3 worldPosition;
Vector3 worldRight;
Vector3 worldUp;
Vector3 worldForward;
Color clearColor;
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraView(
nativeHandle,
out view);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraProjection(
nativeHandle,
out projection);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraViewProjection(
nativeHandle,
out viewProjection);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldPosition(
nativeHandle,
out worldPosition);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldRight(
nativeHandle,
out worldRight);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldUp(
nativeHandle,
out worldUp);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldForward(
nativeHandle,
out worldForward);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraClearColor(
nativeHandle,
out clearColor);
return new CameraData(
view,
projection,
viewProjection,
worldPosition,
worldRight,
worldUp,
worldForward,
clearColor,
(RenderClearFlags)InternalCalls
.Rendering_ScriptableRenderContext_GetCameraClearFlags(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraPerspectiveProjection(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraVerticalFovRadians(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraOrthographicSize(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraAspectRatio(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraNearClipPlane(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraFarClipPlane(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraViewportWidth(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraViewportHeight(
nativeHandle));
}
public static LightingData ResolveLightingData(
ScriptableRenderContext context)
{
if (context == null)
{
return LightingData.Default;
}
ulong nativeHandle = context.nativeHandle;
Vector3 mainDirectionalLightDirection;
Color mainDirectionalLightColor;
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightDirection(
nativeHandle,
out mainDirectionalLightDirection);
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightColor(
nativeHandle,
out mainDirectionalLightColor);
return new LightingData(
new DirectionalLightData(
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightEnabled(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightCastsShadows(
nativeHandle),
mainDirectionalLightDirection,
mainDirectionalLightColor,
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightIntensity(
nativeHandle)),
InternalCalls
.Rendering_ScriptableRenderContext_GetHasMainDirectionalShadow(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetAdditionalLightCount(
nativeHandle));
}
public static ShadowData ResolveShadowData(
ScriptableRenderContext context)
{
if (context == null)
{
return ShadowData.Default;
}
ulong nativeHandle = context.nativeHandle;
Matrix4x4 viewProjection;
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowViewProjection(
nativeHandle,
out viewProjection);
return new ShadowData(
new DirectionalShadowData(
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowEnabled(
nativeHandle),
viewProjection,
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowOrthographicHalfExtent(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowNearClipPlane(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowFarClipPlane(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapWidth(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapHeight(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowWorldTexelSize(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowReceiverDepthBias(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowNormalBiasScale(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowStrength(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasFactor(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasUnits(
nativeHandle)));
}
public static EnvironmentData ResolveEnvironmentData(
ScriptableRenderContext context)
{
if (context == null)
{
return EnvironmentData.Default;
}
ulong nativeHandle = context.nativeHandle;
Color skyboxTopColor;
Color skyboxHorizonColor;
Color skyboxBottomColor;
InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentSkyboxTopColor(
nativeHandle,
out skyboxTopColor);
InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentSkyboxHorizonColor(
nativeHandle,
out skyboxHorizonColor);
InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentSkyboxBottomColor(
nativeHandle,
out skyboxBottomColor);
return new EnvironmentData(
(RenderEnvironmentMode)InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentMode(
nativeHandle),
skyboxTopColor,
skyboxHorizonColor,
skyboxBottomColor);
}
public static FinalColorData ResolveFinalColorData(
ScriptableRenderContext context)
{
if (context == null)
{
return FinalColorData.Default;
}
ulong nativeHandle = context.nativeHandle;
Vector4 finalColorScale;
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorScale(
nativeHandle,
out finalColorScale);
FinalColorSettings settings =
FinalColorSettings.CreateDefault();
settings.outputTransferMode =
(FinalColorOutputTransferMode)InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorOutputTransferMode(
nativeHandle);
settings.exposureMode =
(FinalColorExposureMode)InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorExposureMode(
nativeHandle);
settings.exposureValue =
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorExposureValue(
nativeHandle);
settings.toneMappingMode =
(FinalColorToneMappingMode)InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorToneMappingMode(
nativeHandle);
settings.finalColorScale =
finalColorScale;
return new FinalColorData(
settings,
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorHasPipelineDefaults(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorHasCameraOverrides(
nativeHandle));
}
public static StageColorData ResolveStageColorData(
ScriptableRenderContext context)
{
if (context == null)
{
return StageColorData.Default;
}
ulong nativeHandle = context.nativeHandle;
return new StageColorData(
(CameraFrameColorSource)InternalCalls
.Rendering_ScriptableRenderContext_GetStageColorSource(
nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor(
nativeHandle));
}
}
}

View File

@@ -0,0 +1,25 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class ShadowData
{
internal static readonly ShadowData Default =
new ShadowData(
DirectionalShadowData.Default);
internal ShadowData(
DirectionalShadowData mainDirectionalShadow)
{
this.mainDirectionalShadow =
mainDirectionalShadow ??
DirectionalShadowData.Default;
}
public DirectionalShadowData mainDirectionalShadow { get; }
public bool hasMainDirectionalShadow =>
mainDirectionalShadow.enabled;
}
}

View File

@@ -0,0 +1,29 @@
using XCEngine;
namespace XCEngine.Rendering.Universal
{
public sealed class StageColorData
{
internal static readonly StageColorData Default =
new StageColorData(
CameraFrameColorSource.ExplicitSurface,
false);
internal StageColorData(
CameraFrameColorSource source,
bool usesGraphManagedOutputColor)
{
this.source = source;
this.usesGraphManagedOutputColor =
usesGraphManagedOutputColor;
}
public CameraFrameColorSource source { get; }
public bool usesGraphManagedSourceColor =>
source != CameraFrameColorSource.ExplicitSurface;
public bool usesGraphManagedOutputColor { get; }
}
}