using System; using System.Collections.Generic; using UnityEngine.Scripting.APIUpdating; namespace UnityEngine.Rendering.Universal { // 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. /// [MovedFrom("UnityEngine.Rendering.LWRP")] public enum RenderPassEvent { BeforeRendering = 0, BeforeRenderingShadows = 50, AfterRenderingShadows = 100, BeforeRenderingPrepasses = 150, AfterRenderingPrePasses = 200, BeforeRenderingOpaques = 250, AfterRenderingOpaques = 300, BeforeRenderingSkybox = 350, AfterRenderingSkybox = 400, BeforeRenderingTransparents = 450, AfterRenderingTransparents = 500, BeforeRenderingPostProcessing = 550, AfterRenderingPostProcessing = 600, AfterRendering = 1000, } /// /// ScriptableRenderPass implements a logical rendering pass that can be used to extend LWRP renderer. /// [MovedFrom("UnityEngine.Rendering.LWRP")] public abstract class ScriptableRenderPass { public RenderPassEvent renderPassEvent { get; set; } public RenderTargetIdentifier colorAttachment { get => m_ColorAttachment; } public RenderTargetIdentifier depthAttachment { get => m_DepthAttachment; } public ClearFlag clearFlag { get => m_ClearFlag; } public Color clearColor { get => m_ClearColor; } internal bool overrideCameraTarget { get; set; } internal bool isBlitRenderPass { get; set; } RenderTargetIdentifier m_ColorAttachment = BuiltinRenderTextureType.CameraTarget; RenderTargetIdentifier m_DepthAttachment = BuiltinRenderTextureType.CameraTarget; ClearFlag m_ClearFlag = ClearFlag.None; Color m_ClearColor = Color.black; public ScriptableRenderPass() { renderPassEvent = RenderPassEvent.AfterRenderingOpaques; m_ColorAttachment = BuiltinRenderTextureType.CameraTarget; m_DepthAttachment = BuiltinRenderTextureType.CameraTarget; m_ClearFlag = ClearFlag.None; m_ClearColor = Color.black; overrideCameraTarget = false; isBlitRenderPass = false; } /// /// 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. /// public void ConfigureTarget(RenderTargetIdentifier colorAttachment, RenderTargetIdentifier depthAttachment) { overrideCameraTarget = true; m_ColorAttachment = colorAttachment; m_DepthAttachment = depthAttachment; } /// /// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget. /// This method should be called inside Configure. /// /// Color attachment identifier. /// public void ConfigureTarget(RenderTargetIdentifier colorAttachment) { overrideCameraTarget = true; m_ColorAttachment = colorAttachment; m_DepthAttachment = BuiltinRenderTextureType.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 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) {} /// /// Cleanup any allocated data that was created during the execution of the pass. /// /// Use this CommandBuffer to cleanup any generated data public virtual void FrameCleanup(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); /// /// 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. /// 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); } /// /// Adds a Render Post-processing command for execution. This changes the active render target in the ScriptableRenderer to destination. /// /// Command buffer to record command for execution. /// Camera rendering data. /// Render texture descriptor for source. /// Source texture or render target identifier. /// Destination texture or render target identifier. /// If true, only renders opaque post-processing effects. Otherwise, renders before and after stack post-processing effects. /// If true, flips image vertically. #if POST_PROCESSING_STACK_2_0_0_OR_NEWER [Obsolete("The use of the Post-processing Stack V2 is deprecated in the Universal Render Pipeline. Use the builtin post-processing effects instead.")] public void RenderPostProcessing(CommandBuffer cmd, ref CameraData cameraData, RenderTextureDescriptor sourceDescriptor, RenderTargetIdentifier source, RenderTargetIdentifier destination, bool opaqueOnly, bool flip) { } #endif /// /// 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) { Camera camera = renderingData.cameraData.camera; SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortingCriteria }; DrawingSettings settings = new DrawingSettings(shaderTagId, sortingSettings) { perObjectData = renderingData.perObjectData, mainLightIndex = renderingData.lightData.mainLightIndex, enableDynamicBatching = renderingData.supportsDynamicBatching, // Disable instancing for preview cameras. This is consistent with the built-in forward renderer. Also fixes case 1127324. enableInstancing = camera.cameraType == CameraType.Preview ? false : true, }; return settings; } /// /// 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) { if (shaderTagIdList == null || shaderTagIdList.Count == 0) { Debug.LogWarning("ShaderTagId list is invalid. DrawingSettings is created with default pipeline ShaderTagId"); return CreateDrawingSettings(new ShaderTagId("UniversalPipeline"), ref renderingData, sortingCriteria); } DrawingSettings settings = CreateDrawingSettings(shaderTagIdList[0], ref renderingData, sortingCriteria); for (int i = 1; i < shaderTagIdList.Count; ++i) settings.SetShaderPassName(i, shaderTagIdList[i]); return settings; } public static bool operator <(ScriptableRenderPass lhs, ScriptableRenderPass rhs) { return lhs.renderPassEvent < rhs.renderPassEvent; } public static bool operator >(ScriptableRenderPass lhs, ScriptableRenderPass rhs) { return lhs.renderPassEvent > rhs.renderPassEvent; } // TODO: Remove this. Currently only used by FinalBlit pass. internal void SetRenderTarget( CommandBuffer cmd, RenderTargetIdentifier colorAttachment, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, ClearFlag clearFlags, Color clearColor, TextureDimension dimension) { if (dimension == TextureDimension.Tex2DArray) CoreUtils.SetRenderTarget(cmd, colorAttachment, clearFlags, clearColor, 0, CubemapFace.Unknown, -1); else CoreUtils.SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction, clearFlags, clearColor); } } }