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.

ScriptableRendererData.cs 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. #if UNITY_EDITOR
  5. using System.Linq;
  6. using UnityEditor;
  7. using ShaderKeywordFilter = UnityEditor.ShaderKeywordFilter;
  8. #endif
  9. namespace UnityEngine.Rendering.Universal
  10. {
  11. /// <summary>
  12. /// Class <c>ScriptableRendererData</c> contains resources for a <c>ScriptableRenderer</c>.
  13. /// <seealso cref="ScriptableRenderer"/>
  14. /// </summary>
  15. [Icon("UnityEngine/Rendering/RenderPipelineAsset Icon")]
  16. public abstract partial class ScriptableRendererData : ScriptableObject
  17. {
  18. internal bool isInvalidated { get; set; }
  19. /// <summary>
  20. /// Creates the instance of the ScriptableRenderer.
  21. /// </summary>
  22. /// <returns>The instance of ScriptableRenderer</returns>
  23. protected abstract ScriptableRenderer Create();
  24. [SerializeField] internal List<ScriptableRendererFeature> m_RendererFeatures = new List<ScriptableRendererFeature>(10);
  25. [SerializeField] internal List<long> m_RendererFeatureMap = new List<long>(10);
  26. [SerializeField] bool m_UseNativeRenderPass = false;
  27. /// <summary>
  28. /// List of additional render pass features for this renderer.
  29. /// </summary>
  30. public List<ScriptableRendererFeature> rendererFeatures
  31. {
  32. get => m_RendererFeatures;
  33. }
  34. /// <summary>
  35. /// Use SetDirty when changing seeings in the ScriptableRendererData.
  36. /// It will rebuild the render passes with the new data.
  37. /// </summary>
  38. public new void SetDirty()
  39. {
  40. isInvalidated = true;
  41. }
  42. internal ScriptableRenderer InternalCreateRenderer()
  43. {
  44. isInvalidated = false;
  45. return Create();
  46. }
  47. /// <summary>
  48. /// Editor-only function that Unity calls when the script is loaded or a value changes in the Inspector.
  49. /// </summary>
  50. protected virtual void OnValidate()
  51. {
  52. SetDirty();
  53. #if UNITY_EDITOR
  54. // Only validate ScriptableRendererFeatures when all scripts have finished compiling (to avoid false-negatives
  55. // when ScriptableRendererFeatures haven't been compiled before this check).
  56. if (!EditorApplication.isCompiling && m_RendererFeatures.Contains(null))
  57. ValidateRendererFeatures();
  58. #endif
  59. }
  60. /// <summary>
  61. /// This function is called when the object becomes enabled and active.
  62. /// </summary>
  63. protected virtual void OnEnable()
  64. {
  65. SetDirty();
  66. }
  67. /// <summary>
  68. /// Specifies whether the renderer should use Native Render Pass.
  69. /// </summary>
  70. public bool useNativeRenderPass
  71. {
  72. get => m_UseNativeRenderPass;
  73. set
  74. {
  75. SetDirty();
  76. m_UseNativeRenderPass = value;
  77. }
  78. }
  79. /// <summary>
  80. /// Returns true if contains renderer feature with specified type.
  81. /// </summary>
  82. /// <param name="rendererFeature">RenderFeature output parameter.</param>
  83. /// <typeparam name="T">Renderer Feature type.</typeparam>
  84. /// <returns></returns>
  85. public bool TryGetRendererFeature<T>(out T rendererFeature) where T : ScriptableRendererFeature
  86. {
  87. foreach (var target in rendererFeatures)
  88. {
  89. if (target.GetType() == typeof(T))
  90. {
  91. rendererFeature = target as T;
  92. return true;
  93. }
  94. }
  95. rendererFeature = null;
  96. return false;
  97. }
  98. #if UNITY_EDITOR
  99. internal virtual Material GetDefaultMaterial(DefaultMaterialType materialType)
  100. {
  101. return null;
  102. }
  103. internal virtual Shader GetDefaultShader()
  104. {
  105. return null;
  106. }
  107. internal bool ValidateRendererFeatures()
  108. {
  109. // Get all Subassets
  110. var subassets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(this));
  111. var linkedIds = new List<long>();
  112. var loadedAssets = new Dictionary<long, object>();
  113. var mapValid = m_RendererFeatureMap != null && m_RendererFeatureMap?.Count == m_RendererFeatures?.Count;
  114. var debugOutput = $"{name}\nValid Sub-assets:\n";
  115. // Collect valid, compiled sub-assets
  116. foreach (var asset in subassets)
  117. {
  118. if (asset == null || !asset.GetType().IsSubclassOf(typeof(ScriptableRendererFeature))) continue;
  119. AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out var guid, out long localId);
  120. loadedAssets.Add(localId, asset);
  121. debugOutput += $"-{asset.name}\n--localId={localId}\n";
  122. }
  123. // Collect assets that are connected to the list
  124. for (var i = 0; i < m_RendererFeatures?.Count; i++)
  125. {
  126. if (!m_RendererFeatures[i]) continue;
  127. if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_RendererFeatures[i], out var guid, out long localId))
  128. {
  129. linkedIds.Add(localId);
  130. }
  131. }
  132. var mapDebug = mapValid ? "Linking" : "Map missing, will attempt to re-map";
  133. debugOutput += $"Feature List Status({mapDebug}):\n";
  134. // Try fix missing references
  135. for (var i = 0; i < m_RendererFeatures?.Count; i++)
  136. {
  137. if (m_RendererFeatures[i] == null)
  138. {
  139. if (mapValid && m_RendererFeatureMap[i] != 0)
  140. {
  141. var localId = m_RendererFeatureMap[i];
  142. loadedAssets.TryGetValue(localId, out var asset);
  143. m_RendererFeatures[i] = (ScriptableRendererFeature)asset;
  144. }
  145. else
  146. {
  147. m_RendererFeatures[i] = (ScriptableRendererFeature)GetUnusedAsset(ref linkedIds, ref loadedAssets);
  148. }
  149. }
  150. debugOutput += m_RendererFeatures[i] != null ? $"-{i}:Linked\n" : $"-{i}:Missing\n";
  151. }
  152. UpdateMap();
  153. if (!m_RendererFeatures.Contains(null))
  154. return true;
  155. Debug.LogError($"{name} is missing RendererFeatures\nThis could be due to missing scripts or compile error.", this);
  156. return false;
  157. }
  158. internal bool DuplicateFeatureCheck(Type type)
  159. {
  160. Attribute isSingleFeature = type.GetCustomAttribute(typeof(DisallowMultipleRendererFeature));
  161. if (isSingleFeature == null)
  162. return false;
  163. if (m_RendererFeatures == null)
  164. return false;
  165. for (int i = 0; i < m_RendererFeatures.Count; i++)
  166. {
  167. ScriptableRendererFeature feature = m_RendererFeatures[i];
  168. if (feature == null)
  169. continue;
  170. if (feature.GetType() == type)
  171. return true;
  172. }
  173. return false;
  174. }
  175. private static object GetUnusedAsset(ref List<long> usedIds, ref Dictionary<long, object> assets)
  176. {
  177. foreach (var asset in assets)
  178. {
  179. var alreadyLinked = usedIds.Any(used => asset.Key == used);
  180. if (alreadyLinked)
  181. continue;
  182. usedIds.Add(asset.Key);
  183. return asset.Value;
  184. }
  185. return null;
  186. }
  187. private void UpdateMap()
  188. {
  189. if (m_RendererFeatureMap.Count != m_RendererFeatures.Count)
  190. {
  191. m_RendererFeatureMap.Clear();
  192. m_RendererFeatureMap.AddRange(new long[m_RendererFeatures.Count]);
  193. }
  194. for (int i = 0; i < rendererFeatures.Count; i++)
  195. {
  196. if (m_RendererFeatures[i] == null) continue;
  197. if (!AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_RendererFeatures[i], out var guid, out long localId)) continue;
  198. m_RendererFeatureMap[i] = localId;
  199. }
  200. }
  201. #endif
  202. }
  203. }