309 lines
10 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
|