Files
XCEngine/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs

309 lines
10 KiB
C#

using System;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class ScriptableRenderPass
{
private const string kColorScaleFullscreenPassName =
"Universal.ColorScaleFullscreen";
private const string kFinalColorFullscreenPassName =
"Universal.FinalColorFullscreen";
private const string kShaderVectorFullscreenPassName =
"Universal.ShaderVectorFullscreen";
protected ScriptableRenderPass()
{
}
public RenderPassEvent renderPassEvent { get; protected set; } =
RenderPassEvent.BeforeRenderingOpaques;
public virtual bool SupportsStage(
CameraFrameStage stage)
{
RendererBlock block;
return TryResolveRendererBlock(
renderPassEvent,
out block) &&
RendererBlockUtility.GetStage(block) == stage;
}
internal bool SupportsRendererBlock(
RendererBlock block)
{
RendererBlock resolvedBlock;
return TryResolveRendererBlock(
renderPassEvent,
out resolvedBlock) &&
resolvedBlock == block;
}
internal bool Record(
ScriptableRenderContext context,
RenderingData renderingData)
{
return RecordRenderGraph(
context,
renderingData);
}
protected abstract bool RecordRenderGraph(
ScriptableRenderContext context,
RenderingData renderingData);
protected bool RecordColorScaleFullscreenPass(
ScriptableRenderContext context,
Vector4 colorScale)
{
RenderGraphTextureHandle sourceColor;
RenderGraphTextureHandle outputColor;
return TryResolveDefaultFullscreenTargets(
context,
out sourceColor,
out outputColor) &&
RecordColorScaleFullscreenPass(
context,
sourceColor,
outputColor,
colorScale);
}
protected bool RecordColorScaleFullscreenPass(
ScriptableRenderContext context,
RenderGraphTextureHandle sourceColor,
RenderGraphTextureHandle outputColor,
Vector4 colorScale,
string passName = null)
{
if (context == null ||
!outputColor.isValid)
{
return false;
}
RenderGraphRasterPassBuilder passBuilder =
context.AddRasterPass(
ResolveFullscreenPassName(
passName,
kColorScaleFullscreenPassName));
if (sourceColor.isValid)
{
passBuilder.UseColorSource(sourceColor);
}
return passBuilder
.SetColorAttachment(outputColor)
.SetColorScaleFullscreenExecution(colorScale)
.Commit();
}
protected bool RecordShaderVectorFullscreenPass(
ScriptableRenderContext context,
string shaderPath,
Vector4 vectorPayload,
string passName = null)
{
if (string.IsNullOrEmpty(shaderPath))
{
throw new ArgumentException(
"Fullscreen shader path cannot be null or empty.",
nameof(shaderPath));
}
RenderGraphTextureHandle sourceColor;
RenderGraphTextureHandle outputColor;
return TryResolveDefaultFullscreenTargets(
context,
out sourceColor,
out outputColor) &&
RecordShaderVectorFullscreenPass(
context,
sourceColor,
outputColor,
shaderPath,
vectorPayload,
passName: passName);
}
protected bool RecordShaderVectorFullscreenPass(
ScriptableRenderContext context,
RenderGraphTextureHandle sourceColor,
RenderGraphTextureHandle outputColor,
string shaderPath,
Vector4 vectorPayload,
string shaderPassName = null,
string passName = null)
{
if (string.IsNullOrEmpty(shaderPath))
{
throw new ArgumentException(
"Fullscreen shader path cannot be null or empty.",
nameof(shaderPath));
}
if (context == null ||
!outputColor.isValid)
{
return false;
}
RenderGraphRasterPassBuilder passBuilder =
context.AddRasterPass(
ResolveFullscreenPassName(
passName,
kShaderVectorFullscreenPassName));
if (sourceColor.isValid)
{
passBuilder.UseColorSource(sourceColor);
}
return passBuilder
.SetColorAttachment(outputColor)
.SetShaderVectorFullscreenExecution(
shaderPath,
vectorPayload,
shaderPassName)
.Commit();
}
protected bool RecordFinalColorFullscreenPass(
ScriptableRenderContext context,
FinalColorSettings settings,
string passName = null)
{
RenderGraphTextureHandle sourceColor;
RenderGraphTextureHandle outputColor;
return TryResolveDefaultFullscreenTargets(
context,
out sourceColor,
out outputColor) &&
RecordFinalColorFullscreenPass(
context,
sourceColor,
outputColor,
settings,
passName);
}
protected bool RecordFinalColorFullscreenPass(
ScriptableRenderContext context,
RenderGraphTextureHandle sourceColor,
RenderGraphTextureHandle outputColor,
FinalColorSettings settings,
string passName = null)
{
if (context == null ||
!outputColor.isValid)
{
return false;
}
RenderGraphRasterPassBuilder passBuilder =
context.AddRasterPass(
ResolveFullscreenPassName(
passName,
kFinalColorFullscreenPassName));
if (sourceColor.isValid)
{
passBuilder.UseColorSource(sourceColor);
}
return passBuilder
.SetColorAttachment(outputColor)
.SetFinalColorFullscreenExecution(settings)
.Commit();
}
internal static bool TryResolveStage(
RenderPassEvent passEvent,
out CameraFrameStage stage)
{
RendererBlock block;
if (TryResolveRendererBlock(
passEvent,
out block))
{
stage =
RendererBlockUtility.GetStage(block);
return true;
}
stage = CameraFrameStage.MainScene;
return false;
}
internal static bool TryResolveRendererBlock(
RenderPassEvent passEvent,
out RendererBlock block)
{
switch (passEvent)
{
case RenderPassEvent.BeforeRenderingShadows:
case RenderPassEvent.AfterRenderingShadows:
block = RendererBlock.ShadowCaster;
return true;
case RenderPassEvent.BeforeRenderingPrePasses:
case RenderPassEvent.AfterRenderingPrePasses:
block = RendererBlock.DepthPrepass;
return true;
case RenderPassEvent.BeforeRenderingOpaques:
case RenderPassEvent.RenderOpaques:
case RenderPassEvent.AfterRenderingOpaques:
block = RendererBlock.MainOpaque;
return true;
case RenderPassEvent.BeforeRenderingSkybox:
case RenderPassEvent.RenderSkybox:
case RenderPassEvent.AfterRenderingSkybox:
block = RendererBlock.MainSkybox;
return true;
case RenderPassEvent.BeforeRenderingTransparents:
case RenderPassEvent.RenderTransparents:
case RenderPassEvent.AfterRenderingTransparents:
block = RendererBlock.MainTransparent;
return true;
case RenderPassEvent.BeforeRenderingPostProcessing:
case RenderPassEvent.AfterRenderingPostProcessing:
block = RendererBlock.PostProcess;
return true;
case RenderPassEvent.BeforeRenderingFinalOutput:
case RenderPassEvent.AfterRenderingFinalOutput:
block = RendererBlock.FinalOutput;
return true;
default:
block = RendererBlock.MainOpaque;
return false;
}
}
private static bool TryResolveDefaultFullscreenTargets(
ScriptableRenderContext context,
out RenderGraphTextureHandle sourceColor,
out RenderGraphTextureHandle outputColor)
{
sourceColor = new RenderGraphTextureHandle();
outputColor = new RenderGraphTextureHandle();
if (context == null)
{
return false;
}
sourceColor = context.sourceColorTexture;
outputColor = context.primaryColorTarget;
return sourceColor.isValid &&
outputColor.isValid;
}
private static string ResolveFullscreenPassName(
string passName,
string defaultPassName)
{
return string.IsNullOrEmpty(passName)
? defaultPassName
: passName;
}
}
}