LitGUI.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.Rendering;
  4. using UnityEngine.Scripting.APIUpdating;
  5. namespace UnityEditor.Rendering.Universal.ShaderGUI
  6. {
  7. [MovedFrom("UnityEditor.Rendering.LWRP.ShaderGUI")] public static class LitGUI
  8. {
  9. public enum WorkflowMode
  10. {
  11. Specular = 0,
  12. Metallic
  13. }
  14. public enum SmoothnessMapChannel
  15. {
  16. SpecularMetallicAlpha,
  17. AlbedoAlpha,
  18. }
  19. public static class Styles
  20. {
  21. public static GUIContent workflowModeText = new GUIContent("Workflow Mode",
  22. "Select a workflow that fits your textures. Choose between Metallic or Specular.");
  23. public static GUIContent specularMapText =
  24. new GUIContent("Specular Map", "Sets and configures the map and color for the Specular workflow.");
  25. public static GUIContent metallicMapText =
  26. new GUIContent("Metallic Map", "Sets and configures the map for the Metallic workflow.");
  27. public static GUIContent smoothnessText = new GUIContent("Smoothness",
  28. "Controls the spread of highlights and reflections on the surface.");
  29. public static GUIContent smoothnessMapChannelText =
  30. new GUIContent("Source",
  31. "Specifies where to sample a smoothness map from. By default, uses the alpha channel for your map.");
  32. public static GUIContent highlightsText = new GUIContent("Specular Highlights",
  33. "When enabled, the Material reflects the shine from direct lighting.");
  34. public static GUIContent reflectionsText =
  35. new GUIContent("Environment Reflections",
  36. "When enabled, the Material samples reflections from the nearest Reflection Probes or Lighting Probe.");
  37. public static GUIContent occlusionText = new GUIContent("Occlusion Map",
  38. "Sets an occlusion map to simulate shadowing from ambient lighting.");
  39. public static readonly string[] metallicSmoothnessChannelNames = {"Metallic Alpha", "Albedo Alpha"};
  40. public static readonly string[] specularSmoothnessChannelNames = {"Specular Alpha", "Albedo Alpha"};
  41. }
  42. public struct LitProperties
  43. {
  44. // Surface Option Props
  45. public MaterialProperty workflowMode;
  46. // Surface Input Props
  47. public MaterialProperty metallic;
  48. public MaterialProperty specColor;
  49. public MaterialProperty metallicGlossMap;
  50. public MaterialProperty specGlossMap;
  51. public MaterialProperty smoothness;
  52. public MaterialProperty smoothnessMapChannel;
  53. public MaterialProperty bumpMapProp;
  54. public MaterialProperty bumpScaleProp;
  55. public MaterialProperty occlusionStrength;
  56. public MaterialProperty occlusionMap;
  57. // Advanced Props
  58. public MaterialProperty highlights;
  59. public MaterialProperty reflections;
  60. public LitProperties(MaterialProperty[] properties)
  61. {
  62. // Surface Option Props
  63. workflowMode = BaseShaderGUI.FindProperty("_WorkflowMode", properties, false);
  64. // Surface Input Props
  65. metallic = BaseShaderGUI.FindProperty("_Metallic", properties);
  66. specColor = BaseShaderGUI.FindProperty("_SpecColor", properties, false);
  67. metallicGlossMap = BaseShaderGUI.FindProperty("_MetallicGlossMap", properties);
  68. specGlossMap = BaseShaderGUI.FindProperty("_SpecGlossMap", properties, false);
  69. smoothness = BaseShaderGUI.FindProperty("_Smoothness", properties, false);
  70. smoothnessMapChannel = BaseShaderGUI.FindProperty("_SmoothnessTextureChannel", properties, false);
  71. bumpMapProp = BaseShaderGUI.FindProperty("_BumpMap", properties, false);
  72. bumpScaleProp = BaseShaderGUI.FindProperty("_BumpScale", properties, false);
  73. occlusionStrength = BaseShaderGUI.FindProperty("_OcclusionStrength", properties, false);
  74. occlusionMap = BaseShaderGUI.FindProperty("_OcclusionMap", properties, false);
  75. // Advanced Props
  76. highlights = BaseShaderGUI.FindProperty("_SpecularHighlights", properties, false);
  77. reflections = BaseShaderGUI.FindProperty("_EnvironmentReflections", properties, false);
  78. }
  79. }
  80. public static void Inputs(LitProperties properties, MaterialEditor materialEditor, Material material)
  81. {
  82. DoMetallicSpecularArea(properties, materialEditor, material);
  83. BaseShaderGUI.DrawNormalArea(materialEditor, properties.bumpMapProp, properties.bumpScaleProp);
  84. if (properties.occlusionMap != null)
  85. {
  86. materialEditor.TexturePropertySingleLine(Styles.occlusionText, properties.occlusionMap,
  87. properties.occlusionMap.textureValue != null ? properties.occlusionStrength : null);
  88. }
  89. }
  90. public static void DoMetallicSpecularArea(LitProperties properties, MaterialEditor materialEditor, Material material)
  91. {
  92. string[] smoothnessChannelNames;
  93. bool hasGlossMap = false;
  94. if (properties.workflowMode == null ||
  95. (WorkflowMode) properties.workflowMode.floatValue == WorkflowMode.Metallic)
  96. {
  97. hasGlossMap = properties.metallicGlossMap.textureValue != null;
  98. smoothnessChannelNames = Styles.metallicSmoothnessChannelNames;
  99. materialEditor.TexturePropertySingleLine(Styles.metallicMapText, properties.metallicGlossMap,
  100. hasGlossMap ? null : properties.metallic);
  101. }
  102. else
  103. {
  104. hasGlossMap = properties.specGlossMap.textureValue != null;
  105. smoothnessChannelNames = Styles.specularSmoothnessChannelNames;
  106. BaseShaderGUI.TextureColorProps(materialEditor, Styles.specularMapText, properties.specGlossMap,
  107. hasGlossMap ? null : properties.specColor);
  108. }
  109. EditorGUI.indentLevel++;
  110. DoSmoothness(properties, material, smoothnessChannelNames);
  111. EditorGUI.indentLevel--;
  112. }
  113. public static void DoSmoothness(LitProperties properties, Material material, string[] smoothnessChannelNames)
  114. {
  115. var opaque = ((BaseShaderGUI.SurfaceType) material.GetFloat("_Surface") ==
  116. BaseShaderGUI.SurfaceType.Opaque);
  117. EditorGUI.indentLevel++;
  118. EditorGUI.BeginChangeCheck();
  119. EditorGUI.showMixedValue = properties.smoothness.hasMixedValue;
  120. var smoothness = EditorGUILayout.Slider(Styles.smoothnessText, properties.smoothness.floatValue, 0f, 1f);
  121. if (EditorGUI.EndChangeCheck())
  122. properties.smoothness.floatValue = smoothness;
  123. EditorGUI.showMixedValue = false;
  124. if (properties.smoothnessMapChannel != null) // smoothness channel
  125. {
  126. EditorGUI.indentLevel++;
  127. EditorGUI.BeginDisabledGroup(!opaque);
  128. EditorGUI.BeginChangeCheck();
  129. EditorGUI.showMixedValue = properties.smoothnessMapChannel.hasMixedValue;
  130. var smoothnessSource = (int) properties.smoothnessMapChannel.floatValue;
  131. if (opaque)
  132. smoothnessSource = EditorGUILayout.Popup(Styles.smoothnessMapChannelText, smoothnessSource,
  133. smoothnessChannelNames);
  134. else
  135. EditorGUILayout.Popup(Styles.smoothnessMapChannelText, 0, smoothnessChannelNames);
  136. if (EditorGUI.EndChangeCheck())
  137. properties.smoothnessMapChannel.floatValue = smoothnessSource;
  138. EditorGUI.showMixedValue = false;
  139. EditorGUI.EndDisabledGroup();
  140. EditorGUI.indentLevel--;
  141. }
  142. EditorGUI.indentLevel--;
  143. }
  144. public static SmoothnessMapChannel GetSmoothnessMapChannel(Material material)
  145. {
  146. int ch = (int) material.GetFloat("_SmoothnessTextureChannel");
  147. if (ch == (int) SmoothnessMapChannel.AlbedoAlpha)
  148. return SmoothnessMapChannel.AlbedoAlpha;
  149. return SmoothnessMapChannel.SpecularMetallicAlpha;
  150. }
  151. public static void SetMaterialKeywords(Material material)
  152. {
  153. // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
  154. // (MaterialProperty value might come from renderer material property block)
  155. var hasGlossMap = false;
  156. var isSpecularWorkFlow = false;
  157. var opaque = ((BaseShaderGUI.SurfaceType) material.GetFloat("_Surface") ==
  158. BaseShaderGUI.SurfaceType.Opaque);
  159. if (material.HasProperty("_WorkflowMode"))
  160. {
  161. isSpecularWorkFlow = (WorkflowMode) material.GetFloat("_WorkflowMode") == WorkflowMode.Specular;
  162. if (isSpecularWorkFlow)
  163. hasGlossMap = material.GetTexture("_SpecGlossMap") != null;
  164. else
  165. hasGlossMap = material.GetTexture("_MetallicGlossMap") != null;
  166. }
  167. else
  168. {
  169. hasGlossMap = material.GetTexture("_MetallicGlossMap") != null;
  170. }
  171. CoreUtils.SetKeyword(material, "_SPECULAR_SETUP", isSpecularWorkFlow);
  172. CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", hasGlossMap);
  173. if (material.HasProperty("_SpecularHighlights"))
  174. CoreUtils.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF",
  175. material.GetFloat("_SpecularHighlights") == 0.0f);
  176. if (material.HasProperty("_EnvironmentReflections"))
  177. CoreUtils.SetKeyword(material, "_ENVIRONMENTREFLECTIONS_OFF",
  178. material.GetFloat("_EnvironmentReflections") == 0.0f);
  179. if (material.HasProperty("_OcclusionMap"))
  180. CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap"));
  181. if (material.HasProperty("_SmoothnessTextureChannel"))
  182. {
  183. CoreUtils.SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A",
  184. GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha && opaque);
  185. }
  186. }
  187. }
  188. }