123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- using UnityEngine;
- using UnityEngine.Rendering;
-
- namespace UnityEditor.Rendering.Universal.ShaderGUI
- {
- /// <summary>
- /// Editor script for the Lit material inspector.
- /// </summary>
- public static class LitGUI
- {
- /// <summary>
- /// Workflow modes for the shader.
- /// </summary>
- public enum WorkflowMode
- {
- /// <summary>
- /// Use this for specular workflow.
- /// </summary>
- Specular = 0,
-
- /// <summary>
- /// Use this for metallic workflow.
- /// </summary>
- Metallic
- }
-
- /// <summary>
- /// Options to select the texture channel where the smoothness value is stored.
- /// </summary>
- public enum SmoothnessMapChannel
- {
- /// <summary>
- /// Use this when smoothness is stored in the alpha channel of the Specular/Metallic Map.
- /// </summary>
- SpecularMetallicAlpha,
-
- /// <summary>
- /// Use this when smoothness is stored in the alpha channel of the Albedo Map.
- /// </summary>
- AlbedoAlpha,
- }
-
- /// <summary>
- /// Container for the text and tooltips used to display the shader.
- /// </summary>
- public static class Styles
- {
- /// <summary>
- /// The text and tooltip for the workflow Mode GUI.
- /// </summary>
- public static GUIContent workflowModeText = EditorGUIUtility.TrTextContent("Workflow Mode",
- "Select a workflow that fits your textures. Choose between Metallic or Specular.");
-
- /// <summary>
- /// The text and tooltip for the specular Map GUI.
- /// </summary>
- public static GUIContent specularMapText =
- EditorGUIUtility.TrTextContent("Specular Map", "Designates a Specular Map and specular color determining the apperance of reflections on this Material's surface.");
-
- /// <summary>
- /// The text and tooltip for the metallic Map GUI.
- /// </summary>
- public static GUIContent metallicMapText =
- EditorGUIUtility.TrTextContent("Metallic Map", "Sets and configures the map for the Metallic workflow.");
-
- /// <summary>
- /// The text and tooltip for the smoothness GUI.
- /// </summary>
- public static GUIContent smoothnessText = EditorGUIUtility.TrTextContent("Smoothness",
- "Controls the spread of highlights and reflections on the surface.");
-
- /// <summary>
- /// The text and tooltip for the smoothness source GUI.
- /// </summary>
- public static GUIContent smoothnessMapChannelText =
- EditorGUIUtility.TrTextContent("Source",
- "Specifies where to sample a smoothness map from. By default, uses the alpha channel for your map.");
-
- /// <summary>
- /// The text and tooltip for the specular Highlights GUI.
- /// </summary>
- public static GUIContent highlightsText = EditorGUIUtility.TrTextContent("Specular Highlights",
- "When enabled, the Material reflects the shine from direct lighting.");
-
- /// <summary>
- /// The text and tooltip for the environment Reflections GUI.
- /// </summary>
- public static GUIContent reflectionsText =
- EditorGUIUtility.TrTextContent("Environment Reflections",
- "When enabled, the Material samples reflections from the nearest Reflection Probes or Lighting Probe.");
-
- /// <summary>
- /// The text and tooltip for the height map GUI.
- /// </summary>
- public static GUIContent heightMapText = EditorGUIUtility.TrTextContent("Height Map",
- "Defines a Height Map that will drive a parallax effect in the shader making the surface seem displaced.");
-
- /// <summary>
- /// The text and tooltip for the occlusion map GUI.
- /// </summary>
- public static GUIContent occlusionText = EditorGUIUtility.TrTextContent("Occlusion Map",
- "Sets an occlusion map to simulate shadowing from ambient lighting.");
-
- /// <summary>
- /// The names for smoothness alpha options available for metallic workflow.
- /// </summary>
- public static readonly string[] metallicSmoothnessChannelNames = { "Metallic Alpha", "Albedo Alpha" };
-
- /// <summary>
- /// The names for smoothness alpha options available for specular workflow.
- /// </summary>
- public static readonly string[] specularSmoothnessChannelNames = { "Specular Alpha", "Albedo Alpha" };
-
- /// <summary>
- /// The text and tooltip for the enabling/disabling clear coat GUI.
- /// </summary>
- public static GUIContent clearCoatText = EditorGUIUtility.TrTextContent("Clear Coat",
- "A multi-layer material feature which simulates a thin layer of coating on top of the surface material." +
- "\nPerformance cost is considerable as the specular component is evaluated twice, once per layer.");
-
- /// <summary>
- /// The text and tooltip for the clear coat Mask GUI.
- /// </summary>
- public static GUIContent clearCoatMaskText = EditorGUIUtility.TrTextContent("Mask",
- "Specifies the amount of the coat blending." +
- "\nActs as a multiplier of the clear coat map mask value or as a direct mask value if no map is specified." +
- "\nThe map specifies clear coat mask in the red channel and clear coat smoothness in the green channel.");
-
- /// <summary>
- /// The text and tooltip for the clear coat smoothness GUI.
- /// </summary>
- public static GUIContent clearCoatSmoothnessText = EditorGUIUtility.TrTextContent("Smoothness",
- "Specifies the smoothness of the coating." +
- "\nActs as a multiplier of the clear coat map smoothness value or as a direct smoothness value if no map is specified.");
- }
-
- /// <summary>
- /// Container for the properties used in the <c>LitGUI</c> editor script.
- /// </summary>
- public struct LitProperties
- {
- // Surface Option Props
-
- /// <summary>
- /// The MaterialProperty for workflow mode.
- /// </summary>
- public MaterialProperty workflowMode;
-
-
- // Surface Input Props
-
- /// <summary>
- /// The MaterialProperty for metallic value.
- /// </summary>
- public MaterialProperty metallic;
-
- /// <summary>
- /// The MaterialProperty for specular color.
- /// </summary>
- public MaterialProperty specColor;
-
- /// <summary>
- /// The MaterialProperty for metallic Smoothness map.
- /// </summary>
- public MaterialProperty metallicGlossMap;
-
- /// <summary>
- /// The MaterialProperty for specular smoothness map.
- /// </summary>
- public MaterialProperty specGlossMap;
-
- /// <summary>
- /// The MaterialProperty for smoothness value.
- /// </summary>
- public MaterialProperty smoothness;
-
- /// <summary>
- /// The MaterialProperty for smoothness alpha channel.
- /// </summary>
- public MaterialProperty smoothnessMapChannel;
-
- /// <summary>
- /// The MaterialProperty for normal map.
- /// </summary>
- public MaterialProperty bumpMapProp;
-
- /// <summary>
- /// The MaterialProperty for normal map scale.
- /// </summary>
- public MaterialProperty bumpScaleProp;
-
- /// <summary>
- /// The MaterialProperty for height map.
- /// </summary>
- public MaterialProperty parallaxMapProp;
-
- /// <summary>
- /// The MaterialProperty for height map scale.
- /// </summary>
- public MaterialProperty parallaxScaleProp;
-
- /// <summary>
- /// The MaterialProperty for occlusion strength.
- /// </summary>
- public MaterialProperty occlusionStrength;
-
- /// <summary>
- /// The MaterialProperty for occlusion map.
- /// </summary>
- public MaterialProperty occlusionMap;
-
-
- // Advanced Props
-
- /// <summary>
- /// The MaterialProperty for specular highlights.
- /// </summary>
- public MaterialProperty highlights;
-
- /// <summary>
- /// The MaterialProperty for environment reflections.
- /// </summary>
- public MaterialProperty reflections;
-
- /// <summary>
- /// The MaterialProperty for enabling/disabling clear coat.
- /// </summary>
- public MaterialProperty clearCoat; // Enable/Disable dummy property
-
- /// <summary>
- /// The MaterialProperty for clear coat map.
- /// </summary>
- public MaterialProperty clearCoatMap;
-
- /// <summary>
- /// The MaterialProperty for clear coat mask.
- /// </summary>
- public MaterialProperty clearCoatMask;
-
- /// <summary>
- /// The MaterialProperty for clear coat smoothness.
- /// </summary>
- public MaterialProperty clearCoatSmoothness;
-
- /// <summary>
- /// Constructor for the <c>LitProperties</c> container struct.
- /// </summary>
- /// <param name="properties"></param>
- public LitProperties(MaterialProperty[] properties)
- {
- // Surface Option Props
- workflowMode = BaseShaderGUI.FindProperty("_WorkflowMode", properties, false);
- // Surface Input Props
- metallic = BaseShaderGUI.FindProperty("_Metallic", properties);
- specColor = BaseShaderGUI.FindProperty("_SpecColor", properties, false);
- metallicGlossMap = BaseShaderGUI.FindProperty("_MetallicGlossMap", properties);
- specGlossMap = BaseShaderGUI.FindProperty("_SpecGlossMap", properties, false);
- smoothness = BaseShaderGUI.FindProperty("_Smoothness", properties, false);
- smoothnessMapChannel = BaseShaderGUI.FindProperty("_SmoothnessTextureChannel", properties, false);
- bumpMapProp = BaseShaderGUI.FindProperty("_BumpMap", properties, false);
- bumpScaleProp = BaseShaderGUI.FindProperty("_BumpScale", properties, false);
- parallaxMapProp = BaseShaderGUI.FindProperty("_ParallaxMap", properties, false);
- parallaxScaleProp = BaseShaderGUI.FindProperty("_Parallax", properties, false);
- occlusionStrength = BaseShaderGUI.FindProperty("_OcclusionStrength", properties, false);
- occlusionMap = BaseShaderGUI.FindProperty("_OcclusionMap", properties, false);
- // Advanced Props
- highlights = BaseShaderGUI.FindProperty("_SpecularHighlights", properties, false);
- reflections = BaseShaderGUI.FindProperty("_EnvironmentReflections", properties, false);
-
- clearCoat = BaseShaderGUI.FindProperty("_ClearCoat", properties, false);
- clearCoatMap = BaseShaderGUI.FindProperty("_ClearCoatMap", properties, false);
- clearCoatMask = BaseShaderGUI.FindProperty("_ClearCoatMask", properties, false);
- clearCoatSmoothness = BaseShaderGUI.FindProperty("_ClearCoatSmoothness", properties, false);
- }
- }
-
- /// <summary>
- /// Draws the surface inputs GUI.
- /// </summary>
- /// <param name="properties"></param>
- /// <param name="materialEditor"></param>
- /// <param name="material"></param>
- public static void Inputs(LitProperties properties, MaterialEditor materialEditor, Material material)
- {
- DoMetallicSpecularArea(properties, materialEditor, material);
- BaseShaderGUI.DrawNormalArea(materialEditor, properties.bumpMapProp, properties.bumpScaleProp);
-
- if (HeightmapAvailable(material))
- DoHeightmapArea(properties, materialEditor);
-
- if (properties.occlusionMap != null)
- {
- materialEditor.TexturePropertySingleLine(Styles.occlusionText, properties.occlusionMap,
- properties.occlusionMap.textureValue != null ? properties.occlusionStrength : null);
- }
-
- // Check that we have all the required properties for clear coat,
- // otherwise we will get null ref exception from MaterialEditor GUI helpers.
- if (ClearCoatAvailable(material))
- DoClearCoat(properties, materialEditor, material);
- }
-
- private static bool ClearCoatAvailable(Material material)
- {
- return material.HasProperty("_ClearCoat")
- && material.HasProperty("_ClearCoatMap")
- && material.HasProperty("_ClearCoatMask")
- && material.HasProperty("_ClearCoatSmoothness");
- }
-
- private static bool HeightmapAvailable(Material material)
- {
- return material.HasProperty("_Parallax")
- && material.HasProperty("_ParallaxMap");
- }
-
- private static void DoHeightmapArea(LitProperties properties, MaterialEditor materialEditor)
- {
- materialEditor.TexturePropertySingleLine(Styles.heightMapText, properties.parallaxMapProp,
- properties.parallaxMapProp.textureValue != null ? properties.parallaxScaleProp : null);
- }
-
- private static bool ClearCoatEnabled(Material material)
- {
- return material.HasProperty("_ClearCoat") && material.GetFloat("_ClearCoat") > 0.0;
- }
-
- /// <summary>
- /// Draws the clear coat GUI.
- /// </summary>
- /// <param name="properties"></param>
- /// <param name="materialEditor"></param>
- /// <param name="material"></param>
- public static void DoClearCoat(LitProperties properties, MaterialEditor materialEditor, Material material)
- {
- materialEditor.ShaderProperty(properties.clearCoat, Styles.clearCoatText);
- var coatEnabled = material.GetFloat("_ClearCoat") > 0.0;
-
- EditorGUI.BeginDisabledGroup(!coatEnabled);
- {
- EditorGUI.indentLevel += 2;
- materialEditor.TexturePropertySingleLine(Styles.clearCoatMaskText, properties.clearCoatMap, properties.clearCoatMask);
-
- // Texture and HDR color controls
- materialEditor.ShaderProperty(properties.clearCoatSmoothness, Styles.clearCoatSmoothnessText);
-
- EditorGUI.indentLevel -= 2;
- }
- EditorGUI.EndDisabledGroup();
- }
-
- /// <summary>
- /// Draws the metallic/specular area GUI.
- /// </summary>
- /// <param name="properties"></param>
- /// <param name="materialEditor"></param>
- /// <param name="material"></param>
- public static void DoMetallicSpecularArea(LitProperties properties, MaterialEditor materialEditor, Material material)
- {
- string[] smoothnessChannelNames;
- bool hasGlossMap = false;
- if (properties.workflowMode == null ||
- (WorkflowMode)properties.workflowMode.floatValue == WorkflowMode.Metallic)
- {
- hasGlossMap = properties.metallicGlossMap.textureValue != null;
- smoothnessChannelNames = Styles.metallicSmoothnessChannelNames;
- materialEditor.TexturePropertySingleLine(Styles.metallicMapText, properties.metallicGlossMap,
- hasGlossMap ? null : properties.metallic);
- }
- else
- {
- hasGlossMap = properties.specGlossMap.textureValue != null;
- smoothnessChannelNames = Styles.specularSmoothnessChannelNames;
- BaseShaderGUI.TextureColorProps(materialEditor, Styles.specularMapText, properties.specGlossMap,
- hasGlossMap ? null : properties.specColor);
- }
- DoSmoothness(materialEditor, material, properties.smoothness, properties.smoothnessMapChannel, smoothnessChannelNames);
- }
-
- internal static bool IsOpaque(Material material)
- {
- bool opaque = true;
- if (material.HasProperty(Property.SurfaceType))
- opaque = ((BaseShaderGUI.SurfaceType)material.GetFloat(Property.SurfaceType) == BaseShaderGUI.SurfaceType.Opaque);
- return opaque;
- }
-
- /// <summary>
- /// Draws the smoothness GUI.
- /// </summary>
- /// <param name="materialEditor"></param>
- /// <param name="material"></param>
- /// <param name="smoothness"></param>
- /// <param name="smoothnessMapChannel"></param>
- /// <param name="smoothnessChannelNames"></param>
- public static void DoSmoothness(MaterialEditor materialEditor, Material material, MaterialProperty smoothness, MaterialProperty smoothnessMapChannel, string[] smoothnessChannelNames)
- {
- EditorGUI.indentLevel += 2;
-
- materialEditor.ShaderProperty(smoothness, Styles.smoothnessText);
-
- if (smoothnessMapChannel != null) // smoothness channel
- {
- var opaque = IsOpaque(material);
- EditorGUI.indentLevel++;
- EditorGUI.showMixedValue = smoothnessMapChannel.hasMixedValue;
- if (opaque)
- {
- MaterialEditor.BeginProperty(smoothnessMapChannel);
- EditorGUI.BeginChangeCheck();
- var smoothnessSource = (int)smoothnessMapChannel.floatValue;
- smoothnessSource = EditorGUILayout.Popup(Styles.smoothnessMapChannelText, smoothnessSource, smoothnessChannelNames);
- if (EditorGUI.EndChangeCheck())
- smoothnessMapChannel.floatValue = smoothnessSource;
- MaterialEditor.EndProperty();
- }
- else
- {
- EditorGUI.BeginDisabledGroup(true);
- EditorGUILayout.Popup(Styles.smoothnessMapChannelText, 0, smoothnessChannelNames);
- EditorGUI.EndDisabledGroup();
- }
- EditorGUI.showMixedValue = false;
- EditorGUI.indentLevel--;
- }
- EditorGUI.indentLevel -= 2;
- }
-
- /// <summary>
- /// Retrieves the alpha channel used for smoothness.
- /// </summary>
- /// <param name="material"></param>
- /// <returns>The Alpha channel used for Smoothness.</returns>
- public static SmoothnessMapChannel GetSmoothnessMapChannel(Material material)
- {
- int ch = (int)material.GetFloat("_SmoothnessTextureChannel");
- if (ch == (int)SmoothnessMapChannel.AlbedoAlpha)
- return SmoothnessMapChannel.AlbedoAlpha;
-
- return SmoothnessMapChannel.SpecularMetallicAlpha;
- }
-
- // (shared by all lit shaders, including shadergraph Lit Target and Lit.shader)
- internal static void SetupSpecularWorkflowKeyword(Material material, out bool isSpecularWorkflow)
- {
- isSpecularWorkflow = false; // default is metallic workflow
- if (material.HasProperty(Property.SpecularWorkflowMode))
- isSpecularWorkflow = ((WorkflowMode)material.GetFloat(Property.SpecularWorkflowMode)) == WorkflowMode.Specular;
- CoreUtils.SetKeyword(material, "_SPECULAR_SETUP", isSpecularWorkflow);
- }
-
- /// <summary>
- /// Sets up the keywords for the Lit shader and material.
- /// </summary>
- /// <param name="material"></param>
- public static void SetMaterialKeywords(Material material)
- {
- SetupSpecularWorkflowKeyword(material, out bool isSpecularWorkFlow);
-
- // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
- // (MaterialProperty value might come from renderer material property block)
- var specularGlossMap = isSpecularWorkFlow ? "_SpecGlossMap" : "_MetallicGlossMap";
- var hasGlossMap = material.GetTexture(specularGlossMap) != null;
-
- CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", hasGlossMap);
-
- if (material.HasProperty("_SpecularHighlights"))
- CoreUtils.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF",
- material.GetFloat("_SpecularHighlights") == 0.0f);
- if (material.HasProperty("_EnvironmentReflections"))
- CoreUtils.SetKeyword(material, "_ENVIRONMENTREFLECTIONS_OFF",
- material.GetFloat("_EnvironmentReflections") == 0.0f);
- if (material.HasProperty("_OcclusionMap"))
- CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap"));
-
- if (material.HasProperty("_ParallaxMap"))
- CoreUtils.SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap"));
-
- if (material.HasProperty("_SmoothnessTextureChannel"))
- {
- var opaque = IsOpaque(material);
- CoreUtils.SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A",
- GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha && opaque);
- }
-
- // Clear coat keywords are independent to remove possibility of invalid combinations.
- if (ClearCoatEnabled(material))
- {
- var hasMap = material.HasProperty("_ClearCoatMap") && material.GetTexture("_ClearCoatMap") != null;
- if (hasMap)
- {
- CoreUtils.SetKeyword(material, "_CLEARCOAT", false);
- CoreUtils.SetKeyword(material, "_CLEARCOATMAP", true);
- }
- else
- {
- CoreUtils.SetKeyword(material, "_CLEARCOAT", true);
- CoreUtils.SetKeyword(material, "_CLEARCOATMAP", false);
- }
- }
- else
- {
- CoreUtils.SetKeyword(material, "_CLEARCOAT", false);
- CoreUtils.SetKeyword(material, "_CLEARCOATMAP", false);
- }
- }
- }
- }
|