1
0

PBRStandardShaderGUI.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
  2. #if UNITY_EDITOR
  3. using System;
  4. using UnityEngine;
  5. using UnityEditor;
  6. internal class PBRStandardShaderGUI : ShaderGUI
  7. {
  8. public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
  9. {
  10. SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode"));
  11. string[] shaderKeywords = material.shaderKeywords;
  12. for (int i = 0; i < shaderKeywords.Length; i++)
  13. {
  14. material.DisableKeyword(shaderKeywords[i]);
  15. }
  16. if (oldShader.name == "Standard" || oldShader.name == "Standard (Specular setup)")
  17. {
  18. material.SetColor("_Color", material.GetColor("_Color"));
  19. material.SetTexture("albedoTexture", material.GetTexture("_MainTex"));
  20. material.SetFloat("smoothness", material.GetFloat("_Glossiness"));
  21. material.SetFloat("smoothnessTextureScale", material.GetFloat("_GlossMapScale"));
  22. smoothnessMapChannelGUI = (SmoothnessMapChannel)material.GetFloat("_SmoothnessTextureChannel");
  23. material.SetInt("_SmoothnessMapChannelGUI", (int)smoothnessMapChannelGUI);
  24. if (oldShader.name == "Standard")
  25. {
  26. material.SetFloat("metallic", material.GetFloat("_Metallic"));
  27. material.SetTexture("metallicGlossTexture", material.GetTexture("_MetallicGlossMap"));
  28. }
  29. if (oldShader.name == "Standard (Specular setup)")
  30. {
  31. // material.SetFloat("", material.GetFloat("_SpecularHighlights"));
  32. // material.SetTexture("metallicGlossTexture", material.GetTexture("_SpecGlossMap"));
  33. }
  34. material.SetFloat("normalTextureScale", material.GetFloat("_BumpScale"));
  35. material.SetTexture("normalTexture", material.GetTexture("_BumpMap"));
  36. material.SetFloat("parallaxTextureScale", material.GetFloat("_Parallax"));
  37. material.SetTexture("parallaxTexture", material.GetTexture("_ParallaxMap"));
  38. material.SetFloat("occlusionTextureStrength", material.GetFloat("_OcclusionStrength"));
  39. material.SetTexture("occlusionTexture", material.GetTexture("_OcclusionMap"));
  40. material.SetColor("_EmissionColor", material.GetColor("_EmissionColor"));
  41. material.SetTexture("_EmissionMap", material.GetTexture("_EmissionMap"));
  42. }
  43. else
  44. {
  45. material.SetInt("_SmoothnessMapChannelGUI", 0);
  46. }
  47. SetMaterialKeywords(material);
  48. material.shader = newShader;
  49. }
  50. public enum BlendMode
  51. {
  52. Opaque,
  53. Cutout,
  54. Fade, // Old school alpha-blending mode, fresnel does not affect amount of transparency
  55. Transparent // Physically plausible transparency mode, implemented as alpha pre-multiply
  56. }
  57. public enum SmoothnessMapChannel
  58. {
  59. //SpecularMetallicAlpha,
  60. //AlbedoAlpha,
  61. MetallicAlpha,
  62. AlbedoAlpha
  63. }
  64. private static class Styles
  65. {
  66. public static GUIContent uvSetLabel = EditorGUIUtility.TrTextContent("UV Set");
  67. public static GUIContent albedoText = EditorGUIUtility.TrTextContent("Albedo", "Albedo (RGB) and Transparency (A)");
  68. public static GUIContent alphaCutoffText = EditorGUIUtility.TrTextContent("Alpha Cutoff", "Threshold for alpha cutoff");
  69. public static GUIContent specularMapText = EditorGUIUtility.TrTextContent("Specular", "Specular (RGB) and Smoothness (A)");
  70. public static GUIContent metallicMapText = EditorGUIUtility.TrTextContent("Metallic", "Metallic (R) and Smoothness (A)");
  71. public static GUIContent smoothnessText = EditorGUIUtility.TrTextContent("Smoothness", "Smoothness value");
  72. public static GUIContent smoothnessScaleText = EditorGUIUtility.TrTextContent("Smoothness", "Smoothness scale factor");
  73. public static GUIContent smoothnessMapChannelText = EditorGUIUtility.TrTextContent("Source", "Smoothness texture and channel");
  74. public static GUIContent smoothnessMapChannelText2 = EditorGUIUtility.TrTextContent("Source", "Smoothness texture and channel");
  75. public static GUIContent highlightsText = EditorGUIUtility.TrTextContent("Specular Highlights", "Specular Highlights");
  76. public static GUIContent reflectionsText = EditorGUIUtility.TrTextContent("Reflections", "Glossy Reflections");
  77. public static GUIContent normalMapText = EditorGUIUtility.TrTextContent("Normal Map", "Normal Map");
  78. public static GUIContent heightMapText = EditorGUIUtility.TrTextContent("Height Map", "Height Map (G)");
  79. public static GUIContent occlusionText = EditorGUIUtility.TrTextContent("Occlusion", "Occlusion (G)");
  80. public static GUIContent emissionText = EditorGUIUtility.TrTextContent("Color", "Emission (RGB)");
  81. public static GUIContent detailMaskText = EditorGUIUtility.TrTextContent("Detail Mask", "Mask for Secondary Maps (A)");
  82. public static GUIContent detailAlbedoText = EditorGUIUtility.TrTextContent("Detail Albedo x2", "Albedo (RGB) multiplied by 2");
  83. public static GUIContent detailNormalMapText = EditorGUIUtility.TrTextContent("Normal Map", "Normal Map");
  84. public static GUIContent tillingOffset = EditorGUIUtility.TrTextContent("TillingOffset","Texture tilling and offset");
  85. public static string primaryMapsText = "Main Maps";
  86. public static string secondaryMapsText = "Secondary Maps";
  87. public static string forwardText = "Forward Rendering Options";
  88. public static string renderingMode = "Rendering Mode";
  89. public static string Source = "Source";
  90. public static string advancedText = "Advanced Options";
  91. public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
  92. }
  93. MaterialProperty blendMode = null;
  94. MaterialProperty albedoMap = null;
  95. MaterialProperty _Color = null;
  96. MaterialProperty alphaCutoff = null;
  97. MaterialProperty metallicMap = null;
  98. MaterialProperty metallic = null;
  99. MaterialProperty smoothness = null;
  100. MaterialProperty smoothnessScale = null;
  101. MaterialProperty smoothnessMapChannel = null;
  102. //MaterialProperty highlights = null;
  103. //MaterialProperty reflections = null;
  104. MaterialProperty bumpScale = null;
  105. MaterialProperty bumpMap = null;
  106. MaterialProperty occlusionStrength = null;
  107. MaterialProperty occlusionMap = null;
  108. MaterialProperty heigtMapScale = null;
  109. MaterialProperty heightMap = null;
  110. MaterialProperty _EmissionColor = null;
  111. MaterialProperty emissionMap = null;
  112. //MaterialProperty detailMask = null;
  113. //MaterialProperty detailAlbedoMap = null;
  114. //MaterialProperty detailNormalMapScale = null;
  115. //MaterialProperty detailNormalMap = null;
  116. //MaterialProperty uvSetSecondary = null;
  117. MaterialProperty tilingOffset = null;
  118. MaterialEditor m_MaterialEditor;
  119. bool m_FirstTimeApply = true;
  120. SmoothnessMapChannel smoothnessMapChannelGUI = SmoothnessMapChannel.MetallicAlpha;
  121. public void FindProperties(MaterialProperty[] props)
  122. {
  123. _Color = FindProperty("_Color", props);
  124. albedoMap = FindProperty("albedoTexture", props);
  125. alphaCutoff = FindProperty("_Cutoff", props);
  126. smoothness = FindProperty("smoothness", props);
  127. smoothnessScale = FindProperty("smoothnessTextureScale", props, false);
  128. // smoothnessMapChannel = FindProperty("_SmoothnessTextureChannel", props, false);
  129. metallic = FindProperty("metallic", props, false);
  130. metallicMap = FindProperty("metallicGlossTexture", props, false);
  131. //highlights = FindProperty("_SpecularHighlights", props, false);
  132. //reflections = FindProperty("_GlossyReflections", props, false);
  133. bumpScale = FindProperty("normalTextureScale", props);
  134. bumpMap = FindProperty("normalTexture", props);
  135. heigtMapScale = FindProperty("parallaxTextureScale", props);
  136. heightMap = FindProperty("parallaxTexture", props);
  137. occlusionStrength = FindProperty("occlusionTextureStrength", props);
  138. occlusionMap = FindProperty("occlusionTexture", props);
  139. _EmissionColor = FindProperty("_EmissionColor", props);
  140. emissionMap = FindProperty("_EmissionMap", props);
  141. tilingOffset = FindProperty("tilingOffset",props);
  142. //detailMask = FindProperty("_DetailMask", props);
  143. //detailAlbedoMap = FindProperty("_DetailAlbedoMap", props);
  144. //detailNormalMapScale = FindProperty("_DetailNormalMapScale", props);
  145. //detailNormalMap = FindProperty("_DetailNormalMap", props);
  146. //uvSetSecondary = FindProperty("_UVSec", props);
  147. blendMode = FindProperty("_Mode", props);
  148. }
  149. public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
  150. {
  151. FindProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
  152. m_MaterialEditor = materialEditor;
  153. Material material = materialEditor.target as Material;
  154. // Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing
  155. // material to a standard shader.
  156. // Do this before any GUI code has been issued to prevent layout issues in subsequent GUILayout statements (case 780071)
  157. if (m_FirstTimeApply)
  158. {
  159. MaterialChanged(material);
  160. m_FirstTimeApply = false;
  161. if(material.HasProperty("_SmoothnessMapChannelGUI"))
  162. smoothnessMapChannelGUI = (SmoothnessMapChannel)material.GetInt("_SmoothnessMapChannelGUI");
  163. else
  164. smoothnessMapChannelGUI = SmoothnessMapChannel.MetallicAlpha;
  165. }
  166. ShaderPropertiesGUI(material);
  167. }
  168. public void ShaderPropertiesGUI(Material material)
  169. {
  170. // Use default labelWidth
  171. EditorGUIUtility.labelWidth = 0f;
  172. // Detect any changes to the material
  173. EditorGUI.BeginChangeCheck();
  174. {
  175. BlendModePopup();
  176. // Primary properties
  177. GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel);
  178. DoAlbedoArea(material);
  179. DoSpecularMetallicArea(material);
  180. DoNormalArea();
  181. m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap, heightMap.textureValue != null ? heigtMapScale : null);
  182. m_MaterialEditor.TexturePropertySingleLine(Styles.occlusionText, occlusionMap, occlusionMap.textureValue != null ? occlusionStrength : null);
  183. //m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
  184. DoEmissionArea(material);
  185. //EditorGUI.BeginChangeCheck();
  186. //m_MaterialEditor.TextureScaleOffsetProperty(albedoMap);
  187. //if (EditorGUI.EndChangeCheck())
  188. // emissionMap.textureScaleAndOffset = albedoMap.textureScaleAndOffset; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake
  189. //EditorGUILayout.Space();
  190. GUILayout.Label(Styles.tillingOffset);
  191. m_MaterialEditor.VectorProperty(tilingOffset,"");
  192. //// Secondary properties
  193. //GUILayout.Label(Styles.secondaryMapsText, EditorStyles.boldLabel);
  194. //m_MaterialEditor.TexturePropertySingleLine(Styles.detailAlbedoText, detailAlbedoMap);
  195. //m_MaterialEditor.TexturePropertySingleLine(Styles.detailNormalMapText, detailNormalMap, detailNormalMapScale);
  196. //m_MaterialEditor.TextureScaleOffsetProperty(detailAlbedoMap);
  197. //m_MaterialEditor.ShaderProperty(uvSetSecondary, Styles.uvSetLabel.text);
  198. // Third properties
  199. //���ú꣬�Ƚ�ֹ
  200. //GUILayout.Label(Styles.forwardText, EditorStyles.boldLabel);
  201. //if (highlights != null)
  202. // m_MaterialEditor.ShaderProperty(highlights, Styles.highlightsText);
  203. //if (reflections != null)
  204. // m_MaterialEditor.ShaderProperty(reflections, Styles.reflectionsText);
  205. }
  206. if (EditorGUI.EndChangeCheck())
  207. {
  208. foreach (var obj in blendMode.targets)
  209. MaterialChanged((Material)obj);
  210. }
  211. EditorGUILayout.Space();
  212. }
  213. void BlendModePopup()
  214. {
  215. EditorGUI.showMixedValue = blendMode.hasMixedValue;
  216. var mode = (BlendMode)blendMode.floatValue;
  217. EditorGUI.BeginChangeCheck();
  218. mode = (BlendMode)EditorGUILayout.Popup(Styles.renderingMode, (int)mode, Styles.blendNames);
  219. if (EditorGUI.EndChangeCheck())
  220. {
  221. m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Mode");
  222. blendMode.floatValue = (float)mode;
  223. }
  224. EditorGUI.showMixedValue = false;
  225. }
  226. void DoNormalArea()
  227. {
  228. m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap, bumpMap.textureValue != null ? bumpScale : null);
  229. if (bumpScale.floatValue != 1 && UnityEditorInternal.InternalEditorUtility.IsMobilePlatform(EditorUserBuildSettings.activeBuildTarget))
  230. if (m_MaterialEditor.HelpBoxWithButton(
  231. EditorGUIUtility.TrTextContent("Bump scale is not supported on mobile platforms"),
  232. EditorGUIUtility.TrTextContent("Fix Now")))
  233. {
  234. bumpScale.floatValue = 1;
  235. }
  236. }
  237. void DoAlbedoArea(Material material)
  238. {
  239. m_MaterialEditor.TexturePropertySingleLine(Styles.albedoText, albedoMap, _Color);
  240. if (((BlendMode)material.GetFloat("_Mode") == BlendMode.Cutout))
  241. {
  242. m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
  243. }
  244. }
  245. void DoEmissionArea(Material material)
  246. {
  247. // Emission for GI?
  248. if (m_MaterialEditor.EmissionEnabledProperty())
  249. {
  250. bool hadEmissionTexture = emissionMap.textureValue != null;
  251. // Texture and HDR color controls
  252. m_MaterialEditor.TexturePropertyWithHDRColor(Styles.emissionText, emissionMap, _EmissionColor, false);
  253. // If texture was assigned and color was black set color to white
  254. float brightness = _EmissionColor.colorValue.maxColorComponent;
  255. if (emissionMap.textureValue != null && !hadEmissionTexture && brightness <= 0f)
  256. _EmissionColor.colorValue = Color.white;
  257. material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive;
  258. // change the GI flag and fix it up with emissive as black if necessary
  259. m_MaterialEditor.LightmapEmissionFlagsProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel, true);
  260. }
  261. }
  262. void DoSpecularMetallicArea(Material material)
  263. {
  264. bool hasGlossMap = false;
  265. hasGlossMap = metallicMap.textureValue != null;
  266. m_MaterialEditor.TexturePropertySingleLine(Styles.metallicMapText, metallicMap, hasGlossMap ? null : metallic);
  267. bool showSmoothnessScale = hasGlossMap;
  268. if (smoothnessMapChannel != null)
  269. {
  270. int smoothnessChannel = (int)smoothnessMapChannel.floatValue;
  271. if (smoothnessChannel == (int)SmoothnessMapChannel.AlbedoAlpha)
  272. showSmoothnessScale = true;
  273. }
  274. int indentation = 2; // align with labels of texture properties
  275. m_MaterialEditor.ShaderProperty(showSmoothnessScale ? smoothnessScale : smoothness, showSmoothnessScale ? Styles.smoothnessScaleText : Styles.smoothnessText, indentation);
  276. ++indentation;
  277. //miner12.23
  278. GUILayout.BeginHorizontal();
  279. GUILayout.Label("", GUILayout.Width(27));
  280. //GUILayout.Label("Source",GUILayout.Width(153));
  281. smoothnessMapChannelGUI = (SmoothnessMapChannel)EditorGUILayout.EnumPopup("Source", smoothnessMapChannelGUI, GUILayout.ExpandWidth(true));
  282. if (smoothnessMapChannelGUI == SmoothnessMapChannel.AlbedoAlpha)
  283. {
  284. material.EnableKeyword("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA");
  285. }
  286. else
  287. {
  288. material.DisableKeyword("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA");
  289. }
  290. material.SetInt("_SmoothnessMapChannelGUI", (int)smoothnessMapChannelGUI);
  291. GUILayout.EndHorizontal();
  292. //if (smoothnessMapChannel != null)
  293. // m_MaterialEditor.ShaderProperty(smoothnessMapChannel, Styles.smoothnessMapChannelText, indentation);
  294. }
  295. public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode)
  296. {
  297. switch (blendMode)
  298. {
  299. case BlendMode.Opaque:
  300. material.SetOverrideTag("RenderType", "");
  301. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  302. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
  303. material.SetInt("_ZWrite", 1);
  304. material.DisableKeyword("ALPHATEST");
  305. material.DisableKeyword("TRANSPARENTBLEND");
  306. material.renderQueue = -1;
  307. break;
  308. case BlendMode.Cutout:
  309. material.SetOverrideTag("RenderType", "TransparentCutout");
  310. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  311. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
  312. material.SetInt("_ZWrite", 1);
  313. material.EnableKeyword("ALPHATEST");
  314. material.DisableKeyword("TRANSPARENTBLEND");
  315. material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
  316. break;
  317. case BlendMode.Fade:
  318. material.SetOverrideTag("RenderType", "Transparent");
  319. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
  320. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  321. material.SetInt("_ZWrite", 0);
  322. material.DisableKeyword("ALPHATEST");
  323. material.DisableKeyword("TRANSPARENTBLEND");
  324. material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
  325. break;
  326. case BlendMode.Transparent:
  327. material.SetOverrideTag("RenderType", "Transparent");
  328. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  329. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  330. material.SetInt("_ZWrite", 0);
  331. material.DisableKeyword("ALPHATEST");
  332. material.EnableKeyword("TRANSPARENTBLEND");
  333. material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
  334. break;
  335. }
  336. }
  337. //static SmoothnessMapChannel GetSmoothnessMapChannel(Material material)
  338. //{
  339. // int ch = (int)material.GetFloat("_SmoothnessTextureChannel");
  340. // if (ch == (int)SmoothnessMapChannel.AlbedoAlpha)
  341. // return SmoothnessMapChannel.AlbedoAlpha;
  342. // else
  343. // return SmoothnessMapChannel.SpecularMetallicAlpha;
  344. //}
  345. static void SetMaterialKeywords(Material material)
  346. {
  347. // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
  348. // (MaterialProperty value might come from renderer material property block)
  349. SetKeyword(material, "NORMALTEXTURE", material.GetTexture("normalTexture") || material.GetTexture("_DetailNormalMap"));
  350. SetKeyword(material, "METALLICGLOSSTEXTURE", material.GetTexture("metallicGlossTexture"));
  351. SetKeyword(material, "PARALLAXTEXTURE", material.GetTexture("parallaxTexture"));
  352. SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap"));
  353. // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect
  354. // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color.
  355. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color.
  356. //MaterialEditor.FixupEmissiveFlag(material);
  357. bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;
  358. SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled);
  359. if (material.HasProperty("_SmoothnessTextureChannel"))
  360. {
  361. // SetKeyword(material, "SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha);
  362. }
  363. }
  364. static void MaterialChanged(Material material)
  365. {
  366. SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode"));
  367. SetMaterialKeywords(material);
  368. }
  369. static void SetKeyword(Material m, string keyword, bool state)
  370. {
  371. if (state)
  372. m.EnableKeyword(keyword);
  373. else
  374. m.DisableKeyword(keyword);
  375. }
  376. }
  377. // namespace UnityEditor
  378. #endif