StandardSpecularShaderGUI.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. using System;
  2. using UnityEngine;
  3. using UnityEditor;
  4. public class StandardSpecularShaderGUI : ShaderGUI
  5. {
  6. public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
  7. {
  8. SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode"));
  9. string[] shaderKeywords = material.shaderKeywords;
  10. for (int i = 0; i < shaderKeywords.Length; i++)
  11. {
  12. material.DisableKeyword(shaderKeywords[i]);
  13. }
  14. if (oldShader.name == "Standard" || oldShader.name == "Standard (Specular setup)")
  15. {
  16. material.SetColor("_Color", material.GetColor("_Color"));
  17. material.SetTexture("albedoTexture", material.GetTexture("_MainTex"));
  18. material.SetFloat("smoothness", material.GetFloat("_Glossiness"));
  19. material.SetFloat("smoothnessTextureScale", material.GetFloat("_GlossMapScale"));
  20. smoothnessMapChannelGUI = (SmoothnessMapChannel)material.GetFloat("_SmoothnessTextureChannel");
  21. material.SetInt("_SmoothnessMapChannelGUI", (int)smoothnessMapChannelGUI);
  22. //if (oldShader.name == "Standard")
  23. //{
  24. // material.SetFloat("metallic", material.GetFloat("_Metallic"));
  25. // material.SetTexture("metallicGlossTexture", material.GetTexture("_MetallicGlossMap"));
  26. //}
  27. if (oldShader.name == "Standard (Specular setup)")
  28. {
  29. material.SetColor("specularColor", material.GetColor("_SpecColor"));
  30. material.SetTexture("specularTexture", material.GetTexture("_SpecGlossMap"));
  31. }
  32. material.SetFloat("normalTextureScale", material.GetFloat("_BumpScale"));
  33. material.SetTexture("normalTexture", material.GetTexture("_BumpMap"));
  34. material.SetFloat("parallaxTextureScale", material.GetFloat("_Parallax"));
  35. material.SetTexture("parallaxTexture", material.GetTexture("_ParallaxMap"));
  36. material.SetFloat("occlusionTextureStrength", material.GetFloat("_OcclusionStrength"));
  37. material.SetTexture("occlusionTexture", material.GetTexture("_OcclusionMap"));
  38. material.SetColor("_EmissionColor", material.GetColor("_EmissionColor"));
  39. material.SetTexture("_EmissionMap", material.GetTexture("_EmissionMap"));
  40. }
  41. else
  42. {
  43. material.SetInt("_SmoothnessMapChannelGUI", (int)SmoothnessMapChannel.SpecularAlpha);
  44. }
  45. SetMaterialKeywords(material);
  46. material.shader = newShader;
  47. }
  48. public enum BlendMode
  49. {
  50. Opaque,
  51. Cutout,
  52. Fade, // 旧的阿尔法混合模式,菲涅耳不影响透明度
  53. Transparent // 预乘
  54. }
  55. public enum SmoothnessMapChannel
  56. {
  57. SpecularAlpha,
  58. AlbedoAlpha
  59. }
  60. MaterialProperty _Color = null;
  61. MaterialProperty albedoMap = null;
  62. MaterialProperty alphaCutoff = null;
  63. MaterialProperty smoothness = null;
  64. MaterialProperty smoothnessScale = null;
  65. MaterialProperty smoothnessMapChannel = null;
  66. MaterialProperty specularColor = null;
  67. MaterialProperty specularMap = null;
  68. //MaterialProperty highlights = null;
  69. //MaterialProperty reflections = null;
  70. MaterialProperty bumpScale = null;
  71. MaterialProperty bumpMap = null;
  72. MaterialProperty heigtMapScale = null;
  73. MaterialProperty heightMap = null;
  74. MaterialProperty occlusionStrength = null;
  75. MaterialProperty occlusionMap = null;
  76. MaterialProperty _EmissionColor = null;
  77. MaterialProperty emissionMap = null;
  78. //MaterialProperty detailMask = null;
  79. //MaterialProperty detailAlbedoMap = null;
  80. //MaterialProperty detailNormalMapScale = null;
  81. //MaterialProperty detailNormalMap = null;
  82. //MaterialProperty uvSetSecondary = null;
  83. MaterialProperty tilingOffset = null;
  84. MaterialProperty blendMode = null;
  85. MaterialEditor m_MaterialEditor;
  86. bool m_FirstTimeApply = true;
  87. SmoothnessMapChannel smoothnessMapChannelGUI = SmoothnessMapChannel.SpecularAlpha;
  88. public void FindProperties(MaterialProperty[] props)
  89. {
  90. _Color = FindProperty("_Color", props);
  91. albedoMap = FindProperty("albedoTexture", props);
  92. alphaCutoff = FindProperty("_Cutoff", props);
  93. smoothness = FindProperty("smoothness", props);
  94. smoothnessScale = FindProperty("smoothnessTextureScale", props, false);
  95. // smoothnessMapChannel = FindProperty("_SmoothnessTextureChannel", props, false);
  96. specularColor = FindProperty("specularColor", props);
  97. specularMap = FindProperty("specularTexture", props);
  98. //highlights = FindProperty("_SpecularHighlights", props);
  99. //reflections = FindProperty("_GlossyReflections", props);
  100. bumpScale = FindProperty("normalTextureScale", props);
  101. bumpMap = FindProperty("normalTexture", props);
  102. heigtMapScale = FindProperty("parallaxTextureScale", props);
  103. heightMap = FindProperty("parallaxTexture", props);
  104. occlusionStrength = FindProperty("occlusionTextureStrength", props);
  105. occlusionMap = FindProperty("occlusionTexture", props);
  106. _EmissionColor = FindProperty("_EmissionColor", props);
  107. emissionMap = FindProperty("_EmissionMap", props);
  108. tilingOffset = FindProperty("tilingOffset", props);
  109. //detailMask = FindProperty("_DetailMask", props);
  110. //detailAlbedoMap = FindProperty("_DetailAlbedoMap", props);
  111. //detailNormalMapScale = FindProperty("_DetailNormalMapScale", props);
  112. //detailNormalMap = FindProperty("_DetailNormalMap", props);
  113. //uvSetSecondary = FindProperty("_UVSec", props);
  114. blendMode = FindProperty("_Mode", props);
  115. }
  116. public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
  117. {
  118. FindProperties(props);
  119. m_MaterialEditor = materialEditor;
  120. Material material = materialEditor.target as Material;
  121. if (m_FirstTimeApply)
  122. {
  123. MaterialChanged(material);
  124. m_FirstTimeApply = false;
  125. if(material.HasProperty("_SmoothnessMapChannelGUI"))
  126. smoothnessMapChannelGUI = (SmoothnessMapChannel)material.GetInt("_SmoothnessMapChannelGUI");
  127. }
  128. ShaderPropertiesGUI(material);
  129. }
  130. public void ShaderPropertiesGUI(Material material)
  131. {
  132. EditorGUIUtility.labelWidth = 0f;
  133. EditorGUI.BeginChangeCheck();
  134. {
  135. BlendModePopup();
  136. GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel);
  137. DoAlbedoArea(material);
  138. DoSpecularArea(material);
  139. DoNormalArea();
  140. m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap, heightMap.textureValue != null ? heigtMapScale : null);
  141. m_MaterialEditor.TexturePropertySingleLine(Styles.occlusionText, occlusionMap, occlusionMap.textureValue != null ? occlusionStrength : null);
  142. //m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
  143. DoEmissionArea(material);
  144. //EditorGUI.BeginChangeCheck();
  145. //m_MaterialEditor.TextureScaleOffsetProperty(albedoMap);
  146. //if (EditorGUI.EndChangeCheck())
  147. // emissionMap.textureScaleAndOffset = albedoMap.textureScaleAndOffset; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake
  148. //EditorGUILayout.Space();
  149. GUILayout.Label(Styles.tillingOffset);
  150. m_MaterialEditor.VectorProperty(tilingOffset, "");
  151. //GUILayout.Label(Styles.secondaryMapsText, EditorStyles.boldLabel);
  152. //m_MaterialEditor.TexturePropertySingleLine(Styles.detailAlbedoText, detailAlbedoMap);
  153. //m_MaterialEditor.TexturePropertySingleLine(Styles.detailNormalMapText, detailNormalMap, detailNormalMapScale);
  154. //m_MaterialEditor.TextureScaleOffsetProperty(detailAlbedoMap);
  155. //m_MaterialEditor.ShaderProperty(uvSetSecondary, Styles.uvSetLabel.text);
  156. //GUILayout.Label(Styles.forwardText, EditorStyles.boldLabel);
  157. //if (highlights != null)
  158. // m_MaterialEditor.ShaderProperty(highlights, Styles.highlightsText);
  159. //if (reflections != null)
  160. // m_MaterialEditor.ShaderProperty(reflections, Styles.reflectionsText);
  161. }
  162. if (EditorGUI.EndChangeCheck())
  163. {
  164. foreach (var obj in blendMode.targets)
  165. MaterialChanged((Material)obj);
  166. }
  167. EditorGUILayout.Space();
  168. }
  169. void BlendModePopup()
  170. {
  171. EditorGUI.showMixedValue = blendMode.hasMixedValue;
  172. var mode = (BlendMode)blendMode.floatValue;
  173. EditorGUI.BeginChangeCheck();
  174. mode = (BlendMode)EditorGUILayout.Popup(Styles.renderingMode, (int)mode, Styles.blendNames);
  175. if (EditorGUI.EndChangeCheck())
  176. {
  177. m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Mode");
  178. blendMode.floatValue = (float)mode;
  179. }
  180. EditorGUI.showMixedValue = false;
  181. }
  182. void DoNormalArea()
  183. {
  184. m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap, bumpMap.textureValue != null ? bumpScale : null);
  185. if (bumpScale.floatValue != 1 && UnityEditorInternal.InternalEditorUtility.IsMobilePlatform(EditorUserBuildSettings.activeBuildTarget))
  186. if (m_MaterialEditor.HelpBoxWithButton(
  187. EditorGUIUtility.TrTextContent("Bump scale is not supported on mobile platforms"),
  188. EditorGUIUtility.TrTextContent("Fix Now")))
  189. {
  190. bumpScale.floatValue = 1;
  191. }
  192. }
  193. void DoAlbedoArea(Material material)
  194. {
  195. m_MaterialEditor.TexturePropertySingleLine(Styles.albedoText, albedoMap, _Color);
  196. if (((BlendMode)material.GetFloat("_Mode") == BlendMode.Cutout))
  197. {
  198. m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
  199. }
  200. }
  201. void DoEmissionArea(Material material)
  202. {
  203. if (m_MaterialEditor.EmissionEnabledProperty())
  204. {
  205. bool hadEmissionTexture = emissionMap.textureValue != null;
  206. m_MaterialEditor.TexturePropertyWithHDRColor(Styles.emissionText, emissionMap, _EmissionColor, false);
  207. float brightness = _EmissionColor.colorValue.maxColorComponent;
  208. if (emissionMap.textureValue != null && !hadEmissionTexture && brightness <= 0f)
  209. _EmissionColor.colorValue = Color.white;
  210. // m_MaterialEditor.LightmapEmissionFlagsProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel, true);
  211. }
  212. }
  213. static void MaterialChanged(Material material)
  214. {
  215. SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode"));
  216. SetMaterialKeywords(material);
  217. }
  218. void DoSpecularArea(Material material)
  219. {
  220. bool hasGlossMap = false;
  221. hasGlossMap = specularMap.textureValue != null;
  222. m_MaterialEditor.TexturePropertySingleLine(Styles.specularMapText, specularMap, hasGlossMap ? null : specularColor);
  223. bool showSmoothnessScale = hasGlossMap;
  224. if (smoothnessMapChannel != null)
  225. {
  226. int smoothnessChannel = (int)smoothnessMapChannel.floatValue;
  227. if (smoothnessChannel == (int)SmoothnessMapChannel.AlbedoAlpha)
  228. showSmoothnessScale = true;
  229. }
  230. int indentation = 2; // align with labels of texture properties
  231. m_MaterialEditor.ShaderProperty(showSmoothnessScale ? smoothnessScale : smoothness, showSmoothnessScale ? Styles.smoothnessScaleText : Styles.smoothnessText, indentation);
  232. ++indentation;
  233. //miner12.23
  234. GUILayout.BeginHorizontal();
  235. GUILayout.Label("", GUILayout.Width(27));
  236. //GUILayout.Label("Source",GUILayout.Width(153));
  237. smoothnessMapChannelGUI = (SmoothnessMapChannel)EditorGUILayout.EnumPopup("Source", smoothnessMapChannelGUI, GUILayout.ExpandWidth(true));
  238. if (smoothnessMapChannelGUI == SmoothnessMapChannel.AlbedoAlpha)
  239. {
  240. material.EnableKeyword("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA");
  241. }
  242. else
  243. {
  244. material.DisableKeyword("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA");
  245. }
  246. material.SetInt("_SmoothnessMapChannelGUI", (int)smoothnessMapChannelGUI);
  247. GUILayout.EndHorizontal();
  248. //if (smoothnessMapChannel != null)
  249. // m_MaterialEditor.ShaderProperty(smoothnessMapChannel, Styles.smoothnessMapChannelText, indentation);
  250. }
  251. static void SetKeyword(Material m, string keyword, bool state)
  252. {
  253. if (state)
  254. m.EnableKeyword(keyword);
  255. else
  256. m.DisableKeyword(keyword);
  257. }
  258. public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode)
  259. {
  260. switch (blendMode)
  261. {
  262. case BlendMode.Opaque:
  263. material.SetOverrideTag("RenderType", "");
  264. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  265. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
  266. material.SetInt("_ZWrite", 1);
  267. material.DisableKeyword("ALPHATEST");
  268. material.DisableKeyword("TRANSPARENTBLEND");
  269. material.renderQueue = -1;
  270. break;
  271. case BlendMode.Cutout:
  272. material.SetOverrideTag("RenderType", "TransparentCutout");
  273. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  274. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
  275. material.SetInt("_ZWrite", 1);
  276. material.EnableKeyword("ALPHATEST");
  277. material.DisableKeyword("TRANSPARENTBLEND");
  278. material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
  279. break;
  280. case BlendMode.Fade:
  281. material.SetOverrideTag("RenderType", "Transparent");
  282. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
  283. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  284. material.SetInt("_ZWrite", 0);
  285. material.DisableKeyword("ALPHATEST");
  286. material.DisableKeyword("TRANSPARENTBLEND");
  287. material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
  288. break;
  289. case BlendMode.Transparent:
  290. material.SetOverrideTag("RenderType", "Transparent");
  291. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  292. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  293. material.SetInt("_ZWrite", 0);
  294. material.DisableKeyword("ALPHATEST");
  295. material.EnableKeyword("TRANSPARENTBLEND");
  296. material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
  297. break;
  298. }
  299. }
  300. //static SmoothnessMapChannel GetSmoothnessMapChannel(Material material)
  301. //{
  302. // int ch = (int)material.GetFloat("_SmoothnessTextureChannel");
  303. // if (ch == (int)SmoothnessMapChannel.AlbedoAlpha)
  304. // return SmoothnessMapChannel.AlbedoAlpha;
  305. // else
  306. // return SmoothnessMapChannel.SpecularMetallicAlpha;
  307. //}
  308. static void SetMaterialKeywords(Material material)
  309. {
  310. SetKeyword(material, "NORMALTEXTURE", material.GetTexture("normalTexture") || material.GetTexture("_DetailNormalMap"));
  311. if(material.HasProperty("specularTexture"))
  312. SetKeyword(material, "SPECULARGLOSSTEXTURE", material.GetTexture("specularTexture"));
  313. SetKeyword(material, "PARALLAXTEXTURE", material.GetTexture("parallaxTexture"));
  314. //SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap"));
  315. // MaterialEditor.FixupEmissiveFlag(material);
  316. bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;
  317. SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled);
  318. //if (material.HasProperty("_SmoothnessTextureChannel"))
  319. //{
  320. // SetKeyword(material, "SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha);
  321. //}
  322. }
  323. private static class Styles
  324. {
  325. public static GUIContent uvSetLabel = EditorGUIUtility.TrTextContent("UV Set");
  326. public static GUIContent albedoText = EditorGUIUtility.TrTextContent("Albedo", "Albedo (RGB) and Transparency (A)");
  327. public static GUIContent alphaCutoffText = EditorGUIUtility.TrTextContent("Alpha Cutoff", "Threshold for alpha cutoff");
  328. public static GUIContent specularMapText = EditorGUIUtility.TrTextContent("Specular", "Specular (RGB) and Smoothness (A)");
  329. public static GUIContent smoothnessText = EditorGUIUtility.TrTextContent("Smoothness", "Smoothness value");
  330. public static GUIContent smoothnessScaleText = EditorGUIUtility.TrTextContent("Smoothness", "Smoothness scale factor");
  331. public static GUIContent smoothnessMapChannelText = EditorGUIUtility.TrTextContent("Source", "Smoothness texture and channel");
  332. public static GUIContent highlightsText = EditorGUIUtility.TrTextContent("Specular Highlights", "Specular Highlights");
  333. public static GUIContent reflectionsText = EditorGUIUtility.TrTextContent("Reflections", "Glossy Reflections");
  334. public static GUIContent normalMapText = EditorGUIUtility.TrTextContent("Normal Map", "Normal Map");
  335. public static GUIContent heightMapText = EditorGUIUtility.TrTextContent("Height Map", "Height Map (G)");
  336. public static GUIContent occlusionText = EditorGUIUtility.TrTextContent("Occlusion", "Occlusion (G)");
  337. public static GUIContent emissionText = EditorGUIUtility.TrTextContent("Color", "Emission (RGB)");
  338. public static GUIContent detailMaskText = EditorGUIUtility.TrTextContent("Detail Mask", "Mask for Secondary Maps (A)");
  339. public static GUIContent detailAlbedoText = EditorGUIUtility.TrTextContent("Detail Albedo x2", "Albedo (RGB) multiplied by 2");
  340. public static GUIContent detailNormalMapText = EditorGUIUtility.TrTextContent("Normal Map", "Normal Map");
  341. public static GUIContent tillingOffset = EditorGUIUtility.TrTextContent("TillingOffset", "Texture tilling and offset");
  342. public static string primaryMapsText = "Main Maps";
  343. public static string secondaryMapsText = "Secondary Maps";
  344. public static string forwardText = "Forward Rendering Options";
  345. public static string renderingMode = "Rendering Mode";
  346. public static string advancedText = "Advanced Options";
  347. public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
  348. }
  349. }