refactor(rendering): split managed SRP layers and namespaces

This commit is contained in:
2026-04-19 02:38:48 +08:00
parent 612e3ba0b3
commit 7429f22fb1
46 changed files with 629 additions and 351 deletions

View File

@@ -0,0 +1,12 @@
using XCEngine;
namespace XCEngine.Rendering
{
public enum CameraFrameColorSource
{
ExplicitSurface = 0,
MainSceneColor = 1,
PostProcessColor = 2
}
}

View File

@@ -0,0 +1,18 @@
using XCEngine;
namespace XCEngine.Rendering
{
public enum CameraFrameStage : byte
{
PreScenePasses = 0,
ShadowCaster = 1,
DepthOnly = 2,
MainScene = 3,
PostProcess = 4,
FinalOutput = 5,
ObjectId = 6,
PostScenePasses = 7,
OverlayPasses = 8
}
}

View File

@@ -0,0 +1,11 @@
using XCEngine;
namespace XCEngine.Rendering
{
public enum FinalColorExposureMode : byte
{
Disabled = 0,
Fixed = 1
}
}

View File

@@ -0,0 +1,11 @@
using XCEngine;
namespace XCEngine.Rendering
{
public enum FinalColorOutputTransferMode : byte
{
Disabled = 0,
LinearToSRGB = 1
}
}

View File

@@ -0,0 +1,24 @@
using System.Runtime.InteropServices;
using XCEngine;
namespace XCEngine.Rendering
{
[StructLayout(LayoutKind.Sequential)]
public struct FinalColorSettings
{
public FinalColorOutputTransferMode outputTransferMode;
public FinalColorExposureMode exposureMode;
public float exposureValue;
public FinalColorToneMappingMode toneMappingMode;
public Vector4 finalColorScale;
public static FinalColorSettings CreateDefault()
{
FinalColorSettings settings = new FinalColorSettings();
settings.exposureValue = 1.0f;
settings.finalColorScale = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
return settings;
}
}
}

View File

@@ -0,0 +1,12 @@
using XCEngine;
namespace XCEngine.Rendering
{
public enum FinalColorToneMappingMode : byte
{
Disabled = 0,
Neutral = 1,
ACES = 2
}
}

View File

@@ -0,0 +1,15 @@
using System;
using XCEngine;
namespace XCEngine.Rendering
{
public static class GraphicsSettings
{
public static ScriptableRenderPipelineAsset renderPipelineAsset
{
get => InternalCalls.Rendering_GetRenderPipelineAsset();
set => InternalCalls.Rendering_SetRenderPipelineAsset(value);
}
}
}

View File

@@ -0,0 +1,12 @@
using XCEngine;
namespace XCEngine.Rendering
{
public abstract class RenderPipelineAsset : Object
{
protected RenderPipelineAsset()
{
}
}
}

View File

