Brak opisu
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.

DecalShaderGraphGUI.cs 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. using System;
  2. using UnityEditor.ShaderGraph;
  3. using UnityEngine;
  4. using UnityEngine.Rendering;
  5. using UnityEngine.Rendering.Universal;
  6. using UnityEngine.Rendering.Universal.Internal;
  7. namespace UnityEditor.Rendering.Universal
  8. {
  9. /// <summary>
  10. /// Scope that indicates start of <see cref="DecalProjector"/> GUI.
  11. /// </summary>
  12. internal class DecalProjectorScope : GUI.Scope
  13. {
  14. public DecalProjectorScope()
  15. {
  16. DecalShaderGraphGUI.isDecalProjectorGUI = true;
  17. }
  18. protected override void CloseScope()
  19. {
  20. DecalShaderGraphGUI.isDecalProjectorGUI = false;
  21. }
  22. }
  23. /// <summary>
  24. /// Represents the GUI for Decal Shader Graph materials.
  25. /// </summary>
  26. internal class DecalShaderGraphGUI : UnityEditor.ShaderGUI
  27. {
  28. internal class Styles
  29. {
  30. public static GUIContent inputs = new GUIContent("Inputs");
  31. public static GUIContent advancedOptions = new GUIContent("Advanced Options");
  32. public static GUIContent meshDecalBiasType = new GUIContent("Mesh Bias Type", "Set the type of bias that is applied to the mesh decal. Depth Bias applies a bias to the final depth value, while View bias applies a world space bias (in meters) alongside the view vector.");
  33. public static GUIContent meshDecalDepthBiasText = new GUIContent("Depth Bias", "Sets a depth bias to stop the decal's Mesh from overlapping with other Meshes.");
  34. public static GUIContent meshDecalViewBiasText = new GUIContent("View Bias", "Sets a world-space bias alongside the view vector to stop the decal's Mesh from overlapping with other Meshes. The unit is meters.");
  35. public static GUIContent drawOrderText = new GUIContent("Priority", "Controls the draw order of Decal Projectors. URP draws decals with lower values first.");
  36. }
  37. protected enum Expandable
  38. {
  39. Inputs = 1 << 0,
  40. Advanced = 1 << 1,
  41. }
  42. public static bool isDecalProjectorGUI { get; set; }
  43. const string kDecalMeshBiasType = "_DecalMeshBiasType";
  44. const string kDecalMeshDepthBias = "_DecalMeshDepthBias";
  45. const string kDecalViewDepthBias = "_DecalMeshViewBias";
  46. const string kDrawOrder = "_DrawOrder";
  47. readonly MaterialHeaderScopeList m_MaterialScopeList = new MaterialHeaderScopeList(uint.MaxValue & ~((uint)Expandable.Advanced));
  48. MaterialEditor m_MaterialEditor;
  49. MaterialProperty[] m_Properties;
  50. MaterialProperty decalMeshBiasType;
  51. MaterialProperty decalMeshDepthBias;
  52. MaterialProperty decalMeshViewBias;
  53. MaterialProperty drawOrder;
  54. public DecalShaderGraphGUI()
  55. {
  56. m_MaterialScopeList.RegisterHeaderScope(Styles.inputs, Expandable.Inputs, DrawExposedProperties);
  57. m_MaterialScopeList.RegisterHeaderScope(Styles.advancedOptions, Expandable.Advanced, DrawSortingProperties);
  58. }
  59. /// <summary>
  60. /// Override this function to implement your custom GUI. To display a user interface similar to HDRP shaders, use a MaterialUIBlockList.
  61. /// </summary>
  62. /// <param name="materialEditor">The current material editor.</param>
  63. /// <param name="props">The list of properties the material has.</param>
  64. public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
  65. {
  66. DecalMeshWarning();
  67. m_MaterialEditor = materialEditor;
  68. FindProperties(props);
  69. Material material = materialEditor.target as Material;
  70. using (var changed = new EditorGUI.ChangeCheckScope())
  71. {
  72. m_MaterialScopeList.DrawHeaders(materialEditor, material);
  73. }
  74. // We should always do this call at the end
  75. materialEditor.serializedObject.ApplyModifiedProperties();
  76. }
  77. private void FindProperties(MaterialProperty[] properties)
  78. {
  79. decalMeshBiasType = FindProperty(kDecalMeshBiasType, properties);
  80. decalMeshViewBias = FindProperty(kDecalViewDepthBias, properties);
  81. decalMeshDepthBias = FindProperty(kDecalMeshDepthBias, properties);
  82. drawOrder = FindProperty(kDrawOrder, properties);
  83. m_Properties = properties;
  84. }
  85. private void DrawExposedProperties(Material material)
  86. {
  87. MaterialProperty[] properties = m_Properties;
  88. MaterialEditor materialEditor = m_MaterialEditor;
  89. // TODO: scope
  90. var fieldWidth = EditorGUIUtility.fieldWidth;
  91. var labelWidth = EditorGUIUtility.labelWidth;
  92. // Copy of MaterialEditor.PropertiesDefaultGUI that excludes properties of PerRendererData
  93. materialEditor.SetDefaultGUIWidths();
  94. for (var i = 0; i < properties.Length; i++)
  95. {
  96. if ((properties[i].flags & (MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData)) != 0)
  97. continue;
  98. float h = materialEditor.GetPropertyHeight(properties[i], properties[i].displayName);
  99. Rect r = EditorGUILayout.GetControlRect(true, h, EditorStyles.layerMaskField);
  100. materialEditor.ShaderProperty(r, properties[i], properties[i].displayName);
  101. }
  102. EditorGUIUtility.fieldWidth = fieldWidth;
  103. EditorGUIUtility.labelWidth = labelWidth;
  104. }
  105. private void DrawSortingProperties(Material material)
  106. {
  107. MaterialEditor materialEditor = m_MaterialEditor;
  108. materialEditor.EnableInstancingField();
  109. DrawOrder();
  110. materialEditor.ShaderProperty(decalMeshBiasType, Styles.meshDecalBiasType);
  111. DecalMeshDepthBiasType decalBias = (DecalMeshDepthBiasType)decalMeshBiasType.floatValue;
  112. EditorGUI.indentLevel++;
  113. switch (decalBias)
  114. {
  115. case DecalMeshDepthBiasType.DepthBias:
  116. materialEditor.ShaderProperty(decalMeshDepthBias, Styles.meshDecalDepthBiasText);
  117. break;
  118. case DecalMeshDepthBiasType.ViewBias:
  119. materialEditor.ShaderProperty(decalMeshViewBias, Styles.meshDecalViewBiasText);
  120. break;
  121. }
  122. EditorGUI.indentLevel--;
  123. }
  124. private void DrawOrder()
  125. {
  126. MaterialEditor materialEditor = m_MaterialEditor;
  127. EditorGUI.BeginChangeCheck();
  128. EditorGUI.showMixedValue = drawOrder.hasMixedValue;
  129. var queue = EditorGUILayout.IntSlider(Styles.drawOrderText, (int)drawOrder.floatValue, -50, 50);
  130. if (EditorGUI.EndChangeCheck())
  131. {
  132. foreach (var target in materialEditor.targets)
  133. {
  134. var material = target as Material;
  135. material.renderQueue = 2000 + queue;
  136. }
  137. drawOrder.floatValue = queue;
  138. }
  139. EditorGUI.showMixedValue = false;
  140. }
  141. private void DecalMeshWarning()
  142. {
  143. if (isDecalProjectorGUI)
  144. return;
  145. var urp = UniversalRenderPipeline.asset;
  146. if (urp == null)
  147. return;
  148. bool hasDecalScreenSpace = false;
  149. var renderers = urp.m_RendererDataList;
  150. foreach (var renderer in renderers)
  151. {
  152. if (renderer.TryGetRendererFeature(out DecalRendererFeature decalRendererFeature))
  153. {
  154. var technique = decalRendererFeature.GetTechnique(renderer);
  155. if (technique == DecalTechnique.ScreenSpace || technique == DecalTechnique.GBuffer)
  156. {
  157. hasDecalScreenSpace = true;
  158. break;
  159. }
  160. }
  161. }
  162. if (hasDecalScreenSpace)
  163. EditorGUILayout.HelpBox("Decals with Screen Space technique only support rendering with DecalProjector component.", MessageType.Warning);
  164. }
  165. }
  166. }