暫無描述
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.

UniversalAdditionalCameraData.cs 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine.Serialization;
  6. using UnityEngine.Assertions;
  7. namespace UnityEngine.Rendering.Universal
  8. {
  9. /// <summary>
  10. /// Holds information about whether to override certain camera rendering options from the render pipeline asset.
  11. /// When set to <c>Off</c> option will be disabled regardless of what is set on the pipeline asset.
  12. /// When set to <c>On</c> option will be enabled regardless of what is set on the pipeline asset.
  13. /// When set to <c>UsePipelineSetting</c> value set in the <see cref="UniversalRenderPipelineAsset"/>.
  14. /// </summary>
  15. public enum CameraOverrideOption
  16. {
  17. /// <summary>
  18. /// Use this to disable regardless of what is set on the pipeline asset.
  19. /// </summary>
  20. Off,
  21. /// <summary>
  22. /// Use this to enable regardless of what is set on the pipeline asset.
  23. /// </summary>
  24. On,
  25. /// <summary>
  26. /// Use this to choose the setting set on the pipeline asset.
  27. /// </summary>
  28. [InspectorName("Use settings from Render Pipeline Asset")]
  29. UsePipelineSettings,
  30. }
  31. /// <summary>
  32. /// Options to control the renderer override.
  33. /// This enum is no longer in use.
  34. /// </summary>
  35. [Obsolete("Renderer override is no longer used, renderers are referenced by index on the pipeline asset.")]
  36. public enum RendererOverrideOption
  37. {
  38. /// <summary>
  39. /// Use this to choose a custom override.
  40. /// </summary>
  41. Custom,
  42. /// <summary>
  43. /// Use this to choose the setting set on the pipeline asset.
  44. /// </summary>
  45. UsePipelineSettings,
  46. }
  47. /// <summary>
  48. /// Holds information about the post-processing anti-aliasing mode.
  49. /// When set to <c>None</c> no post-processing anti-aliasing pass will be performed.
  50. /// When set to <c>Fast</c> a fast approximated anti-aliasing pass will render when resolving the camera to screen.
  51. /// When set to <c>SubpixelMorphologicalAntiAliasing</c> SMAA pass will render when resolving the camera to screen.
  52. /// You can choose the SMAA quality by setting <seealso cref="AntialiasingQuality"/>.
  53. /// </summary>
  54. public enum AntialiasingMode
  55. {
  56. /// <summary>
  57. /// Use this to have no post-processing anti-aliasing pass performed.
  58. /// </summary>
  59. [InspectorName("No Anti-aliasing")]
  60. None,
  61. /// <summary>
  62. /// Use this to have a fast approximated anti-aliasing pass rendered when resolving the camera to screen
  63. /// </summary>
  64. [InspectorName("Fast Approximate Anti-aliasing (FXAA)")]
  65. FastApproximateAntialiasing,
  66. /// <summary>
  67. /// Use this to have a <c>SubpixelMorphologicalAntiAliasing</c> SMAA pass rendered when resolving the camera to screen
  68. /// You can choose the SMAA quality by setting <seealso cref="AntialiasingQuality"/>.
  69. /// </summary>
  70. [InspectorName("Subpixel Morphological Anti-aliasing (SMAA)")]
  71. SubpixelMorphologicalAntiAliasing,
  72. /// <summary>
  73. /// Use this to have a temporal anti-aliasing pass rendered when resolving camera to screen.
  74. /// </summary>
  75. [InspectorName("Temporal Anti-aliasing (TAA)")]
  76. TemporalAntiAliasing,
  77. }
  78. /// <summary>
  79. /// Holds information about the render type of a camera. Options are Base or Overlay.
  80. /// Base rendering type allows the camera to render to either the screen or to a texture.
  81. /// Overlay rendering type allows the camera to render on top of a previous camera output, thus compositing camera results.
  82. /// </summary>
  83. public enum CameraRenderType
  84. {
  85. /// <summary>
  86. /// Use this to select the base camera render type.
  87. /// Base rendering type allows the camera to render to either the screen or to a texture.
  88. /// </summary>
  89. Base,
  90. /// <summary>
  91. /// Use this to select the overlay camera render type.
  92. /// Overlay rendering type allows the camera to render on top of a previous camera output, thus compositing camera results.
  93. /// </summary>
  94. Overlay,
  95. }
  96. /// <summary>
  97. /// Controls <c>SubpixelMorphologicalAntiAliasing</c> SMAA anti-aliasing quality.
  98. /// </summary>
  99. public enum AntialiasingQuality
  100. {
  101. /// <summary>
  102. /// Use this to select the low <c>SubpixelMorphologicalAntiAliasing</c> SMAA quality
  103. /// </summary>
  104. Low,
  105. /// <summary>
  106. /// Use this to select the medium <c>SubpixelMorphologicalAntiAliasing</c> SMAA quality
  107. /// </summary>
  108. Medium,
  109. /// <summary>
  110. /// Use this to select the high <c>SubpixelMorphologicalAntiAliasing</c> SMAA quality
  111. /// </summary>
  112. High
  113. }
  114. /// <summary>
  115. /// Contains extension methods for Camera class.
  116. /// </summary>
  117. public static class CameraExtensions
  118. {
  119. /// <summary>
  120. /// Universal Render Pipeline exposes additional rendering data in a separate component.
  121. /// This method returns the additional data component for the given camera or create one if it doesn't exist yet.
  122. /// </summary>
  123. /// <param name="camera"></param>
  124. /// <returns>The <c>UniversalAdditionalCameraData</c> for this camera.</returns>
  125. /// <see cref="UniversalAdditionalCameraData"/>
  126. public static UniversalAdditionalCameraData GetUniversalAdditionalCameraData(this Camera camera)
  127. {
  128. var gameObject = camera.gameObject;
  129. bool componentExists = gameObject.TryGetComponent<UniversalAdditionalCameraData>(out var cameraData);
  130. if (!componentExists)
  131. cameraData = gameObject.AddComponent<UniversalAdditionalCameraData>();
  132. return cameraData;
  133. }
  134. /// <summary>
  135. /// Returns the VolumeFrameworkUpdateMode set on the camera.
  136. /// </summary>
  137. /// <param name="camera"></param>
  138. /// <returns></returns>
  139. public static VolumeFrameworkUpdateMode GetVolumeFrameworkUpdateMode(this Camera camera)
  140. {
  141. UniversalAdditionalCameraData cameraData = camera.GetUniversalAdditionalCameraData();
  142. return cameraData.volumeFrameworkUpdateMode;
  143. }
  144. /// <summary>
  145. /// Sets the VolumeFrameworkUpdateMode for the camera.
  146. /// </summary>
  147. /// <param name="camera"></param>
  148. /// <param name="mode"></param>
  149. public static void SetVolumeFrameworkUpdateMode(this Camera camera, VolumeFrameworkUpdateMode mode)
  150. {
  151. UniversalAdditionalCameraData cameraData = camera.GetUniversalAdditionalCameraData();
  152. if (cameraData.volumeFrameworkUpdateMode == mode)
  153. return;
  154. bool requiredUpdatePreviously = cameraData.requiresVolumeFrameworkUpdate;
  155. cameraData.volumeFrameworkUpdateMode = mode;
  156. // We only update the local volume stacks for cameras set to ViaScripting.
  157. // Otherwise it will be updated in every frame.
  158. // We also check the previous value to make sure we're not updating when
  159. // switching between Camera ViaScripting and the URP Asset set to ViaScripting
  160. if (requiredUpdatePreviously && !cameraData.requiresVolumeFrameworkUpdate)
  161. camera.UpdateVolumeStack(cameraData);
  162. }
  163. /// <summary>
  164. /// Updates the volume stack for this camera.
  165. /// This function will only update the stack when the camera has VolumeFrameworkUpdateMode set to ViaScripting
  166. /// or when it set to UsePipelineSettings and the update mode on the Render Pipeline Asset is set to ViaScripting.
  167. /// </summary>
  168. /// <param name="camera"></param>
  169. public static void UpdateVolumeStack(this Camera camera)
  170. {
  171. UniversalAdditionalCameraData cameraData = camera.GetUniversalAdditionalCameraData();
  172. camera.UpdateVolumeStack(cameraData);
  173. }
  174. /// <summary>
  175. /// Updates the volume stack for this camera.
  176. /// This function will only update the stack when the camera has ViaScripting selected or if
  177. /// the camera is set to UsePipelineSettings and the Render Pipeline Asset is set to ViaScripting.
  178. /// </summary>
  179. /// <param name="camera"></param>
  180. /// <param name="cameraData"></param>
  181. public static void UpdateVolumeStack(this Camera camera, UniversalAdditionalCameraData cameraData)
  182. {
  183. Assert.IsNotNull(cameraData, "cameraData can not be null when updating the volume stack.");
  184. // We only update the local volume stacks for cameras set to ViaScripting.
  185. // Otherwise it will be updated in the frame.
  186. if (cameraData.requiresVolumeFrameworkUpdate)
  187. return;
  188. // Create stack for camera
  189. if (cameraData.volumeStack == null)
  190. cameraData.GetOrCreateVolumeStack();
  191. camera.GetVolumeLayerMaskAndTrigger(cameraData, out LayerMask layerMask, out Transform trigger);
  192. VolumeManager.instance.Update(cameraData.volumeStack, trigger, layerMask);
  193. }
  194. /// <summary>
  195. /// Destroys the volume stack for this camera.
  196. /// </summary>
  197. /// <param name="camera"></param>
  198. public static void DestroyVolumeStack(this Camera camera)
  199. {
  200. UniversalAdditionalCameraData cameraData = camera.GetUniversalAdditionalCameraData();
  201. camera.DestroyVolumeStack(cameraData);
  202. }
  203. /// <summary>
  204. /// Destroys the volume stack for this camera.
  205. /// </summary>
  206. /// <param name="camera"></param>
  207. /// <param name="cameraData"></param>
  208. public static void DestroyVolumeStack(this Camera camera, UniversalAdditionalCameraData cameraData)
  209. {
  210. if (cameraData == null || cameraData.volumeStack == null)
  211. return;
  212. cameraData.volumeStack = null;
  213. }
  214. /// <summary>
  215. /// Returns the mask and trigger assigned for volumes on the camera.
  216. /// </summary>
  217. /// <param name="camera"></param>
  218. /// <param name="cameraData"></param>
  219. /// <param name="layerMask"></param>
  220. /// <param name="trigger"></param>
  221. internal static void GetVolumeLayerMaskAndTrigger(this Camera camera, UniversalAdditionalCameraData cameraData, out LayerMask layerMask, out Transform trigger)
  222. {
  223. // Default values when there's no additional camera data available
  224. layerMask = 1; // "Default"
  225. trigger = camera.transform;
  226. if (cameraData != null)
  227. {
  228. layerMask = cameraData.volumeLayerMask;
  229. trigger = (cameraData.volumeTrigger != null) ? cameraData.volumeTrigger : trigger;
  230. }
  231. else if (camera.cameraType == CameraType.SceneView)
  232. {
  233. // Try to mirror the MainCamera volume layer mask for the scene view - do not mirror the target
  234. var mainCamera = Camera.main;
  235. UniversalAdditionalCameraData mainAdditionalCameraData = null;
  236. if (mainCamera != null && mainCamera.TryGetComponent(out mainAdditionalCameraData))
  237. {
  238. layerMask = mainAdditionalCameraData.volumeLayerMask;
  239. }
  240. trigger = (mainAdditionalCameraData != null && mainAdditionalCameraData.volumeTrigger != null) ? mainAdditionalCameraData.volumeTrigger : trigger;
  241. }
  242. }
  243. }
  244. static class CameraTypeUtility
  245. {
  246. static string[] s_CameraTypeNames = Enum.GetNames(typeof(CameraRenderType)).ToArray();
  247. public static string GetName(this CameraRenderType type)
  248. {
  249. int typeInt = (int)type;
  250. if (typeInt < 0 || typeInt >= s_CameraTypeNames.Length)
  251. typeInt = (int)CameraRenderType.Base;
  252. return s_CameraTypeNames[typeInt];
  253. }
  254. }
  255. /// <summary>
  256. /// Class containing various additional camera data used by URP.
  257. /// </summary>
  258. [DisallowMultipleComponent]
  259. [RequireComponent(typeof(Camera))]
  260. [ImageEffectAllowedInSceneView]
  261. [ExecuteAlways] // NOTE: This is required to get calls to OnDestroy() always. Graphics resources are released in OnDestroy().
  262. [URPHelpURL("universal-additional-camera-data")]
  263. public class UniversalAdditionalCameraData : MonoBehaviour, ISerializationCallbackReceiver, IAdditionalData
  264. {
  265. const string k_GizmoPath = "Packages/com.unity.render-pipelines.universal/Editor/Gizmos/";
  266. const string k_BaseCameraGizmoPath = k_GizmoPath + "Camera_Base.png";
  267. const string k_OverlayCameraGizmoPath = k_GizmoPath + "Camera_Base.png";
  268. const string k_PostProcessingGizmoPath = k_GizmoPath + "Camera_PostProcessing.png";
  269. [FormerlySerializedAs("renderShadows"), SerializeField]
  270. bool m_RenderShadows = true;
  271. [SerializeField]
  272. CameraOverrideOption m_RequiresDepthTextureOption = CameraOverrideOption.UsePipelineSettings;
  273. [SerializeField]
  274. CameraOverrideOption m_RequiresOpaqueTextureOption = CameraOverrideOption.UsePipelineSettings;
  275. [SerializeField] CameraRenderType m_CameraType = CameraRenderType.Base;
  276. [SerializeField] List<Camera> m_Cameras = new List<Camera>();
  277. [SerializeField] int m_RendererIndex = -1;
  278. [SerializeField] LayerMask m_VolumeLayerMask = 1; // "Default"
  279. [SerializeField] Transform m_VolumeTrigger = null;
  280. [SerializeField] VolumeFrameworkUpdateMode m_VolumeFrameworkUpdateModeOption = VolumeFrameworkUpdateMode.UsePipelineSettings;
  281. [SerializeField] bool m_RenderPostProcessing = false;
  282. [SerializeField] AntialiasingMode m_Antialiasing = AntialiasingMode.None;
  283. [SerializeField] AntialiasingQuality m_AntialiasingQuality = AntialiasingQuality.High;
  284. [SerializeField] bool m_StopNaN = false;
  285. [SerializeField] bool m_Dithering = false;
  286. [SerializeField] bool m_ClearDepth = true;
  287. [SerializeField] bool m_AllowXRRendering = true;
  288. [SerializeField] bool m_AllowHDROutput = true;
  289. [SerializeField] bool m_UseScreenCoordOverride;
  290. [SerializeField] Vector4 m_ScreenSizeOverride;
  291. [SerializeField] Vector4 m_ScreenCoordScaleBias;
  292. [NonSerialized] Camera m_Camera;
  293. // Deprecated:
  294. [FormerlySerializedAs("requiresDepthTexture"), SerializeField]
  295. bool m_RequiresDepthTexture = false;
  296. [FormerlySerializedAs("requiresColorTexture"), SerializeField]
  297. bool m_RequiresColorTexture = false;
  298. [HideInInspector] [SerializeField] float m_Version = 2;
  299. // These persist over multiple frames
  300. [NonSerialized] MotionVectorsPersistentData m_MotionVectorsPersistentData = new MotionVectorsPersistentData();
  301. // The URP camera history texture manager. Persistent per camera textures.
  302. [NonSerialized] internal UniversalCameraHistory m_History = new UniversalCameraHistory();
  303. [SerializeField] internal TemporalAA.Settings m_TaaSettings = TemporalAA.Settings.Create();
  304. /// <summary>
  305. /// The serialized version of the class. Used for upgrading.
  306. /// </summary>
  307. public float version => m_Version;
  308. static UniversalAdditionalCameraData s_DefaultAdditionalCameraData = null;
  309. internal static UniversalAdditionalCameraData defaultAdditionalCameraData
  310. {
  311. get
  312. {
  313. if (s_DefaultAdditionalCameraData == null)
  314. s_DefaultAdditionalCameraData = new UniversalAdditionalCameraData();
  315. return s_DefaultAdditionalCameraData;
  316. }
  317. }
  318. #if UNITY_EDITOR
  319. internal new Camera camera
  320. #else
  321. internal Camera camera
  322. #endif
  323. {
  324. get
  325. {
  326. if (!m_Camera)
  327. {
  328. gameObject.TryGetComponent<Camera>(out m_Camera);
  329. }
  330. return m_Camera;
  331. }
  332. }
  333. void Start()
  334. {
  335. // Need to ensure correct behavoiur for overlay cameras settings their clear flag to nothing.
  336. // This can't be done in the upgrade since the camera component can't be retrieved in the deserialization phase.
  337. // OnValidate ensure future cameras won't have this issue.
  338. if (m_CameraType == CameraRenderType.Overlay)
  339. camera.clearFlags = CameraClearFlags.Nothing;
  340. }
  341. /// <summary>
  342. /// Controls if this camera should render shadows.
  343. /// </summary>
  344. public bool renderShadows
  345. {
  346. get => m_RenderShadows;
  347. set => m_RenderShadows = value;
  348. }
  349. /// <summary>
  350. /// Controls if a camera should render depth.
  351. /// The depth is available to be bound in shaders as _CameraDepthTexture.
  352. /// <seealso cref="CameraOverrideOption"/>
  353. /// </summary>
  354. public CameraOverrideOption requiresDepthOption
  355. {
  356. get => m_RequiresDepthTextureOption;
  357. set => m_RequiresDepthTextureOption = value;
  358. }
  359. /// <summary>
  360. /// Controls if a camera should copy the color contents of a camera after rendering opaques.
  361. /// The color texture is available to be bound in shaders as _CameraOpaqueTexture.
  362. /// </summary>
  363. public CameraOverrideOption requiresColorOption
  364. {
  365. get => m_RequiresOpaqueTextureOption;
  366. set => m_RequiresOpaqueTextureOption = value;
  367. }
  368. /// <summary>
  369. /// Returns the camera renderType.
  370. /// <see cref="CameraRenderType"/>.
  371. /// </summary>
  372. public CameraRenderType renderType
  373. {
  374. get => m_CameraType;
  375. set => m_CameraType = value;
  376. }
  377. /// <summary>
  378. /// Returns the camera stack. Only valid for Base cameras.
  379. /// Will return null if it is not a Base camera.
  380. /// <seealso cref="CameraRenderType"/>.
  381. /// </summary>
  382. public List<Camera> cameraStack
  383. {
  384. get
  385. {
  386. if (renderType != CameraRenderType.Base)
  387. {
  388. var camera = gameObject.GetComponent<Camera>();
  389. Debug.LogWarning(string.Format("{0}: This camera is of {1} type. Only Base cameras can have a camera stack.", camera.name, renderType));
  390. return null;
  391. }
  392. if (!scriptableRenderer.SupportsCameraStackingType(CameraRenderType.Base))
  393. {
  394. var camera = gameObject.GetComponent<Camera>();
  395. Debug.LogWarning(string.Format("{0}: This camera has a ScriptableRenderer that doesn't support camera stacking. Camera stack is null.", camera.name));
  396. return null;
  397. }
  398. return m_Cameras;
  399. }
  400. }
  401. internal void UpdateCameraStack()
  402. {
  403. #if UNITY_EDITOR
  404. Undo.RecordObject(this, "Update camera stack");
  405. #endif
  406. int prev = m_Cameras.Count;
  407. m_Cameras.RemoveAll(cam => cam == null);
  408. int curr = m_Cameras.Count;
  409. int removedCamsCount = prev - curr;
  410. if (removedCamsCount != 0)
  411. {
  412. Debug.LogWarning(name + ": " + removedCamsCount + " camera overlay" + (removedCamsCount > 1 ? "s" : "") + " no longer exists and will be removed from the camera stack.");
  413. }
  414. }
  415. /// <summary>
  416. /// If true, this camera will clear depth value before rendering. Only valid for Overlay cameras.
  417. /// </summary>
  418. public bool clearDepth
  419. {
  420. get => m_ClearDepth;
  421. }
  422. /// <summary>
  423. /// Returns true if this camera needs to render depth information in a texture.
  424. /// If enabled, depth texture is available to be bound and read from shaders as _CameraDepthTexture after rendering skybox.
  425. /// </summary>
  426. public bool requiresDepthTexture
  427. {
  428. get
  429. {
  430. if (m_RequiresDepthTextureOption == CameraOverrideOption.UsePipelineSettings)
  431. {
  432. return UniversalRenderPipeline.asset.supportsCameraDepthTexture;
  433. }
  434. else
  435. {
  436. return m_RequiresDepthTextureOption == CameraOverrideOption.On;
  437. }
  438. }
  439. set { m_RequiresDepthTextureOption = (value) ? CameraOverrideOption.On : CameraOverrideOption.Off; }
  440. }
  441. /// <summary>
  442. /// Returns true if this camera requires to color information in a texture.
  443. /// If enabled, color texture is available to be bound and read from shaders as _CameraOpaqueTexture after rendering skybox.
  444. /// </summary>
  445. public bool requiresColorTexture
  446. {
  447. get
  448. {
  449. if (m_RequiresOpaqueTextureOption == CameraOverrideOption.UsePipelineSettings)
  450. {
  451. return UniversalRenderPipeline.asset.supportsCameraOpaqueTexture;
  452. }
  453. else
  454. {
  455. return m_RequiresOpaqueTextureOption == CameraOverrideOption.On;
  456. }
  457. }
  458. set { m_RequiresOpaqueTextureOption = (value) ? CameraOverrideOption.On : CameraOverrideOption.Off; }
  459. }
  460. /// <summary>
  461. /// Returns the <see cref="ScriptableRenderer"/> that is used to render this camera.
  462. /// </summary>
  463. public ScriptableRenderer scriptableRenderer
  464. {
  465. get
  466. {
  467. if (UniversalRenderPipeline.asset is null)
  468. return null;
  469. if (!UniversalRenderPipeline.asset.ValidateRendererData(m_RendererIndex))
  470. {
  471. int defaultIndex = UniversalRenderPipeline.asset.m_DefaultRendererIndex;
  472. Debug.LogWarning(
  473. $"Renderer at <b>index {m_RendererIndex.ToString()}</b> is missing for camera <b>{camera.name}</b>, falling back to Default Renderer. <b>{UniversalRenderPipeline.asset.m_RendererDataList[defaultIndex].name}</b>",
  474. UniversalRenderPipeline.asset);
  475. return UniversalRenderPipeline.asset.GetRenderer(defaultIndex);
  476. }
  477. return UniversalRenderPipeline.asset.GetRenderer(m_RendererIndex);
  478. }
  479. }
  480. /// <summary>
  481. /// Use this to set this Camera's current <see cref="ScriptableRenderer"/> to one listed on the Render Pipeline Asset. Takes an index that maps to the list on the Render Pipeline Asset.
  482. /// </summary>
  483. /// <param name="index">The index that maps to the RendererData list on the currently assigned Render Pipeline Asset</param>
  484. public void SetRenderer(int index)
  485. {
  486. m_RendererIndex = index;
  487. }
  488. /// <summary>
  489. /// Returns the selected scene-layers affecting this camera.
  490. /// </summary>
  491. public LayerMask volumeLayerMask
  492. {
  493. get => m_VolumeLayerMask;
  494. set => m_VolumeLayerMask = value;
  495. }
  496. /// <summary>
  497. /// Returns the Transform that acts as a trigger for Volume blending.
  498. /// </summary>
  499. public Transform volumeTrigger
  500. {
  501. get => m_VolumeTrigger;
  502. set => m_VolumeTrigger = value;
  503. }
  504. /// <summary>
  505. /// Returns the selected mode for Volume Frame Updates.
  506. /// </summary>
  507. internal VolumeFrameworkUpdateMode volumeFrameworkUpdateMode
  508. {
  509. get => m_VolumeFrameworkUpdateModeOption;
  510. set => m_VolumeFrameworkUpdateModeOption = value;
  511. }
  512. /// <summary>
  513. /// Returns true if this camera requires the volume framework to be updated every frame.
  514. /// </summary>
  515. public bool requiresVolumeFrameworkUpdate
  516. {
  517. get
  518. {
  519. if (m_VolumeFrameworkUpdateModeOption == VolumeFrameworkUpdateMode.UsePipelineSettings)
  520. {
  521. return UniversalRenderPipeline.asset.volumeFrameworkUpdateMode != VolumeFrameworkUpdateMode.ViaScripting;
  522. }
  523. return m_VolumeFrameworkUpdateModeOption == VolumeFrameworkUpdateMode.EveryFrame;
  524. }
  525. }
  526. /// <summary>
  527. /// Container for volume stacks in order to reuse stacks and avoid
  528. /// creating new ones every time a new camera is instantiated.
  529. /// </summary>
  530. private static List<VolumeStack> s_CachedVolumeStacks;
  531. /// <summary>
  532. /// Returns the current volume stack used by this camera.
  533. /// </summary>
  534. public VolumeStack volumeStack
  535. {
  536. get => m_VolumeStack;
  537. set
  538. {
  539. // If the volume stack is being removed,
  540. // add it back to the list so it can be reused later
  541. if (value == null && m_VolumeStack != null && m_VolumeStack.isValid)
  542. {
  543. if (s_CachedVolumeStacks == null)
  544. s_CachedVolumeStacks = new List<VolumeStack>(4);
  545. s_CachedVolumeStacks.Add(m_VolumeStack);
  546. }
  547. m_VolumeStack = value;
  548. }
  549. }
  550. VolumeStack m_VolumeStack = null;
  551. /// <summary>
  552. /// Tries to retrieve a volume stack from the container
  553. /// and creates a new one if that fails.
  554. /// </summary>
  555. internal void GetOrCreateVolumeStack()
  556. {
  557. // Try first to reuse a volume stack
  558. if (s_CachedVolumeStacks != null && s_CachedVolumeStacks.Count > 0)
  559. {
  560. int index = s_CachedVolumeStacks.Count - 1;
  561. var stack = s_CachedVolumeStacks[index];
  562. s_CachedVolumeStacks.RemoveAt(index);
  563. if (stack.isValid)
  564. volumeStack = stack;
  565. }
  566. // Create a new stack if was not possible to reuse an old one
  567. if (volumeStack == null)
  568. volumeStack = VolumeManager.instance.CreateStack();
  569. }
  570. /// <summary>
  571. /// Returns true if this camera should render post-processing.
  572. /// </summary>
  573. public bool renderPostProcessing
  574. {
  575. get => m_RenderPostProcessing;
  576. set => m_RenderPostProcessing = value;
  577. }
  578. /// <summary>
  579. /// Returns the current anti-aliasing mode used by this camera.
  580. /// <see cref="AntialiasingMode"/>.
  581. /// </summary>
  582. public AntialiasingMode antialiasing
  583. {
  584. get => m_Antialiasing;
  585. set => m_Antialiasing = value;
  586. }
  587. /// <summary>
  588. /// Returns the current anti-aliasing quality used by this camera.
  589. /// <seealso cref="antialiasingQuality"/>.
  590. /// </summary>
  591. public AntialiasingQuality antialiasingQuality
  592. {
  593. get => m_AntialiasingQuality;
  594. set => m_AntialiasingQuality = value;
  595. }
  596. /// <summary>
  597. /// Returns the current temporal anti-aliasing settings used by this camera.
  598. /// </summary>
  599. public ref TemporalAA.Settings taaSettings
  600. {
  601. get { return ref m_TaaSettings; }
  602. }
  603. /// <summary>
  604. /// Returns the URP camera history texture read access.
  605. /// Used to register requests and to read the existing history textures by external systems.
  606. /// </summary>
  607. public ICameraHistoryReadAccess history => m_History;
  608. // Returns the URP camera history texture manager with full access for internal systems.
  609. // NOTE: Only the pipeline should write/render history textures. Should be kept internal.
  610. //
  611. // The history is camera specific. The UniversalAdditionalCameraData is the URP specific camera (data).
  612. // Therefore it owns the UniversalCameraHistory. The history should follow the camera lifetime.
  613. internal UniversalCameraHistory historyManager => m_History;
  614. /// <summary>
  615. /// Motion data that persists over a frame.
  616. /// </summary>
  617. internal MotionVectorsPersistentData motionVectorsPersistentData => m_MotionVectorsPersistentData;
  618. /// <summary>
  619. /// Reset post-process history.
  620. /// </summary>
  621. public bool resetHistory
  622. {
  623. get => m_TaaSettings.resetHistoryFrames != 0;
  624. set
  625. {
  626. m_TaaSettings.resetHistoryFrames += value ? 1 : 0;
  627. m_MotionVectorsPersistentData.Reset();
  628. // Reset the jitter period for consistent test results.
  629. // Not technically history, but this is here to avoid adding testing only public API.
  630. m_TaaSettings.jitterFrameCountOffset = -Time.frameCount;
  631. }
  632. }
  633. /// <summary>
  634. /// Returns true if this camera should automatically replace NaN/Inf in shaders by a black pixel to avoid breaking some effects.
  635. /// </summary>
  636. public bool stopNaN
  637. {
  638. get => m_StopNaN;
  639. set => m_StopNaN = value;
  640. }
  641. /// <summary>
  642. /// Returns true if this camera applies 8-bit dithering to the final render to reduce color banding
  643. /// </summary>
  644. public bool dithering
  645. {
  646. get => m_Dithering;
  647. set => m_Dithering = value;
  648. }
  649. /// <summary>
  650. /// Returns true if this camera allows render in XR.
  651. /// </summary>
  652. public bool allowXRRendering
  653. {
  654. get => m_AllowXRRendering;
  655. set => m_AllowXRRendering = value;
  656. }
  657. /// <summary>
  658. /// Returns true if the camera uses Screen Coordinates Override.
  659. /// </summary>
  660. public bool useScreenCoordOverride
  661. {
  662. get => m_UseScreenCoordOverride;
  663. set => m_UseScreenCoordOverride = value;
  664. }
  665. /// <summary>
  666. /// Screen size used when Screen Coordinates Override is active.
  667. /// </summary>
  668. public Vector4 screenSizeOverride
  669. {
  670. get => m_ScreenSizeOverride;
  671. set => m_ScreenSizeOverride = value;
  672. }
  673. /// <summary>
  674. /// Transform applied to screen coordinates when Screen Coordinates Override is active.
  675. /// </summary>
  676. public Vector4 screenCoordScaleBias
  677. {
  678. get => m_ScreenCoordScaleBias;
  679. set => m_ScreenCoordScaleBias = value;
  680. }
  681. /// <summary>
  682. /// Returns true if this camera allows outputting to HDR displays.
  683. /// </summary>
  684. public bool allowHDROutput
  685. {
  686. get => m_AllowHDROutput;
  687. set => m_AllowHDROutput = value;
  688. }
  689. /// <inheritdoc/>
  690. public void OnBeforeSerialize()
  691. {
  692. }
  693. /// <inheritdoc/>
  694. public void OnAfterDeserialize()
  695. {
  696. if (version <= 1)
  697. {
  698. m_RequiresDepthTextureOption = (m_RequiresDepthTexture) ? CameraOverrideOption.On : CameraOverrideOption.Off;
  699. m_RequiresOpaqueTextureOption = (m_RequiresColorTexture) ? CameraOverrideOption.On : CameraOverrideOption.Off;
  700. m_Version = 2;
  701. }
  702. }
  703. /// <inheritdoc/>
  704. public void OnValidate()
  705. {
  706. if (m_CameraType == CameraRenderType.Overlay && m_Camera != null)
  707. {
  708. m_Camera.clearFlags = CameraClearFlags.Nothing;
  709. }
  710. }
  711. /// <inheritdoc/>
  712. public void OnDrawGizmos()
  713. {
  714. string gizmoName = "";
  715. Color tint = Color.white;
  716. if (m_CameraType == CameraRenderType.Base)
  717. {
  718. gizmoName = k_BaseCameraGizmoPath;
  719. }
  720. else if (m_CameraType == CameraRenderType.Overlay)
  721. {
  722. gizmoName = k_OverlayCameraGizmoPath;
  723. }
  724. #if UNITY_2019_2_OR_NEWER
  725. #if UNITY_EDITOR
  726. if (Selection.activeObject == gameObject)
  727. {
  728. // Get the preferences selection color
  729. tint = SceneView.selectedOutlineColor;
  730. }
  731. #endif
  732. if (!string.IsNullOrEmpty(gizmoName))
  733. {
  734. Gizmos.DrawIcon(transform.position, gizmoName, true, tint);
  735. }
  736. if (renderPostProcessing)
  737. {
  738. Gizmos.DrawIcon(transform.position, k_PostProcessingGizmoPath, true, tint);
  739. }
  740. #else
  741. if (renderPostProcessing)
  742. {
  743. Gizmos.DrawIcon(transform.position, k_PostProcessingGizmoPath);
  744. }
  745. Gizmos.DrawIcon(transform.position, gizmoName);
  746. #endif
  747. }
  748. /// <inheritdoc/>
  749. public void OnDestroy()
  750. {
  751. m_Camera.DestroyVolumeStack(this);
  752. if (camera.cameraType != CameraType.SceneView )
  753. scriptableRenderer?.ReleaseRenderTargets();
  754. m_History?.Dispose();
  755. m_History = null;
  756. }
  757. }
  758. }