using Misaki.ShaderGUI; using System.Linq; using UnityEditor; using UnityEditor.Rendering; using UnityEngine; using static Misaki.HdrpToon.UtsShaderPropertyName.SurfaceInputs; namespace Misaki.HdrpToon.Editor { public class SurfaceInputsScope : MaterialUIScope { private static class Properties { public static MaterialProperty NormalMap; public static MaterialProperty NormalMapScale; public static MaterialProperty MaskMap; public static MaterialProperty Metallic; public static MaterialProperty MetallicRemapMin; public static MaterialProperty MetallicRemapMax; public static MaterialProperty AORemapMin; public static MaterialProperty AORemapMax; public static MaterialProperty Smoothness; public static MaterialProperty SmoothnessRemapMin; public static MaterialProperty SmoothnessRemapMax; public static MaterialProperty AnisotropyMap; public static MaterialProperty Anisotropy; public static MaterialProperty KKColor; public static MaterialProperty BSDFContribution; public static MaterialProperty SpecularColorMap; public static MaterialProperty SpecularColor; public static MaterialProperty SpecularFeather; public static MaterialProperty SpecularStep; public static MaterialProperty emissiveColorLDR; public static MaterialProperty emissiveColorMap; public static MaterialProperty emissiveIntensity; public static MaterialProperty albedoAffectEmissive; public static MaterialProperty emissiveExposureWeight; } private static class Styles { public static readonly GUIContent NormalMapText = new("Normal Map", "A texture that dictates the bumpiness of the material."); public static readonly GUIContent MaskMapText = new("Mask Map", "A texture that dictates the physical properties of the material. R channel for metallic, G channel for ambient occlusion, A channel for smoothness"); public static readonly GUIContent MetallicText = new("Metallic", "Specifies the metallic value of the material."); public static readonly GUIContent MetallicRemap = new("Metallic Remap", "Remap the max and min value of metallic"); public static readonly GUIContent AORemap = new("AO Remap", "Remap the max and min value of ambient occlusion"); public static readonly GUIContent SmoothnessText = new("Smoothness", "Specifies the smoothness of the material."); public static readonly GUIContent SmoothnessRemapText = new("Smoothness Remap", "Remap the max and min value of smoothness"); public static readonly GUIContent AnisotropyMapText = new("Anisotropy Map", "Specifies the anisotropy map of the material."); public static readonly GUIContent KKColorText = new("KK specular Color", "Specifies the color of KK specular."); public static readonly GUIContent BSDFContributionText = new("BSDF Contribution", "BSDF smoothness contribution, 1 means KK Hair smoothness will fully contribute bsdf calculation"); public static readonly GUIContent SpecularColorMapText = new("Specular Color Map", "Specifies the specular color map of the material."); public static readonly GUIContent SpecRemap = new("Specular Remap", "Feather and step value of Toon Specular"); public static readonly GUIContent emissiveColorText = new("Emissive Color", "The color and color map to set for emissive effect."); public static readonly GUIContent albedoAffectEmissiveText = new("Albedo Affect Emissive", "Enable to affect emissive color with base color"); public static readonly GUIContent emissiveIntensityText = new("Emissive Intensity", "Set the intensity of the emissive color,in Nits"); public static readonly GUIContent emissiveExposureWeightText = new("Exposure Weight", "Controls how the camera exposure influences the perceived intensity of the emissivity. A weight of 0 means that the emissive intensity is calculated ignoring the exposure; increasing this weight progressively increases the influence of exposure on the final emissive value."); } protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.SurfaceInputs; protected override GUIContent Header => new("Surface Inputs"); public override void LoadMaterialProperties() { Properties.NormalMap = FindProperty("_NormalMap"); Properties.NormalMapScale = FindProperty("_NormalScale"); Properties.MaskMap = FindProperty("_MaskMap"); Properties.Metallic = FindProperty("_Metallic"); Properties.MetallicRemapMin = FindProperty("_MetallicRemapMin"); Properties.MetallicRemapMax = FindProperty("_MetallicRemapMax"); Properties.AORemapMin = FindProperty("_AORemapMin"); Properties.AORemapMax = FindProperty("_AORemapMax"); Properties.SmoothnessRemapMin = FindProperty("_SmoothnessRemapMin"); Properties.SmoothnessRemapMax = FindProperty("_SmoothnessRemapMax"); Properties.Smoothness = FindProperty("_Smoothness"); Properties.AnisotropyMap = FindProperty("_AnisotropyMap"); Properties.Anisotropy = FindProperty("_Anisotropy"); Properties.KKColor = FindProperty("_KKColor"); Properties.BSDFContribution = FindProperty("_BSDFContribution"); Properties.SpecularColorMap = FindProperty("_SpecularColorMap"); Properties.SpecularColor = FindProperty("_SpecularColor"); Properties.SpecularFeather = FindProperty("_ToonSpecularFeather"); Properties.SpecularStep = FindProperty("_ToonSpecularStep"); Properties.emissiveColorLDR = FindProperty(EMISSIVE_COLOR_LDR); Properties.emissiveColorMap = FindProperty(EMISSIVE_COLOR_MAP); Properties.albedoAffectEmissive = FindProperty(ALBEDO_AFFECT_EMISSIVE); Properties.emissiveIntensity = FindProperty(EMISSIVE_INTENSITY); Properties.emissiveExposureWeight = FindProperty(EMISSIVE_EXPOSURE_WEIGHT); } protected override void DrawContent() { editor.KeywordTexturePropertySingleLine(Styles.NormalMapText, Properties.NormalMap, Properties.NormalMapScale); if (materials.All(mat => mat.GetPBRMode() != PBRMode.Off)) { if (editor.KeywordTexturePropertySingleLine(Styles.MaskMapText, Properties.MaskMap)) { editor.MinMaxShaderProperty(Properties.MetallicRemapMin, Properties.MetallicRemapMax, 0, 1, Styles.MetallicRemap); editor.MinMaxShaderProperty(Properties.AORemapMin, Properties.AORemapMax, 0, 1, Styles.AORemap); editor.MinMaxShaderProperty(Properties.SmoothnessRemapMin, Properties.SmoothnessRemapMax, 0, 1, Styles.SmoothnessRemapText); } else { if (materials.All(mat => mat.GetPBRMode() != PBRMode.KKHair)) { editor.ShaderProperty(Properties.Metallic, Styles.MetallicText); } editor.ShaderProperty(Properties.Smoothness, Styles.SmoothnessText); } } if (materials.All(mat => mat.GetPBRMode() == PBRMode.Anisotropy || mat.GetPBRMode() == PBRMode.KKHair)) { EditorGUILayout.Space(); editor.KeywordTexturePropertySingleLine(Styles.AnisotropyMapText, Properties.AnisotropyMap, Properties.Anisotropy); if (materials.All(mat => mat.GetPBRMode() == PBRMode.KKHair)) { editor.ShaderProperty(Properties.KKColor, Styles.KKColorText); editor.ShaderProperty(Properties.BSDFContribution, Styles.BSDFContributionText); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Anisotropy Map only ST"); editor.TextureScaleOffsetProperty(Properties.AnisotropyMap); } else if (materials.All(mat => mat.GetPBRMode() == PBRMode.Toon)) { EditorGUILayout.Space(); editor.KeywordTexturePropertySingleLine(Styles.SpecularColorMapText, Properties.SpecularColorMap, Properties.SpecularColor); editor.MinMaxShaderProperty(Properties.SpecularFeather, Properties.SpecularStep, 0, 1, Styles.SpecRemap); } EditorGUILayout.Space(); using (var EmissiveIntentLevel = new EditorGUI.IndentLevelScope(-1)) { EditorGUILayout.LabelField("Emissive", EditorStyles.boldLabel); } EditorGUI.BeginChangeCheck(); editor.KeywordTexturePropertySingleLine(Styles.emissiveColorText, Properties.emissiveColorMap, Properties.emissiveColorLDR, "_EMISSIVE_COLOR_MAP"); editor.ShaderProperty(Properties.emissiveIntensity, Styles.emissiveIntensityText); if (EditorGUI.EndChangeCheck()) { foreach (var material in materials) { if (material.HasProperty(EMISSIVE_COLOR_LDR) && material.HasProperty(EMISSIVE_INTENSITY) && material.HasProperty(EMISSIVE_COLOR)) { // Important: The color picker for kEmissiveColorLDR is LDR and in sRGB color space but Unity don't perform any color space conversion in the color // picker BUT only when sending the color data to the shader... So as we are doing our own calculation here in C#, we must do the conversion ourselves. var emissiveColorLDR = material.GetColor(EMISSIVE_COLOR_LDR); var emissiveColorLDRLinear = new Color(Mathf.GammaToLinearSpace(emissiveColorLDR.r), Mathf.GammaToLinearSpace(emissiveColorLDR.g), Mathf.GammaToLinearSpace(emissiveColorLDR.b)); material.SetColor(EMISSIVE_COLOR, emissiveColorLDRLinear * material.GetFloat(EMISSIVE_INTENSITY)); } } } EditorGUILayout.Space(); editor.ShaderProperty(Properties.albedoAffectEmissive, Styles.albedoAffectEmissiveText); editor.ShaderProperty(Properties.emissiveExposureWeight, Styles.emissiveExposureWeightText); } } }