ScriptableRenderPass.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine.Scripting.APIUpdating;
  4. namespace UnityEngine.Rendering.Universal
  5. {
  6. // Note: Spaced built-in events so we can add events in between them
  7. // We need to leave room as we sort render passes based on event.
  8. // Users can also inject render pass events in a specific point by doing RenderPassEvent + offset
  9. /// <summary>
  10. /// Controls when the render pass executes.
  11. /// </summary>
  12. [MovedFrom("UnityEngine.Rendering.LWRP")] public enum RenderPassEvent
  13. {
  14. BeforeRendering = 0,
  15. BeforeRenderingShadows = 50,
  16. AfterRenderingShadows = 100,
  17. BeforeRenderingPrepasses = 150,
  18. AfterRenderingPrePasses = 200,
  19. BeforeRenderingOpaques = 250,
  20. AfterRenderingOpaques = 300,
  21. BeforeRenderingSkybox = 350,
  22. AfterRenderingSkybox = 400,
  23. BeforeRenderingTransparents = 450,
  24. AfterRenderingTransparents = 500,
  25. BeforeRenderingPostProcessing = 550,
  26. AfterRenderingPostProcessing = 600,
  27. AfterRendering = 1000,
  28. }
  29. /// <summary>
  30. /// <c>ScriptableRenderPass</c> implements a logical rendering pass that can be used to extend Universal RP renderer.
  31. /// </summary>
  32. [MovedFrom("UnityEngine.Rendering.LWRP")] public abstract class ScriptableRenderPass
  33. {
  34. public RenderPassEvent renderPassEvent { get; set; }
  35. public RenderTargetIdentifier[] colorAttachments
  36. {
  37. get => m_ColorAttachments;
  38. }
  39. public RenderTargetIdentifier colorAttachment
  40. {
  41. get => m_ColorAttachments[0];
  42. }
  43. public RenderTargetIdentifier depthAttachment
  44. {
  45. get => m_DepthAttachment;
  46. }
  47. public ClearFlag clearFlag
  48. {
  49. get => m_ClearFlag;
  50. }
  51. public Color clearColor
  52. {
  53. get => m_ClearColor;
  54. }
  55. internal int eyeIndex { get; set; }
  56. internal bool overrideCameraTarget { get; set; }
  57. internal bool isBlitRenderPass { get; set; }
  58. RenderTargetIdentifier[] m_ColorAttachments = new RenderTargetIdentifier[]{BuiltinRenderTextureType.CameraTarget};
  59. RenderTargetIdentifier m_DepthAttachment = BuiltinRenderTextureType.CameraTarget;
  60. ClearFlag m_ClearFlag = ClearFlag.None;
  61. Color m_ClearColor = Color.black;
  62. public ScriptableRenderPass()
  63. {
  64. renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
  65. m_ColorAttachments = new RenderTargetIdentifier[]{BuiltinRenderTextureType.CameraTarget, 0, 0, 0, 0, 0, 0, 0};
  66. m_DepthAttachment = BuiltinRenderTextureType.CameraTarget;
  67. m_ClearFlag = ClearFlag.None;
  68. m_ClearColor = Color.black;
  69. overrideCameraTarget = false;
  70. isBlitRenderPass = false;
  71. eyeIndex = 0;
  72. }
  73. /// <summary>
  74. /// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
  75. /// This method should be called inside Configure.
  76. /// </summary>
  77. /// <param name="colorAttachment">Color attachment identifier.</param>
  78. /// <param name="depthAttachment">Depth attachment identifier.</param>
  79. /// <seealso cref="Configure"/>
  80. public void ConfigureTarget(RenderTargetIdentifier colorAttachment, RenderTargetIdentifier depthAttachment)
  81. {
  82. m_DepthAttachment = depthAttachment;
  83. ConfigureTarget(colorAttachment);
  84. }
  85. /// <summary>
  86. /// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
  87. /// This method should be called inside Configure.
  88. /// </summary>
  89. /// <param name="colorAttachment">Color attachment identifier.</param>
  90. /// <param name="depthAttachment">Depth attachment identifier.</param>
  91. /// <seealso cref="Configure"/>
  92. public void ConfigureTarget(RenderTargetIdentifier[] colorAttachments, RenderTargetIdentifier depthAttachment)
  93. {
  94. overrideCameraTarget = true;
  95. uint nonNullColorBuffers = RenderingUtils.GetValidColorBufferCount(colorAttachments);
  96. if( nonNullColorBuffers > SystemInfo.supportedRenderTargetCount)
  97. Debug.LogError("Trying to set " + nonNullColorBuffers + " renderTargets, which is more than the maximum supported:" + SystemInfo.supportedRenderTargetCount);
  98. m_ColorAttachments = colorAttachments;
  99. m_DepthAttachment = depthAttachment;
  100. }
  101. /// <summary>
  102. /// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
  103. /// This method should be called inside Configure.
  104. /// </summary>
  105. /// <param name="colorAttachment">Color attachment identifier.</param>
  106. /// <seealso cref="Configure"/>
  107. public void ConfigureTarget(RenderTargetIdentifier colorAttachment)
  108. {
  109. overrideCameraTarget = true;
  110. m_ColorAttachments[0] = colorAttachment;
  111. for (int i = 1; i < m_ColorAttachments.Length; ++i)
  112. m_ColorAttachments[i] = 0;
  113. }
  114. /// <summary>
  115. /// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
  116. /// This method should be called inside Configure.
  117. /// </summary>
  118. /// <param name="colorAttachment">Color attachment identifier.</param>
  119. /// <seealso cref="Configure"/>
  120. public void ConfigureTarget(RenderTargetIdentifier[] colorAttachments)
  121. {
  122. ConfigureTarget(colorAttachments, BuiltinRenderTextureType.CameraTarget);
  123. }
  124. /// <summary>
  125. /// Configures clearing for the render targets for this render pass. Call this inside Configure.
  126. /// </summary>
  127. /// <param name="clearFlag">ClearFlag containing information about what targets to clear.</param>
  128. /// <param name="clearColor">Clear color.</param>
  129. /// <seealso cref="Configure"/>
  130. public void ConfigureClear(ClearFlag clearFlag, Color clearColor)
  131. {
  132. m_ClearFlag = clearFlag;
  133. m_ClearColor = clearColor;
  134. }
  135. /// <summary>
  136. /// This method is called by the renderer before executing the render pass.
  137. /// Override this method if you need to to configure render targets and their clear state, and to create temporary render target textures.
  138. /// If a render pass doesn't override this method, this render pass renders to the active Camera's render target.
  139. /// You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
  140. /// </summary>
  141. /// <param name="cmd">CommandBuffer to enqueue rendering commands. This will be executed by the pipeline.</param>
  142. /// <param name="cameraTextureDescriptor">Render texture descriptor of the camera render target.</param>
  143. /// <seealso cref="ConfigureTarget"/>
  144. /// <seealso cref="ConfigureClear"/>
  145. public virtual void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
  146. {}
  147. /// <summary>
  148. /// Called upon finish rendering a camera. You can use this callback to release any resources created
  149. /// by this render
  150. /// pass that need to be cleanup once camera has finished rendering.
  151. /// This method be called for all cameras in a camera stack.
  152. /// </summary>
  153. /// <param name="cmd">Use this CommandBuffer to cleanup any generated data</param>
  154. public virtual void FrameCleanup(CommandBuffer cmd)
  155. {}
  156. /// <summary>
  157. /// Called upon finish rendering a camera stack. You can use this callback to release any resources created
  158. /// by this render pass that need to be cleanup once all cameras in the stack have finished rendering.
  159. /// This method will be called once after rendering the last camera in the camera stack.
  160. /// Cameras that don't have an explicit camera stack are also considered stacked rendering.
  161. /// In that case the Base camera is the first and last camera in the stack.
  162. /// </summary>
  163. /// <param name="cmd">Use this CommandBuffer to cleanup any generated data</param>
  164. /// NB: We are not so sure about this API. Thus, why internal.
  165. internal virtual void OnFinishCameraStackRendering(CommandBuffer cmd)
  166. {}
  167. /// <summary>
  168. /// Execute the pass. This is where custom rendering occurs. Specific details are left to the implementation
  169. /// </summary>
  170. /// <param name="context">Use this render context to issue any draw commands during execution</param>
  171. /// <param name="renderingData">Current rendering state information</param>
  172. public abstract void Execute(ScriptableRenderContext context, ref RenderingData renderingData);
  173. /// <summary>
  174. /// Add a blit command to the context for execution. This changes the active render target in the ScriptableRenderer to
  175. /// destination.
  176. /// </summary>
  177. /// <param name="cmd">Command buffer to record command for execution.</param>
  178. /// <param name="source">Source texture or target identifier to blit from.</param>
  179. /// <param name="destination">Destination texture or target identifier to blit into. This becomes the renderer active render target.</param>
  180. /// <param name="material">Material to use.</param>
  181. /// <param name="passIndex">Shader pass to use. Default is 0.</param>
  182. /// <seealso cref="ScriptableRenderer"/>
  183. public void Blit(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material = null, int passIndex = 0)
  184. {
  185. ScriptableRenderer.SetRenderTarget(cmd, destination, BuiltinRenderTextureType.CameraTarget, clearFlag, clearColor);
  186. cmd.Blit(source, destination, material, passIndex);
  187. }
  188. /// <summary>
  189. /// Adds a Render Post-processing command for execution. This changes the active render target in the ScriptableRenderer to destination.
  190. /// This method is only used for compatibility with the Post-processing V2 package.
  191. /// </summary>
  192. /// <param name="cmd">Command buffer to record command for execution.</param>
  193. /// <param name="cameraData">Camera rendering data.</param>
  194. /// <param name="sourceDescriptor">Render texture descriptor for source.</param>
  195. /// <param name="source">Source texture or render target identifier.</param>
  196. /// <param name="destination">Destination texture or render target identifier.</param>
  197. /// <param name="opaqueOnly">If true, only renders opaque post-processing effects. Otherwise, renders before and after stack post-processing effects.</param>
  198. /// <param name="flip">If true, flips image vertically.</param>
  199. [Obsolete("RenderPostProcessing only works with Post-processing v2. The use of the Post-processing Stack V2 is deprecated in the Universal Render Pipeline.")]
  200. public void RenderPostProcessing(CommandBuffer cmd, ref CameraData cameraData, RenderTextureDescriptor sourceDescriptor, RenderTargetIdentifier source, RenderTargetIdentifier destination, bool opaqueOnly, bool flip)
  201. {
  202. #if POST_PROCESSING_STACK_2_0_0_OR_NEWER
  203. ScriptableRenderer.ConfigureActiveTarget(destination, BuiltinRenderTextureType.CameraTarget);
  204. RenderingUtils.RenderPostProcessingCompat(cmd, ref cameraData, sourceDescriptor, source, destination, opaqueOnly, flip);
  205. #endif
  206. }
  207. /// <summary>
  208. /// Creates <c>DrawingSettings</c> based on current the rendering state.
  209. /// </summary>
  210. /// <param name="shaderTagId">Shader pass tag to render.</param>
  211. /// <param name="renderingData">Current rendering state.</param>
  212. /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
  213. /// <returns></returns>
  214. /// <seealso cref="DrawingSettings"/>
  215. public DrawingSettings CreateDrawingSettings(ShaderTagId shaderTagId, ref RenderingData renderingData, SortingCriteria sortingCriteria)
  216. {
  217. Camera camera = renderingData.cameraData.camera;
  218. SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortingCriteria };
  219. DrawingSettings settings = new DrawingSettings(shaderTagId, sortingSettings)
  220. {
  221. perObjectData = renderingData.perObjectData,
  222. mainLightIndex = renderingData.lightData.mainLightIndex,
  223. enableDynamicBatching = renderingData.supportsDynamicBatching,
  224. // Disable instancing for preview cameras. This is consistent with the built-in forward renderer. Also fixes case 1127324.
  225. enableInstancing = camera.cameraType == CameraType.Preview ? false : true,
  226. };
  227. return settings;
  228. }
  229. /// <summary>
  230. /// Creates <c>DrawingSettings</c> based on current rendering state.
  231. /// </summary>
  232. /// /// <param name="shaderTagIdList">List of shader pass tag to render.</param>
  233. /// <param name="renderingData">Current rendering state.</param>
  234. /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
  235. /// <returns></returns>
  236. /// <seealso cref="DrawingSettings"/>
  237. public DrawingSettings CreateDrawingSettings(List<ShaderTagId> shaderTagIdList,
  238. ref RenderingData renderingData, SortingCriteria sortingCriteria)
  239. {
  240. if (shaderTagIdList == null || shaderTagIdList.Count == 0)
  241. {
  242. Debug.LogWarning("ShaderTagId list is invalid. DrawingSettings is created with default pipeline ShaderTagId");
  243. return CreateDrawingSettings(new ShaderTagId("UniversalPipeline"), ref renderingData, sortingCriteria);
  244. }
  245. DrawingSettings settings = CreateDrawingSettings(shaderTagIdList[0], ref renderingData, sortingCriteria);
  246. for (int i = 1; i < shaderTagIdList.Count; ++i)
  247. settings.SetShaderPassName(i, shaderTagIdList[i]);
  248. return settings;
  249. }
  250. public static bool operator <(ScriptableRenderPass lhs, ScriptableRenderPass rhs)
  251. {
  252. return lhs.renderPassEvent < rhs.renderPassEvent;
  253. }
  254. public static bool operator >(ScriptableRenderPass lhs, ScriptableRenderPass rhs)
  255. {
  256. return lhs.renderPassEvent > rhs.renderPassEvent;
  257. }
  258. // TODO: Remove this. Currently only used by FinalBlit pass.
  259. internal void SetRenderTarget(
  260. CommandBuffer cmd,
  261. RenderTargetIdentifier colorAttachment,
  262. RenderBufferLoadAction colorLoadAction,
  263. RenderBufferStoreAction colorStoreAction,
  264. ClearFlag clearFlags,
  265. Color clearColor,
  266. TextureDimension dimension)
  267. {
  268. if (dimension == TextureDimension.Tex2DArray)
  269. CoreUtils.SetRenderTarget(cmd, colorAttachment, clearFlags, clearColor, 0, CubemapFace.Unknown, -1);
  270. else
  271. CoreUtils.SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction, clearFlags, clearColor);
  272. }
  273. }
  274. }