No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ScriptableRenderer.cs 121KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370
  1. using System;
  2. using System.Diagnostics;
  3. using System.Collections.Generic;
  4. using Unity.Collections;
  5. using UnityEditor;
  6. using UnityEngine.Experimental.Rendering;
  7. using UnityEngine.Rendering.RenderGraphModule;
  8. namespace UnityEngine.Rendering.Universal
  9. {
  10. /// <summary>
  11. /// Class <c>ScriptableRenderer</c> implements a rendering strategy. It describes how culling and lighting works and
  12. /// the effects supported.
  13. ///
  14. /// TODO RENDERGRAPH: UPDATE THIS DOC FOR THE RENDERGRAPH PATH
  15. /// A renderer can be used for all cameras or be overridden on a per-camera basis. It will implement light culling and setup
  16. /// and describe a list of <c>ScriptableRenderPass</c> to execute in a frame. The renderer can be extended to support more effect with additional
  17. /// <c>ScriptableRendererFeature</c>. Resources for the renderer are serialized in <c>ScriptableRendererData</c>.
  18. ///
  19. /// The renderer resources are serialized in <c>ScriptableRendererData</c>.
  20. /// <seealso cref="ScriptableRendererData"/>
  21. /// <seealso cref="ScriptableRendererFeature"/>
  22. /// <seealso cref="ScriptableRenderPass"/>
  23. /// </summary>
  24. public abstract partial class ScriptableRenderer : IDisposable
  25. {
  26. private static partial class Profiling
  27. {
  28. private const string k_Name = nameof(ScriptableRenderer);
  29. public static readonly ProfilingSampler setPerCameraShaderVariables = new ProfilingSampler($"{k_Name}.{nameof(SetPerCameraShaderVariables)}");
  30. public static readonly ProfilingSampler sortRenderPasses = new ProfilingSampler($"Sort Render Passes");
  31. public static readonly ProfilingSampler recordRenderGraph = new ProfilingSampler($"On Record Render Graph");
  32. public static readonly ProfilingSampler setupLights = new ProfilingSampler($"{k_Name}.{nameof(SetupLights)}");
  33. public static readonly ProfilingSampler setupCamera = new ProfilingSampler($"Setup Camera Properties");
  34. public static readonly ProfilingSampler vfxProcessCamera = new ProfilingSampler($"VFX Process Camera");
  35. public static readonly ProfilingSampler addRenderPasses = new ProfilingSampler($"{k_Name}.{nameof(AddRenderPasses)}");
  36. public static readonly ProfilingSampler setupRenderPasses = new ProfilingSampler($"{k_Name}.{nameof(SetupRenderPasses)}");
  37. public static readonly ProfilingSampler clearRenderingState = new ProfilingSampler($"{k_Name}.{nameof(ClearRenderingState)}");
  38. public static readonly ProfilingSampler internalStartRendering = new ProfilingSampler($"{k_Name}.{nameof(InternalStartRendering)}");
  39. public static readonly ProfilingSampler internalFinishRenderingCommon = new ProfilingSampler($"{k_Name}.{nameof(InternalFinishRenderingCommon)}");
  40. public static readonly ProfilingSampler drawGizmos = new ProfilingSampler($"{nameof(DrawGizmos)}");
  41. public static readonly ProfilingSampler drawWireOverlay = new ProfilingSampler($"{nameof(DrawWireOverlay)}");
  42. internal static readonly ProfilingSampler beginXRRendering = new ProfilingSampler($"Begin XR Rendering");
  43. internal static readonly ProfilingSampler endXRRendering = new ProfilingSampler($"End XR Rendering");
  44. internal static readonly ProfilingSampler initRenderGraphFrame = new ProfilingSampler($"Initialize Frame");
  45. internal static readonly ProfilingSampler setEditorTarget = new ProfilingSampler($"Set Editor Target");
  46. public static class RenderBlock
  47. {
  48. private const string k_Name = nameof(RenderPassBlock);
  49. public static readonly ProfilingSampler beforeRendering = new ProfilingSampler($"{k_Name}.{nameof(RenderPassBlock.BeforeRendering)}");
  50. public static readonly ProfilingSampler mainRenderingOpaque = new ProfilingSampler($"{k_Name}.{nameof(RenderPassBlock.MainRenderingOpaque)}");
  51. public static readonly ProfilingSampler mainRenderingTransparent = new ProfilingSampler($"{k_Name}.{nameof(RenderPassBlock.MainRenderingTransparent)}");
  52. public static readonly ProfilingSampler afterRendering = new ProfilingSampler($"{k_Name}.{nameof(RenderPassBlock.AfterRendering)}");
  53. }
  54. public static class RenderPass
  55. {
  56. private const string k_Name = nameof(ScriptableRenderPass);
  57. // Disable obsolete warning for internal usage
  58. #pragma warning disable CS0618
  59. public static readonly ProfilingSampler configure = new ProfilingSampler($"{k_Name}.{nameof(ScriptableRenderPass.Configure)}");
  60. #pragma warning restore CS0618
  61. public static readonly ProfilingSampler setRenderPassAttachments = new ProfilingSampler($"{k_Name}.{nameof(ScriptableRenderer.SetRenderPassAttachments)}");
  62. }
  63. }
  64. /// <summary>
  65. /// This setting controls if the camera editor should display the camera stack category.
  66. /// If your renderer is not supporting stacking this one should return 0.
  67. /// For the UI to show the Camera Stack widget this must support CameraRenderType.Base.
  68. /// <see cref="CameraRenderType"/>
  69. /// </summary>
  70. /// <returns>The bitmask of the supported camera render types in the renderer's current state.</returns>
  71. public virtual int SupportedCameraStackingTypes()
  72. {
  73. return 0;
  74. }
  75. /// <summary>
  76. /// Check if the given camera render type is supported in the renderer's current state.
  77. /// </summary>
  78. /// <param name="cameraRenderType">The camera render type that is checked if supported.</param>
  79. /// <returns>True if the given camera render type is supported in the renderer's current state.</returns>
  80. public bool SupportsCameraStackingType(CameraRenderType cameraRenderType)
  81. {
  82. return (SupportedCameraStackingTypes() & 1 << (int)cameraRenderType) != 0;
  83. }
  84. // NOTE: This is a temporary solution until ScriptableRenderer has a system for partially shared features.
  85. // TAA (and similar) affect the whole pipe. The code is split into two parts in terms of ownership.
  86. // The ScriptableRenderer "shared" code (Camera) and the ScriptableRenderer "specific" code (the ScriptableRenderPasses).
  87. // For example: TAA is enabled and configured from the Camera, which is used by any ScriptableRenderer.
  88. // TAA also jitters the Camera matrix for all ScriptableRenderers.
  89. // However a Renderer might not implement a motion vector pass, which the TAA needs to function correctly.
  90. //
  91. /// <summary>
  92. /// Check if the ScriptableRenderer implements a motion vector pass for temporal techniques.
  93. /// The Camera will check this to enable/disable features and/or apply jitter when required.
  94. ///
  95. /// For example, Temporal Anti-aliasing in the Camera settings is enabled only if the ScriptableRenderer can support motion vectors.
  96. /// </summary>
  97. /// <returns>Returns true if the ScriptableRenderer implements a motion vector pass. False otherwise.</returns>
  98. protected internal virtual bool SupportsMotionVectors()
  99. {
  100. return false;
  101. }
  102. /// <summary>
  103. /// Override to provide a custom profiling name
  104. /// </summary>
  105. protected ProfilingSampler profilingExecute { get; set; }
  106. /// <summary>
  107. /// Used to determine whether to release render targets used by the renderer when the renderer is no more active
  108. /// </summary>
  109. internal bool hasReleasedRTs = true;
  110. /// <summary>
  111. /// Configures the supported features for this renderer. When creating custom renderers
  112. /// for Universal Render Pipeline you can choose to opt-in or out for specific features.
  113. /// </summary>
  114. public class RenderingFeatures
  115. {
  116. /// <summary>
  117. /// This setting controls if the camera editor should display the camera stack category.
  118. /// Renderers that don't support camera stacking will only render camera of type CameraRenderType.Base
  119. /// <see cref="CameraRenderType"/>
  120. /// <seealso cref="UniversalAdditionalCameraData.cameraStack"/>
  121. /// </summary>
  122. [Obsolete("cameraStacking has been deprecated use SupportedCameraRenderTypes() in ScriptableRenderer instead.", true)]
  123. public bool cameraStacking { get; set; } = false;
  124. /// <summary>
  125. /// This setting controls if the Universal Render Pipeline asset should expose MSAA option.
  126. /// </summary>
  127. public bool msaa { get; set; } = true;
  128. }
  129. /// <summary>
  130. /// The class responsible for providing access to debug view settings to renderers and render passes.
  131. /// </summary>
  132. internal DebugHandler DebugHandler { get; }
  133. /// <summary>
  134. /// The renderer we are currently rendering with, for low-level render control only.
  135. /// <c>current</c> is null outside rendering scope.
  136. /// Similar to https://docs.unity3d.com/ScriptReference/Camera-current.html
  137. /// </summary>
  138. internal static ScriptableRenderer current = null;
  139. /// <summary>
  140. /// Set camera matrices. This method will set <c>UNITY_MATRIX_V</c>, <c>UNITY_MATRIX_P</c>, <c>UNITY_MATRIX_VP</c> to camera matrices.
  141. /// Additionally this will also set <c>unity_CameraProjection</c> and <c>unity_CameraProjection</c>.
  142. /// If <c>setInverseMatrices</c> is set to true this function will also set <c>UNITY_MATRIX_I_V</c> and <c>UNITY_MATRIX_I_VP</c>.
  143. /// This function has no effect when rendering in stereo. When in stereo rendering you cannot override camera matrices.
  144. /// If you need to set general purpose view and projection matrices call <see cref="SetViewAndProjectionMatrices(CommandBuffer, Matrix4x4, Matrix4x4, bool)"/> instead.
  145. /// </summary>
  146. /// <param name="cmd">CommandBuffer to submit data to GPU.</param>
  147. /// <param name="cameraData">CameraData containing camera matrices information.</param>
  148. /// <param name="setInverseMatrices">Set this to true if you also need to set inverse camera matrices.</param>
  149. public static void SetCameraMatrices(CommandBuffer cmd, ref CameraData cameraData, bool setInverseMatrices)
  150. {
  151. // Disable obsolete warning for internal usage
  152. #pragma warning disable CS0618
  153. SetCameraMatrices(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData.universalCameraData, setInverseMatrices, cameraData.IsCameraProjectionMatrixFlipped());
  154. #pragma warning restore CS0618
  155. }
  156. /// <summary>
  157. /// Set camera matrices. This method will set <c>UNITY_MATRIX_V</c>, <c>UNITY_MATRIX_P</c>, <c>UNITY_MATRIX_VP</c> to camera matrices.
  158. /// Additionally this will also set <c>unity_CameraProjection</c> and <c>unity_CameraProjection</c>.
  159. /// If <c>setInverseMatrices</c> is set to true this function will also set <c>UNITY_MATRIX_I_V</c> and <c>UNITY_MATRIX_I_VP</c>.
  160. /// This function has no effect when rendering in stereo. When in stereo rendering you cannot override camera matrices.
  161. /// If you need to set general purpose view and projection matrices call <see cref="SetViewAndProjectionMatrices(CommandBuffer, Matrix4x4, Matrix4x4, bool)"/> instead.
  162. /// </summary>
  163. /// <param name="cmd">CommandBuffer to submit data to GPU.</param>
  164. /// <param name="cameraData">CameraData containing camera matrices information.</param>
  165. /// <param name="setInverseMatrices">Set this to true if you also need to set inverse camera matrices.</param>
  166. public static void SetCameraMatrices(CommandBuffer cmd, UniversalCameraData cameraData, bool setInverseMatrices)
  167. {
  168. // Disable obsolete warning for internal usage
  169. #pragma warning disable CS0618
  170. SetCameraMatrices(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData, setInverseMatrices, cameraData.IsCameraProjectionMatrixFlipped());
  171. #pragma warning restore CS0618
  172. }
  173. internal static void SetCameraMatrices(RasterCommandBuffer cmd, UniversalCameraData cameraData, bool setInverseMatrices, bool isTargetFlipped)
  174. {
  175. #if ENABLE_VR && ENABLE_XR_MODULE
  176. if (cameraData.xr.enabled)
  177. {
  178. cameraData.PushBuiltinShaderConstantsXR(cmd, isTargetFlipped);
  179. XRSystemUniversal.MarkShaderProperties(cmd, cameraData.xrUniversal, isTargetFlipped);
  180. return;
  181. }
  182. #endif
  183. // NOTE: the URP default main view/projection matrices are the CameraData view/projection matrices.
  184. Matrix4x4 viewMatrix = cameraData.GetViewMatrix();
  185. Matrix4x4 projectionMatrix = cameraData.GetProjectionMatrix(); // Jittered, non-gpu
  186. // TODO: Investigate why SetViewAndProjectionMatrices is causing y-flip / winding order issue
  187. // for now using cmd.SetViewProjecionMatrices
  188. //SetViewAndProjectionMatrices(cmd, viewMatrix, cameraData.GetDeviceProjectionMatrix(), setInverseMatrices);
  189. // Set the default view/projection, note: projectionMatrix will be set as a gpu-projection (gfx api adjusted) for rendering.
  190. cmd.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
  191. if (setInverseMatrices)
  192. {
  193. Matrix4x4 gpuProjectionMatrix = cameraData.GetGPUProjectionMatrix(isTargetFlipped); // TODO: invProjection might NOT match the actual projection (invP*P==I) as the target flip logic has diverging paths.
  194. Matrix4x4 inverseViewMatrix = Matrix4x4.Inverse(viewMatrix);
  195. Matrix4x4 inverseProjectionMatrix = Matrix4x4.Inverse(gpuProjectionMatrix);
  196. Matrix4x4 inverseViewProjection = inverseViewMatrix * inverseProjectionMatrix;
  197. // There's an inconsistency in handedness between unity_matrixV and unity_WorldToCamera
  198. // Unity changes the handedness of unity_WorldToCamera (see Camera::CalculateMatrixShaderProps)
  199. // we will also change it here to avoid breaking existing shaders. (case 1257518)
  200. Matrix4x4 worldToCameraMatrix = Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)) * viewMatrix;
  201. Matrix4x4 cameraToWorldMatrix = worldToCameraMatrix.inverse;
  202. cmd.SetGlobalMatrix(ShaderPropertyId.worldToCameraMatrix, worldToCameraMatrix);
  203. cmd.SetGlobalMatrix(ShaderPropertyId.cameraToWorldMatrix, cameraToWorldMatrix);
  204. cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewMatrix, inverseViewMatrix);
  205. cmd.SetGlobalMatrix(ShaderPropertyId.inverseProjectionMatrix, inverseProjectionMatrix);
  206. cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewAndProjectionMatrix, inverseViewProjection);
  207. }
  208. // TODO: Add SetPerCameraClippingPlaneProperties here once we are sure it correctly behaves in overlay camera for some time
  209. }
  210. /// <summary>
  211. /// Set camera and screen shader variables as described in https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
  212. /// </summary>
  213. /// <param name="cmd">CommandBuffer to submit data to GPU.</param>
  214. /// <param name="cameraData">CameraData containing camera matrices information.</param>
  215. /// <typeparam name="T">Base type for the CommandBuffer</typeparam>
  216. void SetPerCameraShaderVariables(RasterCommandBuffer cmd, UniversalCameraData cameraData)
  217. {
  218. // Disable obsolete warning for internal usage
  219. #pragma warning disable CS0618
  220. SetPerCameraShaderVariables(cmd, cameraData, new Vector2Int(cameraData.cameraTargetDescriptor.width, cameraData.cameraTargetDescriptor.height), cameraData.IsCameraProjectionMatrixFlipped());
  221. #pragma warning restore CS0618
  222. }
  223. void SetPerCameraShaderVariables(RasterCommandBuffer cmd, UniversalCameraData cameraData, Vector2Int cameraTargetSizeCopy, bool isTargetFlipped)
  224. {
  225. using var profScope = new ProfilingScope(Profiling.setPerCameraShaderVariables);
  226. Camera camera = cameraData.camera;
  227. float scaledCameraTargetWidth = (float)cameraTargetSizeCopy.x;
  228. float scaledCameraTargetHeight = (float)cameraTargetSizeCopy.y;
  229. float cameraWidth = (float)camera.pixelWidth;
  230. float cameraHeight = (float)camera.pixelHeight;
  231. // Use eye texture's width and height as screen params when XR is enabled
  232. if (cameraData.xr.enabled)
  233. {
  234. cameraWidth = (float)cameraTargetSizeCopy.x;
  235. cameraHeight = (float)cameraTargetSizeCopy.y;
  236. useRenderPassEnabled = false;
  237. }
  238. if (camera.allowDynamicResolution)
  239. {
  240. scaledCameraTargetWidth *= ScalableBufferManager.widthScaleFactor;
  241. scaledCameraTargetHeight *= ScalableBufferManager.heightScaleFactor;
  242. }
  243. float near = camera.nearClipPlane;
  244. float far = camera.farClipPlane;
  245. float invNear = Mathf.Approximately(near, 0.0f) ? 0.0f : 1.0f / near;
  246. float invFar = Mathf.Approximately(far, 0.0f) ? 0.0f : 1.0f / far;
  247. float isOrthographic = camera.orthographic ? 1.0f : 0.0f;
  248. // From http://www.humus.name/temp/Linearize%20depth.txt
  249. // But as depth component textures on OpenGL always return in 0..1 range (as in D3D), we have to use
  250. // the same constants for both D3D and OpenGL here.
  251. // OpenGL would be this:
  252. // zc0 = (1.0 - far / near) / 2.0;
  253. // zc1 = (1.0 + far / near) / 2.0;
  254. // D3D is this:
  255. float zc0 = 1.0f - far * invNear;
  256. float zc1 = far * invNear;
  257. Vector4 zBufferParams = new Vector4(zc0, zc1, zc0 * invFar, zc1 * invFar);
  258. if (SystemInfo.usesReversedZBuffer)
  259. {
  260. zBufferParams.y += zBufferParams.x;
  261. zBufferParams.x = -zBufferParams.x;
  262. zBufferParams.w += zBufferParams.z;
  263. zBufferParams.z = -zBufferParams.z;
  264. }
  265. // Projection flip sign logic is very deep in GfxDevice::SetInvertProjectionMatrix
  266. // This setup is tailored especially for overlay camera game view
  267. // For other scenarios this will be overwritten correctly by SetupCameraProperties
  268. float projectionFlipSign = isTargetFlipped ? -1.0f : 1.0f;
  269. Vector4 projectionParams = new Vector4(projectionFlipSign, near, far, 1.0f * invFar);
  270. cmd.SetGlobalVector(ShaderPropertyId.projectionParams, projectionParams);
  271. Vector4 orthoParams = new Vector4(camera.orthographicSize * cameraData.aspectRatio, camera.orthographicSize, 0.0f, isOrthographic);
  272. // Camera and Screen variables as described in https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
  273. cmd.SetGlobalVector(ShaderPropertyId.worldSpaceCameraPos, cameraData.worldSpaceCameraPos);
  274. cmd.SetGlobalVector(ShaderPropertyId.screenParams, new Vector4(cameraWidth, cameraHeight, 1.0f + 1.0f / cameraWidth, 1.0f + 1.0f / cameraHeight));
  275. cmd.SetGlobalVector(ShaderPropertyId.scaledScreenParams, new Vector4(scaledCameraTargetWidth, scaledCameraTargetHeight, 1.0f + 1.0f / scaledCameraTargetWidth, 1.0f + 1.0f / scaledCameraTargetHeight));
  276. cmd.SetGlobalVector(ShaderPropertyId.zBufferParams, zBufferParams);
  277. cmd.SetGlobalVector(ShaderPropertyId.orthoParams, orthoParams);
  278. cmd.SetGlobalVector(ShaderPropertyId.screenSize, new Vector4(scaledCameraTargetWidth, scaledCameraTargetHeight, 1.0f / scaledCameraTargetWidth, 1.0f / scaledCameraTargetHeight));
  279. cmd.SetKeyword(ShaderGlobalKeywords.SCREEN_COORD_OVERRIDE, cameraData.useScreenCoordOverride);
  280. cmd.SetGlobalVector(ShaderPropertyId.screenSizeOverride, cameraData.screenSizeOverride);
  281. cmd.SetGlobalVector(ShaderPropertyId.screenCoordScaleBias, cameraData.screenCoordScaleBias);
  282. // { w / RTHandle.maxWidth, h / RTHandle.maxHeight } : xy = currFrame, zw = prevFrame
  283. // TODO(@sandy-carter) set to RTHandles.rtHandleProperties.rtHandleScale once dynamic scaling is set up
  284. cmd.SetGlobalVector(ShaderPropertyId.rtHandleScale, Vector4.one);
  285. // Calculate a bias value which corrects the mip lod selection logic when image scaling is active.
  286. // We clamp this value to 0.0 or less to make sure we don't end up reducing image detail in the downsampling case.
  287. float mipBias = Math.Min((float)-Math.Log(cameraWidth / scaledCameraTargetWidth, 2.0f), 0.0f);
  288. // Temporal Anti-aliasing can use negative mip bias to increase texture sharpness and new information for the jitter.
  289. float taaMipBias = Math.Min(cameraData.taaSettings.mipBias, 0.0f);
  290. mipBias = Math.Min(mipBias, taaMipBias);
  291. cmd.SetGlobalVector(ShaderPropertyId.globalMipBias, new Vector2(mipBias, Mathf.Pow(2.0f, mipBias)));
  292. //Set per camera matrices.
  293. SetCameraMatrices(cmd, cameraData, true, isTargetFlipped);
  294. }
  295. /// <summary>
  296. /// Set the Camera billboard properties.
  297. /// </summary>
  298. /// <param name="cmd">CommandBuffer to submit data to GPU.</param>
  299. /// <param name="cameraData">CameraData containing camera matrices information.</param>
  300. void SetPerCameraBillboardProperties(RasterCommandBuffer cmd, UniversalCameraData cameraData)
  301. {
  302. Matrix4x4 worldToCameraMatrix = cameraData.GetViewMatrix();
  303. Vector3 cameraPos = cameraData.worldSpaceCameraPos;
  304. cmd.SetKeyword(ShaderGlobalKeywords.BillboardFaceCameraPos, QualitySettings.billboardsFaceCameraPosition);
  305. Vector3 billboardTangent;
  306. Vector3 billboardNormal;
  307. float cameraXZAngle;
  308. CalculateBillboardProperties(worldToCameraMatrix, out billboardTangent, out billboardNormal, out cameraXZAngle);
  309. cmd.SetGlobalVector(ShaderPropertyId.billboardNormal, new Vector4(billboardNormal.x, billboardNormal.y, billboardNormal.z, 0.0f));
  310. cmd.SetGlobalVector(ShaderPropertyId.billboardTangent, new Vector4(billboardTangent.x, billboardTangent.y, billboardTangent.z, 0.0f));
  311. cmd.SetGlobalVector(ShaderPropertyId.billboardCameraParams, new Vector4(cameraPos.x, cameraPos.y, cameraPos.z, cameraXZAngle));
  312. }
  313. private static void CalculateBillboardProperties(
  314. in Matrix4x4 worldToCameraMatrix,
  315. out Vector3 billboardTangent,
  316. out Vector3 billboardNormal,
  317. out float cameraXZAngle)
  318. {
  319. Matrix4x4 cameraToWorldMatrix = worldToCameraMatrix;
  320. cameraToWorldMatrix = cameraToWorldMatrix.transpose;
  321. Vector3 cameraToWorldMatrixAxisX = new Vector3(cameraToWorldMatrix.m00, cameraToWorldMatrix.m10, cameraToWorldMatrix.m20);
  322. Vector3 cameraToWorldMatrixAxisY = new Vector3(cameraToWorldMatrix.m01, cameraToWorldMatrix.m11, cameraToWorldMatrix.m21);
  323. Vector3 cameraToWorldMatrixAxisZ = new Vector3(cameraToWorldMatrix.m02, cameraToWorldMatrix.m12, cameraToWorldMatrix.m22);
  324. Vector3 front = cameraToWorldMatrixAxisZ;
  325. Vector3 worldUp = Vector3.up;
  326. Vector3 cross = Vector3.Cross(front, worldUp);
  327. billboardTangent = !Mathf.Approximately(cross.sqrMagnitude, 0.0f)
  328. ? cross.normalized
  329. : cameraToWorldMatrixAxisX;
  330. billboardNormal = Vector3.Cross(worldUp, billboardTangent);
  331. billboardNormal = !Mathf.Approximately(billboardNormal.sqrMagnitude, 0.0f)
  332. ? billboardNormal.normalized
  333. : cameraToWorldMatrixAxisY;
  334. // SpeedTree generates billboards starting from looking towards X- and rotates counter clock-wisely
  335. Vector3 worldRight = new Vector3(0, 0, 1);
  336. // signed angle is calculated on X-Z plane
  337. float s = worldRight.x * billboardTangent.z - worldRight.z * billboardTangent.x;
  338. float c = worldRight.x * billboardTangent.x + worldRight.z * billboardTangent.z;
  339. cameraXZAngle = Mathf.Atan2(s, c);
  340. // convert to [0,2PI)
  341. if (cameraXZAngle < 0)
  342. cameraXZAngle += 2 * Mathf.PI;
  343. }
  344. private void SetPerCameraClippingPlaneProperties(RasterCommandBuffer cmd, UniversalCameraData cameraData)
  345. {
  346. // Disable obsolete warning for internal usage
  347. #pragma warning disable CS0618
  348. SetPerCameraClippingPlaneProperties(cmd, in cameraData, cameraData.IsCameraProjectionMatrixFlipped());
  349. #pragma warning restore CS0618
  350. }
  351. private void SetPerCameraClippingPlaneProperties(RasterCommandBuffer cmd, in UniversalCameraData cameraData, bool isTargetFlipped)
  352. {
  353. Matrix4x4 projectionMatrix = cameraData.GetGPUProjectionMatrix(isTargetFlipped);
  354. Matrix4x4 viewMatrix = cameraData.GetViewMatrix();
  355. Matrix4x4 viewProj = CoreMatrixUtils.MultiplyProjectionMatrix(projectionMatrix, viewMatrix, cameraData.camera.orthographic);
  356. Plane[] planes = s_Planes;
  357. GeometryUtility.CalculateFrustumPlanes(viewProj, planes);
  358. Vector4[] cameraWorldClipPlanes = s_VectorPlanes;
  359. for (int i = 0; i < planes.Length; ++i)
  360. cameraWorldClipPlanes[i] = new Vector4(planes[i].normal.x, planes[i].normal.y, planes[i].normal.z, planes[i].distance);
  361. cmd.SetGlobalVectorArray(ShaderPropertyId.cameraWorldClipPlanes, cameraWorldClipPlanes);
  362. }
  363. /// <summary>
  364. /// Set shader time variables as described in https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
  365. /// </summary>
  366. /// <param name="cmd">CommandBuffer to submit data to GPU.</param>
  367. /// <param name="time">Time.</param>
  368. /// <param name="deltaTime">Delta time.</param>
  369. /// <param name="smoothDeltaTime">Smooth delta time.</param>
  370. static void SetShaderTimeValues(IBaseCommandBuffer cmd, float time, float deltaTime, float smoothDeltaTime)
  371. {
  372. float timeEights = time / 8f;
  373. float timeFourth = time / 4f;
  374. float timeHalf = time / 2f;
  375. float lastTime = time - ShaderUtils.PersistentDeltaTime;
  376. // Time values
  377. Vector4 timeVector = time * new Vector4(1f / 20f, 1f, 2f, 3f);
  378. Vector4 sinTimeVector = new Vector4(Mathf.Sin(timeEights), Mathf.Sin(timeFourth), Mathf.Sin(timeHalf), Mathf.Sin(time));
  379. Vector4 cosTimeVector = new Vector4(Mathf.Cos(timeEights), Mathf.Cos(timeFourth), Mathf.Cos(timeHalf), Mathf.Cos(time));
  380. Vector4 deltaTimeVector = new Vector4(deltaTime, 1f / deltaTime, smoothDeltaTime, 1f / smoothDeltaTime);
  381. Vector4 timeParametersVector = new Vector4(time, Mathf.Sin(time), Mathf.Cos(time), 0.0f);
  382. Vector4 lastTimeParametersVector = new Vector4(lastTime, Mathf.Sin(lastTime), Mathf.Cos(lastTime), 0.0f);
  383. cmd.SetGlobalVector(ShaderPropertyId.time, timeVector);
  384. cmd.SetGlobalVector(ShaderPropertyId.sinTime, sinTimeVector);
  385. cmd.SetGlobalVector(ShaderPropertyId.cosTime, cosTimeVector);
  386. cmd.SetGlobalVector(ShaderPropertyId.deltaTime, deltaTimeVector);
  387. cmd.SetGlobalVector(ShaderPropertyId.timeParameters, timeParametersVector);
  388. cmd.SetGlobalVector(ShaderPropertyId.lastTimeParameters, lastTimeParametersVector);
  389. }
  390. /// <summary>
  391. /// Returns the camera color target for this renderer.
  392. /// It's only valid to call cameraColorTarget in the scope of <c>ScriptableRenderPass</c>.
  393. /// <seealso cref="ScriptableRenderPass"/>.
  394. /// </summary>
  395. [Obsolete("Use cameraColorTargetHandle", true)]
  396. public RenderTargetIdentifier cameraColorTarget => throw new NotSupportedException("cameraColorTarget has been deprecated. Use cameraColorTargetHandle instead");
  397. /// <summary>
  398. /// Returns the camera color target for this renderer.
  399. /// It's only valid to call cameraColorTargetHandle in the scope of <c>ScriptableRenderPass</c>.
  400. /// <seealso cref="ScriptableRenderPass"/>.
  401. /// </summary>
  402. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  403. public RTHandle cameraColorTargetHandle
  404. {
  405. get
  406. {
  407. if (!m_IsPipelineExecuting)
  408. {
  409. Debug.LogError("You can only call cameraColorTargetHandle inside the scope of a ScriptableRenderPass. Otherwise the pipeline camera target texture might have not been created or might have already been disposed.");
  410. return null;
  411. }
  412. return m_CameraColorTarget;
  413. }
  414. }
  415. /// <summary>
  416. /// Returns the frontbuffer color target. Returns null if not implemented by the renderer.
  417. /// It's only valid to call GetCameraColorFrontBuffer in the scope of <c>ScriptableRenderPass</c>.
  418. /// </summary>
  419. /// <param name="cmd"></param>
  420. /// <returns></returns>
  421. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  422. virtual internal RTHandle GetCameraColorFrontBuffer(CommandBuffer cmd)
  423. {
  424. return null;
  425. }
  426. /// <summary>
  427. /// Returns the backbuffer color target. Returns null if not implemented by the renderer.
  428. /// It's only valid to call GetCameraColorBackBuffer in the scope of <c>ScriptableRenderPass</c>.
  429. /// </summary>
  430. /// <param name="cmd"></param>
  431. /// <returns></returns>
  432. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  433. virtual internal RTHandle GetCameraColorBackBuffer(CommandBuffer cmd)
  434. {
  435. return null;
  436. }
  437. /// <summary>
  438. /// Returns the camera depth target for this renderer.
  439. /// It's only valid to call cameraDepthTarget in the scope of <c>ScriptableRenderPass</c>.
  440. /// <seealso cref="ScriptableRenderPass"/>.
  441. /// </summary>
  442. [Obsolete("Use cameraDepthTargetHandle", true)]
  443. public RenderTargetIdentifier cameraDepthTarget => throw new NotSupportedException("cameraDepthTarget has been deprecated. Use cameraDepthTargetHandle instead");
  444. /// <summary>
  445. /// Returns the camera depth target for this renderer.
  446. /// It's only valid to call cameraDepthTargetHandle in the scope of <c>ScriptableRenderPass</c>.
  447. /// <seealso cref="ScriptableRenderPass"/>.
  448. /// </summary>
  449. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  450. public RTHandle cameraDepthTargetHandle
  451. {
  452. get
  453. {
  454. if (!m_IsPipelineExecuting)
  455. {
  456. Debug.LogError("You can only call cameraDepthTargetHandle inside the scope of a ScriptableRenderPass. Otherwise the pipeline camera target texture might have not been created or might have already been disposed.");
  457. return null;
  458. }
  459. return m_CameraDepthTarget;
  460. }
  461. }
  462. /// <summary>
  463. /// Returns a list of renderer features added to this renderer.
  464. /// <seealso cref="ScriptableRendererFeature"/>
  465. /// </summary>
  466. protected List<ScriptableRendererFeature> rendererFeatures
  467. {
  468. get => m_RendererFeatures;
  469. }
  470. /// <summary>
  471. /// Returns a list of render passes scheduled to be executed by this renderer.
  472. /// <seealso cref="ScriptableRenderPass"/>
  473. /// </summary>
  474. protected List<ScriptableRenderPass> activeRenderPassQueue
  475. {
  476. get => m_ActiveRenderPassQueue;
  477. }
  478. /// <summary>
  479. /// Supported rendering features by this renderer.
  480. /// <see cref="SupportedRenderingFeatures"/>
  481. /// </summary>
  482. public RenderingFeatures supportedRenderingFeatures { get; set; } = new RenderingFeatures();
  483. /// <summary>
  484. /// List of unsupported Graphics APIs for this renderer.
  485. /// <see cref="unsupportedGraphicsDeviceTypes"/>
  486. /// </summary>
  487. public GraphicsDeviceType[] unsupportedGraphicsDeviceTypes { get; set; } = new GraphicsDeviceType[0];
  488. static class RenderPassBlock
  489. {
  490. // Executes render passes that are inputs to the main rendering
  491. // but don't depend on camera state. They all render in monoscopic mode. f.ex, shadow maps.
  492. public static readonly int BeforeRendering = 0;
  493. // Main bulk of render pass execution. They required camera state to be properly set
  494. // and when enabled they will render in stereo.
  495. public static readonly int MainRenderingOpaque = 1;
  496. public static readonly int MainRenderingTransparent = 2;
  497. // Execute after Post-processing.
  498. public static readonly int AfterRendering = 3;
  499. }
  500. private StoreActionsOptimization m_StoreActionsOptimizationSetting = StoreActionsOptimization.Auto;
  501. private static bool m_UseOptimizedStoreActions = false;
  502. const int k_RenderPassBlockCount = 4;
  503. /// <summary>
  504. /// The RTHandle for the Camera Target.
  505. /// </summary>
  506. protected static readonly RTHandle k_CameraTarget = RTHandles.Alloc(BuiltinRenderTextureType.CameraTarget);
  507. List<ScriptableRenderPass> m_ActiveRenderPassQueue = new List<ScriptableRenderPass>(32);
  508. List<ScriptableRendererFeature> m_RendererFeatures = new List<ScriptableRendererFeature>(10);
  509. RTHandle m_CameraColorTarget;
  510. RTHandle m_CameraDepthTarget;
  511. RTHandle m_CameraResolveTarget;
  512. bool m_FirstTimeCameraColorTargetIsBound = true; // flag used to track when m_CameraColorTarget should be cleared (if necessary), as well as other special actions only performed the first time m_CameraColorTarget is bound as a render target
  513. bool m_FirstTimeCameraDepthTargetIsBound = true; // flag used to track when m_CameraDepthTarget should be cleared (if necessary), the first time m_CameraDepthTarget is bound as a render target
  514. // The pipeline can only guarantee the camera target texture are valid when the pipeline is executing.
  515. // Trying to access the camera target before or after might be that the pipeline texture have already been disposed.
  516. bool m_IsPipelineExecuting = false;
  517. // Temporary variable to disable custom passes using render pass ( due to it potentially breaking projects with custom render features )
  518. // To enable it - override SupportsNativeRenderPass method in the feature and return true
  519. internal bool disableNativeRenderPassInFeatures = false;
  520. internal bool useRenderPassEnabled = false;
  521. // Used to cache nameID of m_ActiveColorAttachments for CoreUtils without allocating arrays at each call
  522. static RenderTargetIdentifier[] m_ActiveColorAttachmentIDs = new RenderTargetIdentifier[8];
  523. static RTHandle[] m_ActiveColorAttachments = new RTHandle[8];
  524. static RTHandle m_ActiveDepthAttachment;
  525. ContextContainer m_frameData = new();
  526. internal ContextContainer frameData => m_frameData;
  527. private static RenderBufferStoreAction[] m_ActiveColorStoreActions = new RenderBufferStoreAction[]
  528. {
  529. RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store,
  530. RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store
  531. };
  532. private static RenderBufferStoreAction m_ActiveDepthStoreAction = RenderBufferStoreAction.Store;
  533. // CommandBuffer.SetRenderTarget(RenderTargetIdentifier[] colors, RenderTargetIdentifier depth, int mipLevel, CubemapFace cubemapFace, int depthSlice);
  534. // called from CoreUtils.SetRenderTarget will issue a warning assert from native c++ side if "colors" array contains some invalid RTIDs.
  535. // To avoid that warning assert we trim the RenderTargetIdentifier[] arrays we pass to CoreUtils.SetRenderTarget.
  536. // To avoid re-allocating a new array every time we do that, we re-use one of these arrays for both RTHandles and RenderTargetIdentifiers:
  537. static RenderTargetIdentifier[][] m_TrimmedColorAttachmentCopyIDs =
  538. {
  539. Array.Empty<RenderTargetIdentifier>(), // only used to make indexing code easier to read
  540. new RenderTargetIdentifier[1],
  541. new RenderTargetIdentifier[2],
  542. new RenderTargetIdentifier[3],
  543. new RenderTargetIdentifier[4],
  544. new RenderTargetIdentifier[5],
  545. new RenderTargetIdentifier[6],
  546. new RenderTargetIdentifier[7],
  547. new RenderTargetIdentifier[8],
  548. };
  549. static RTHandle[][] m_TrimmedColorAttachmentCopies =
  550. {
  551. Array.Empty<RTHandle>(), // only used to make indexing code easier to read
  552. new RTHandle[1],
  553. new RTHandle[2],
  554. new RTHandle[3],
  555. new RTHandle[4],
  556. new RTHandle[5],
  557. new RTHandle[6],
  558. new RTHandle[7],
  559. new RTHandle[8],
  560. };
  561. private static Plane[] s_Planes = new Plane[6];
  562. private static Vector4[] s_VectorPlanes = new Vector4[6];
  563. internal bool useDepthPriming { get; set; } = false;
  564. internal bool stripShadowsOffVariants { get; set; } = false;
  565. internal bool stripAdditionalLightOffVariants { get; set; } = false;
  566. /// <summary>
  567. /// Creates a new <c>ScriptableRenderer</c> instance.
  568. /// </summary>
  569. /// <param name="data">The <c>ScriptableRendererData</c> data to initialize the renderer.</param>
  570. /// <seealso cref="ScriptableRendererData"/>
  571. public ScriptableRenderer(ScriptableRendererData data)
  572. {
  573. #if DEVELOPMENT_BUILD || UNITY_EDITOR
  574. DebugHandler = new DebugHandler();
  575. #endif
  576. profilingExecute = new ProfilingSampler($"{nameof(ScriptableRenderer)}.{nameof(ScriptableRenderer.Execute)}: {data.name}");
  577. foreach (var feature in data.rendererFeatures)
  578. {
  579. if (feature == null)
  580. continue;
  581. feature.Create();
  582. m_RendererFeatures.Add(feature);
  583. }
  584. ResetNativeRenderPassFrameData();
  585. useRenderPassEnabled = data.useNativeRenderPass;
  586. Clear(CameraRenderType.Base);
  587. m_ActiveRenderPassQueue.Clear();
  588. if (UniversalRenderPipeline.asset)
  589. {
  590. m_StoreActionsOptimizationSetting = UniversalRenderPipeline.asset.storeActionsOptimization;
  591. }
  592. m_UseOptimizedStoreActions = m_StoreActionsOptimizationSetting != StoreActionsOptimization.Store;
  593. }
  594. /// <summary>
  595. /// Disposable pattern implementation.
  596. /// Cleans up resources used by the renderer.
  597. /// </summary>
  598. public void Dispose()
  599. {
  600. // Dispose all renderer features...
  601. for (int i = 0; i < m_RendererFeatures.Count; ++i)
  602. {
  603. if (rendererFeatures[i] == null)
  604. continue;
  605. rendererFeatures[i].Dispose();
  606. }
  607. Dispose(true);
  608. hasReleasedRTs = true;
  609. GC.SuppressFinalize(this);
  610. }
  611. /// <summary>
  612. /// Called by Dispose().
  613. /// Override this function to clean up resources in your renderer.
  614. /// Be sure to call this base dispose in your overridden function to free resources allocated by the base.
  615. /// </summary>
  616. /// <param name="disposing"></param>
  617. protected virtual void Dispose(bool disposing)
  618. {
  619. DebugHandler?.Dispose();
  620. }
  621. internal virtual void ReleaseRenderTargets()
  622. {
  623. }
  624. /// <summary>
  625. /// Configures the camera target.
  626. /// </summary>
  627. /// <param name="colorTarget">Camera color target. Pass BuiltinRenderTextureType.CameraTarget if rendering to backbuffer.</param>
  628. /// <param name="depthTarget">Camera depth target. Pass BuiltinRenderTextureType.CameraTarget if color has depth or rendering to backbuffer.</param>
  629. [Obsolete("Use RTHandles for colorTarget and depthTarget", true)]
  630. public void ConfigureCameraTarget(RenderTargetIdentifier colorTarget, RenderTargetIdentifier depthTarget)
  631. {
  632. throw new NotSupportedException("ConfigureCameraTarget with RenderTargetIdentifier has been deprecated. Use it with RTHandles instead");
  633. }
  634. /// <summary>
  635. /// Configures the camera target.
  636. /// </summary>
  637. /// <param name="colorTarget">Camera color target. Pass k_CameraTarget if rendering to backbuffer.</param>
  638. /// <param name="depthTarget">Camera depth target. Pass k_CameraTarget if color has depth or rendering to backbuffer.</param>
  639. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  640. public void ConfigureCameraTarget(RTHandle colorTarget, RTHandle depthTarget)
  641. {
  642. m_CameraColorTarget = colorTarget;
  643. m_CameraDepthTarget = depthTarget;
  644. }
  645. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  646. internal void ConfigureCameraTarget(RTHandle colorTarget, RTHandle depthTarget, RTHandle resolveTarget)
  647. {
  648. m_CameraColorTarget = colorTarget;
  649. m_CameraDepthTarget = depthTarget;
  650. m_CameraResolveTarget = resolveTarget;
  651. }
  652. // This should be removed when early camera color target assignment is removed.
  653. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  654. internal void ConfigureCameraColorTarget(RTHandle colorTarget)
  655. {
  656. m_CameraColorTarget = colorTarget;
  657. }
  658. /// <summary>
  659. /// Configures the render passes that will execute for this renderer.
  660. /// This method is called per-camera every frame.
  661. /// </summary>
  662. /// <param name="context">Use this render context to issue any draw commands during execution.</param>
  663. /// <param name="renderingData">Current render state information.</param>
  664. /// <seealso cref="ScriptableRenderPass"/>
  665. /// <seealso cref="ScriptableRendererFeature"/>
  666. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  667. public abstract void Setup(ScriptableRenderContext context, ref RenderingData renderingData);
  668. /// <summary>
  669. /// Override this method to implement the lighting setup for the renderer. You can use this to
  670. /// compute and upload light CBUFFER for example.
  671. /// </summary>
  672. /// <param name="context">Use this render context to issue any draw commands during execution.</param>
  673. /// <param name="renderingData">Current render state information.</param>
  674. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  675. public virtual void SetupLights(ScriptableRenderContext context, ref RenderingData renderingData)
  676. {
  677. }
  678. /// <summary>
  679. /// Override this method to configure the culling parameters for the renderer. You can use this to configure if
  680. /// lights should be culled per-object or the maximum shadow distance for example.
  681. /// </summary>
  682. /// <param name="cullingParameters">Use this to change culling parameters used by the render pipeline.</param>
  683. /// <param name="cameraData">Current render state information.</param>
  684. public virtual void SetupCullingParameters(ref ScriptableCullingParameters cullingParameters,
  685. ref CameraData cameraData)
  686. {
  687. }
  688. /// <summary>
  689. /// Called upon finishing rendering the camera stack. You can release any resources created by the renderer here.
  690. /// </summary>
  691. /// <param name="cmd"></param>
  692. public virtual void FinishRendering(CommandBuffer cmd)
  693. {
  694. }
  695. /// <summary>
  696. /// Override this method to initialize before recording the render graph, such as resources.
  697. /// </summary>
  698. public virtual void OnBeginRenderGraphFrame()
  699. {
  700. }
  701. /// <summary>
  702. /// Override this method to record the RenderGraph passes to be used by the RenderGraph render path.
  703. /// </summary>
  704. /// <param name="context">Use this render context to issue any draw commands during execution.</param>
  705. /// <param name="renderingData">Current render state information.</param>
  706. internal virtual void OnRecordRenderGraph(RenderGraph renderGraph, ScriptableRenderContext context)
  707. {
  708. }
  709. /// <summary>
  710. /// Override this method to cleanup things after recording the render graph, such as resources.
  711. /// </summary>
  712. public virtual void OnEndRenderGraphFrame()
  713. {
  714. }
  715. private void InitRenderGraphFrame(RenderGraph renderGraph)
  716. {
  717. using (var builder = renderGraph.AddUnsafePass<PassData>(Profiling.initRenderGraphFrame.name, out var passData,
  718. Profiling.initRenderGraphFrame))
  719. {
  720. passData.renderer = this;
  721. builder.AllowPassCulling(false);
  722. builder.SetRenderFunc((PassData data, UnsafeGraphContext rgContext) =>
  723. {
  724. UnsafeCommandBuffer cmd = rgContext.cmd;
  725. #if UNITY_EDITOR
  726. float time = Application.isPlaying ? Time.time : Time.realtimeSinceStartup;
  727. #else
  728. float time = Time.time;
  729. #endif
  730. float deltaTime = Time.deltaTime;
  731. float smoothDeltaTime = Time.smoothDeltaTime;
  732. ClearRenderingState(cmd);
  733. SetShaderTimeValues(cmd, time, deltaTime, smoothDeltaTime);
  734. });
  735. }
  736. }
  737. private class VFXProcessCameraPassData
  738. {
  739. internal UniversalRenderingData renderingData;
  740. internal Camera camera;
  741. internal VFX.VFXCameraXRSettings cameraXRSettings;
  742. internal XRPass xrPass;
  743. };
  744. internal void ProcessVFXCameraCommand(RenderGraph renderGraph)
  745. {
  746. UniversalRenderingData renderingData = frameData.Get<UniversalRenderingData>();
  747. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  748. XRPass xr = cameraData.xr;
  749. using (var builder = renderGraph.AddUnsafePass<VFXProcessCameraPassData>("ProcessVFXCameraCommand", out var passData,
  750. Profiling.vfxProcessCamera))
  751. {
  752. passData.camera = cameraData.camera;
  753. passData.renderingData = renderingData;
  754. passData.cameraXRSettings.viewTotal = xr.enabled ? 2u : 1u;
  755. passData.cameraXRSettings.viewCount = xr.enabled ? (uint)xr.viewCount : 1u;
  756. passData.cameraXRSettings.viewOffset = (uint)xr.multipassId;
  757. passData.xrPass = xr.enabled ? xr : null;
  758. builder.AllowPassCulling(false);
  759. builder.SetRenderFunc((VFXProcessCameraPassData data, UnsafeGraphContext context) =>
  760. {
  761. if (data.xrPass != null)
  762. data.xrPass.StartSinglePass(context.cmd);
  763. //Triggers dispatch per camera, all global parameters should have been setup at this stage.
  764. CommandBufferHelpers.VFXManager_ProcessCameraCommand(data.camera, context.cmd, data.cameraXRSettings, data.renderingData.cullResults);
  765. if (data.xrPass != null)
  766. data.xrPass.StopSinglePass(context.cmd);
  767. });
  768. }
  769. }
  770. internal void SetupRenderGraphCameraProperties(RenderGraph renderGraph, bool isTargetBackbuffer)
  771. {
  772. using (var builder = renderGraph.AddRasterRenderPass<PassData>(Profiling.setupCamera.name, out var passData,
  773. Profiling.setupCamera))
  774. {
  775. passData.renderer = this;
  776. passData.cameraData = frameData.Get<UniversalCameraData>();
  777. passData.cameraTargetSizeCopy = new Vector2Int(passData.cameraData.cameraTargetDescriptor.width, passData.cameraData.cameraTargetDescriptor.height);
  778. passData.isTargetBackbuffer = isTargetBackbuffer;
  779. builder.AllowPassCulling(false);
  780. builder.AllowGlobalStateModification(true);
  781. builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
  782. {
  783. bool yFlip = !SystemInfo.graphicsUVStartsAtTop || data.isTargetBackbuffer;
  784. // This is still required because of the following reasons:
  785. // - Camera billboard properties.
  786. // - Camera frustum planes: unity_CameraWorldClipPlanes[6]
  787. // - _ProjectionParams.x logic is deep inside GfxDevice
  788. // NOTE: The only reason we have to call this here and not at the beginning (before shadows)
  789. // is because this need to be called for each eye in multi pass VR.
  790. // The side effect is that this will override some shader properties we already setup and we will have to
  791. // reset them.
  792. if (data.cameraData.renderType == CameraRenderType.Base)
  793. {
  794. context.cmd.SetupCameraProperties(data.cameraData.camera);
  795. data.renderer.SetPerCameraShaderVariables(context.cmd, data.cameraData, data.cameraTargetSizeCopy, !yFlip);
  796. }
  797. else
  798. {
  799. // Set new properties
  800. data.renderer.SetPerCameraShaderVariables(context.cmd, data.cameraData, data.cameraTargetSizeCopy, !yFlip);
  801. data.renderer.SetPerCameraClippingPlaneProperties(context.cmd, in data.cameraData, !yFlip);
  802. data.renderer.SetPerCameraBillboardProperties(context.cmd, data.cameraData);
  803. }
  804. #if UNITY_EDITOR
  805. float time = Application.isPlaying ? Time.time : Time.realtimeSinceStartup;
  806. #else
  807. float time = Time.time;
  808. #endif
  809. float deltaTime = Time.deltaTime;
  810. float smoothDeltaTime = Time.smoothDeltaTime;
  811. // Reset shader time variables as they were overridden in SetupCameraProperties. If we don't do it we might have a mismatch between shadows and main rendering
  812. SetShaderTimeValues(context.cmd, time, deltaTime, smoothDeltaTime);
  813. });
  814. }
  815. }
  816. private class DrawGizmosPassData
  817. {
  818. public RendererListHandle gizmoRenderList;
  819. };
  820. /// <summary>
  821. /// TODO RENDERGRAPH
  822. /// </summary>
  823. /// <param name="color"></param>
  824. /// <param name="depth"></param>
  825. /// <param name="gizmoSubset"></param>
  826. /// <param name="renderingData"></param>
  827. internal void DrawRenderGraphGizmos(RenderGraph renderGraph, ContextContainer frameData, TextureHandle color, TextureHandle depth, GizmoSubset gizmoSubset)
  828. {
  829. #if UNITY_EDITOR
  830. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  831. if (!Handles.ShouldRenderGizmos() || cameraData.camera.sceneViewFilterMode == Camera.SceneViewFilterMode.ShowFiltered)
  832. return;
  833. using (var builder = renderGraph.AddRasterRenderPass<DrawGizmosPassData>("Draw Gizmos Pass", out var passData,
  834. Profiling.drawGizmos))
  835. {
  836. builder.SetRenderAttachment(color, 0, AccessFlags.Write);
  837. builder.SetRenderAttachmentDepth(depth, AccessFlags.ReadWrite);
  838. passData.gizmoRenderList = renderGraph.CreateGizmoRendererList(cameraData.camera, gizmoSubset);
  839. builder.UseRendererList(passData.gizmoRenderList);
  840. builder.AllowPassCulling(false);
  841. builder.SetRenderFunc((DrawGizmosPassData data, RasterGraphContext rgContext) =>
  842. {
  843. using (new ProfilingScope(rgContext.cmd, Profiling.drawGizmos))
  844. {
  845. rgContext.cmd.DrawRendererList(data.gizmoRenderList);
  846. }
  847. });
  848. }
  849. #endif
  850. }
  851. private class DrawWireOverlayPassData
  852. {
  853. public RendererListHandle wireOverlayList;
  854. };
  855. internal void DrawRenderGraphWireOverlay(RenderGraph renderGraph, ContextContainer frameData, TextureHandle color)
  856. {
  857. #if UNITY_EDITOR
  858. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  859. if (!cameraData.isSceneViewCamera)
  860. return;
  861. using (var builder = renderGraph.AddRasterRenderPass<DrawWireOverlayPassData>(Profiling.drawWireOverlay.name, out var passData,
  862. Profiling.drawWireOverlay))
  863. {
  864. builder.SetRenderAttachment(color, 0, AccessFlags.Write);
  865. passData.wireOverlayList = renderGraph.CreateWireOverlayRendererList(cameraData.camera);
  866. builder.UseRendererList(passData.wireOverlayList);
  867. builder.AllowPassCulling(false);
  868. builder.SetRenderFunc(static (DrawWireOverlayPassData data, RasterGraphContext rgContext) =>
  869. {
  870. using (new ProfilingScope(rgContext.cmd, Profiling.drawWireOverlay))
  871. {
  872. rgContext.cmd.DrawRendererList(data.wireOverlayList);
  873. }
  874. });
  875. }
  876. #endif
  877. }
  878. private class BeginXRPassData
  879. {
  880. internal UniversalCameraData cameraData;
  881. };
  882. internal void BeginRenderGraphXRRendering(RenderGraph renderGraph)
  883. {
  884. #if ENABLE_VR && ENABLE_XR_MODULE
  885. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  886. if (!cameraData.xr.enabled)
  887. return;
  888. bool isDefaultXRViewport = XRSystem.GetRenderViewportScale() == 1.0f;
  889. // For untethered XR, intermediate pass' foveation is currenlty unsupported with non-default viewport.
  890. // Must be configured during the recording timeline before adding other XR intermediate passes.
  891. cameraData.xrUniversal.canFoveateIntermediatePasses = !PlatformAutoDetect.isXRMobile || isDefaultXRViewport;
  892. using (var builder = renderGraph.AddRasterRenderPass<BeginXRPassData>("BeginXRRendering", out var passData,
  893. Profiling.beginXRRendering))
  894. {
  895. passData.cameraData = cameraData;
  896. builder.AllowPassCulling(false);
  897. builder.AllowGlobalStateModification(true);
  898. builder.SetRenderFunc((BeginXRPassData data, RasterGraphContext context) =>
  899. {
  900. if (data.cameraData.xr.enabled)
  901. {
  902. if (data.cameraData.xrUniversal.isLateLatchEnabled)
  903. data.cameraData.xrUniversal.canMarkLateLatch = true;
  904. data.cameraData.xr.StartSinglePass(context.cmd);
  905. if (data.cameraData.xr.supportsFoveatedRendering)
  906. {
  907. context.cmd.ConfigureFoveatedRendering(data.cameraData.xr.foveatedRenderingInfo);
  908. if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster))
  909. context.cmd.SetKeyword(ShaderGlobalKeywords.FoveatedRenderingNonUniformRaster, true);
  910. }
  911. }
  912. });
  913. }
  914. #endif
  915. }
  916. private class EndXRPassData
  917. {
  918. public UniversalCameraData cameraData;
  919. };
  920. internal void EndRenderGraphXRRendering(RenderGraph renderGraph)
  921. {
  922. #if ENABLE_VR && ENABLE_XR_MODULE
  923. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  924. if (!cameraData.xr.enabled)
  925. return;
  926. using (var builder = renderGraph.AddRasterRenderPass<EndXRPassData>("EndXRRendering", out var passData,
  927. Profiling.endXRRendering))
  928. {
  929. passData.cameraData = cameraData;
  930. builder.AllowPassCulling(false);
  931. builder.AllowGlobalStateModification(true);
  932. builder.SetRenderFunc((EndXRPassData data, RasterGraphContext context) =>
  933. {
  934. if (data.cameraData.xr.enabled)
  935. {
  936. data.cameraData.xr.StopSinglePass(context.cmd);
  937. }
  938. if (XRSystem.foveatedRenderingCaps != FoveatedRenderingCaps.None)
  939. {
  940. if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster))
  941. context.cmd.SetKeyword(ShaderGlobalKeywords.FoveatedRenderingNonUniformRaster, false);
  942. context.cmd.ConfigureFoveatedRendering(IntPtr.Zero);
  943. }
  944. });
  945. }
  946. #endif
  947. }
  948. private class DummyData
  949. {
  950. };
  951. private void SetEditorTarget(RenderGraph renderGraph)
  952. {
  953. using (var builder = renderGraph.AddUnsafePass<DummyData>("SetEditorTarget", out var passData,
  954. Profiling.setEditorTarget))
  955. {
  956. builder.AllowPassCulling(false);
  957. builder.SetRenderFunc((DummyData data, UnsafeGraphContext context) =>
  958. {
  959. context.cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget,
  960. RenderBufferLoadAction.Load, RenderBufferStoreAction.Store, // color
  961. RenderBufferLoadAction.Load, RenderBufferStoreAction.DontCare); // depth
  962. });
  963. }
  964. }
  965. private class PassData
  966. {
  967. internal ScriptableRenderer renderer;
  968. internal UniversalCameraData cameraData;
  969. internal bool isTargetBackbuffer;
  970. // The size of the camera target changes during the frame so we must make a copy of it here to preserve its record-time value.
  971. internal Vector2Int cameraTargetSizeCopy;
  972. };
  973. /// <summary>
  974. /// TODO RENDERGRAPH
  975. /// </summary>
  976. /// <param name="context"></param>
  977. /// <param name="renderingData"></param>
  978. internal void RecordRenderGraph(RenderGraph renderGraph, ScriptableRenderContext context)
  979. {
  980. using (new ProfilingScope(ProfilingSampler.Get(URPProfileId.RecordRenderGraph)))
  981. {
  982. OnBeginRenderGraphFrame();
  983. using (new ProfilingScope(Profiling.sortRenderPasses))
  984. {
  985. // Sort the render pass queue
  986. SortStable(m_ActiveRenderPassQueue);
  987. }
  988. InitRenderGraphFrame(renderGraph);
  989. using (new ProfilingScope(Profiling.recordRenderGraph))
  990. {
  991. OnRecordRenderGraph(renderGraph, context);
  992. }
  993. OnEndRenderGraphFrame();
  994. // The editor scene view still relies on some builtin passes (i.e. drawing the scene grid). The builtin
  995. // passes are not explicitly setting RTs and rely on the last active render target being set. Unfortunately
  996. // this does not play nice with the NRP RG path, since we don't use the SetRenderTarget API anymore.
  997. // For this reason, as a workaround, in editor scene view we set explicitly set the RT to SceneViewRT.
  998. // TODO: this will go away once we remove the builtin dependencies and implement the grid in SRP.
  999. #if UNITY_EDITOR
  1000. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  1001. if (cameraData.isSceneViewCamera)
  1002. SetEditorTarget(renderGraph);
  1003. #endif
  1004. }
  1005. }
  1006. /// <summary>
  1007. /// TODO RENDERGRAPH
  1008. /// </summary>
  1009. /// <param name="context"></param>
  1010. /// <param name="renderingData"></param>
  1011. internal void FinishRenderGraphRendering(CommandBuffer cmd)
  1012. {
  1013. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  1014. OnFinishRenderGraphRendering(cmd);
  1015. InternalFinishRenderingCommon(cmd, cameraData.resolveFinalTarget);
  1016. }
  1017. /// <summary>
  1018. /// TODO RENDERGRAPH
  1019. /// </summary>
  1020. /// <param name="context"></param>
  1021. /// <param name="renderingData"></param>
  1022. internal virtual void OnFinishRenderGraphRendering(CommandBuffer cmd)
  1023. {
  1024. }
  1025. internal void RecordCustomRenderGraphPassesInEventRange(RenderGraph renderGraph, RenderPassEvent eventStart, RenderPassEvent eventEnd)
  1026. {
  1027. // Only iterate over the active pass queue if we have a non-empty range
  1028. if (eventStart != eventEnd)
  1029. {
  1030. foreach (ScriptableRenderPass pass in m_ActiveRenderPassQueue)
  1031. {
  1032. if (pass.renderPassEvent >= eventStart && pass.renderPassEvent < eventEnd)
  1033. pass.RecordRenderGraph(renderGraph, m_frameData);
  1034. }
  1035. }
  1036. }
  1037. internal void CalculateSplitEventRange(RenderPassEvent startInjectionPoint, RenderPassEvent targetEvent, out RenderPassEvent startEvent, out RenderPassEvent splitEvent, out RenderPassEvent endEvent)
  1038. {
  1039. int range = ScriptableRenderPass.GetRenderPassEventRange(startInjectionPoint);
  1040. startEvent = startInjectionPoint;
  1041. endEvent = startEvent + range;
  1042. splitEvent = (RenderPassEvent)Math.Clamp((int)targetEvent, (int)startEvent, (int)endEvent);
  1043. }
  1044. internal void RecordCustomRenderGraphPasses(RenderGraph renderGraph, RenderPassEvent startInjectionPoint, RenderPassEvent endInjectionPoint)
  1045. {
  1046. int range = ScriptableRenderPass.GetRenderPassEventRange(endInjectionPoint);
  1047. RecordCustomRenderGraphPassesInEventRange(renderGraph, startInjectionPoint, endInjectionPoint + range);
  1048. }
  1049. internal void RecordCustomRenderGraphPasses(RenderGraph renderGraph, RenderPassEvent injectionPoint)
  1050. {
  1051. RecordCustomRenderGraphPasses(renderGraph, injectionPoint, injectionPoint);
  1052. }
  1053. // ScriptableRenderPass if executed in a critical point (such as in between Deferred and GBuffer) has to have
  1054. // interruptFramebufferFetchEvent set to actually interrupt it so we could fall back to non framebuffer fetch path
  1055. internal bool InterruptFramebufferFetch(FramebufferFetchEvent fetchEvent, RenderPassEvent startInjectionPoint, RenderPassEvent endInjectionPoint)
  1056. {
  1057. int range = ScriptableRenderPass.GetRenderPassEventRange(endInjectionPoint);
  1058. int nextValue = (int) endInjectionPoint + range;
  1059. foreach (ScriptableRenderPass pass in m_ActiveRenderPassQueue)
  1060. {
  1061. if (pass.renderPassEvent >= startInjectionPoint && (int) pass.renderPassEvent < nextValue)
  1062. switch (fetchEvent)
  1063. {
  1064. case FramebufferFetchEvent.FetchGbufferInDeferred:
  1065. if (pass.breakGBufferAndDeferredRenderPass)
  1066. return true;
  1067. break;
  1068. default:
  1069. continue;
  1070. }
  1071. }
  1072. return false;
  1073. }
  1074. internal void SetPerCameraProperties(ScriptableRenderContext context, UniversalCameraData cameraData, Camera camera,
  1075. CommandBuffer cmd)
  1076. {
  1077. if (cameraData.renderType == CameraRenderType.Base)
  1078. {
  1079. context.SetupCameraProperties(camera);
  1080. SetPerCameraShaderVariables(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData);
  1081. }
  1082. else
  1083. {
  1084. // Set new properties
  1085. SetPerCameraShaderVariables(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData);
  1086. SetPerCameraClippingPlaneProperties(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData);
  1087. SetPerCameraBillboardProperties(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData);
  1088. }
  1089. }
  1090. /// <summary>
  1091. /// Execute the enqueued render passes. This automatically handles editor and stereo rendering.
  1092. /// </summary>
  1093. /// <param name="context">Use this render context to issue any draw commands during execution.</param>
  1094. /// <param name="renderingData">Current render state information.</param>
  1095. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1096. public void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  1097. {
  1098. // Disable Gizmos when using scene overrides. Gizmos break some effects like Overdraw debug.
  1099. bool drawGizmos = UniversalRenderPipelineDebugDisplaySettings.Instance.renderingSettings.sceneOverrideMode == DebugSceneOverrideMode.None;
  1100. hasReleasedRTs = false;
  1101. m_IsPipelineExecuting = true;
  1102. UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
  1103. Camera camera = cameraData.camera;
  1104. // Let renderer features call their own setup functions when targets are valid
  1105. if (rendererFeatures.Count != 0 && !renderingData.cameraData.isPreviewCamera)
  1106. SetupRenderPasses(in renderingData);
  1107. CommandBuffer cmd = renderingData.commandBuffer;
  1108. // TODO: move skybox code from C++ to URP in order to remove the call to context.Submit() inside DrawSkyboxPass
  1109. // Until then, we can't use nested profiling scopes with XR multipass
  1110. CommandBuffer cmdScope = renderingData.cameraData.xr.enabled ? null : cmd;
  1111. using (new ProfilingScope(cmdScope, profilingExecute))
  1112. {
  1113. InternalStartRendering(context, ref renderingData);
  1114. // Cache the time for after the call to `SetupCameraProperties` and set the time variables in shader
  1115. // For now we set the time variables per camera, as we plan to remove `SetupCameraProperties`.
  1116. // Setting the time per frame would take API changes to pass the variable to each camera render.
  1117. // Once `SetupCameraProperties` is gone, the variable should be set higher in the call-stack.
  1118. #if UNITY_EDITOR
  1119. float time = Application.isPlaying ? Time.time : Time.realtimeSinceStartup;
  1120. #else
  1121. float time = Time.time;
  1122. #endif
  1123. float deltaTime = Time.deltaTime;
  1124. float smoothDeltaTime = Time.smoothDeltaTime;
  1125. // Initialize Camera Render State
  1126. ClearRenderingState(CommandBufferHelpers.GetRasterCommandBuffer(cmd));
  1127. SetShaderTimeValues(CommandBufferHelpers.GetRasterCommandBuffer(cmd), time, deltaTime, smoothDeltaTime);
  1128. context.ExecuteCommandBuffer(cmd);
  1129. cmd.Clear();
  1130. using (new ProfilingScope(Profiling.sortRenderPasses))
  1131. {
  1132. // Sort the render pass queue
  1133. SortStable(m_ActiveRenderPassQueue);
  1134. }
  1135. using (new ProfilingScope(Profiling.RenderPass.configure))
  1136. {
  1137. foreach (var pass in activeRenderPassQueue)
  1138. {
  1139. // Disable obsolete warning for internal usage
  1140. #pragma warning disable CS0618
  1141. pass.Configure(cmd, cameraData.cameraTargetDescriptor);
  1142. #pragma warning restore CS0618
  1143. }
  1144. context.ExecuteCommandBuffer(cmd);
  1145. cmd.Clear();
  1146. }
  1147. SetupNativeRenderPassFrameData(cameraData, useRenderPassEnabled);
  1148. using var renderBlocks = new RenderBlocks(m_ActiveRenderPassQueue);
  1149. using (new ProfilingScope(Profiling.setupLights))
  1150. {
  1151. SetupLights(context, ref renderingData);
  1152. }
  1153. #if VISUAL_EFFECT_GRAPH_0_0_1_OR_NEWER
  1154. using (new ProfilingScope(Profiling.setupCamera))
  1155. {
  1156. //Camera variables need to be setup for the VFXManager.ProcessCameraCommand to work properly.
  1157. //VFXManager.ProcessCameraCommand needs to be called before any rendering (incl. shadows)
  1158. SetPerCameraProperties(context, cameraData, camera, cmd);
  1159. VFX.VFXCameraXRSettings cameraXRSettings;
  1160. cameraXRSettings.viewTotal = cameraData.xr.enabled ? 2u : 1u;
  1161. cameraXRSettings.viewCount = cameraData.xr.enabled ? (uint)cameraData.xr.viewCount : 1u;
  1162. cameraXRSettings.viewOffset = (uint)cameraData.xr.multipassId;
  1163. if (cameraData.xr.enabled)
  1164. cameraData.xr.StartSinglePass(cmd);
  1165. VFX.VFXManager.ProcessCameraCommand(camera, cmd, cameraXRSettings, renderingData.cullResults);
  1166. if (cameraData.xr.enabled)
  1167. cameraData.xr.StopSinglePass(cmd);
  1168. }
  1169. #endif
  1170. // Before Render Block. This render blocks always execute in mono rendering.
  1171. // Camera is not setup.
  1172. // Used to render input textures like shadowmaps.
  1173. if (renderBlocks.GetLength(RenderPassBlock.BeforeRendering) > 0)
  1174. {
  1175. // TODO: Separate command buffers per pass break the profiling scope order/hierarchy.
  1176. // If a single buffer is used and passed as a param to passes,
  1177. // put all of the "block" scopes back into the command buffer. (null -> cmd)
  1178. using var profScope = new ProfilingScope(Profiling.RenderBlock.beforeRendering);
  1179. ExecuteBlock(RenderPassBlock.BeforeRendering, in renderBlocks, context, ref renderingData);
  1180. }
  1181. using (new ProfilingScope(Profiling.setupCamera))
  1182. {
  1183. // This is still required because of the following reasons:
  1184. // - Camera billboard properties.
  1185. // - Camera frustum planes: unity_CameraWorldClipPlanes[6]
  1186. // - _ProjectionParams.x logic is deep inside GfxDevice
  1187. // NOTE: The only reason we have to call this here and not at the beginning (before shadows)
  1188. // is because this need to be called for each eye in multi pass VR.
  1189. // The side effect is that this will override some shader properties we already setup and we will have to
  1190. // reset them.
  1191. SetPerCameraProperties(context, cameraData, camera, cmd);
  1192. // Reset shader time variables as they were overridden in SetupCameraProperties. If we don't do it we might have a mismatch between shadows and main rendering
  1193. SetShaderTimeValues(CommandBufferHelpers.GetRasterCommandBuffer(cmd), time, deltaTime, smoothDeltaTime);
  1194. }
  1195. context.ExecuteCommandBuffer(cmd);
  1196. cmd.Clear();
  1197. BeginXRRendering(cmd, context, ref renderingData.cameraData);
  1198. // In the opaque and transparent blocks the main rendering executes.
  1199. // Opaque blocks...
  1200. if (renderBlocks.GetLength(RenderPassBlock.MainRenderingOpaque) > 0)
  1201. {
  1202. // TODO: Separate command buffers per pass break the profiling scope order/hierarchy.
  1203. // If a single buffer is used (passed as a param) for passes,
  1204. // put all of the "block" scopes back into the command buffer. (i.e. null -> cmd)
  1205. using var profScope = new ProfilingScope(Profiling.RenderBlock.mainRenderingOpaque);
  1206. ExecuteBlock(RenderPassBlock.MainRenderingOpaque, in renderBlocks, context, ref renderingData);
  1207. }
  1208. // Transparent blocks...
  1209. if (renderBlocks.GetLength(RenderPassBlock.MainRenderingTransparent) > 0)
  1210. {
  1211. using var profScope = new ProfilingScope(Profiling.RenderBlock.mainRenderingTransparent);
  1212. ExecuteBlock(RenderPassBlock.MainRenderingTransparent, in renderBlocks, context, ref renderingData);
  1213. }
  1214. #if ENABLE_VR && ENABLE_XR_MODULE
  1215. // Late latching is not supported after this point in the frame
  1216. if (cameraData.xr.enabled)
  1217. cameraData.xrUniversal.canMarkLateLatch = false;
  1218. #endif
  1219. // Draw Gizmos...
  1220. if (drawGizmos)
  1221. {
  1222. DrawGizmos(context, camera, GizmoSubset.PreImageEffects, ref renderingData);
  1223. }
  1224. // In this block after rendering drawing happens, e.g, post processing, video player capture.
  1225. if (renderBlocks.GetLength(RenderPassBlock.AfterRendering) > 0)
  1226. {
  1227. using var profScope = new ProfilingScope(Profiling.RenderBlock.afterRendering);
  1228. ExecuteBlock(RenderPassBlock.AfterRendering, in renderBlocks, context, ref renderingData);
  1229. }
  1230. EndXRRendering(cmd, context, ref renderingData.cameraData);
  1231. DrawWireOverlay(context, camera);
  1232. if (drawGizmos)
  1233. {
  1234. DrawGizmos(context, camera, GizmoSubset.PostImageEffects, ref renderingData);
  1235. }
  1236. InternalFinishRenderingExecute(context, cmd, cameraData.resolveFinalTarget);
  1237. for (int i = 0; i < m_ActiveRenderPassQueue.Count; ++i)
  1238. {
  1239. m_ActiveRenderPassQueue[i].m_ColorAttachmentIndices.Dispose();
  1240. m_ActiveRenderPassQueue[i].m_InputAttachmentIndices.Dispose();
  1241. }
  1242. }
  1243. context.ExecuteCommandBuffer(cmd);
  1244. cmd.Clear();
  1245. }
  1246. /// <summary>
  1247. /// Enqueues a render pass for execution.
  1248. /// </summary>
  1249. /// <param name="pass">Render pass to be enqueued.</param>
  1250. public void EnqueuePass(ScriptableRenderPass pass)
  1251. {
  1252. m_ActiveRenderPassQueue.Add(pass);
  1253. if (disableNativeRenderPassInFeatures)
  1254. pass.useNativeRenderPass = false;
  1255. }
  1256. /// <summary>
  1257. /// Returns a clear flag based on CameraClearFlags.
  1258. /// </summary>
  1259. /// <param name="cameraData">The Camera data.</param>
  1260. /// <returns>A clear flag that tells if color and/or depth should be cleared.</returns>
  1261. /// <seealso cref="CameraData"/>
  1262. protected static ClearFlag GetCameraClearFlag(ref CameraData cameraData)
  1263. {
  1264. var universalCameraData = cameraData.universalCameraData;
  1265. return GetCameraClearFlag(universalCameraData);
  1266. }
  1267. /// <summary>
  1268. /// Returns a clear flag based on CameraClearFlags.
  1269. /// </summary>
  1270. /// <param name="cameraData">The Camera data.</param>
  1271. /// <returns>A clear flag that tells if color and/or depth should be cleared.</returns>
  1272. /// <seealso cref="CameraData"/>
  1273. protected static ClearFlag GetCameraClearFlag(UniversalCameraData cameraData)
  1274. {
  1275. var cameraClearFlags = cameraData.camera.clearFlags;
  1276. // Universal RP doesn't support CameraClearFlags.DepthOnly and CameraClearFlags.Nothing.
  1277. // CameraClearFlags.DepthOnly has the same effect of CameraClearFlags.SolidColor
  1278. // CameraClearFlags.Nothing clears Depth on PC/Desktop and in mobile it clears both
  1279. // depth and color.
  1280. // CameraClearFlags.Skybox clears depth only.
  1281. // Implementation details:
  1282. // Camera clear flags are used to initialize the attachments on the first render pass.
  1283. // ClearFlag is used together with Tile Load action to figure out how to clear the camera render target.
  1284. // In Tile Based GPUs ClearFlag.Depth + RenderBufferLoadAction.DontCare becomes DontCare load action.
  1285. // RenderBufferLoadAction.DontCare in PC/Desktop behaves as not clearing screen
  1286. // RenderBufferLoadAction.DontCare in Vulkan/Metal behaves as DontCare load action
  1287. // RenderBufferLoadAction.DontCare in GLES behaves as glInvalidateBuffer
  1288. // Overlay cameras composite on top of previous ones. They don't clear color.
  1289. // For overlay cameras we check if depth should be cleared on not.
  1290. if (cameraData.renderType == CameraRenderType.Overlay)
  1291. return (cameraData.clearDepth) ? ClearFlag.DepthStencil : ClearFlag.None;
  1292. // Certain debug modes (e.g. wireframe/overdraw modes) require that we override clear flags and clear everything.
  1293. var debugHandler = cameraData.renderer.DebugHandler;
  1294. if (debugHandler != null && debugHandler.IsActiveForCamera(cameraData.isPreviewCamera) && debugHandler.IsScreenClearNeeded)
  1295. return ClearFlag.All;
  1296. // XRTODO: remove once we have visible area of occlusion mesh available
  1297. if (cameraClearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null && cameraData.postProcessEnabled && cameraData.xr.enabled)
  1298. return ClearFlag.All;
  1299. if ((cameraClearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null) ||
  1300. cameraClearFlags == CameraClearFlags.Nothing)
  1301. {
  1302. // Clear color if msaa is used. If color is not cleared will alpha to coverage blend with previous frame if alpha clipping is enabled of any opaque objects.
  1303. if (cameraData.cameraTargetDescriptor.msaaSamples > 1)
  1304. {
  1305. // Sets the clear color to black to make the alpha to coverage blending blend with black when using alpha clipping.
  1306. cameraData.camera.backgroundColor = Color.black;
  1307. return ClearFlag.DepthStencil | ClearFlag.Color;
  1308. }
  1309. else
  1310. {
  1311. return ClearFlag.DepthStencil;
  1312. }
  1313. }
  1314. return ClearFlag.All;
  1315. }
  1316. /// <summary>
  1317. /// Calls <c>OnCull</c> for each feature added to this renderer.
  1318. /// <seealso cref="ScriptableRendererFeature.OnCameraPreCull(ScriptableRenderer, in CameraData)"/>
  1319. /// </summary>
  1320. /// <param name="cameraData">Current render state information.</param>
  1321. internal void OnPreCullRenderPasses(in CameraData cameraData)
  1322. {
  1323. // Add render passes from custom renderer features
  1324. for (int i = 0; i < rendererFeatures.Count; ++i)
  1325. {
  1326. if (!rendererFeatures[i].isActive)
  1327. {
  1328. continue;
  1329. }
  1330. rendererFeatures[i].OnCameraPreCull(this, in cameraData);
  1331. }
  1332. }
  1333. /// <summary>
  1334. /// Calls <c>AddRenderPasses</c> for each feature added to this renderer.
  1335. /// <seealso cref="ScriptableRendererFeature.AddRenderPasses(ScriptableRenderer, ref RenderingData)"/>
  1336. /// </summary>
  1337. /// <param name="renderingData"></param>
  1338. internal void AddRenderPasses(ref RenderingData renderingData)
  1339. {
  1340. using var profScope = new ProfilingScope(Profiling.addRenderPasses);
  1341. // Add render passes from custom renderer features
  1342. for (int i = 0; i < rendererFeatures.Count; ++i)
  1343. {
  1344. if (!rendererFeatures[i].isActive)
  1345. {
  1346. continue;
  1347. }
  1348. if (!rendererFeatures[i].SupportsNativeRenderPass())
  1349. disableNativeRenderPassInFeatures = true;
  1350. rendererFeatures[i].AddRenderPasses(this, ref renderingData);
  1351. disableNativeRenderPassInFeatures = false;
  1352. }
  1353. // Remove any null render pass that might have been added by user by mistake
  1354. int count = activeRenderPassQueue.Count;
  1355. for (int i = count - 1; i >= 0; i--)
  1356. {
  1357. if (activeRenderPassQueue[i] == null)
  1358. activeRenderPassQueue.RemoveAt(i);
  1359. }
  1360. // if any pass was injected, the "automatic" store optimization policy will disable the optimized load actions
  1361. if (count > 0 && m_StoreActionsOptimizationSetting == StoreActionsOptimization.Auto)
  1362. m_UseOptimizedStoreActions = false;
  1363. }
  1364. /// <summary>
  1365. /// Calls <c>Setup</c> for each feature added to this renderer.
  1366. /// <seealso cref="ScriptableRendererFeature.SetupRenderPasses(ScriptableRenderer, in RenderingData)"/>
  1367. /// </summary>
  1368. /// <param name="renderingData"></param>
  1369. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1370. protected void SetupRenderPasses(in RenderingData renderingData)
  1371. {
  1372. using var profScope = new ProfilingScope(Profiling.setupRenderPasses);
  1373. // Add render passes from custom renderer features
  1374. for (int i = 0; i < rendererFeatures.Count; ++i)
  1375. {
  1376. if (!rendererFeatures[i].isActive)
  1377. continue;
  1378. rendererFeatures[i].SetupRenderPasses(this, in renderingData);
  1379. }
  1380. }
  1381. static void ClearRenderingState(IBaseCommandBuffer cmd)
  1382. {
  1383. using var profScope = new ProfilingScope(Profiling.clearRenderingState);
  1384. // Reset per-camera shader keywords. They are enabled depending on which render passes are executed.
  1385. cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadows, false);
  1386. cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadowCascades, false);
  1387. cmd.SetKeyword(ShaderGlobalKeywords.AdditionalLightsVertex, false);
  1388. cmd.SetKeyword(ShaderGlobalKeywords.AdditionalLightsPixel, false);
  1389. cmd.SetKeyword(ShaderGlobalKeywords.ForwardPlus, false);
  1390. cmd.SetKeyword(ShaderGlobalKeywords.AdditionalLightShadows, false);
  1391. cmd.SetKeyword(ShaderGlobalKeywords.ReflectionProbeBlending, false);
  1392. cmd.SetKeyword(ShaderGlobalKeywords.ReflectionProbeBoxProjection, false);
  1393. cmd.SetKeyword(ShaderGlobalKeywords.SoftShadows, false);
  1394. cmd.SetKeyword(ShaderGlobalKeywords.SoftShadowsLow, false);
  1395. cmd.SetKeyword(ShaderGlobalKeywords.SoftShadowsMedium, false);
  1396. cmd.SetKeyword(ShaderGlobalKeywords.SoftShadowsHigh, false);
  1397. cmd.SetKeyword(ShaderGlobalKeywords.MixedLightingSubtractive, false);
  1398. cmd.SetKeyword(ShaderGlobalKeywords.LightmapShadowMixing, false);
  1399. cmd.SetKeyword(ShaderGlobalKeywords.ShadowsShadowMask, false);
  1400. cmd.SetKeyword(ShaderGlobalKeywords.LinearToSRGBConversion, false);
  1401. cmd.SetKeyword(ShaderGlobalKeywords.LightLayers, false);
  1402. cmd.SetGlobalVector(ScreenSpaceAmbientOcclusionPass.s_AmbientOcclusionParamID, Vector4.zero);
  1403. }
  1404. internal void Clear(CameraRenderType cameraType)
  1405. {
  1406. m_ActiveColorAttachments[0] = k_CameraTarget;
  1407. for (int i = 1; i < m_ActiveColorAttachments.Length; ++i)
  1408. m_ActiveColorAttachments[i] = null;
  1409. for (int i = 0; i < m_ActiveColorAttachments.Length; ++i)
  1410. m_ActiveColorAttachmentIDs[i] = m_ActiveColorAttachments[i]?.nameID ?? 0;
  1411. m_ActiveDepthAttachment = k_CameraTarget;
  1412. m_FirstTimeCameraColorTargetIsBound = cameraType == CameraRenderType.Base;
  1413. m_FirstTimeCameraDepthTargetIsBound = true;
  1414. m_CameraColorTarget = null;
  1415. m_CameraDepthTarget = null;
  1416. }
  1417. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1418. void ExecuteBlock(int blockIndex, in RenderBlocks renderBlocks,
  1419. ScriptableRenderContext context, ref RenderingData renderingData, bool submit = false)
  1420. {
  1421. UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
  1422. foreach (int currIndex in renderBlocks.GetRange(blockIndex))
  1423. {
  1424. var renderPass = m_ActiveRenderPassQueue[currIndex];
  1425. ExecuteRenderPass(context, renderPass, cameraData, ref renderingData);
  1426. }
  1427. if (submit)
  1428. context.Submit();
  1429. }
  1430. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1431. private bool IsRenderPassEnabled(ScriptableRenderPass renderPass)
  1432. {
  1433. return renderPass.useNativeRenderPass && useRenderPassEnabled;
  1434. }
  1435. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1436. void ExecuteRenderPass(ScriptableRenderContext context, ScriptableRenderPass renderPass, UniversalCameraData cameraData, ref RenderingData renderingData)
  1437. {
  1438. // TODO: Separate command buffers per pass break the profiling scope order/hierarchy.
  1439. // If a single buffer is used (passed as a param) and passed to renderPass.Execute, put the scope into command buffer (i.e. null -> cmd)
  1440. using var profScope = new ProfilingScope(renderPass.profilingSampler);
  1441. var cmd = renderingData.commandBuffer;
  1442. // Selectively enable foveated rendering
  1443. if (cameraData.xr.supportsFoveatedRendering)
  1444. {
  1445. if ((renderPass.renderPassEvent >= RenderPassEvent.BeforeRenderingPrePasses && renderPass.renderPassEvent < RenderPassEvent.BeforeRenderingPostProcessing)
  1446. || (renderPass.renderPassEvent > RenderPassEvent.AfterRendering && XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.FoveationImage)))
  1447. {
  1448. cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Enabled);
  1449. }
  1450. }
  1451. // Track CPU only as GPU markers for this scope were "too noisy".
  1452. using (new ProfilingScope(Profiling.RenderPass.setRenderPassAttachments))
  1453. SetRenderPassAttachments(cmd, renderPass, cameraData);
  1454. // Also, we execute the commands recorded at this point to ensure SetRenderTarget is called before RenderPass.Execute
  1455. context.ExecuteCommandBuffer(cmd);
  1456. cmd.Clear();
  1457. if (IsRenderPassEnabled(renderPass) && cameraData.isRenderPassSupportedCamera)
  1458. ExecuteNativeRenderPass(context, renderPass, cameraData, ref renderingData); // cmdBuffer is executed inside
  1459. else
  1460. {
  1461. // Disable obsolete warning for internal usage
  1462. #pragma warning disable CS0618
  1463. renderPass.Execute(context, ref renderingData);
  1464. #pragma warning restore CS0618
  1465. context.ExecuteCommandBuffer(cmd);
  1466. cmd.Clear();
  1467. }
  1468. if (cameraData.xr.enabled)
  1469. {
  1470. if (cameraData.xr.supportsFoveatedRendering)
  1471. cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Disabled);
  1472. // Inform the late latching system for XR once we're done with a render pass
  1473. XRSystemUniversal.UnmarkShaderProperties(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData.xrUniversal);
  1474. context.ExecuteCommandBuffer(cmd);
  1475. cmd.Clear();
  1476. }
  1477. }
  1478. // Scene filtering is enabled when in prefab editing mode
  1479. internal bool IsSceneFilteringEnabled(Camera camera)
  1480. {
  1481. #if UNITY_EDITOR
  1482. if (CoreUtils.IsSceneFilteringEnabled() && camera.sceneViewFilterMode == Camera.SceneViewFilterMode.ShowFiltered)
  1483. return true;
  1484. #endif
  1485. return false;
  1486. }
  1487. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1488. void SetRenderPassAttachments(CommandBuffer cmd, ScriptableRenderPass renderPass, UniversalCameraData cameraData)
  1489. {
  1490. Camera camera = cameraData.camera;
  1491. ClearFlag cameraClearFlag = GetCameraClearFlag(cameraData);
  1492. // Invalid configuration - use current attachment setup
  1493. // Note: we only check color buffers. This is only technically correct because for shadowmaps and depth only passes
  1494. // we bind depth as color and Unity handles it underneath. so we never have a situation that all color buffers are null and depth is bound.
  1495. uint validColorBuffersCount = RenderingUtils.GetValidColorBufferCount(renderPass.colorAttachmentHandles);
  1496. if (validColorBuffersCount == 0)
  1497. return;
  1498. // We use a different code path for MRT since it calls a different version of API SetRenderTarget
  1499. if (RenderingUtils.IsMRT(renderPass.colorAttachmentHandles))
  1500. {
  1501. // In the MRT path we assume that all color attachments are REAL color attachments,
  1502. // and that the depth attachment is a REAL depth attachment too.
  1503. // Determine what attachments need to be cleared. ----------------
  1504. bool needCustomCameraColorClear = false;
  1505. bool needCustomCameraDepthClear = false;
  1506. int cameraColorTargetIndex = RenderingUtils.IndexOf(renderPass.colorAttachmentHandles, m_CameraColorTarget);
  1507. if (cameraColorTargetIndex != -1 && (m_FirstTimeCameraColorTargetIsBound))
  1508. {
  1509. m_FirstTimeCameraColorTargetIsBound = false; // register that we did clear the camera target the first time it was bound
  1510. // Overlay cameras composite on top of previous ones. They don't clear.
  1511. // MTT: Commented due to not implemented yet
  1512. // if (renderingData.cameraData.renderType == CameraRenderType.Overlay)
  1513. // clearFlag = ClearFlag.None;
  1514. // We need to specifically clear the camera color target.
  1515. // But there is still a chance we don't need to issue individual clear() on each render-targets if they all have the same clear parameters.
  1516. needCustomCameraColorClear = (cameraClearFlag & ClearFlag.Color) != (renderPass.clearFlag & ClearFlag.Color)
  1517. || cameraData.backgroundColor != renderPass.clearColor;
  1518. }
  1519. // Note: if we have to give up the assumption that no depthTarget can be included in the MRT colorAttachments, we might need something like this:
  1520. // int cameraTargetDepthIndex = IndexOf(renderPass.colorAttachments, m_CameraDepthTarget);
  1521. // if( !renderTargetAlreadySet && cameraTargetDepthIndex != -1 && m_FirstTimeCameraDepthTargetIsBound)
  1522. // { ...
  1523. // }
  1524. var depthTargetID = m_CameraDepthTarget.nameID;
  1525. #if ENABLE_VR && ENABLE_XR_MODULE
  1526. if (cameraData.xr.enabled)
  1527. depthTargetID = new RenderTargetIdentifier(depthTargetID, 0, CubemapFace.Unknown, -1);
  1528. #endif
  1529. if (new RenderTargetIdentifier(renderPass.depthAttachmentHandle.nameID, 0) == new RenderTargetIdentifier(depthTargetID, 0) // Strip the depthSlice
  1530. && m_FirstTimeCameraDepthTargetIsBound)
  1531. {
  1532. m_FirstTimeCameraDepthTargetIsBound = false;
  1533. needCustomCameraDepthClear = (cameraClearFlag & ClearFlag.DepthStencil) != (renderPass.clearFlag & ClearFlag.DepthStencil);
  1534. }
  1535. // Perform all clear operations needed. ----------------
  1536. // We try to minimize calls to SetRenderTarget().
  1537. // We get here only if cameraColorTarget needs to be handled separately from the rest of the color attachments.
  1538. if (needCustomCameraColorClear)
  1539. {
  1540. // Clear camera color render-target separately from the rest of the render-targets.
  1541. if ((cameraClearFlag & ClearFlag.Color) != 0 && (!IsRenderPassEnabled(renderPass) || !cameraData.isRenderPassSupportedCamera))
  1542. SetRenderTarget(cmd, renderPass.colorAttachmentHandles[cameraColorTargetIndex], renderPass.depthAttachmentHandle, ClearFlag.Color, cameraData.backgroundColor);
  1543. if ((renderPass.clearFlag & ClearFlag.Color) != 0)
  1544. {
  1545. uint otherTargetsCount = RenderingUtils.CountDistinct(renderPass.colorAttachmentHandles, m_CameraColorTarget);
  1546. var nonCameraAttachments = m_TrimmedColorAttachmentCopies[otherTargetsCount];
  1547. int writeIndex = 0;
  1548. for (int readIndex = 0; readIndex < renderPass.colorAttachmentHandles.Length; ++readIndex)
  1549. {
  1550. if (renderPass.colorAttachmentHandles[readIndex] != null &&
  1551. renderPass.colorAttachmentHandles[readIndex].nameID != 0 &&
  1552. renderPass.colorAttachmentHandles[readIndex].nameID != m_CameraColorTarget.nameID)
  1553. {
  1554. nonCameraAttachments[writeIndex] = renderPass.colorAttachmentHandles[readIndex];
  1555. ++writeIndex;
  1556. }
  1557. }
  1558. var nonCameraAttachmentIDs = m_TrimmedColorAttachmentCopyIDs[otherTargetsCount];
  1559. for (int i = 0; i < otherTargetsCount; ++i)
  1560. nonCameraAttachmentIDs[i] = nonCameraAttachments[i].nameID;
  1561. if (writeIndex != otherTargetsCount)
  1562. Debug.LogError("writeIndex and otherTargetsCount values differed. writeIndex:" + writeIndex + " otherTargetsCount:" + otherTargetsCount);
  1563. if (!IsRenderPassEnabled(renderPass) || !cameraData.isRenderPassSupportedCamera)
  1564. SetRenderTarget(cmd, nonCameraAttachments, nonCameraAttachmentIDs, m_CameraDepthTarget, ClearFlag.Color, renderPass.clearColor);
  1565. }
  1566. }
  1567. // Bind all attachments, clear color only if there was no custom behaviour for cameraColorTarget, clear depth as needed.
  1568. ClearFlag finalClearFlag = ClearFlag.None;
  1569. finalClearFlag |= needCustomCameraDepthClear ? (cameraClearFlag & ClearFlag.DepthStencil) : (renderPass.clearFlag & ClearFlag.DepthStencil);
  1570. finalClearFlag |= needCustomCameraColorClear ? (IsRenderPassEnabled(renderPass) ? (cameraClearFlag & ClearFlag.Color) : 0) : (renderPass.clearFlag & ClearFlag.Color);
  1571. if (IsRenderPassEnabled(renderPass) && cameraData.isRenderPassSupportedCamera)
  1572. SetNativeRenderPassMRTAttachmentList(renderPass, cameraData, needCustomCameraColorClear, finalClearFlag);
  1573. // Only setup render target if current render pass attachments are different from the active ones.
  1574. if (!RenderingUtils.SequenceEqual(renderPass.colorAttachmentHandles, m_ActiveColorAttachments)
  1575. || renderPass.depthAttachmentHandle.nameID != m_ActiveDepthAttachment
  1576. || finalClearFlag != ClearFlag.None)
  1577. {
  1578. int lastValidRTindex = RenderingUtils.LastValid(renderPass.colorAttachmentHandles);
  1579. if (lastValidRTindex >= 0)
  1580. {
  1581. int rtCount = lastValidRTindex + 1;
  1582. var trimmedAttachments = m_TrimmedColorAttachmentCopies[rtCount];
  1583. for (int i = 0; i < rtCount; ++i)
  1584. trimmedAttachments[i] = renderPass.colorAttachmentHandles[i];
  1585. var trimmedAttachmentIDs = m_TrimmedColorAttachmentCopyIDs[rtCount];
  1586. for (int i = 0; i < rtCount; ++i)
  1587. trimmedAttachmentIDs[i] = trimmedAttachments[i].nameID;
  1588. if (!IsRenderPassEnabled(renderPass) || !cameraData.isRenderPassSupportedCamera)
  1589. {
  1590. var depthAttachment = m_CameraDepthTarget;
  1591. if (renderPass.overrideCameraTarget)
  1592. depthAttachment = renderPass.depthAttachmentHandle;
  1593. else
  1594. m_FirstTimeCameraDepthTargetIsBound = false;
  1595. // Only one RTHandle is necessary to set the viewport in dynamic scaling, use depth
  1596. SetRenderTarget(cmd, trimmedAttachments, trimmedAttachmentIDs, depthAttachment, finalClearFlag, renderPass.clearColor);
  1597. }
  1598. #if ENABLE_VR && ENABLE_XR_MODULE
  1599. if (cameraData.xr.enabled)
  1600. {
  1601. // SetRenderTarget might alter the internal device state(winding order).
  1602. // Non-stereo buffer is already updated internally when switching render target. We update stereo buffers here to keep the consistency.
  1603. int xrTargetIndex = RenderingUtils.IndexOf(renderPass.colorAttachmentHandles, cameraData.xr.renderTarget);
  1604. bool renderIntoTexture = xrTargetIndex == -1;
  1605. cameraData.PushBuiltinShaderConstantsXR(CommandBufferHelpers.GetRasterCommandBuffer(cmd), renderIntoTexture);
  1606. XRSystemUniversal.MarkShaderProperties(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData.xrUniversal, renderIntoTexture);
  1607. }
  1608. #endif
  1609. }
  1610. }
  1611. }
  1612. else
  1613. {
  1614. // Currently in non-MRT case, color attachment can actually be a depth attachment.
  1615. var passColorAttachment = renderPass.colorAttachmentHandle;
  1616. var passDepthAttachment = renderPass.depthAttachmentHandle;
  1617. // When render pass doesn't call ConfigureTarget we assume it's expected to render to camera target
  1618. // which might be backbuffer or the framebuffer render textures.
  1619. if (!renderPass.overrideCameraTarget)
  1620. {
  1621. // Default render pass attachment for passes before main rendering is current active
  1622. // early return so we don't change current render target setup.
  1623. if (renderPass.renderPassEvent < RenderPassEvent.BeforeRenderingPrePasses)
  1624. return;
  1625. // Otherwise default is the pipeline camera target.
  1626. passColorAttachment = m_CameraColorTarget;
  1627. passDepthAttachment = m_CameraDepthTarget;
  1628. }
  1629. ClearFlag finalClearFlag = ClearFlag.None;
  1630. Color finalClearColor;
  1631. if (passColorAttachment.nameID == m_CameraColorTarget.nameID && m_FirstTimeCameraColorTargetIsBound)
  1632. {
  1633. m_FirstTimeCameraColorTargetIsBound = false; // register that we did clear the camera target the first time it was bound
  1634. finalClearFlag |= (cameraClearFlag & ClearFlag.Color);
  1635. // on platforms that support Load and Store actions having the clear flag means that the action will be DontCare, which is something we want when the color target is bound the first time
  1636. // (passColorAttachment.nameID != BuiltinRenderTextureType.CameraTarget) check below ensures camera UI's clearFlag is respected when targeting built-in backbuffer.
  1637. if (SystemInfo.usesLoadStoreActions && new RenderTargetIdentifier(passColorAttachment.nameID, 0, depthSlice: 0) != BuiltinRenderTextureType.CameraTarget)
  1638. finalClearFlag |= renderPass.clearFlag;
  1639. finalClearColor = cameraData.backgroundColor;
  1640. if (m_FirstTimeCameraDepthTargetIsBound)
  1641. {
  1642. // m_CameraColorTarget can be an opaque pointer to a RenderTexture with depth-surface.
  1643. // We cannot infer this information here, so we must assume both camera color and depth are first-time bound here (this is the legacy behaviour).
  1644. m_FirstTimeCameraDepthTargetIsBound = false;
  1645. finalClearFlag |= (cameraClearFlag & ClearFlag.DepthStencil);
  1646. }
  1647. }
  1648. else
  1649. {
  1650. finalClearFlag |= (renderPass.clearFlag & ClearFlag.Color);
  1651. finalClearColor = renderPass.clearColor;
  1652. }
  1653. // Condition (m_CameraDepthTarget!=BuiltinRenderTextureType.CameraTarget) below prevents m_FirstTimeCameraDepthTargetIsBound flag from being reset during non-camera passes (such as Color Grading LUT). This ensures that in those cases, cameraDepth will actually be cleared during the later camera pass.
  1654. if (new RenderTargetIdentifier(m_CameraDepthTarget.nameID, 0, depthSlice: 0) != BuiltinRenderTextureType.CameraTarget && (passDepthAttachment.nameID == m_CameraDepthTarget.nameID || passColorAttachment.nameID == m_CameraDepthTarget.nameID) && m_FirstTimeCameraDepthTargetIsBound)
  1655. {
  1656. m_FirstTimeCameraDepthTargetIsBound = false;
  1657. finalClearFlag |= (cameraClearFlag & ClearFlag.DepthStencil);
  1658. // finalClearFlag |= (cameraClearFlag & ClearFlag.Color); // <- m_CameraDepthTarget is never a color-surface, so no need to add this here.
  1659. }
  1660. else
  1661. finalClearFlag |= (renderPass.clearFlag & ClearFlag.DepthStencil);
  1662. // If scene filtering is enabled (prefab edit mode), the filtering is implemented compositing some builtin ImageEffect passes.
  1663. // For the composition to work, we need to clear the color buffer alpha to 0
  1664. // How filtering works:
  1665. // - SRP frame is fully rendered as background
  1666. // - builtin ImageEffect pass grey-out of the full scene previously rendered
  1667. // - SRP frame rendering only the objects belonging to the prefab being edited (with clearColor.a = 0)
  1668. // - builtin ImageEffect pass compositing the two previous passes
  1669. // TODO: We should implement filtering fully in SRP to remove builtin dependencies
  1670. if (IsSceneFilteringEnabled(camera))
  1671. {
  1672. finalClearColor.a = 0;
  1673. finalClearFlag &= ~ClearFlag.Depth;
  1674. }
  1675. // If the debug-handler needs to clear the screen, update "finalClearColor" accordingly...
  1676. if ((DebugHandler != null) && DebugHandler.IsActiveForCamera(cameraData.isPreviewCamera))
  1677. {
  1678. DebugHandler.TryGetScreenClearColor(ref finalClearColor);
  1679. }
  1680. // Disabling Native RenderPass if not using RTHandles as we will be relying on info inside handles object
  1681. if (IsRenderPassEnabled(renderPass) && cameraData.isRenderPassSupportedCamera)
  1682. {
  1683. SetNativeRenderPassAttachmentList(renderPass, cameraData, passColorAttachment, passDepthAttachment, finalClearFlag, finalClearColor);
  1684. }
  1685. else
  1686. {
  1687. // As alternative we would need a way to check if rts are not going to be used as shader resource
  1688. bool colorAttachmentChanged = false;
  1689. // Special handling for the first attachment to support `renderPass.overrideCameraTarget`.
  1690. if (passColorAttachment.nameID != m_ActiveColorAttachments[0])
  1691. colorAttachmentChanged = true;
  1692. // Check the rest of attachments (1-8)
  1693. for (int i = 1; i < m_ActiveColorAttachments.Length; i++)
  1694. {
  1695. if (renderPass.colorAttachmentHandles[i] != m_ActiveColorAttachments[i])
  1696. {
  1697. colorAttachmentChanged = true;
  1698. break;
  1699. }
  1700. }
  1701. // Only setup render target if current render pass attachments are different from the active ones
  1702. if (colorAttachmentChanged || passDepthAttachment.nameID != m_ActiveDepthAttachment || finalClearFlag != ClearFlag.None ||
  1703. renderPass.colorStoreActions[0] != m_ActiveColorStoreActions[0] || renderPass.depthStoreAction != m_ActiveDepthStoreAction)
  1704. {
  1705. SetRenderTarget(cmd, passColorAttachment, passDepthAttachment, finalClearFlag, finalClearColor, renderPass.colorStoreActions[0], renderPass.depthStoreAction);
  1706. #if ENABLE_VR && ENABLE_XR_MODULE
  1707. if (cameraData.xr.enabled)
  1708. {
  1709. // SetRenderTarget might alter the internal device state(winding order).
  1710. // Non-stereo buffer is already updated internally when switching render target. We update stereo buffers here to keep the consistency.
  1711. bool renderIntoTexture = passColorAttachment.nameID != cameraData.xr.renderTarget;
  1712. cameraData.PushBuiltinShaderConstantsXR(CommandBufferHelpers.GetRasterCommandBuffer(cmd), renderIntoTexture);
  1713. XRSystemUniversal.MarkShaderProperties(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData.xrUniversal, renderIntoTexture);
  1714. }
  1715. #endif
  1716. }
  1717. }
  1718. }
  1719. #if ENABLE_SHADER_DEBUG_PRINT
  1720. ShaderDebugPrintManager.instance.SetShaderDebugPrintInputConstants(cmd, ShaderDebugPrintInputProducer.Get());
  1721. ShaderDebugPrintManager.instance.SetShaderDebugPrintBindings(cmd);
  1722. #endif
  1723. }
  1724. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1725. void BeginXRRendering(CommandBuffer cmd, ScriptableRenderContext context, ref CameraData cameraData)
  1726. {
  1727. #if ENABLE_VR && ENABLE_XR_MODULE
  1728. if (cameraData.xr.enabled)
  1729. {
  1730. if (cameraData.xrUniversal.isLateLatchEnabled)
  1731. cameraData.xrUniversal.canMarkLateLatch = true;
  1732. cameraData.xr.StartSinglePass(cmd);
  1733. if (cameraData.xr.supportsFoveatedRendering)
  1734. {
  1735. cmd.ConfigureFoveatedRendering(cameraData.xr.foveatedRenderingInfo);
  1736. if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster))
  1737. cmd.SetKeyword(ShaderGlobalKeywords.FoveatedRenderingNonUniformRaster, true);
  1738. }
  1739. context.ExecuteCommandBuffer(cmd);
  1740. cmd.Clear();
  1741. }
  1742. #endif
  1743. }
  1744. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1745. void EndXRRendering(CommandBuffer cmd, ScriptableRenderContext context, ref CameraData cameraData)
  1746. {
  1747. #if ENABLE_VR && ENABLE_XR_MODULE
  1748. if (cameraData.xr.enabled)
  1749. {
  1750. cameraData.xr.StopSinglePass(cmd);
  1751. if (XRSystem.foveatedRenderingCaps != FoveatedRenderingCaps.None)
  1752. {
  1753. if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster))
  1754. cmd.SetKeyword(ShaderGlobalKeywords.FoveatedRenderingNonUniformRaster, false);
  1755. cmd.ConfigureFoveatedRendering(IntPtr.Zero);
  1756. }
  1757. context.ExecuteCommandBuffer(cmd);
  1758. cmd.Clear();
  1759. }
  1760. #endif
  1761. }
  1762. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1763. internal static void SetRenderTarget(CommandBuffer cmd, RTHandle colorAttachment, RTHandle depthAttachment, ClearFlag clearFlag, Color clearColor)
  1764. {
  1765. m_ActiveColorAttachments[0] = colorAttachment;
  1766. for (int i = 1; i < m_ActiveColorAttachments.Length; ++i)
  1767. m_ActiveColorAttachments[i] = null;
  1768. for (int i = 0; i < m_ActiveColorAttachments.Length; ++i)
  1769. m_ActiveColorAttachmentIDs[i] = m_ActiveColorAttachments[i]?.nameID ?? 0;
  1770. m_ActiveColorStoreActions[0] = RenderBufferStoreAction.Store;
  1771. m_ActiveDepthStoreAction = RenderBufferStoreAction.Store;
  1772. for (int i = 1; i < m_ActiveColorStoreActions.Length; ++i)
  1773. m_ActiveColorStoreActions[i] = RenderBufferStoreAction.Store;
  1774. m_ActiveDepthAttachment = depthAttachment;
  1775. RenderBufferLoadAction colorLoadAction = ((uint)clearFlag & (uint)ClearFlag.Color) != 0 ? RenderBufferLoadAction.DontCare : RenderBufferLoadAction.Load;
  1776. RenderBufferLoadAction depthLoadAction = ((uint)clearFlag & (uint)ClearFlag.Depth) != 0 || ((uint)clearFlag & (uint)ClearFlag.Stencil) != 0 ?
  1777. RenderBufferLoadAction.DontCare : RenderBufferLoadAction.Load;
  1778. // Storing depth and color in the same RT should only be possible with alias RTHandles, those that create rendertargets with RTAlloc()
  1779. if (colorAttachment.rt == null && depthAttachment.rt == null && depthAttachment.nameID == k_CameraTarget.nameID)
  1780. SetRenderTarget(cmd, colorAttachment, colorLoadAction, RenderBufferStoreAction.Store,
  1781. colorAttachment, depthLoadAction, RenderBufferStoreAction.Store, clearFlag, clearColor);
  1782. else
  1783. SetRenderTarget(cmd, colorAttachment, colorLoadAction, RenderBufferStoreAction.Store,
  1784. depthAttachment, depthLoadAction, RenderBufferStoreAction.Store, clearFlag, clearColor);
  1785. }
  1786. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1787. internal static void SetRenderTarget(CommandBuffer cmd, RTHandle colorAttachment, RTHandle depthAttachment, ClearFlag clearFlag, Color clearColor, RenderBufferStoreAction colorStoreAction, RenderBufferStoreAction depthStoreAction)
  1788. {
  1789. m_ActiveColorAttachments[0] = colorAttachment;
  1790. for (int i = 1; i < m_ActiveColorAttachments.Length; ++i)
  1791. m_ActiveColorAttachments[i] = null;
  1792. for (int i = 0; i < m_ActiveColorAttachments.Length; ++i)
  1793. m_ActiveColorAttachmentIDs[i] = m_ActiveColorAttachments[i]?.nameID ?? 0;
  1794. m_ActiveColorStoreActions[0] = colorStoreAction;
  1795. m_ActiveDepthStoreAction = depthStoreAction;
  1796. for (int i = 1; i < m_ActiveColorStoreActions.Length; ++i)
  1797. m_ActiveColorStoreActions[i] = RenderBufferStoreAction.Store;
  1798. m_ActiveDepthAttachment = depthAttachment;
  1799. RenderBufferLoadAction colorLoadAction = ((uint)clearFlag & (uint)ClearFlag.Color) != 0 ?
  1800. RenderBufferLoadAction.DontCare : RenderBufferLoadAction.Load;
  1801. RenderBufferLoadAction depthLoadAction = ((uint)clearFlag & (uint)ClearFlag.Depth) != 0 ?
  1802. RenderBufferLoadAction.DontCare : RenderBufferLoadAction.Load;
  1803. // if we shouldn't use optimized store actions then fall back to the conservative safe (un-optimal!) route and just store everything
  1804. if (!m_UseOptimizedStoreActions)
  1805. {
  1806. if (colorStoreAction != RenderBufferStoreAction.StoreAndResolve)
  1807. colorStoreAction = RenderBufferStoreAction.Store;
  1808. if (depthStoreAction != RenderBufferStoreAction.StoreAndResolve)
  1809. depthStoreAction = RenderBufferStoreAction.Store;
  1810. }
  1811. SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction,
  1812. depthAttachment, depthLoadAction, depthStoreAction, clearFlag, clearColor);
  1813. }
  1814. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1815. static void SetRenderTarget(CommandBuffer cmd,
  1816. RTHandle colorAttachment,
  1817. RenderBufferLoadAction colorLoadAction,
  1818. RenderBufferStoreAction colorStoreAction,
  1819. RTHandle depthAttachment,
  1820. RenderBufferLoadAction depthLoadAction,
  1821. RenderBufferStoreAction depthStoreAction,
  1822. ClearFlag clearFlags,
  1823. Color clearColor)
  1824. {
  1825. // XRTODO: Revisit the logic. Why treat CameraTarget depth specially?
  1826. if (depthAttachment.nameID == BuiltinRenderTextureType.CameraTarget)
  1827. CoreUtils.SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction,
  1828. colorAttachment, depthLoadAction, depthStoreAction, clearFlags, clearColor);
  1829. else
  1830. CoreUtils.SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction,
  1831. depthAttachment, depthLoadAction, depthStoreAction, clearFlags, clearColor);
  1832. }
  1833. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  1834. static void SetRenderTarget(CommandBuffer cmd, RTHandle[] colorAttachments, RenderTargetIdentifier[] colorAttachmentIDs, RTHandle depthAttachment, ClearFlag clearFlag, Color clearColor)
  1835. {
  1836. m_ActiveColorAttachments = colorAttachments;
  1837. m_ActiveColorAttachmentIDs = colorAttachmentIDs;
  1838. m_ActiveDepthAttachment = depthAttachment;
  1839. CoreUtils.SetRenderTarget(cmd, m_ActiveColorAttachmentIDs, depthAttachment, clearFlag, clearColor);
  1840. }
  1841. internal virtual void SwapColorBuffer(CommandBuffer cmd) { }
  1842. internal virtual void EnableSwapBufferMSAA(bool enable) { }
  1843. [Conditional("UNITY_EDITOR")]
  1844. void DrawGizmos(ScriptableRenderContext context, Camera camera, GizmoSubset gizmoSubset, ref RenderingData renderingData)
  1845. {
  1846. #if UNITY_EDITOR
  1847. if (!Handles.ShouldRenderGizmos() || camera.sceneViewFilterMode == Camera.SceneViewFilterMode.ShowFiltered)
  1848. return;
  1849. var cmd = renderingData.commandBuffer;
  1850. using (new ProfilingScope(cmd, Profiling.drawGizmos))
  1851. {
  1852. context.ExecuteCommandBuffer(cmd);
  1853. cmd.Clear();
  1854. context.DrawGizmos(camera, gizmoSubset);
  1855. }
  1856. context.ExecuteCommandBuffer(cmd);
  1857. cmd.Clear();
  1858. #endif
  1859. }
  1860. [Conditional("UNITY_EDITOR")]
  1861. void DrawWireOverlay(ScriptableRenderContext context, Camera camera)
  1862. {
  1863. context.DrawWireOverlay(camera);
  1864. }
  1865. void InternalStartRendering(ScriptableRenderContext context, ref RenderingData renderingData)
  1866. {
  1867. using (new ProfilingScope(Profiling.internalStartRendering))
  1868. {
  1869. for (int i = 0; i < m_ActiveRenderPassQueue.Count; ++i)
  1870. {
  1871. // Disable obsolete warning for internal usage
  1872. #pragma warning disable CS0618
  1873. m_ActiveRenderPassQueue[i].OnCameraSetup(renderingData.commandBuffer, ref renderingData);
  1874. #pragma warning restore CS0618
  1875. }
  1876. }
  1877. context.ExecuteCommandBuffer(renderingData.commandBuffer);
  1878. renderingData.commandBuffer.Clear();
  1879. }
  1880. // Common ScriptableRenderer.Execute and RenderGraph path
  1881. void InternalFinishRenderingCommon(CommandBuffer cmd, bool resolveFinalTarget)
  1882. {
  1883. using (new ProfilingScope(Profiling.internalFinishRenderingCommon))
  1884. {
  1885. for (int i = 0; i < m_ActiveRenderPassQueue.Count; ++i)
  1886. m_ActiveRenderPassQueue[i].FrameCleanup(cmd);
  1887. // Happens when rendering the last camera in the camera stack.
  1888. if (resolveFinalTarget)
  1889. {
  1890. for (int i = 0; i < m_ActiveRenderPassQueue.Count; ++i)
  1891. {
  1892. // Disable obsolete warning for internal usage
  1893. #pragma warning disable CS0618
  1894. m_ActiveRenderPassQueue[i].OnFinishCameraStackRendering(cmd);
  1895. #pragma warning restore CS0618
  1896. }
  1897. FinishRendering(cmd);
  1898. // We finished camera stacking and released all intermediate pipeline textures.
  1899. m_IsPipelineExecuting = false;
  1900. }
  1901. m_ActiveRenderPassQueue.Clear();
  1902. }
  1903. }
  1904. // ScriptableRenderer.Execute path
  1905. void InternalFinishRenderingExecute(ScriptableRenderContext context, CommandBuffer cmd, bool resolveFinalTarget)
  1906. {
  1907. InternalFinishRenderingCommon(cmd, resolveFinalTarget);
  1908. ResetNativeRenderPassFrameData();
  1909. context.ExecuteCommandBuffer(cmd);
  1910. cmd.Clear();
  1911. }
  1912. internal static void SortStable(List<ScriptableRenderPass> list)
  1913. {
  1914. int j;
  1915. for (int i = 1; i < list.Count; ++i)
  1916. {
  1917. ScriptableRenderPass curr = list[i];
  1918. j = i - 1;
  1919. for (; j >= 0 && curr < list[j]; --j)
  1920. list[j + 1] = list[j];
  1921. list[j + 1] = curr;
  1922. }
  1923. }
  1924. internal struct RenderBlocks : IDisposable
  1925. {
  1926. private NativeArray<RenderPassEvent> m_BlockEventLimits;
  1927. private NativeArray<int> m_BlockRanges;
  1928. private NativeArray<int> m_BlockRangeLengths;
  1929. public RenderBlocks(List<ScriptableRenderPass> activeRenderPassQueue)
  1930. {
  1931. // Upper limits for each block. Each block will contains render passes with events below the limit.
  1932. m_BlockEventLimits = new NativeArray<RenderPassEvent>(k_RenderPassBlockCount, Allocator.Temp);
  1933. m_BlockRanges = new NativeArray<int>(m_BlockEventLimits.Length + 1, Allocator.Temp);
  1934. m_BlockRangeLengths = new NativeArray<int>(m_BlockRanges.Length, Allocator.Temp);
  1935. m_BlockEventLimits[RenderPassBlock.BeforeRendering] = RenderPassEvent.BeforeRenderingPrePasses;
  1936. m_BlockEventLimits[RenderPassBlock.MainRenderingOpaque] = RenderPassEvent.AfterRenderingOpaques;
  1937. m_BlockEventLimits[RenderPassBlock.MainRenderingTransparent] = RenderPassEvent.AfterRenderingPostProcessing;
  1938. m_BlockEventLimits[RenderPassBlock.AfterRendering] = (RenderPassEvent)Int32.MaxValue;
  1939. // blockRanges[0] is always 0
  1940. // blockRanges[i] is the index of the first RenderPass found in m_ActiveRenderPassQueue that has a ScriptableRenderPass.renderPassEvent higher than blockEventLimits[i] (i.e, should be executed after blockEventLimits[i])
  1941. // blockRanges[blockEventLimits.Length] is m_ActiveRenderPassQueue.Count
  1942. FillBlockRanges(activeRenderPassQueue);
  1943. m_BlockEventLimits.Dispose();
  1944. for (int i = 0; i < m_BlockRanges.Length - 1; i++)
  1945. {
  1946. m_BlockRangeLengths[i] = m_BlockRanges[i + 1] - m_BlockRanges[i];
  1947. }
  1948. }
  1949. // RAII like Dispose pattern implementation for 'using' keyword
  1950. public void Dispose()
  1951. {
  1952. m_BlockRangeLengths.Dispose();
  1953. m_BlockRanges.Dispose();
  1954. }
  1955. // Fill in render pass indices for each block. End index is startIndex + 1.
  1956. void FillBlockRanges(List<ScriptableRenderPass> activeRenderPassQueue)
  1957. {
  1958. int currRangeIndex = 0;
  1959. int currRenderPass = 0;
  1960. m_BlockRanges[currRangeIndex++] = 0;
  1961. // For each block, it finds the first render pass index that has an event
  1962. // higher than the block limit.
  1963. for (int i = 0; i < m_BlockEventLimits.Length - 1; ++i)
  1964. {
  1965. while (currRenderPass < activeRenderPassQueue.Count &&
  1966. activeRenderPassQueue[currRenderPass].renderPassEvent < m_BlockEventLimits[i])
  1967. currRenderPass++;
  1968. m_BlockRanges[currRangeIndex++] = currRenderPass;
  1969. }
  1970. m_BlockRanges[currRangeIndex] = activeRenderPassQueue.Count;
  1971. }
  1972. public int GetLength(int index)
  1973. {
  1974. return m_BlockRangeLengths[index];
  1975. }
  1976. // Minimal foreach support
  1977. public struct BlockRange : IDisposable
  1978. {
  1979. int m_Current;
  1980. int m_End;
  1981. public BlockRange(int begin, int end)
  1982. {
  1983. Assertions.Assert.IsTrue(begin <= end);
  1984. m_Current = begin < end ? begin : end;
  1985. m_End = end >= begin ? end : begin;
  1986. m_Current -= 1;
  1987. }
  1988. public BlockRange GetEnumerator() { return this; }
  1989. public bool MoveNext() { return ++m_Current < m_End; }
  1990. public int Current { get => m_Current; }
  1991. public void Dispose() { }
  1992. }
  1993. public BlockRange GetRange(int index)
  1994. {
  1995. return new BlockRange(m_BlockRanges[index], m_BlockRanges[index + 1]);
  1996. }
  1997. }
  1998. internal virtual bool supportsNativeRenderPassRendergraphCompiler { get => false; }
  1999. /// <summary>
  2000. /// Used to determine if this renderer supports the use of GPU occlusion culling.
  2001. /// </summary>
  2002. public virtual bool supportsGPUOcclusion => false;
  2003. }
  2004. }