@@ -0,0 +1,439 @@
using System;
using XCEngine;
namespace XCEngine.Rendering
{
public sealed class ScriptableRenderContext
{
private enum RecordedScenePhase
{
Opaque = 0,
Skybox = 1,
Transparent = 3
}
private enum RecordedSceneInjectionPoint
{
BeforeOpaque = 0,
AfterOpaque = 1,
BeforeSkybox = 2,
AfterSkybox = 3,
BeforeTransparent = 4,
AfterTransparent = 5
}
private enum RecordedFullscreenPassType
{
ColorScale = 0,
ShaderVector = 1
}
private readonly ulong m_nativeHandle;
private CameraData m_cameraData;
private LightingData m_lightingData;
private ShadowData m_shadowData;
private EnvironmentData m_environmentData;
private FinalColorData m_finalColorData;
private StageColorData m_stageColorData;
internal ScriptableRenderContext(ulong nativeHandle)
{
m_nativeHandle = nativeHandle;
}
public CameraFrameStage stage =>
(CameraFrameStage)InternalCalls.Rendering_ScriptableRenderContext_GetStage(
m_nativeHandle);
public CameraData cameraData =>
m_cameraData ?? (m_cameraData = ResolveCameraData());
public LightingData lightingData =>
m_lightingData ?? (m_lightingData = ResolveLightingData());
public ShadowData shadowData =>
m_shadowData ?? (m_shadowData = ResolveShadowData());
public EnvironmentData environmentData =>
m_environmentData ??
(m_environmentData = ResolveEnvironmentData());
public FinalColorData finalColorData =>
m_finalColorData ??
(m_finalColorData = ResolveFinalColorData());
public StageColorData stageColorData =>
m_stageColorData ??
(m_stageColorData = ResolveStageColorData());
internal bool RecordScene()
{
return InternalCalls
.Rendering_ScriptableRenderContext_RecordScene(
m_nativeHandle);
}
internal bool RecordOpaqueScenePhase()
{
return RecordScenePhaseInternal(
RecordedScenePhase.Opaque);
}
internal bool RecordSkyboxScenePhase()
{
return RecordScenePhaseInternal(
RecordedScenePhase.Skybox);
}
internal bool RecordTransparentScenePhase()
{
return RecordScenePhaseInternal(
RecordedScenePhase.Transparent);
}
internal bool RecordBeforeOpaqueInjection()
{
return RecordSceneInjectionPointInternal(
RecordedSceneInjectionPoint.BeforeOpaque);
}
internal bool RecordAfterOpaqueInjection()
{
return RecordSceneInjectionPointInternal(
RecordedSceneInjectionPoint.AfterOpaque);
}
internal bool RecordBeforeSkyboxInjection()
{
return RecordSceneInjectionPointInternal(
RecordedSceneInjectionPoint.BeforeSkybox);
}
internal bool RecordAfterSkyboxInjection()
{
return RecordSceneInjectionPointInternal(
RecordedSceneInjectionPoint.AfterSkybox);
}
internal bool RecordBeforeTransparentInjection()
{
return RecordSceneInjectionPointInternal(
RecordedSceneInjectionPoint.BeforeTransparent);
}
internal bool RecordAfterTransparentInjection()
{
return RecordSceneInjectionPointInternal(
RecordedSceneInjectionPoint.AfterTransparent);
}
internal bool RecordColorScaleFullscreenPass(
Vector4 colorScale)
{
return RecordFullscreenPassInternal(
RecordedFullscreenPassType.ColorScale,
string.Empty,
string.Empty,
colorScale);
}
internal bool RecordShaderVectorFullscreenPass(
string shaderPath,
Vector4 vectorPayload,
string passName = null)
{
if (string.IsNullOrEmpty(shaderPath))
{
throw new ArgumentException(
"Fullscreen shader path cannot be null or empty.",
nameof(shaderPath));
}
return RecordFullscreenPassInternal(
RecordedFullscreenPassType.ShaderVector,
shaderPath,
passName ?? string.Empty,
vectorPayload);
}
private bool RecordScenePhaseInternal(
RecordedScenePhase scenePhase)
{
return InternalCalls
.Rendering_ScriptableRenderContext_RecordScenePhase(
m_nativeHandle,
(int)scenePhase);
}
private bool RecordSceneInjectionPointInternal(
RecordedSceneInjectionPoint injectionPoint)
{
return InternalCalls
.Rendering_ScriptableRenderContext_RecordSceneInjectionPoint(
m_nativeHandle,
(int)injectionPoint);
}
private bool RecordFullscreenPassInternal(
RecordedFullscreenPassType passType,
string shaderPath,
string passName,
Vector4 vectorPayload)
{
return InternalCalls
.Rendering_ScriptableRenderContext_RecordFullscreenPass(
m_nativeHandle,
(int)passType,
shaderPath,
passName,
ref vectorPayload);
}
private CameraData ResolveCameraData()
{
Matrix4x4 view;
Matrix4x4 projection;
Matrix4x4 viewProjection;
Vector3 worldPosition;
Vector3 worldRight;
Vector3 worldUp;
Vector3 worldForward;
Color clearColor;
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraView(
m_nativeHandle,
out view);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraProjection(
m_nativeHandle,
out projection);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraViewProjection(
m_nativeHandle,
out viewProjection);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldPosition(
m_nativeHandle,
out worldPosition);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldRight(
m_nativeHandle,
out worldRight);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldUp(
m_nativeHandle,
out worldUp);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraWorldForward(
m_nativeHandle,
out worldForward);
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraClearColor(
m_nativeHandle,
out clearColor);
return new CameraData(
view,
projection,
viewProjection,
worldPosition,
worldRight,
worldUp,
worldForward,
clearColor,
(RenderClearFlags)InternalCalls
.Rendering_ScriptableRenderContext_GetCameraClearFlags(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraPerspectiveProjection(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraVerticalFovRadians(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraOrthographicSize(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraAspectRatio(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraNearClipPlane(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraFarClipPlane(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraViewportWidth(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetCameraViewportHeight(
m_nativeHandle));
}
private LightingData ResolveLightingData()
{
Vector3 mainDirectionalLightDirection;
Color mainDirectionalLightColor;
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightDirection(
m_nativeHandle,
out mainDirectionalLightDirection);
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightColor(
m_nativeHandle,
out mainDirectionalLightColor);
return new LightingData(
new DirectionalLightData(
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightEnabled(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightCastsShadows(
m_nativeHandle),
mainDirectionalLightDirection,
mainDirectionalLightColor,
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalLightIntensity(
m_nativeHandle)),
InternalCalls
.Rendering_ScriptableRenderContext_GetHasMainDirectionalShadow(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetAdditionalLightCount(
m_nativeHandle));
}
private EnvironmentData ResolveEnvironmentData()
{
Color skyboxTopColor;
Color skyboxHorizonColor;
Color skyboxBottomColor;
InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentSkyboxTopColor(
m_nativeHandle,
out skyboxTopColor);
InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentSkyboxHorizonColor(
m_nativeHandle,
out skyboxHorizonColor);
InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentSkyboxBottomColor(
m_nativeHandle,
out skyboxBottomColor);
return new EnvironmentData(
(RenderEnvironmentMode)InternalCalls
.Rendering_ScriptableRenderContext_GetEnvironmentMode(
m_nativeHandle),
skyboxTopColor,
skyboxHorizonColor,
skyboxBottomColor);
}
private ShadowData ResolveShadowData()
{
Matrix4x4 viewProjection;
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowViewProjection(
m_nativeHandle,
out viewProjection);
return new ShadowData(
new DirectionalShadowData(
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowEnabled(
m_nativeHandle),
viewProjection,
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowOrthographicHalfExtent(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowNearClipPlane(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowFarClipPlane(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapWidth(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapHeight(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowWorldTexelSize(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowReceiverDepthBias(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowNormalBiasScale(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowStrength(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasFactor(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasUnits(
m_nativeHandle)));
}
private FinalColorData ResolveFinalColorData()
{
Vector4 finalColorScale;
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorScale(
m_nativeHandle,
out finalColorScale);
FinalColorSettings settings =
FinalColorSettings.CreateDefault();
settings.outputTransferMode =
(FinalColorOutputTransferMode)InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorOutputTransferMode(
m_nativeHandle);
settings.exposureMode =
(FinalColorExposureMode)InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorExposureMode(
m_nativeHandle);
settings.exposureValue =
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorExposureValue(
m_nativeHandle);
settings.toneMappingMode =
(FinalColorToneMappingMode)InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorToneMappingMode(
m_nativeHandle);
settings.finalColorScale =
finalColorScale;
return new FinalColorData(
settings,
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorHasPipelineDefaults(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetFinalColorHasCameraOverrides(
m_nativeHandle));
}
private StageColorData ResolveStageColorData()
{
return new StageColorData(
(CameraFrameColorSource)InternalCalls
.Rendering_ScriptableRenderContext_GetStageColorSource(
m_nativeHandle),
InternalCalls
.Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor(
m_nativeHandle));
}
}
}

View File

@@ -0,0 +1,24 @@
using XCEngine;
namespace XCEngine.Rendering
{
public abstract class ScriptableRenderPipeline : Object
{
protected ScriptableRenderPipeline()
{
}
protected internal virtual bool SupportsStageRenderGraph(
CameraFrameStage stage)
{
return false;
}
protected internal virtual bool RecordStageRenderGraph(
ScriptableRenderContext context)
{
return false;
}
}
}

View File

@@ -0,0 +1,32 @@
using XCEngine;
namespace XCEngine.Rendering
{
public abstract class ScriptableRenderPipelineAsset : RenderPipelineAsset
{
protected ScriptableRenderPipelineAsset()
{
}
protected internal virtual ScriptableRenderPipeline CreatePipeline()
{
return null;
}
protected internal virtual void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
}
protected internal virtual void ConfigureCameraFramePlan(
ScriptableRenderPipelinePlanningContext context)
{
}
protected internal virtual FinalColorSettings GetDefaultFinalColorSettings()
{
return FinalColorSettings.CreateDefault();
}
}
}

View File

@@ -0,0 +1,37 @@
using XCEngine;
namespace XCEngine.Rendering
{
public sealed class ScriptableRenderPipelineCameraRequestContext
{
private readonly ulong m_nativeHandle;
internal ScriptableRenderPipelineCameraRequestContext(ulong nativeHandle)
{
m_nativeHandle = nativeHandle;
}
public int renderedBaseCameraCount =>
InternalCalls
.Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedBaseCameraCount(
m_nativeHandle);
public int renderedRequestCount =>
InternalCalls
.Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount(
m_nativeHandle);
public bool hasDirectionalShadow =>
InternalCalls
.Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow(
m_nativeHandle);
public void ClearDirectionalShadow()
{
InternalCalls
.Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow(
m_nativeHandle);
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using XCEngine;
namespace XCEngine.Rendering
{
public sealed class ScriptableRenderPipelinePlanningContext
{
private readonly ulong m_nativeHandle;
internal ScriptableRenderPipelinePlanningContext(ulong nativeHandle)
{
m_nativeHandle = nativeHandle;
}
public void ClearFullscreenStage(
CameraFrameStage stage)
{
ValidateFullscreenStage(stage);
InternalCalls.Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage(
m_nativeHandle,
(int)stage);
}
public void RequestFullscreenStage(
CameraFrameStage stage,
CameraFrameColorSource source,
bool usesGraphManagedOutputColor = false)
{
ValidateFullscreenStage(stage);
if (source == CameraFrameColorSource.ExplicitSurface)
{
throw new ArgumentException(
"Managed planning currently requires a graph-managed color source for fullscreen stages.",
nameof(source));
}
if (stage == CameraFrameStage.FinalOutput && usesGraphManagedOutputColor)
{
throw new ArgumentException(
"FinalOutput fullscreen stages cannot publish a graph-managed output color.",
nameof(usesGraphManagedOutputColor));
}
if (!InternalCalls
.Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage(
m_nativeHandle,
(int)stage,
(int)source,
usesGraphManagedOutputColor))
{
throw new InvalidOperationException(
$"Failed to request the managed fullscreen stage '{stage}'.");
}
}
private static void ValidateFullscreenStage(
CameraFrameStage stage)
{
if (stage != CameraFrameStage.PostProcess &&
stage != CameraFrameStage.FinalOutput)
{
throw new ArgumentException(
"Managed planning currently supports only fullscreen sequence stages.",
nameof(stage));
}
}
}
}

View File

@@ -0,0 +1,112 @@
using XCEngine;
namespace XCEngine.Rendering
{
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
{
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
{
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
{
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
{
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
{
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
{
[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
{
public enum RenderEnvironmentMode
{
None = 0,
ProceduralSkybox = 1,
MaterialSkybox = 2
}
}

View File

@@ -0,0 +1,92 @@
using XCEngine;
namespace XCEngine.Rendering
{
public sealed class RenderingData
{
internal RenderingData(CameraFrameStage stage)
: this(
stage,
CameraData.Default,
LightingData.Default,
ShadowData.Default,
EnvironmentData.Default,
FinalColorData.Default,
StageColorData.Default)
{
}
internal RenderingData(ScriptableRenderContext context)
: this(
context != null
? context.stage
: CameraFrameStage.MainScene,
context != null
? context.cameraData
: CameraData.Default,
context != null
? context.lightingData
: LightingData.Default,
context != null
? context.shadowData
: ShadowData.Default,
context != null
? context.environmentData
: EnvironmentData.Default,
context != null
? context.finalColorData
: FinalColorData.Default,
context != null
? context.stageColorData
: StageColorData.Default)
{
}
private RenderingData(
CameraFrameStage stage,
CameraData cameraData,
LightingData lightingData,
ShadowData shadowData,
EnvironmentData environmentData,
FinalColorData finalColorData,
StageColorData stageColorData)
{
this.stage = stage;
this.cameraData = cameraData ?? CameraData.Default;
this.lightingData =
lightingData ?? LightingData.Default;
this.shadowData =
shadowData ?? ShadowData.Default;
this.environmentData =
environmentData ?? EnvironmentData.Default;
this.finalColorData =
finalColorData ?? FinalColorData.Default;
this.stageColorData =
stageColorData ?? StageColorData.Default;
}
public CameraFrameStage stage { get; }
public CameraData cameraData { get; }
public LightingData lightingData { get; }
public ShadowData shadowData { get; }
public EnvironmentData environmentData { get; }
public FinalColorData finalColorData { get; }
public StageColorData stageColorData { get; }
public bool isMainSceneStage =>
stage == CameraFrameStage.MainScene;
public bool isPostProcessStage =>
stage == CameraFrameStage.PostProcess;
public bool isFinalOutputStage =>
stage == CameraFrameStage.FinalOutput;
}
}

View File

@@ -0,0 +1,25 @@
using XCEngine;
namespace XCEngine.Rendering
{
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
{
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; }
}
}

View File

@@ -0,0 +1,83 @@
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.FirstParty
{
internal sealed class ColorScalePostProcessPass
: ScriptableRenderPass
{
private readonly ColorScalePostProcessRendererFeature m_feature;
public ColorScalePostProcessPass(
ColorScalePostProcessRendererFeature feature)
{
m_feature = feature;
renderPassEvent =
RenderPassEvent.BeforeRenderingPostProcessing;
}
protected override bool RecordRenderGraph(
RendererRecordingContext context,
RenderingData renderingData)
{
return context != null &&
renderingData != null &&
renderingData.isPostProcessStage &&
m_feature != null &&
context.RecordColorScaleFullscreenPass(
m_feature.colorScale);
}
}
public sealed class ColorScalePostProcessRendererFeature
: ScriptableRendererFeature
{
private ColorScalePostProcessPass m_pass;
public Vector4 colorScale = new Vector4(
1.0f,
1.0f,
1.0f,
1.0f);
public override void Create()
{
m_pass =
new ColorScalePostProcessPass(this);
}
public override void ConfigureCameraFramePlan(
ScriptableRenderPipelinePlanningContext context)
{
if (context == null)
{
return;
}
context.RequestFullscreenStage(
CameraFrameStage.PostProcess,
CameraFrameColorSource.MainSceneColor);
}
public override void AddRenderPasses(
ScriptableRenderer renderer,
RenderingData renderingData)
{
if (renderer == null ||
renderingData == null ||
!renderingData.isPostProcessStage)
{
return;
}
if (m_pass == null)
{
Create();
}
renderer.EnqueuePass(m_pass);
}
}
}

View File

@@ -0,0 +1,21 @@
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.FirstParty
{
public sealed class DisableDirectionalShadowRendererFeature
: ScriptableRendererFeature
{
public override void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
if (context != null &&
context.hasDirectionalShadow)
{
context.ClearDirectionalShadow();
}
}
}
}

View File

@@ -0,0 +1,24 @@
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.FirstParty
{
public class ForwardRenderPipelineAsset
: RendererBackedRenderPipelineAsset
{
public ForwardRendererData rendererData =
new ForwardRendererData();
protected override ScriptableRendererData GetRendererData()
{
if (rendererData == null)
{
rendererData = new ForwardRendererData();
}
return rendererData;
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.FirstParty
{
internal sealed class ForwardSceneRecordingPass : ScriptableRenderPass
{
private readonly Func<RendererRecordingContext, bool> m_recordAction;
public ForwardSceneRecordingPass(
RenderPassEvent passEvent,
Func<RendererRecordingContext, bool> recordAction)
{
renderPassEvent = passEvent;
m_recordAction = recordAction;
}
protected override bool RecordRenderGraph(
RendererRecordingContext context,
RenderingData renderingData)
{
return context != null &&
renderingData != null &&
renderingData.isMainSceneStage &&
m_recordAction != null &&
m_recordAction(context);
}
}
internal sealed class ForwardSceneFeature : ScriptableRendererFeature
{
private readonly ForwardRendererData m_rendererData;
private readonly ForwardSceneRecordingPass m_beforeOpaquePass =
new ForwardSceneRecordingPass(
RenderPassEvent.BeforeRenderingOpaques,
context => context.RecordBeforeOpaqueInjection());
private readonly ForwardSceneRecordingPass m_opaquePass =
new ForwardSceneRecordingPass(
RenderPassEvent.RenderOpaques,
context => context.RecordOpaqueScenePhase());
private readonly ForwardSceneRecordingPass m_afterOpaquePass =
new ForwardSceneRecordingPass(
RenderPassEvent.AfterRenderingOpaques,
context => context.RecordAfterOpaqueInjection());
private readonly ForwardSceneRecordingPass m_beforeSkyboxPass =
new ForwardSceneRecordingPass(
RenderPassEvent.BeforeRenderingSkybox,
context => context.RecordBeforeSkyboxInjection());
private readonly ForwardSceneRecordingPass m_skyboxPass =
new ForwardSceneRecordingPass(
RenderPassEvent.RenderSkybox,
context => context.RecordSkyboxScenePhase());
private readonly ForwardSceneRecordingPass m_afterSkyboxPass =
new ForwardSceneRecordingPass(
RenderPassEvent.AfterRenderingSkybox,
context => context.RecordAfterSkyboxInjection());
private readonly ForwardSceneRecordingPass m_beforeTransparentPass =
new ForwardSceneRecordingPass(
RenderPassEvent.BeforeRenderingTransparents,
context => context.RecordBeforeTransparentInjection());
private readonly ForwardSceneRecordingPass m_transparentPass =
new ForwardSceneRecordingPass(
RenderPassEvent.RenderTransparents,
context => context.RecordTransparentScenePhase());
private readonly ForwardSceneRecordingPass m_afterTransparentPass =
new ForwardSceneRecordingPass(
RenderPassEvent.AfterRenderingTransparents,
context => context.RecordAfterTransparentInjection());
public ForwardSceneFeature(
ForwardRendererData rendererData)
{
m_rendererData = rendererData;
}
public override void AddRenderPasses(
ScriptableRenderer renderer,
RenderingData renderingData)
{
if (renderer == null ||
renderingData == null ||
!renderingData.isMainSceneStage ||
m_rendererData == null)
{
return;
}
if (m_rendererData.renderOpaque)
{
renderer.EnqueuePass(m_beforeOpaquePass);
renderer.EnqueuePass(m_opaquePass);
renderer.EnqueuePass(m_afterOpaquePass);
}
if (m_rendererData.renderSkybox)
{
renderer.EnqueuePass(m_beforeSkyboxPass);
renderer.EnqueuePass(m_skyboxPass);
renderer.EnqueuePass(m_afterSkyboxPass);
}
if (m_rendererData.renderTransparent)
{
renderer.EnqueuePass(m_beforeTransparentPass);
renderer.EnqueuePass(m_transparentPass);
renderer.EnqueuePass(m_afterTransparentPass);
}
}
}
public sealed class ForwardRenderer : ScriptableRenderer
{
public ForwardRenderer(
ForwardRendererData rendererData)
{
ForwardRendererData resolvedData =
rendererData ?? new ForwardRendererData();
AddFeature(new ForwardSceneFeature(resolvedData));
ScriptableRendererFeature[] rendererFeatures =
resolvedData.CreateRendererFeaturesInstance();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
AddFeature(rendererFeatures[i]);
}
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.FirstParty
{
public class ForwardRendererData : ScriptableRendererData
{
public bool renderOpaque = true;
public bool renderSkybox = true;
public bool renderTransparent = true;
public ScriptableRendererFeature[] rendererFeatures =
Array.Empty<ScriptableRendererFeature>();
protected override ScriptableRenderer CreateRenderer()
{
return new ForwardRenderer(this);
}
protected override ScriptableRendererFeature[] CreateRendererFeatures()
{
return rendererFeatures ??
Array.Empty<ScriptableRendererFeature>();
}
}
}

View File

@@ -0,0 +1,23 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public enum RenderPassEvent
{
BeforeRenderingOpaques = 100,
RenderOpaques = 110,
AfterRenderingOpaques = 120,
BeforeRenderingSkybox = 200,
RenderSkybox = 210,
AfterRenderingSkybox = 220,
BeforeRenderingTransparents = 300,
RenderTransparents = 310,
AfterRenderingTransparents = 320,
BeforeRenderingPostProcessing = 400,
AfterRenderingPostProcessing = 420,
BeforeRenderingFinalOutput = 500,
AfterRenderingFinalOutput = 520
}
}

View File

@@ -0,0 +1,50 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public abstract class RendererBackedRenderPipeline
: ScriptableRenderPipeline
{
private ScriptableRenderer m_renderer;
protected RendererBackedRenderPipeline()
{
}
protected internal virtual ScriptableRenderer CreateRenderer()
{
return null;
}
protected internal override bool SupportsStageRenderGraph(
CameraFrameStage stage)
{
ScriptableRenderer renderer = GetOrCreateRenderer();
return renderer != null &&
renderer.SupportsStageRenderGraph(stage);
}
protected internal override bool RecordStageRenderGraph(
ScriptableRenderContext context)
{
ScriptableRenderer renderer = GetOrCreateRenderer();
return renderer != null &&
renderer.RecordStageRenderGraph(context);
}
protected ScriptableRenderer renderer =>
GetOrCreateRenderer();
private ScriptableRenderer GetOrCreateRenderer()
{
if (m_renderer == null)
{
m_renderer = CreateRenderer();
}
return m_renderer;
}
}
}

View File

@@ -0,0 +1,54 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public abstract class RendererBackedRenderPipelineAsset
: ScriptableRenderPipelineAsset
{
protected RendererBackedRenderPipelineAsset()
{
}
protected internal override ScriptableRenderPipeline CreatePipeline()
{
ScriptableRendererData rendererData =
ResolveRendererData();
return rendererData != null
? new RendererDrivenRenderPipeline(rendererData)
: null;
}
protected internal override void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
ScriptableRendererData rendererData =
ResolveRendererData();
if (rendererData != null)
{
rendererData.ConfigureCameraRenderRequestInstance(
context);
}
}
protected internal override void ConfigureCameraFramePlan(
ScriptableRenderPipelinePlanningContext context)
{
ScriptableRendererData rendererData =
ResolveRendererData();
if (rendererData != null)
{
rendererData.ConfigureCameraFramePlanInstance(
context);
}
}
protected abstract ScriptableRendererData GetRendererData();
private ScriptableRendererData ResolveRendererData()
{
return GetRendererData();
}
}
}

View File

@@ -0,0 +1,25 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public class RendererDrivenRenderPipeline
: RendererBackedRenderPipeline
{
private readonly ScriptableRendererData m_rendererData;
public RendererDrivenRenderPipeline(
ScriptableRendererData rendererData)
{
m_rendererData = rendererData;
}
protected internal override ScriptableRenderer CreateRenderer()
{
return m_rendererData != null
? m_rendererData.CreateRendererInstance()
: null;
}
}
}

View File

@@ -0,0 +1,97 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public sealed class RendererRecordingContext
{
private readonly ScriptableRenderContext m_renderContext;
internal RendererRecordingContext(
ScriptableRenderContext renderContext)
{
m_renderContext = renderContext;
}
public bool RecordScene()
{
return m_renderContext != null &&
m_renderContext.RecordScene();
}
public bool RecordOpaqueScenePhase()
{
return m_renderContext != null &&
m_renderContext.RecordOpaqueScenePhase();
}
public bool RecordSkyboxScenePhase()
{
return m_renderContext != null &&
m_renderContext.RecordSkyboxScenePhase();
}
public bool RecordTransparentScenePhase()
{
return m_renderContext != null &&
m_renderContext.RecordTransparentScenePhase();
}
public bool RecordBeforeOpaqueInjection()
{
return m_renderContext != null &&
m_renderContext.RecordBeforeOpaqueInjection();
}
public bool RecordAfterOpaqueInjection()
{
return m_renderContext != null &&
m_renderContext.RecordAfterOpaqueInjection();
}
public bool RecordBeforeSkyboxInjection()
{
return m_renderContext != null &&
m_renderContext.RecordBeforeSkyboxInjection();
}
public bool RecordAfterSkyboxInjection()
{
return m_renderContext != null &&
m_renderContext.RecordAfterSkyboxInjection();
}
public bool RecordBeforeTransparentInjection()
{
return m_renderContext != null &&
m_renderContext.RecordBeforeTransparentInjection();
}
public bool RecordAfterTransparentInjection()
{
return m_renderContext != null &&
m_renderContext.RecordAfterTransparentInjection();
}
public bool RecordColorScaleFullscreenPass(
Vector4 colorScale)
{
return m_renderContext != null &&
m_renderContext.RecordColorScaleFullscreenPass(
colorScale);
}
public bool RecordShaderVectorFullscreenPass(
string shaderPath,
Vector4 vectorPayload,
string passName = null)
{
return m_renderContext != null &&
m_renderContext.RecordShaderVectorFullscreenPass(
shaderPath,
vectorPayload,
passName);
}
}
}

View File

@@ -0,0 +1,70 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public abstract class ScriptableRenderPass
{
protected ScriptableRenderPass()
{
}
public RenderPassEvent renderPassEvent { get; protected set; } =
RenderPassEvent.BeforeRenderingOpaques;
public virtual bool SupportsStage(
CameraFrameStage stage)
{
CameraFrameStage resolvedStage;
return TryResolveStage(
renderPassEvent,
out resolvedStage) &&
resolvedStage == stage;
}
internal bool Record(
RendererRecordingContext context,
RenderingData renderingData)
{
return RecordRenderGraph(
context,
renderingData);
}
protected abstract bool RecordRenderGraph(
RendererRecordingContext context,
RenderingData renderingData);
internal static bool TryResolveStage(
RenderPassEvent passEvent,
out CameraFrameStage stage)
{
switch (passEvent)
{
case RenderPassEvent.BeforeRenderingOpaques:
case RenderPassEvent.RenderOpaques:
case RenderPassEvent.AfterRenderingOpaques:
case RenderPassEvent.BeforeRenderingSkybox:
case RenderPassEvent.RenderSkybox:
case RenderPassEvent.AfterRenderingSkybox:
case RenderPassEvent.BeforeRenderingTransparents:
case RenderPassEvent.RenderTransparents:
case RenderPassEvent.AfterRenderingTransparents:
stage = CameraFrameStage.MainScene;
return true;
case RenderPassEvent.BeforeRenderingPostProcessing:
case RenderPassEvent.AfterRenderingPostProcessing:
stage = CameraFrameStage.PostProcess;
return true;
case RenderPassEvent.BeforeRenderingFinalOutput:
case RenderPassEvent.AfterRenderingFinalOutput:
stage = CameraFrameStage.FinalOutput;
return true;
default:
stage = CameraFrameStage.MainScene;
return false;
}
}
}
}

View File

@@ -0,0 +1,133 @@
using System.Collections.Generic;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public abstract class ScriptableRenderer
{
private readonly List<ScriptableRendererFeature> m_features =
new List<ScriptableRendererFeature>();
private readonly List<ScriptableRenderPass> m_activePassQueue =
new List<ScriptableRenderPass>();
protected ScriptableRenderer()
{
}
public void EnqueuePass(
ScriptableRenderPass renderPass)
{
if (renderPass == null)
{
return;
}
int insertIndex = m_activePassQueue.Count;
while (insertIndex > 0 &&
m_activePassQueue[insertIndex - 1].renderPassEvent >
renderPass.renderPassEvent)
{
insertIndex--;
}
m_activePassQueue.Insert(
insertIndex,
renderPass);
}
protected void AddFeature(
ScriptableRendererFeature feature)
{
if (feature == null)
{
return;
}
m_features.Add(feature);
feature.Create();
}
protected virtual void AddRenderPasses(
RenderingData renderingData)
{
}
internal bool SupportsStageRenderGraph(
CameraFrameStage stage)
{
RenderingData renderingData = new RenderingData(stage);
BuildPassQueue(renderingData);
for (int i = 0; i < m_activePassQueue.Count; ++i)
{
ScriptableRenderPass renderPass = m_activePassQueue[i];
if (renderPass != null &&
renderPass.SupportsStage(stage))
{
return true;
}
}
return false;
}
internal bool RecordStageRenderGraph(
ScriptableRenderContext context)
{
if (context == null)
{
return false;
}
RenderingData renderingData =
new RenderingData(context);
RendererRecordingContext recordingContext =
new RendererRecordingContext(context);
BuildPassQueue(renderingData);
bool recordedAnyPass = false;
for (int i = 0; i < m_activePassQueue.Count; ++i)
{
ScriptableRenderPass renderPass = m_activePassQueue[i];
if (renderPass == null ||
!renderPass.SupportsStage(renderingData.stage))
{
continue;
}
if (!renderPass.Record(
recordingContext,
renderingData))
{
return false;
}
recordedAnyPass = true;
}
return recordedAnyPass;
}
private void BuildPassQueue(
RenderingData renderingData)
{
m_activePassQueue.Clear();
for (int i = 0; i < m_features.Count; ++i)
{
ScriptableRendererFeature feature = m_features[i];
if (feature == null || !feature.isActive)
{
continue;
}
feature.AddRenderPasses(
this,
renderingData);
}
AddRenderPasses(renderingData);
}
}
}

View File

@@ -0,0 +1,102 @@
using System;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public abstract class ScriptableRendererData : Object
{
private ScriptableRendererFeature[] m_rendererFeatures;
protected ScriptableRendererData()
{
}
internal ScriptableRenderer CreateRendererInstance()
{
return CreateRenderer();
}
internal ScriptableRendererFeature[] CreateRendererFeaturesInstance()
{
return GetRendererFeatures();
}
internal void ConfigureCameraRenderRequestInstance(
ScriptableRenderPipelineCameraRequestContext context)
{
ConfigureCameraRenderRequest(context);
ScriptableRendererFeature[] rendererFeatures =
GetRendererFeatures();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatures[i];
if (rendererFeature == null ||
!rendererFeature.isActive)
{
continue;
}
rendererFeature.ConfigureCameraRenderRequest(
context);
}
}
internal void ConfigureCameraFramePlanInstance(
ScriptableRenderPipelinePlanningContext context)
{
ConfigureCameraFramePlan(context);
ScriptableRendererFeature[] rendererFeatures =
GetRendererFeatures();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatures[i];
if (rendererFeature == null ||
!rendererFeature.isActive)
{
continue;
}
rendererFeature.ConfigureCameraFramePlan(
context);
}
}
protected virtual ScriptableRenderer CreateRenderer()
{
return null;
}
protected virtual void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
}
protected virtual void ConfigureCameraFramePlan(
ScriptableRenderPipelinePlanningContext context)
{
}
protected virtual ScriptableRendererFeature[] CreateRendererFeatures()
{
return Array.Empty<ScriptableRendererFeature>();
}
private ScriptableRendererFeature[] GetRendererFeatures()
{
if (m_rendererFeatures == null)
{
m_rendererFeatures =
CreateRendererFeatures() ??
Array.Empty<ScriptableRendererFeature>();
}
return m_rendererFeatures;
}
}
}

View File

@@ -0,0 +1,35 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Renderer
{
public abstract class ScriptableRendererFeature
{
protected ScriptableRendererFeature()
{
}
public bool isActive { get; set; } = true;
public virtual void Create()
{
}
public virtual void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
}
public virtual void ConfigureCameraFramePlan(
ScriptableRenderPipelinePlanningContext context)
{
}
public virtual void AddRenderPasses(
ScriptableRenderer renderer,
RenderingData renderingData)
{
}
}
}