UniversalRenderPipelineGlobalSettings.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. using System;
  2. using UnityEditor;
  3. using UnityEngine.Serialization;
  4. namespace UnityEngine.Rendering.Universal
  5. {
  6. /// <summary>
  7. /// Universal Render Pipeline's Global Settings.
  8. /// Global settings are unique per Render Pipeline type. In URP, Global Settings contain:
  9. /// - light layer names
  10. /// </summary>
  11. [URPHelpURL("URP-Global-Settings")]
  12. partial class UniversalRenderPipelineGlobalSettings : RenderPipelineGlobalSettings, ISerializationCallbackReceiver
  13. {
  14. #region Version system
  15. #pragma warning disable CS0414
  16. [SerializeField] int k_AssetVersion = 2;
  17. #pragma warning restore CS0414
  18. public void OnBeforeSerialize()
  19. {
  20. }
  21. public void OnAfterDeserialize()
  22. {
  23. #if UNITY_EDITOR
  24. if (k_AssetVersion != 2)
  25. {
  26. EditorApplication.delayCall += () => UpgradeAsset(this.GetInstanceID());
  27. }
  28. #endif
  29. }
  30. #if UNITY_EDITOR
  31. static void UpgradeAsset(int assetInstanceID)
  32. {
  33. UniversalRenderPipelineGlobalSettings asset = EditorUtility.InstanceIDToObject(assetInstanceID) as UniversalRenderPipelineGlobalSettings;
  34. if (asset.k_AssetVersion < 2)
  35. {
  36. #pragma warning disable 618 // Obsolete warning
  37. // Renamed supportRuntimeDebugDisplay => stripDebugVariants, which results in inverted logic
  38. asset.m_StripDebugVariants = !asset.supportRuntimeDebugDisplay;
  39. asset.k_AssetVersion = 2;
  40. #pragma warning restore 618 // Obsolete warning
  41. // For old test projects lets keep post processing stripping enabled, as huge chance they did not used runtime profile creating
  42. #if UNITY_INCLUDE_TESTS
  43. asset.m_StripUnusedPostProcessingVariants = true;
  44. #endif
  45. }
  46. EditorUtility.SetDirty(asset);
  47. }
  48. #endif
  49. #endregion
  50. private static UniversalRenderPipelineGlobalSettings cachedInstance = null;
  51. /// <summary>
  52. /// Active URP Global Settings asset. If the value is null then no UniversalRenderPipelineGlobalSettings has been registered to the Graphics Settings with the UniversalRenderPipeline.
  53. /// </summary>
  54. public static UniversalRenderPipelineGlobalSettings instance
  55. {
  56. get
  57. {
  58. #if !UNITY_EDITOR
  59. // The URP Global Settings could have been changed by script, undo/redo (case 1342987), or file update - file versioning, let us make sure we display the correct one
  60. // In a Player, we do not need to worry about those changes as we only support loading one
  61. if (cachedInstance == null)
  62. #endif
  63. cachedInstance = GraphicsSettings.GetSettingsForRenderPipeline<UniversalRenderPipeline>() as UniversalRenderPipelineGlobalSettings;
  64. return cachedInstance;
  65. }
  66. }
  67. static internal void UpdateGraphicsSettings(UniversalRenderPipelineGlobalSettings newSettings)
  68. {
  69. if (newSettings == cachedInstance)
  70. return;
  71. if (newSettings != null)
  72. GraphicsSettings.RegisterRenderPipelineSettings<UniversalRenderPipeline>(newSettings as RenderPipelineGlobalSettings);
  73. else
  74. GraphicsSettings.UnregisterRenderPipelineSettings<UniversalRenderPipeline>();
  75. cachedInstance = newSettings;
  76. }
  77. /// <summary>Default name when creating an URP Global Settings asset.</summary>
  78. public static readonly string defaultAssetName = "UniversalRenderPipelineGlobalSettings";
  79. #if UNITY_EDITOR
  80. //Making sure there is at least one UniversalRenderPipelineGlobalSettings instance in the project
  81. internal static UniversalRenderPipelineGlobalSettings Ensure(string folderPath = "", bool canCreateNewAsset = true)
  82. {
  83. if (UniversalRenderPipelineGlobalSettings.instance)
  84. return UniversalRenderPipelineGlobalSettings.instance;
  85. UniversalRenderPipelineGlobalSettings assetCreated = null;
  86. string path = $"Assets/{folderPath}/{defaultAssetName}.asset";
  87. assetCreated = AssetDatabase.LoadAssetAtPath<UniversalRenderPipelineGlobalSettings>(path);
  88. if (assetCreated == null)
  89. {
  90. var guidGlobalSettingsAssets = AssetDatabase.FindAssets("t:UniversalRenderPipelineGlobalSettings");
  91. //If we could not find the asset at the default path, find the first one
  92. if (guidGlobalSettingsAssets.Length > 0)
  93. {
  94. var curGUID = guidGlobalSettingsAssets[0];
  95. path = AssetDatabase.GUIDToAssetPath(curGUID);
  96. assetCreated = AssetDatabase.LoadAssetAtPath<UniversalRenderPipelineGlobalSettings>(path);
  97. }
  98. else if (canCreateNewAsset)// or create one altogether
  99. {
  100. if (!AssetDatabase.IsValidFolder("Assets/" + folderPath))
  101. AssetDatabase.CreateFolder("Assets", folderPath);
  102. assetCreated = Create(path);
  103. // TODO: Reenable after next urp template is published
  104. //Debug.LogWarning("No URP Global Settings Asset is assigned. One will be created for you. If you want to modify it, go to Project Settings > Graphics > URP Settings.");
  105. }
  106. else
  107. {
  108. Debug.LogError("If you are building a Player, make sure to save an URP Global Settings asset by opening the project in the Editor first.");
  109. return null;
  110. }
  111. }
  112. Debug.Assert(assetCreated, "Could not create URP's Global Settings - URP may not work correctly - Open Project Settings > Graphics > URP Settings for additional help.");
  113. UpdateGraphicsSettings(assetCreated);
  114. return UniversalRenderPipelineGlobalSettings.instance;
  115. }
  116. internal static UniversalRenderPipelineGlobalSettings Create(string path, UniversalRenderPipelineGlobalSettings src = null)
  117. {
  118. UniversalRenderPipelineGlobalSettings assetCreated = null;
  119. // make sure the asset does not already exists
  120. assetCreated = AssetDatabase.LoadAssetAtPath<UniversalRenderPipelineGlobalSettings>(path);
  121. if (assetCreated == null)
  122. {
  123. assetCreated = ScriptableObject.CreateInstance<UniversalRenderPipelineGlobalSettings>();
  124. if (assetCreated != null)
  125. {
  126. assetCreated.name = System.IO.Path.GetFileName(path);
  127. }
  128. AssetDatabase.CreateAsset(assetCreated, path);
  129. Debug.Assert(assetCreated);
  130. }
  131. if (assetCreated)
  132. {
  133. if (src != null)
  134. {
  135. assetCreated.lightLayerName0 = System.String.Copy(src.lightLayerName0);
  136. assetCreated.lightLayerName1 = System.String.Copy(src.lightLayerName1);
  137. assetCreated.lightLayerName2 = System.String.Copy(src.lightLayerName2);
  138. assetCreated.lightLayerName3 = System.String.Copy(src.lightLayerName3);
  139. assetCreated.lightLayerName4 = System.String.Copy(src.lightLayerName4);
  140. assetCreated.lightLayerName5 = System.String.Copy(src.lightLayerName5);
  141. assetCreated.lightLayerName6 = System.String.Copy(src.lightLayerName6);
  142. assetCreated.lightLayerName7 = System.String.Copy(src.lightLayerName7);
  143. }
  144. AssetDatabase.SaveAssets();
  145. AssetDatabase.Refresh();
  146. }
  147. return assetCreated;
  148. }
  149. #endif
  150. void Reset()
  151. {
  152. UpdateRenderingLayerNames();
  153. }
  154. [System.NonSerialized]
  155. string[] m_RenderingLayerNames;
  156. string[] renderingLayerNames
  157. {
  158. get
  159. {
  160. if (m_RenderingLayerNames == null)
  161. UpdateRenderingLayerNames();
  162. return m_RenderingLayerNames;
  163. }
  164. }
  165. [System.NonSerialized]
  166. string[] m_PrefixedRenderingLayerNames;
  167. string[] prefixedRenderingLayerNames
  168. {
  169. get
  170. {
  171. if (m_PrefixedRenderingLayerNames == null)
  172. UpdateRenderingLayerNames();
  173. return m_PrefixedRenderingLayerNames;
  174. }
  175. }
  176. /// <summary>Names used for display of rendering layer masks.</summary>
  177. public string[] renderingLayerMaskNames => renderingLayerNames;
  178. /// <summary>Names used for display of rendering layer masks with a prefix.</summary>
  179. public string[] prefixedRenderingLayerMaskNames => prefixedRenderingLayerNames;
  180. /// <summary>Regenerate Rendering Layer names and their prefixed versions.</summary>
  181. internal void UpdateRenderingLayerNames()
  182. {
  183. if (m_RenderingLayerNames == null)
  184. m_RenderingLayerNames = new string[32];
  185. int index = 0;
  186. m_RenderingLayerNames[index++] = lightLayerName0;
  187. m_RenderingLayerNames[index++] = lightLayerName1;
  188. m_RenderingLayerNames[index++] = lightLayerName2;
  189. m_RenderingLayerNames[index++] = lightLayerName3;
  190. m_RenderingLayerNames[index++] = lightLayerName4;
  191. m_RenderingLayerNames[index++] = lightLayerName5;
  192. m_RenderingLayerNames[index++] = lightLayerName6;
  193. m_RenderingLayerNames[index++] = lightLayerName7;
  194. // Unused
  195. for (int i = index; i < m_RenderingLayerNames.Length; ++i)
  196. {
  197. m_RenderingLayerNames[i] = string.Format("Unused {0}", i);
  198. }
  199. // Update prefixed
  200. if (m_PrefixedRenderingLayerNames == null)
  201. m_PrefixedRenderingLayerNames = new string[32];
  202. if (m_PrefixedLightLayerNames == null)
  203. m_PrefixedLightLayerNames = new string[8];
  204. for (int i = 0; i < m_PrefixedRenderingLayerNames.Length; ++i)
  205. {
  206. m_PrefixedRenderingLayerNames[i] = string.Format("{0}: {1}", i, m_RenderingLayerNames[i]);
  207. if (i < 8)
  208. m_PrefixedLightLayerNames[i] = m_PrefixedRenderingLayerNames[i];
  209. }
  210. }
  211. [System.NonSerialized]
  212. string[] m_PrefixedLightLayerNames = null;
  213. /// <summary>
  214. /// Names used for display of light layers with Layer's index as prefix.
  215. /// For example: "0: Light Layer Default"
  216. /// </summary>
  217. public string[] prefixedLightLayerNames
  218. {
  219. get
  220. {
  221. if (m_PrefixedLightLayerNames == null)
  222. UpdateRenderingLayerNames();
  223. return m_PrefixedLightLayerNames;
  224. }
  225. }
  226. #region Light Layer Names [3D]
  227. static readonly string[] k_DefaultLightLayerNames = { "Light Layer default", "Light Layer 1", "Light Layer 2", "Light Layer 3", "Light Layer 4", "Light Layer 5", "Light Layer 6", "Light Layer 7" };
  228. /// <summary>Name for light layer 0.</summary>
  229. public string lightLayerName0 = k_DefaultLightLayerNames[0];
  230. /// <summary>Name for light layer 1.</summary>
  231. public string lightLayerName1 = k_DefaultLightLayerNames[1];
  232. /// <summary>Name for light layer 2.</summary>
  233. public string lightLayerName2 = k_DefaultLightLayerNames[2];
  234. /// <summary>Name for light layer 3.</summary>
  235. public string lightLayerName3 = k_DefaultLightLayerNames[3];
  236. /// <summary>Name for light layer 4.</summary>
  237. public string lightLayerName4 = k_DefaultLightLayerNames[4];
  238. /// <summary>Name for light layer 5.</summary>
  239. public string lightLayerName5 = k_DefaultLightLayerNames[5];
  240. /// <summary>Name for light layer 6.</summary>
  241. public string lightLayerName6 = k_DefaultLightLayerNames[6];
  242. /// <summary>Name for light layer 7.</summary>
  243. public string lightLayerName7 = k_DefaultLightLayerNames[7];
  244. [System.NonSerialized]
  245. string[] m_LightLayerNames = null;
  246. /// <summary>
  247. /// Names used for display of light layers.
  248. /// </summary>
  249. public string[] lightLayerNames
  250. {
  251. get
  252. {
  253. if (m_LightLayerNames == null)
  254. {
  255. m_LightLayerNames = new string[8];
  256. }
  257. m_LightLayerNames[0] = lightLayerName0;
  258. m_LightLayerNames[1] = lightLayerName1;
  259. m_LightLayerNames[2] = lightLayerName2;
  260. m_LightLayerNames[3] = lightLayerName3;
  261. m_LightLayerNames[4] = lightLayerName4;
  262. m_LightLayerNames[5] = lightLayerName5;
  263. m_LightLayerNames[6] = lightLayerName6;
  264. m_LightLayerNames[7] = lightLayerName7;
  265. return m_LightLayerNames;
  266. }
  267. }
  268. internal void ResetRenderingLayerNames()
  269. {
  270. lightLayerName0 = k_DefaultLightLayerNames[0];
  271. lightLayerName1 = k_DefaultLightLayerNames[1];
  272. lightLayerName2 = k_DefaultLightLayerNames[2];
  273. lightLayerName3 = k_DefaultLightLayerNames[3];
  274. lightLayerName4 = k_DefaultLightLayerNames[4];
  275. lightLayerName5 = k_DefaultLightLayerNames[5];
  276. lightLayerName6 = k_DefaultLightLayerNames[6];
  277. lightLayerName7 = k_DefaultLightLayerNames[7];
  278. }
  279. #endregion
  280. #region Misc Settings
  281. [SerializeField] bool m_StripDebugVariants = true;
  282. [SerializeField] bool m_StripUnusedPostProcessingVariants = false;
  283. [SerializeField] bool m_StripUnusedVariants = true;
  284. /// <summary>
  285. /// Controls whether debug display shaders for Rendering Debugger are available in Player builds.
  286. /// </summary>
  287. [Obsolete("Please use stripRuntimeDebugShaders instead.", false)]
  288. public bool supportRuntimeDebugDisplay = false;
  289. /// <summary>
  290. /// Controls whether debug display shaders for Rendering Debugger are available in Player builds.
  291. /// </summary>
  292. public bool stripDebugVariants { get => m_StripDebugVariants; set { m_StripDebugVariants = value; } }
  293. /// <summary>
  294. /// Controls whether strips automatically post processing shader variants based on <see cref="VolumeProfile"/> components.
  295. /// It strips based on VolumeProfiles in project and not scenes that actually uses it.
  296. /// </summary>
  297. public bool stripUnusedPostProcessingVariants { get => m_StripUnusedPostProcessingVariants; set { m_StripUnusedPostProcessingVariants = value; } }
  298. /// <summary>
  299. /// Controls whether strip off variants if the feature is enabled.
  300. /// </summary>
  301. public bool stripUnusedVariants { get => m_StripUnusedVariants; set { m_StripUnusedVariants = value; } }
  302. #endregion
  303. }
  304. }