2024-11-01 16:55:46 +08:00
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
{
/// <summary>
/// Input requirements for <c>ScriptableRenderPass</c>.
/// </summary>
/// <seealso cref="ConfigureInput"/>
[Flags]
public enum ScriptableRenderPassInput
{
/// <summary>
/// Used when a <c>ScriptableRenderPass</c> does not require any texture.
/// </summary>
None = 0 ,
/// <summary>
/// Used when a <c>ScriptableRenderPass</c> requires a depth texture.
/// </summary>
Depth = 1 < < 0 ,
/// <summary>
/// Used when a <c>ScriptableRenderPass</c> requires a normal texture.
/// </summary>
Normal = 1 < < 1 ,
/// <summary>
/// Used when a <c>ScriptableRenderPass</c> requires a color texture.
/// </summary>
Color = 1 < < 2 ,
/// <summary>
/// Used when a <c>ScriptableRenderPass</c> requires a motion vectors texture.
/// </summary>
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
/// <summary>
/// Controls when the render pass executes.
/// </summary>
public enum RenderPassEvent
{
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> 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.
/// </summary>
BeforeRendering = 0 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering shadowmaps.
/// Camera matrices and stereo rendering are not setup this point.
/// </summary>
BeforeRenderingShadows = 50 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering shadowmaps.
/// Camera matrices and stereo rendering are not setup this point.
/// </summary>
AfterRenderingShadows = 100 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering prepasses, f.ex, depth prepass.
/// Camera matrices and stereo rendering are already setup at this point.
/// </summary>
BeforeRenderingPrePasses = 150 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering prepasses, f.ex, depth prepass.
/// Camera matrices and stereo rendering are already setup at this point.
/// </summary>
AfterRenderingPrePasses = 200 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering gbuffer pass.
/// </summary>
BeforeRenderingGbuffer = 210 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering gbuffer pass.
/// </summary>
AfterRenderingGbuffer = 220 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering deferred shading pass.
/// </summary>
BeforeRenderingDeferredLights = 230 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering deferred shading pass.
/// </summary>
AfterRenderingDeferredLights = 240 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering opaque objects.
/// </summary>
BeforeRenderingOpaques = 250 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering opaque objects.
/// </summary>
AfterRenderingOpaques = 300 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering the sky.
/// </summary>
BeforeRenderingSkybox = 350 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering the sky.
/// </summary>
AfterRenderingSkybox = 400 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering transparent objects.
/// </summary>
BeforeRenderingTransparents = 450 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering transparent objects.
/// </summary>
AfterRenderingTransparents = 500 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> before rendering post-processing effects.
/// </summary>
BeforeRenderingPostProcessing = 550 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering post-processing effects but before final blit, post-processing AA effects and color grading.
/// </summary>
AfterRenderingPostProcessing = 600 ,
/// <summary>
/// Executes a <c>ScriptableRenderPass</c> after rendering all effects.
/// </summary>
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 + + ;
}
}
}
/// <summary>
/// <c>ScriptableRenderPass</c> implements a logical rendering pass that can be used to extend Universal RP renderer.
/// </summary>
public abstract partial class ScriptableRenderPass
{
/// <summary>
/// RTHandle alias for BuiltinRenderTextureType.CameraTarget which is the backbuffer.
/// </summary>
static public RTHandle k_CameraTarget = RTHandles . Alloc ( BuiltinRenderTextureType . CameraTarget ) ;
/// <summary>
/// The event when the render pass executes.
/// </summary>
public RenderPassEvent renderPassEvent { get ; set ; }
/// <summary>
/// The render target identifiers for color attachments.
/// This is obsolete, use colorAttachmentHandles instead.
/// </summary>
[Obsolete("Use colorAttachmentHandles")]
public RenderTargetIdentifier [ ] colorAttachments
{
get = > m_ColorAttachmentIds ;
}
/// <summary>
/// The render target identifier for color attachment.
/// This is obsolete, use colorAttachmentHandle instead.
/// </summary>
[Obsolete("Use colorAttachmentHandle")]
public RenderTargetIdentifier colorAttachment
{
get = > m_ColorAttachmentIds [ 0 ] ;
}
/// <summary>
/// The render target identifier for depth attachment.
/// This is obsolete, use depthAttachmentHandle instead.
/// </summary>
[Obsolete("Use depthAttachmentHandle")]
public RenderTargetIdentifier depthAttachment
{
get = > m_UsesRTHandles ? new RenderTargetIdentifier ( m_DepthAttachment . nameID , 0 , CubemapFace . Unknown , - 1 ) : m_DepthAttachmentId ;
}
/// <summary>
/// List for the g-buffer attachment handles.
/// </summary>
public RTHandle [ ] colorAttachmentHandles
{
get = > m_ColorAttachments ;
}
/// <summary>
/// The main color attachment handle.
/// </summary>
public RTHandle colorAttachmentHandle
{
get = > m_ColorAttachments [ 0 ] ;
}
/// <summary>
/// The depth attachment handle.
/// </summary>
public RTHandle depthAttachmentHandle
{
get = > m_DepthAttachment ;
}
/// <summary>
/// The store actions for Color.
/// </summary>
public RenderBufferStoreAction [ ] colorStoreActions
{
get = > m_ColorStoreActions ;
}
/// <summary>
/// The store actions for Depth.
/// </summary>
public RenderBufferStoreAction depthStoreAction
{
get = > m_DepthStoreAction ;
}
internal bool [ ] overriddenColorStoreActions
{
get = > m_OverriddenColorStoreActions ;
}
internal bool overriddenDepthStoreAction
{
get = > m_OverriddenDepthStoreAction ;
}
/// <summary>
/// The input requirements for the <c>ScriptableRenderPass</c>, which has been set using <c>ConfigureInput</c>
/// </summary>
/// <seealso cref="ConfigureInput"/>
public ScriptableRenderPassInput input
{
get = > m_Input ;
}
/// <summary>
/// The flag to use when clearing.
/// </summary>
/// <seealso cref="ClearFlag"/>
public ClearFlag clearFlag
{
get = > m_ClearFlag ;
}
/// <summary>
/// The color value to use when clearing.
/// </summary>
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 ;
/// <summary>
/// A ProfilingSampler for the entire render pass. Used as a profiling name by <c>ScriptableRenderer</c> when executing the pass.
/// Default is <c>Unnamed_ScriptableRenderPass</c>.
/// Set <c>base.profilingSampler</c> from the sub-class constructor to set a profiling name for a custom <c>ScriptableRenderPass</c>.
/// </summary>
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 < int > m_ColorAttachmentIndices ;
internal NativeArray < int > 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 ;
}
/// <summary>
/// Creates a new <c>ScriptableRenderPass"</c> instance.
/// </summary>
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
} ;
}
/// <summary>
/// Configures Input Requirements for this render pass.
/// This method should be called inside <c>ScriptableRendererFeature.AddRenderPasses</c>.
/// </summary>
/// <param name="passInput">ScriptableRenderPassInput containing information about what requirements the pass needs.</param>
/// <seealso cref="ScriptableRendererFeature.AddRenderPasses"/>
public void ConfigureInput ( ScriptableRenderPassInput passInput )
{
m_Input = passInput ;
}
/// <summary>
/// Configures the Store Action for a color attachment of this render pass.
/// </summary>
/// <param name="storeAction">RenderBufferStoreAction to use</param>
/// <param name="attachmentIndex">Index of the color attachment</param>
public void ConfigureColorStoreAction ( RenderBufferStoreAction storeAction , uint attachmentIndex = 0 )
{
m_ColorStoreActions [ attachmentIndex ] = storeAction ;
m_OverriddenColorStoreActions [ attachmentIndex ] = true ;
}
/// <summary>
/// Configures the Store Actions for all the color attachments of this render pass.
/// </summary>
/// <param name="storeActions">Array of RenderBufferStoreActions to use</param>
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 ;
}
}
/// <summary>
/// Configures the Store Action for the depth attachment of this render pass.
/// </summary>
/// <param name="storeAction">RenderBufferStoreAction to use</param>
public void ConfigureDepthStoreAction ( RenderBufferStoreAction storeAction )
{
m_DepthStoreAction = storeAction ;
m_OverriddenDepthStoreAction = true ;
}
2026-02-02 15:26:23 +08:00
public void ConfigureInputAttachments ( RTHandle input , bool isTransient = false )
2024-11-01 16:55:46 +08:00
{
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 ] ;
}
/// <summary>
/// Resets render targets to default.
/// This method effectively reset changes done by ConfigureTarget.
/// </summary>
/// <seealso cref="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 ;
}
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachment">Color attachment identifier.</param>
/// <param name="depthAttachment">Depth attachment identifier.</param>
/// <seealso cref="Configure"/>
[Obsolete("Use RTHandles for colorAttachment and depthAttachment")]
public void ConfigureTarget ( RenderTargetIdentifier colorAttachment , RenderTargetIdentifier depthAttachment )
{
m_DepthAttachmentId = depthAttachment ;
m_DepthAttachment = null ;
ConfigureTarget ( colorAttachment ) ;
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachment">Color attachment handle.</param>
/// <param name="depthAttachment">Depth attachment handle.</param>
/// <seealso cref="Configure"/>
public void ConfigureTarget ( RTHandle colorAttachment , RTHandle depthAttachment )
{
m_DepthAttachment = depthAttachment ;
m_DepthAttachmentId = m_DepthAttachment . nameID ;
ConfigureTarget ( colorAttachment ) ;
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachments">Color attachment identifier.</param>
/// <param name="depthAttachment">Depth attachment identifier.</param>
/// <seealso cref="Configure"/>
[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 ;
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachments">Color attachment handle.</param>
/// <param name="depthAttachment">Depth attachment handle.</param>
/// <seealso cref="Configure"/>
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 ] ;
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachment">Color attachment identifier.</param>
/// <seealso cref="Configure"/>
[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 ;
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachment">Color attachment handle.</param>
/// <seealso cref="Configure"/>
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 ;
}
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachments">Color attachment identifiers.</param>
/// <seealso cref="Configure"/>
[Obsolete("Use RTHandles for colorAttachments")]
public void ConfigureTarget ( RenderTargetIdentifier [ ] colorAttachments )
{
ConfigureTarget ( colorAttachments , k_CameraTarget . nameID ) ;
}
/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
/// </summary>
/// <param name="colorAttachments">Color attachment handle.</param>
/// <seealso cref="Configure"/>
public void ConfigureTarget ( RTHandle [ ] colorAttachments )
{
ConfigureTarget ( colorAttachments , k_CameraTarget ) ;
}
/// <summary>
/// Configures clearing for the render targets for this render pass. Call this inside Configure.
/// </summary>
/// <param name="clearFlag">ClearFlag containing information about what targets to clear.</param>
/// <param name="clearColor">Clear color.</param>
/// <seealso cref="Configure"/>
public void ConfigureClear ( ClearFlag clearFlag , Color clearColor )
{
m_ClearFlag = clearFlag ;
m_ClearColor = clearColor ;
}
/// <summary>
/// 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 <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
/// </summary>
/// <param name="cmd">CommandBuffer to enqueue rendering commands. This will be executed by the pipeline.</param>
/// <param name="renderingData">Current rendering state information</param>
/// <seealso cref="ConfigureTarget"/>
/// <seealso cref="ConfigureClear"/>
public virtual void OnCameraSetup ( CommandBuffer cmd , ref RenderingData renderingData )
{ }
/// <summary>
/// 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 <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
/// </summary>
/// <param name="cmd">CommandBuffer to enqueue rendering commands. This will be executed by the pipeline.</param>
/// <param name="cameraTextureDescriptor">Render texture descriptor of the camera render target.</param>
/// <seealso cref="ConfigureTarget"/>
/// <seealso cref="ConfigureClear"/>
public virtual void Configure ( CommandBuffer cmd , RenderTextureDescriptor cameraTextureDescriptor )
{ }
/// <summary>
/// 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 should be called for all cameras in a camera stack.
/// </summary>
/// <param name="cmd">Use this CommandBuffer to cleanup any generated data</param>
public virtual void OnCameraCleanup ( CommandBuffer cmd )
{
}
/// <summary>
/// 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.
/// </summary>
/// <param name="cmd">Use this CommandBuffer to cleanup any generated data</param>
public virtual void OnFinishCameraStackRendering ( CommandBuffer cmd )
{ }
/// <summary>
/// Execute the pass. This is where custom rendering occurs. Specific details are left to the implementation
/// </summary>
/// <param name="context">Use this render context to issue any draw commands during execution</param>
/// <param name="renderingData">Current rendering state information</param>
public abstract void Execute ( ScriptableRenderContext context , ref RenderingData renderingData ) ;
/// <summary>
/// TODO RENDERGRAPH
/// </summary>
/// <param name="renderingData"></param>
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." ) ;
}
/// <summary>
/// Add a blit command to the context for execution. This changes the active render target in the ScriptableRenderer to
/// destination.
/// </summary>
/// <param name="cmd">Command buffer to record command for execution.</param>
/// <param name="source">Source texture or target identifier to blit from.</param>
/// <param name="destination">Destination texture or target identifier to blit into. This becomes the renderer active render target.</param>
/// <param name="material">Material to use.</param>
/// <param name="passIndex">Shader pass to use. Default is 0.</param>
/// <seealso cref="ScriptableRenderer"/>
[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 ) ;
}
/// <summary>
/// Add a blit command to the context for execution. This changes the active render target in the ScriptableRenderer to
/// destination.
/// </summary>
/// <param name="cmd">Command buffer to record command for execution.</param>
/// <param name="source">Source texture or target handle to blit from.</param>
/// <param name="destination">Destination texture or target handle to blit into. This becomes the renderer active render target.</param>
/// <param name="material">Material to use.</param>
/// <param name="passIndex">Shader pass to use. Default is 0.</param>
/// <seealso cref="ScriptableRenderer"/>
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 ) ;
}
/// <summary>
/// Add a blit command to the context for execution. This applies the material to the color target.
/// </summary>
/// <param name="cmd">Command buffer to record command for execution.</param>
/// <param name="data">RenderingData to access the active renderer.</param>
/// <param name="material">Material to use.</param>
/// <param name="passIndex">Shader pass to use. Default is 0.</param>
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 ) ;
}
/// <summary>
/// Add a blit command to the context for execution. This applies the material to the color target.
/// </summary>
/// <param name="cmd">Command buffer to record command for execution.</param>
/// <param name="data">RenderingData to access the active renderer.</param>
/// <param name="source">Source texture or target identifier to blit from.</param>
/// <param name="material">Material to use.</param>
/// <param name="passIndex">Shader pass to use. Default is 0.</param>
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 ) ;
}
/// <summary>
/// Creates <c>DrawingSettings</c> based on current the rendering state.
/// </summary>
/// <param name="shaderTagId">Shader pass tag to render.</param>
/// <param name="renderingData">Current rendering state.</param>
/// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
/// <returns></returns>
/// <seealso cref="DrawingSettings"/>
public DrawingSettings CreateDrawingSettings ( ShaderTagId shaderTagId , ref RenderingData renderingData , SortingCriteria sortingCriteria )
{
return RenderingUtils . CreateDrawingSettings ( shaderTagId , ref renderingData , sortingCriteria ) ;
}
/// <summary>
/// Creates <c>DrawingSettings</c> based on current rendering state.
/// </summary>
/// /// <param name="shaderTagIdList">List of shader pass tag to render.</param>
/// <param name="renderingData">Current rendering state.</param>
/// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
/// <returns></returns>
/// <seealso cref="DrawingSettings"/>
public DrawingSettings CreateDrawingSettings ( List < ShaderTagId > shaderTagIdList ,
ref RenderingData renderingData , SortingCriteria sortingCriteria )
{
return RenderingUtils . CreateDrawingSettings ( shaderTagIdList , ref renderingData , sortingCriteria ) ;
}
/// <summary>
/// Compares two instances of <c>ScriptableRenderPass</c> by their <c>RenderPassEvent</c> and returns if <paramref name="lhs"/> is executed before <paramref name="rhs"/>.
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
/// <returns></returns>
public static bool operator < ( ScriptableRenderPass lhs , ScriptableRenderPass rhs )
{
return lhs . renderPassEvent < rhs . renderPassEvent ;
}
/// <summary>
/// Compares two instances of <c>ScriptableRenderPass</c> by their <c>RenderPassEvent</c> and returns if <paramref name="lhs"/> is executed after <paramref name="rhs"/>.
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
/// <returns></returns>
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 ;
}
}
}