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

RenderSettingsConverter.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Rendering;
  5. using UnityEngine.Rendering.Universal;
  6. using ShadowQuality = UnityEngine.ShadowQuality;
  7. using ShadowResolution = UnityEngine.ShadowResolution;
  8. namespace UnityEditor.Rendering.Universal
  9. {
  10. internal class RenderSettingsConverter : RenderPipelineConverter
  11. {
  12. public override int priority => -9000;
  13. public override string name => "Rendering Settings";
  14. public override string info =>
  15. "This converter will look at creating Universal Render Pipeline assets and respective Renderer Assets and configure" +
  16. " their settings based on equivalent settings from builtin renderer.";
  17. public override Type container => typeof(BuiltInToURPConverterContainer);
  18. // Used to store settings specific to Graphics Tiers
  19. GraphicsTierSettings m_GraphicsTierSettings;
  20. // Settings items, currently tracks Quality settings only
  21. List<SettingsItem> m_SettingsItems;
  22. // List of the rendering modes required
  23. List<RenderingMode> m_RenderingModes;
  24. const string k_PipelineAssetPath = "Settings";
  25. public override void OnInitialize(InitializeConverterContext context, Action callback)
  26. {
  27. m_SettingsItems = new List<SettingsItem>();
  28. m_RenderingModes = new List<RenderingMode>();
  29. // check graphics tiers
  30. GatherGraphicsTiers();
  31. // check quality levels
  32. GatherQualityLevels(ref context);
  33. callback?.Invoke();
  34. }
  35. /// <summary>
  36. /// Grabs the 3rd tier from the Graphics Tier Settings based off the current build platform
  37. /// </summary>
  38. private void GatherGraphicsTiers()
  39. {
  40. var targetGrp = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
  41. var tier = EditorGraphicsSettings.GetTierSettings(targetGrp, GraphicsTier.Tier3);
  42. // Add the Graphic Tier Render Path settings as the first rendering mode
  43. m_RenderingModes.Add(GetEquivalentRenderMode(tier.renderingPath));
  44. m_GraphicsTierSettings.RenderingPath = tier.renderingPath;
  45. m_GraphicsTierSettings.ReflectionProbeBlending = tier.reflectionProbeBlending;
  46. m_GraphicsTierSettings.ReflectionProbeBoxProjection = tier.reflectionProbeBoxProjection;
  47. m_GraphicsTierSettings.CascadeShadows = tier.cascadedShadowMaps;
  48. m_GraphicsTierSettings.HDR = tier.hdr;
  49. }
  50. /// <summary>
  51. /// Iterates over all Quality Settings and saves relevant settings to a RenderSettingsItem.
  52. /// This will also create the required information for the Render Pipeline Converter UI.
  53. /// </summary>
  54. /// <param name="context">Converter context to add elements to.</param>
  55. private void GatherQualityLevels(ref InitializeConverterContext context)
  56. {
  57. var currentQuality = QualitySettings.GetQualityLevel();
  58. var id = 0;
  59. foreach (var levelName in QualitySettings.names)
  60. {
  61. QualitySettings.SetQualityLevel(id);
  62. var projectSettings = new RenderSettingItem
  63. {
  64. Index = id,
  65. LevelName = levelName,
  66. PixelLightCount = QualitySettings.pixelLightCount,
  67. MSAA = QualitySettings.antiAliasing,
  68. Shadows = QualitySettings.shadows,
  69. ShadowResolution = QualitySettings.shadowResolution,
  70. ShadowDistance = QualitySettings.shadowDistance,
  71. ShadowCascadeCount = QualitySettings.shadowCascades,
  72. CascadeSplit2 = QualitySettings.shadowCascade2Split,
  73. CascadeSplit4 = QualitySettings.shadowCascade4Split,
  74. SoftParticles = QualitySettings.softParticles,
  75. };
  76. m_SettingsItems.Add(projectSettings);
  77. var setting = QualitySettings.GetRenderPipelineAssetAt(id);
  78. var item = new ConverterItemDescriptor { name = $"Quality Level {id}: {levelName}" };
  79. if (setting != null)
  80. {
  81. item.warningMessage = setting.GetType() == typeof(UniversalRenderPipelineAsset)
  82. ? "Contains URP Asset, will override existing asset."
  83. : "Contains SRP Asset, will override existing asset with URP asset.";
  84. }
  85. context.AddAssetToConvert(item);
  86. id++;
  87. }
  88. QualitySettings.SetQualityLevel(currentQuality);
  89. }
  90. public override void OnRun(ref RunItemContext context)
  91. {
  92. var item = context.item;
  93. // is quality item
  94. if (m_SettingsItems[item.index].GetType() == typeof(RenderSettingItem))
  95. {
  96. GeneratePipelineAsset(m_SettingsItems[item.index] as RenderSettingItem);
  97. }
  98. }
  99. private void GeneratePipelineAsset(RenderSettingItem settings)
  100. {
  101. // store current quality level
  102. var currentQualityLevel = QualitySettings.GetQualityLevel();
  103. //creating pipeline asset
  104. var asset =
  105. ScriptableObject.CreateInstance(typeof(UniversalRenderPipelineAsset)) as UniversalRenderPipelineAsset;
  106. if (!AssetDatabase.IsValidFolder($"Assets/{k_PipelineAssetPath}"))
  107. AssetDatabase.CreateFolder("Assets", k_PipelineAssetPath);
  108. var path = $"Assets/{k_PipelineAssetPath}/{settings.LevelName}_PipelineAsset.asset";
  109. // Setting Pipeline Asset settings
  110. SetPipelineSettings(asset, settings);
  111. // Create Renderers
  112. var defaultIndex = 0;
  113. var renderers = new List<ScriptableRendererData>();
  114. if (m_RenderingModes.Contains(RenderingMode.Forward))
  115. {
  116. renderers.Add(CreateRendererDataAsset(path, RenderingPath.Forward, "ForwardRenderer"));
  117. if (GetEquivalentRenderMode(m_GraphicsTierSettings.RenderingPath) == RenderingMode.Forward)
  118. defaultIndex = m_RenderingModes.IndexOf(RenderingMode.Forward);
  119. }
  120. if (m_RenderingModes.Contains(RenderingMode.Deferred))
  121. {
  122. renderers.Add(CreateRendererDataAsset(path, RenderingPath.DeferredShading, "DeferredRenderer"));
  123. if (GetEquivalentRenderMode(m_GraphicsTierSettings.RenderingPath) == RenderingMode.Deferred)
  124. defaultIndex = m_RenderingModes.IndexOf(RenderingMode.Deferred);
  125. }
  126. asset.m_RendererDataList = renderers.ToArray();
  127. asset.m_DefaultRendererIndex = defaultIndex;
  128. // Create Pipeline asset on disk
  129. AssetDatabase.CreateAsset(asset, path);
  130. // Assign asset
  131. QualitySettings.SetQualityLevel(settings.Index);
  132. QualitySettings.renderPipeline = asset;
  133. // return to original quality level
  134. QualitySettings.SetQualityLevel(currentQualityLevel);
  135. // Set graphics settings
  136. if (currentQualityLevel == settings.Index || GraphicsSettings.defaultRenderPipeline == null || GraphicsSettings.defaultRenderPipeline.GetType() !=
  137. typeof(UniversalRenderPipelineAsset))
  138. {
  139. GraphicsSettings.defaultRenderPipeline = asset;
  140. }
  141. }
  142. private ScriptableRendererData CreateRendererDataAsset(string assetPath, RenderingPath renderingPath,
  143. string fileName)
  144. {
  145. var rendererAsset =
  146. UniversalRenderPipelineAsset.CreateRendererAsset(assetPath, RendererType.UniversalRenderer, true, fileName)
  147. as UniversalRendererData;
  148. //Missing API to set deferred or forward
  149. rendererAsset.renderingMode =
  150. renderingPath == RenderingPath.Forward ? RenderingMode.Forward : RenderingMode.Deferred;
  151. //missing API to assign to pipeline asset
  152. return rendererAsset;
  153. }
  154. /// <summary>
  155. /// Sets all relevant RP settings in order they appear in URP
  156. /// </summary>
  157. /// <param name="asset">Pipeline asset to set</param>
  158. /// <param name="settings">The ProjectSettingItem with stored settings</param>
  159. private void SetPipelineSettings(UniversalRenderPipelineAsset asset, RenderSettingItem settings)
  160. {
  161. // General
  162. asset.supportsCameraDepthTexture = settings.SoftParticles;
  163. // Quality
  164. asset.supportsHDR = m_GraphicsTierSettings.HDR;
  165. asset.msaaSampleCount = settings.MSAA == 0 ? 1 : settings.MSAA;
  166. // Main Light
  167. asset.mainLightRenderingMode = settings.PixelLightCount == 0
  168. ? LightRenderingMode.Disabled
  169. : LightRenderingMode.PerPixel;
  170. asset.supportsMainLightShadows = settings.Shadows != ShadowQuality.Disable;
  171. asset.mainLightShadowmapResolution =
  172. GetEquivalentMainlightShadowResolution((int)settings.ShadowResolution);
  173. // Additional Lights
  174. asset.additionalLightsRenderingMode = settings.PixelLightCount == 0
  175. ? LightRenderingMode.PerVertex
  176. : LightRenderingMode.PerPixel;
  177. asset.maxAdditionalLightsCount = settings.PixelLightCount != 0 ? Mathf.Max(0, settings.PixelLightCount) : 4;
  178. asset.supportsAdditionalLightShadows = settings.Shadows != ShadowQuality.Disable;
  179. asset.additionalLightsShadowmapResolution =
  180. GetEquivalentAdditionalLightAtlasShadowResolution((int)settings.ShadowResolution);
  181. // Reflection Probes
  182. asset.reflectionProbeBlending = m_GraphicsTierSettings.ReflectionProbeBlending;
  183. asset.reflectionProbeBoxProjection = m_GraphicsTierSettings.ReflectionProbeBoxProjection;
  184. // Shadows
  185. asset.shadowDistance = settings.ShadowDistance;
  186. asset.shadowCascadeCount = m_GraphicsTierSettings.CascadeShadows ? settings.ShadowCascadeCount : 1;
  187. asset.cascade2Split = settings.CascadeSplit2;
  188. asset.cascade4Split = settings.CascadeSplit4;
  189. asset.supportsSoftShadows = settings.Shadows == ShadowQuality.All;
  190. }
  191. #region HelperFunctions
  192. private static int GetEquivalentMainlightShadowResolution(int value)
  193. {
  194. return GetEquivalentShadowResolution(value);
  195. }
  196. private static int GetEquivalentAdditionalLightAtlasShadowResolution(int value)
  197. {
  198. return GetEquivalentShadowResolution(value);
  199. }
  200. private static int GetEquivalentShadowResolution(int value)
  201. {
  202. switch (value)
  203. {
  204. case 0: // low
  205. return 1024;
  206. case 1: // med
  207. return 2048;
  208. case 2: // high
  209. return 4096;
  210. case 3: // very high
  211. return 4096;
  212. default: // backup
  213. return 1024;
  214. }
  215. }
  216. private RenderingMode GetEquivalentRenderMode(RenderingPath path)
  217. {
  218. switch (path)
  219. {
  220. case RenderingPath.VertexLit:
  221. case RenderingPath.Forward:
  222. return RenderingMode.Forward;
  223. case RenderingPath.DeferredShading:
  224. return RenderingMode.Deferred;
  225. default:
  226. return RenderingMode.Forward;
  227. }
  228. }
  229. #endregion
  230. #region Data
  231. private struct GraphicsTierSettings
  232. {
  233. public bool ReflectionProbeBoxProjection;
  234. public bool ReflectionProbeBlending;
  235. public bool CascadeShadows;
  236. public bool HDR;
  237. public RenderingPath RenderingPath;
  238. }
  239. private class SettingsItem { }
  240. private class RenderSettingItem : SettingsItem
  241. {
  242. // General
  243. public int Index;
  244. public string LevelName;
  245. // Settings
  246. public int PixelLightCount;
  247. public int MSAA;
  248. public ShadowQuality Shadows;
  249. public ShadowResolution ShadowResolution;
  250. public float ShadowDistance;
  251. public int ShadowCascadeCount;
  252. public float CascadeSplit2;
  253. public Vector3 CascadeSplit4;
  254. public bool SoftParticles;
  255. }
  256. #endregion
  257. }
  258. }