using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using Unity.Collections;
using UnityEngine.Scripting.APIUpdating;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.RenderGraphModule;
namespace UnityEngine.Rendering.Universal
{
///
/// Input requirements for ScriptableRenderPass.
///
///
[Flags]
public enum ScriptableRenderPassInput
{
///
/// Used when a ScriptableRenderPass does not require any texture.
///
None = 0,
///
/// Used when a ScriptableRenderPass requires a depth texture.
///
Depth = 1 << 0,
///
/// Used when a ScriptableRenderPass requires a normal texture.
///
Normal = 1 << 1,
///
/// Used when a ScriptableRenderPass requires a color texture.
///
Color = 1 << 2,
///
/// Used when a ScriptableRenderPass requires a motion vectors texture.
///
Motion = 1 << 3,
}
// Note: Spaced built-in events so we can add events in between them
// We need to leave room as we sort render passes based on event.
// Users can also inject render pass events in a specific point by doing RenderPassEvent + offset
///
/// Controls when the render pass executes.
///
public enum RenderPassEvent
{
///
/// Executes a ScriptableRenderPass before rendering any other passes in the pipeline.
/// Camera matrices and stereo rendering are not setup this point.
/// You can use this to draw to custom input textures used later in the pipeline, f.ex LUT textures.
///
BeforeRendering = 0,
///
/// Executes a ScriptableRenderPass before rendering shadowmaps.
/// Camera matrices and stereo rendering are not setup this point.
///
BeforeRenderingShadows = 50,
///
/// Executes a ScriptableRenderPass after rendering shadowmaps.
/// Camera matrices and stereo rendering are not setup this point.
///
AfterRenderingShadows = 100,
///
/// Executes a ScriptableRenderPass before rendering prepasses, f.ex, depth prepass.
/// Camera matrices and stereo rendering are already setup at this point.
///
BeforeRenderingPrePasses = 150,
///
/// Executes a ScriptableRenderPass after rendering prepasses, f.ex, depth prepass.
/// Camera matrices and stereo rendering are already setup at this point.
///
AfterRenderingPrePasses = 200,
///
/// Executes a ScriptableRenderPass before rendering gbuffer pass.
///
BeforeRenderingGbuffer = 210,
///
/// Executes a ScriptableRenderPass after rendering gbuffer pass.
///
AfterRenderingGbuffer = 220,
///
/// Executes a ScriptableRenderPass before rendering deferred shading pass.
///
BeforeRenderingDeferredLights = 230,
///
/// Executes a ScriptableRenderPass after rendering deferred shading pass.
///
AfterRenderingDeferredLights = 240,
///
/// Executes a ScriptableRenderPass before rendering opaque objects.
///
BeforeRenderingOpaques = 250,
///
/// Executes a ScriptableRenderPass after rendering opaque objects.
///
AfterRenderingOpaques = 300,
///
/// Executes a ScriptableRenderPass before rendering the sky.
///
BeforeRenderingSkybox = 350,
///
/// Executes a ScriptableRenderPass after rendering the sky.
///
AfterRenderingSkybox = 400,
///
/// Executes a ScriptableRenderPass before rendering transparent objects.
///
BeforeRenderingTransparents = 450,
///
/// Executes a ScriptableRenderPass after rendering transparent objects.
///
AfterRenderingTransparents = 500,
///
/// Executes a ScriptableRenderPass before rendering post-processing effects.
///
BeforeRenderingPostProcessing = 550,
///
/// Executes a ScriptableRenderPass after rendering post-processing effects but before final blit, post-processing AA effects and color grading.
///
AfterRenderingPostProcessing = 600,
///
/// Executes a ScriptableRenderPass after rendering all effects.
///
AfterRendering = 1000,
}
internal static class RenderPassEventsEnumValues
{
// we cache the values in this array at construction time to avoid runtime allocations, which we would cause if we accessed valuesInternal directly
public static int[] values;
static RenderPassEventsEnumValues()
{
System.Array valuesInternal = Enum.GetValues(typeof(RenderPassEvent));
values = new int[valuesInternal.Length];
int index = 0;
foreach (int value in valuesInternal)
{
values[index] = value;
index++;
}
}
}
///
/// ScriptableRenderPass implements a logical rendering pass that can be used to extend Universal RP renderer.
///
public abstract partial class ScriptableRenderPass
{
///
/// RTHandle alias for BuiltinRenderTextureType.CameraTarget which is the backbuffer.
///
static public RTHandle k_CameraTarget = RTHandles.Alloc(BuiltinRenderTextureType.CameraTarget);
///
/// The event when the render pass executes.
///
public RenderPassEvent renderPassEvent { get; set; }
///
/// The render target identifiers for color attachments.
/// This is obsolete, use colorAttachmentHandles instead.
///
[Obsolete("Use colorAttachmentHandles")]
public RenderTargetIdentifier[] colorAttachments
{
get => m_ColorAttachmentIds;
}
///
/// The render target identifier for color attachment.
/// This is obsolete, use colorAttachmentHandle instead.
///
[Obsolete("Use colorAttachmentHandle")]
public RenderTargetIdentifier colorAttachment
{
get => m_ColorAttachmentIds[0];
}
///
/// The render target identifier for depth attachment.
/// This is obsolete, use depthAttachmentHandle instead.
///
[Obsolete("Use depthAttachmentHandle")]
public RenderTargetIdentifier depthAttachment
{
get => m_UsesRTHandles ? new RenderTargetIdentifier(m_DepthAttachment.nameID, 0, CubemapFace.Unknown, -1) : m_DepthAttachmentId;
}
///
/// List for the g-buffer attachment handles.
///
public RTHandle[] colorAttachmentHandles
{
get => m_ColorAttachments;
}
///
/// The main color attachment handle.
///
public RTHandle colorAttachmentHandle
{
get => m_ColorAttachments[0];
}
///
/// The depth attachment handle.
///
public RTHandle depthAttachmentHandle
{
get => m_DepthAttachment;
}
///
/// The store actions for Color.
///
public RenderBufferStoreAction[] colorStoreActions
{
get => m_ColorStoreActions;
}
///
/// The store actions for Depth.
///
public RenderBufferStoreAction depthStoreAction
{
get => m_DepthStoreAction;
}
internal bool[] overriddenColorStoreActions
{
get => m_OverriddenColorStoreActions;
}
internal bool overriddenDepthStoreAction
{
get => m_OverriddenDepthStoreAction;
}
///
/// The input requirements for the ScriptableRenderPass, which has been set using ConfigureInput
///
///
public ScriptableRenderPassInput input
{
get => m_Input;
}
///
/// The flag to use when clearing.
///
///
public ClearFlag clearFlag
{
get => m_ClearFlag;
}
///
/// The color value to use when clearing.
///
public Color clearColor
{
get => m_ClearColor;
}
RenderBufferStoreAction[] m_ColorStoreActions = new RenderBufferStoreAction[] { RenderBufferStoreAction.Store };
RenderBufferStoreAction m_DepthStoreAction = RenderBufferStoreAction.Store;
// by default all store actions are Store. The overridden flags are used to keep track of explicitly requested store actions, to
// help figuring out the correct final store action for merged render passes when using the RenderPass API.
private bool[] m_OverriddenColorStoreActions = new bool[] { false };
private bool m_OverriddenDepthStoreAction = false;
///
/// A ProfilingSampler for the entire render pass. Used as a profiling name by ScriptableRenderer when executing the pass.
/// Default is Unnamed_ScriptableRenderPass.
/// Set base.profilingSampler from the sub-class constructor to set a profiling name for a custom ScriptableRenderPass.
///
protected internal ProfilingSampler profilingSampler { get; set; }
internal bool overrideCameraTarget { get; set; }
internal bool isBlitRenderPass { get; set; }
internal bool useNativeRenderPass { get; set; }
// index to track the position in the current frame
internal int renderPassQueueIndex { get; set; }
internal NativeArray m_ColorAttachmentIndices;
internal NativeArray m_InputAttachmentIndices;
internal GraphicsFormat[] renderTargetFormat { get; set; }
internal bool m_UsesRTHandles;
RTHandle[] m_ColorAttachments;
RenderTargetIdentifier[] m_ColorAttachmentIds;
internal RTHandle[] m_InputAttachments = new RTHandle[8];
internal bool[] m_InputAttachmentIsTransient = new bool[8];
RTHandle m_DepthAttachment;
RenderTargetIdentifier m_DepthAttachmentId;
ScriptableRenderPassInput m_Input = ScriptableRenderPassInput.None;
ClearFlag m_ClearFlag = ClearFlag.None;
Color m_ClearColor = Color.black;
static internal DebugHandler GetActiveDebugHandler(ref RenderingData renderingData)
{
var debugHandler = renderingData.cameraData.renderer.DebugHandler;
if ((debugHandler != null) && debugHandler.IsActiveForCamera(ref renderingData.cameraData))
return debugHandler;
return null;
}
///
/// Creates a new ScriptableRenderPass" instance.
///
public ScriptableRenderPass()
{
m_UsesRTHandles = true;
renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
m_ColorAttachments = new RTHandle[] { k_CameraTarget, null, null, null, null, null, null, null };
m_InputAttachments = new RTHandle[] { null, null, null, null, null, null, null, null };
m_InputAttachmentIsTransient = new bool[] { false, false, false, false, false, false, false, false };
m_DepthAttachment = k_CameraTarget;
m_ColorStoreActions = new RenderBufferStoreAction[] { RenderBufferStoreAction.Store, 0, 0, 0, 0, 0, 0, 0 };
m_DepthStoreAction = RenderBufferStoreAction.Store;
m_OverriddenColorStoreActions = new bool[] { false, false, false, false, false, false, false, false };
m_OverriddenDepthStoreAction = false;
m_DepthAttachment = k_CameraTarget;
m_DepthAttachmentId = m_DepthAttachment.nameID;
m_ColorAttachmentIds = new RenderTargetIdentifier[] { k_CameraTarget.nameID, 0, 0, 0, 0, 0, 0, 0 };
m_ClearFlag = ClearFlag.None;
m_ClearColor = Color.black;
overrideCameraTarget = false;
isBlitRenderPass = false;
profilingSampler = new ProfilingSampler($"Unnamed_{nameof(ScriptableRenderPass)}");
useNativeRenderPass = true;
renderPassQueueIndex = -1;
renderTargetFormat = new GraphicsFormat[]
{
GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None,
GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None
};
}
///
/// Configures Input Requirements for this render pass.
/// This method should be called inside ScriptableRendererFeature.AddRenderPasses.
///
/// ScriptableRenderPassInput containing information about what requirements the pass needs.
///
public void ConfigureInput(ScriptableRenderPassInput passInput)
{
m_Input = passInput;
}
///
/// Configures the Store Action for a color attachment of this render pass.
///
/// RenderBufferStoreAction to use
/// Index of the color attachment
public void ConfigureColorStoreAction(RenderBufferStoreAction storeAction, uint attachmentIndex = 0)
{
m_ColorStoreActions[attachmentIndex] = storeAction;
m_OverriddenColorStoreActions[attachmentIndex] = true;
}
///
/// Configures the Store Actions for all the color attachments of this render pass.
///
/// Array of RenderBufferStoreActions to use
public void ConfigureColorStoreActions(RenderBufferStoreAction[] storeActions)
{
int count = Math.Min(storeActions.Length, m_ColorStoreActions.Length);
for (uint i = 0; i < count; ++i)
{
m_ColorStoreActions[i] = storeActions[i];
m_OverriddenColorStoreActions[i] = true;
}
}
///
/// Configures the Store Action for the depth attachment of this render pass.
///
/// RenderBufferStoreAction to use
public void ConfigureDepthStoreAction(RenderBufferStoreAction storeAction)
{
m_DepthStoreAction = storeAction;
m_OverriddenDepthStoreAction = true;
}
internal void ConfigureInputAttachments(RTHandle input, bool isTransient = false)
{
m_InputAttachments[0] = input;
m_InputAttachmentIsTransient[0] = isTransient;
}
internal void ConfigureInputAttachments(RTHandle[] inputs)
{
m_InputAttachments = inputs;
}
internal void ConfigureInputAttachments(RTHandle[] inputs, bool[] isTransient)
{
ConfigureInputAttachments(inputs);
m_InputAttachmentIsTransient = isTransient;
}
internal void SetInputAttachmentTransient(int idx, bool isTransient)
{
m_InputAttachmentIsTransient[idx] = isTransient;
}
internal bool IsInputAttachmentTransient(int idx)
{
return m_InputAttachmentIsTransient[idx];
}
///
/// Resets render targets to default.
/// This method effectively reset changes done by ConfigureTarget.
///
///
public void ResetTarget()
{
overrideCameraTarget = false;
m_UsesRTHandles = true;
// Reset depth
m_DepthAttachmentId = -1;
m_DepthAttachment = null;
// Reset colors
m_ColorAttachments[0] = null;
m_ColorAttachmentIds[0] = -1;
for (int i = 1; i < m_ColorAttachments.Length; ++i)
{
m_ColorAttachments[i] = null;
m_ColorAttachmentIds[i] = 0;
}
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment identifier.
/// Depth attachment identifier.
///
[Obsolete("Use RTHandles for colorAttachment and depthAttachment")]
public void ConfigureTarget(RenderTargetIdentifier colorAttachment, RenderTargetIdentifier depthAttachment)
{
m_DepthAttachmentId = depthAttachment;
m_DepthAttachment = null;
ConfigureTarget(colorAttachment);
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment handle.
/// Depth attachment handle.
///
public void ConfigureTarget(RTHandle colorAttachment, RTHandle depthAttachment)
{
m_DepthAttachment = depthAttachment;
m_DepthAttachmentId = m_DepthAttachment.nameID;
ConfigureTarget(colorAttachment);
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment identifier.
/// Depth attachment identifier.
///
[Obsolete("Use RTHandles for colorAttachments and depthAttachment")]
public void ConfigureTarget(RenderTargetIdentifier[] colorAttachments, RenderTargetIdentifier depthAttachment)
{
m_UsesRTHandles = false;
overrideCameraTarget = true;
uint nonNullColorBuffers = RenderingUtils.GetValidColorBufferCount(colorAttachments);
if (nonNullColorBuffers > SystemInfo.supportedRenderTargetCount)
Debug.LogError("Trying to set " + nonNullColorBuffers + " renderTargets, which is more than the maximum supported:" + SystemInfo.supportedRenderTargetCount);
m_ColorAttachmentIds = colorAttachments;
m_DepthAttachmentId = depthAttachment;
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment handle.
/// Depth attachment handle.
///
public void ConfigureTarget(RTHandle[] colorAttachments, RTHandle depthAttachment)
{
m_UsesRTHandles = true;
overrideCameraTarget = true;
uint nonNullColorBuffers = RenderingUtils.GetValidColorBufferCount(colorAttachments);
if (nonNullColorBuffers > SystemInfo.supportedRenderTargetCount)
Debug.LogError("Trying to set " + nonNullColorBuffers + " renderTargets, which is more than the maximum supported:" + SystemInfo.supportedRenderTargetCount);
m_ColorAttachments = colorAttachments;
if (m_ColorAttachmentIds.Length != m_ColorAttachments.Length)
m_ColorAttachmentIds = new RenderTargetIdentifier[m_ColorAttachments.Length];
for (var i = 0; i < m_ColorAttachmentIds.Length; ++i)
m_ColorAttachmentIds[i] = new RenderTargetIdentifier(colorAttachments[i].nameID, 0, CubemapFace.Unknown, -1);
m_DepthAttachmentId = depthAttachment.nameID;
m_DepthAttachment = depthAttachment;
}
internal void ConfigureTarget(RTHandle[] colorAttachments, RTHandle depthAttachment, GraphicsFormat[] formats)
{
ConfigureTarget(colorAttachments, depthAttachment);
for (int i = 0; i < formats.Length; ++i)
renderTargetFormat[i] = formats[i];
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment identifier.
///
[Obsolete("Use RTHandle for colorAttachment")]
public void ConfigureTarget(RenderTargetIdentifier colorAttachment)
{
m_UsesRTHandles = false;
overrideCameraTarget = true;
m_ColorAttachmentIds[0] = colorAttachment;
for (int i = 1; i < m_ColorAttachmentIds.Length; ++i)
m_ColorAttachmentIds[i] = 0;
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment handle.
///
public void ConfigureTarget(RTHandle colorAttachment)
{
m_UsesRTHandles = true;
overrideCameraTarget = true;
m_ColorAttachments[0] = colorAttachment;
m_ColorAttachmentIds[0] = new RenderTargetIdentifier(colorAttachment.nameID, 0, CubemapFace.Unknown, -1);
for (int i = 1; i < m_ColorAttachments.Length; ++i)
{
m_ColorAttachments[i] = null;
m_ColorAttachmentIds[i] = 0;
}
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment identifiers.
///
[Obsolete("Use RTHandles for colorAttachments")]
public void ConfigureTarget(RenderTargetIdentifier[] colorAttachments)
{
ConfigureTarget(colorAttachments, k_CameraTarget.nameID);
}
///
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
///
/// Color attachment handle.
///
public void ConfigureTarget(RTHandle[] colorAttachments)
{
ConfigureTarget(colorAttachments, k_CameraTarget);
}
///
/// Configures clearing for the render targets for this render pass. Call this inside Configure.
///
/// ClearFlag containing information about what targets to clear.
/// Clear color.
///
public void ConfigureClear(ClearFlag clearFlag, Color clearColor)
{
m_ClearFlag = clearFlag;
m_ClearColor = clearColor;
}
///
/// This method is called by the renderer before rendering a camera
/// Override this method if you need to to configure render targets and their clear state, and to create temporary render target textures.
/// If a render pass doesn't override this method, this render pass renders to the active Camera's render target.
/// You should never call CommandBuffer.SetRenderTarget. Instead call ConfigureTarget and ConfigureClear.
///
/// CommandBuffer to enqueue rendering commands. This will be executed by the pipeline.
/// Current rendering state information
///
///
public virtual void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{ }
///
/// This method is called by the renderer before executing the render pass.
/// Override this method if you need to to configure render targets and their clear state, and to create temporary render target textures.
/// If a render pass doesn't override this method, this render pass renders to the active Camera's render target.
/// You should never call CommandBuffer.SetRenderTarget. Instead call ConfigureTarget and ConfigureClear.
///
/// CommandBuffer to enqueue rendering commands. This will be executed by the pipeline.
/// Render texture descriptor of the camera render target.
///
///
public virtual void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{ }
///
/// Called upon finish rendering a camera. You can use this callback to release any resources created
/// by this render
/// pass that need to be cleanup once camera has finished rendering.
/// This method be called for all cameras in a camera stack.
///
/// Use this CommandBuffer to cleanup any generated data
public virtual void OnCameraCleanup(CommandBuffer cmd)
{
}
///
/// Called upon finish rendering a camera stack. You can use this callback to release any resources created
/// by this render pass that need to be cleanup once all cameras in the stack have finished rendering.
/// This method will be called once after rendering the last camera in the camera stack.
/// Cameras that don't have an explicit camera stack are also considered stacked rendering.
/// In that case the Base camera is the first and last camera in the stack.
///
/// Use this CommandBuffer to cleanup any generated data
public virtual void OnFinishCameraStackRendering(CommandBuffer cmd)
{ }
///
/// Execute the pass. This is where custom rendering occurs. Specific details are left to the implementation
///
/// Use this render context to issue any draw commands during execution
/// Current rendering state information
public abstract void Execute(ScriptableRenderContext context, ref RenderingData renderingData);
///
/// TODO RENDERGRAPH
///
///
internal virtual void RecordRenderGraph(RenderGraph renderGraph, ref RenderingData renderingData)
{
Debug.LogWarning("RecordRenderGraph is not implemented, the pass " + this.ToString() + " won't be recorded in the current RenderGraph.");
}
///
/// Add a blit command to the context for execution. This changes the active render target in the ScriptableRenderer to
/// destination.
///
/// Command buffer to record command for execution.
/// Source texture or target identifier to blit from.
/// Destination texture or target identifier to blit into. This becomes the renderer active render target.
/// Material to use.
/// Shader pass to use. Default is 0.
///
[Obsolete("Use RTHandles for source and destination")]
public void Blit(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material = null, int passIndex = 0)
{
ScriptableRenderer.SetRenderTarget(cmd, destination, BuiltinRenderTextureType.CameraTarget, clearFlag, clearColor);
cmd.Blit(source, destination, material, passIndex);
}
///
/// Add a blit command to the context for execution. This changes the active render target in the ScriptableRenderer to
/// destination.
///
/// Command buffer to record command for execution.
/// Source texture or target handle to blit from.
/// Destination texture or target handle to blit into. This becomes the renderer active render target.
/// Material to use.
/// Shader pass to use. Default is 0.
///
public void Blit(CommandBuffer cmd, RTHandle source, RTHandle destination, Material material = null, int passIndex = 0)
{
if (material == null)
Blitter.BlitCameraTexture(cmd, source, destination, bilinear: source.rt.filterMode == FilterMode.Bilinear);
else
Blitter.BlitCameraTexture(cmd, source, destination, material, passIndex);
}
///
/// Add a blit command to the context for execution. This applies the material to the color target.
///
/// Command buffer to record command for execution.
/// RenderingData to access the active renderer.
/// Material to use.
/// Shader pass to use. Default is 0.
public void Blit(CommandBuffer cmd, ref RenderingData data, Material material, int passIndex = 0)
{
var renderer = data.cameraData.renderer;
Blit(cmd, renderer.cameraColorTargetHandle, renderer.GetCameraColorFrontBuffer(cmd), material, passIndex);
renderer.SwapColorBuffer(cmd);
}
///
/// Add a blit command to the context for execution. This applies the material to the color target.
///
/// Command buffer to record command for execution.
/// RenderingData to access the active renderer.
/// Source texture or target identifier to blit from.
/// Material to use.
/// Shader pass to use. Default is 0.
public void Blit(CommandBuffer cmd, ref RenderingData data, RTHandle source, Material material, int passIndex = 0)
{
var renderer = data.cameraData.renderer;
Blit(cmd, source, renderer.cameraColorTargetHandle, material, passIndex);
}
///
/// Creates DrawingSettings based on current the rendering state.
///
/// Shader pass tag to render.
/// Current rendering state.
/// Criteria to sort objects being rendered.
///
///
public DrawingSettings CreateDrawingSettings(ShaderTagId shaderTagId, ref RenderingData renderingData, SortingCriteria sortingCriteria)
{
return RenderingUtils.CreateDrawingSettings(shaderTagId, ref renderingData, sortingCriteria);
}
///
/// Creates DrawingSettings based on current rendering state.
///
/// /// List of shader pass tag to render.
/// Current rendering state.
/// Criteria to sort objects being rendered.
///
///
public DrawingSettings CreateDrawingSettings(List shaderTagIdList,
ref RenderingData renderingData, SortingCriteria sortingCriteria)
{
return RenderingUtils.CreateDrawingSettings(shaderTagIdList, ref renderingData, sortingCriteria);
}
///
/// Compares two instances of ScriptableRenderPass by their RenderPassEvent and returns if is executed before .
///
///
///
///
public static bool operator <(ScriptableRenderPass lhs, ScriptableRenderPass rhs)
{
return lhs.renderPassEvent < rhs.renderPassEvent;
}
///
/// Compares two instances of ScriptableRenderPass by their RenderPassEvent and returns if is executed after .
///
///
///
///
public static bool operator >(ScriptableRenderPass lhs, ScriptableRenderPass rhs)
{
return lhs.renderPassEvent > rhs.renderPassEvent;
}
static internal int GetRenderPassEventRange(RenderPassEvent renderPassEvent)
{
int numEvents = RenderPassEventsEnumValues.values.Length;
int currentIndex = 0;
// find the index of the renderPassEvent in the values array
for(int i = 0; i < numEvents; ++i)
{
if (RenderPassEventsEnumValues.values[currentIndex] == (int)renderPassEvent)
break;
currentIndex++;
}
if (currentIndex >= numEvents)
{
Debug.LogError("GetRenderPassEventRange: invalid renderPassEvent value cannot be found in the RenderPassEvent enumeration");
return 0;
}
if (currentIndex + 1 >= numEvents)
return 50; // if this was the last event in the enum, then add 50 as the range
int nextValue = RenderPassEventsEnumValues.values[currentIndex + 1];
return nextValue - (int) renderPassEvent;
}
}
}