using System; using UnityEngine; using UnityEngine.Rendering.HighDefinition; using System.Linq; // Include material common properties names using static UnityEngine.Rendering.HighDefinition.HDMaterialProperties; namespace UnityEditor.Rendering.HighDefinition { /// The UI block that represents the surface inputs for decal materials. public class DecalSurfaceInputsUIBlock : MaterialUIBlock { internal class Styles { public static GUIContent header { get; } = EditorGUIUtility.TrTextContent("Surface Inputs"); public static GUIContent baseColorText = new GUIContent("Base Map", "Specify the base color (RGB) and opacity (A) of the decal."); public static GUIContent baseColorAlphaOnlyText = new GUIContent("Base Map", "Specify the base color (RGB) and opacity (A) of the decal. Since Affect BaseColor is disabled only the opacity (A) is being used."); public static GUIContent baseOpacityText = new GUIContent("Opacity", "Specify the opacity (A) of the decal."); public static GUIContent normalMapText = new GUIContent("Normal Map", "Specifies the normal map for this Material (BC7/BC5/DXT5(nm))."); public static GUIContent decalBlendText = new GUIContent("Global Opacity", "Controls the opacity of the entire decal."); public static GUIContent normalOpacityChannelText = new GUIContent("Normal Opacity Channel", "Specifies the source this Material uses as opacity for its Normal Map."); public static GUIContent smoothnessRemappingText = new GUIContent("Smoothness Remapping", "Controls a remap for the smoothness channel in the Mask Map."); public static GUIContent smoothnessText = new GUIContent("Smoothness", "Controls the smoothness of the decal."); public static GUIContent metallicRemappingText = new GUIContent("Metallic Remapping", "Controls a remap for the metallic channel in the Mask Map."); public static GUIContent metallicText = new GUIContent("Metallic", "Controls the metallic of the decal."); public static GUIContent aoRemappingText = new GUIContent("Ambient Occlusion Remapping", "Controls a remap for the ambient occlusion channel in the Mask Map."); public static GUIContent aoText = new GUIContent("Ambient Occlusion", "Controls the ambient occlusion of the decal."); public static GUIContent maskOpacityChannelText = new GUIContent("Mask Opacity Channel", "Specifies the source this Material uses as opacity for its Mask Map."); public static GUIContent maskMapBlueScaleText = new GUIContent("Scale Mask Map Blue Channel", "Controls the scale of the blue channel of the Mask Map. You can use this as opacity depending on the blend source you choose."); public static GUIContent opacityBlueScaleText = new GUIContent("Mask Opacity", "Controls the opacity of the Mask (Metallic, Ambient Occlusion, Smoothness). You can use this as opacity depending on the blend source you choose."); public static GUIContent useEmissionIntensityText = new GUIContent("Use Emission Intensity", "When enabled, this Material separates emission color and intensity. This makes the Emission Map into an LDR color and exposes the Emission Intensity property."); public static GUIContent emissiveIntensityText = new GUIContent("Emission Intensity", "Sets the overall strength of the emission effect."); public static GUIContent emissiveExposureWeightText = new GUIContent("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."); public static GUIContent decalLayerText = new GUIContent("Decal Layer", "Specifies the current Decal Layers that the Decal affects.This Decal affect corresponding Material with the same Decal Layer flags."); public static GUIContent maskMapText = new GUIContent("Mask Map", "Specifies the Mask Map for this Material - Metal(R), Ambient Occlusion(G), Opacity(B), Smoothness(A)"); } enum BlendSource { BaseColorMapAlpha, MaskMapBlue } string[] blendSourceNames = new string[2]; MaterialProperty baseColorMap = null; MaterialProperty baseColor = null; MaterialProperty normalMap = null; MaterialProperty maskMap = null; MaterialProperty decalBlend = new MaterialProperty(); const string kDecalBlend = "_DecalBlend"; MaterialProperty normalBlendSrc = new MaterialProperty(); const string kNormalBlendSrc = "_NormalBlendSrc"; MaterialProperty maskBlendSrc = new MaterialProperty(); const string kMaskBlendSrc = "_MaskBlendSrc"; MaterialProperty maskmapMetal = new MaterialProperty(); const string kMaskmapMetal = "_MaskmapMetal"; MaterialProperty maskmapAO = new MaterialProperty(); const string kMaskmapAO = "_MaskmapAO"; MaterialProperty maskmapSmoothness = new MaterialProperty(); const string kMaskmapSmoothness = "_MaskmapSmoothness"; MaterialProperty metallicRemapMin = new MaterialProperty(); const string kMetallicRemapMin = "_MetallicRemapMin"; MaterialProperty metallicRemapMax = new MaterialProperty(); const string kMetallicRemapMax = "_MetallicRemapMax"; MaterialProperty AORemapMin = new MaterialProperty(); const string kAORemapMin = "_AORemapMin"; MaterialProperty AORemapMax = new MaterialProperty(); const string kAORemapMax = "_AORemapMax"; MaterialProperty smoothnessRemapMin = new MaterialProperty(); const string kSmoothnessRemapMin = "_SmoothnessRemapMin"; MaterialProperty smoothnessRemapMax = new MaterialProperty(); const string kSmoothnessRemapMax = "_SmoothnessRemapMax"; MaterialProperty AO = new MaterialProperty(); const string kAO = "_AO"; MaterialProperty smoothness = new MaterialProperty(); MaterialProperty metallic = new MaterialProperty(); MaterialProperty maskMapBlueScale = new MaterialProperty(); const string kMaskMapBlueScale = "_DecalMaskMapBlueScale"; MaterialProperty emissiveColor = null; MaterialProperty emissiveColorMap = null; MaterialProperty affectEmission = null; MaterialProperty emissiveIntensity = null; MaterialProperty emissiveIntensityUnit = null; MaterialProperty useEmissiveIntensity = null; MaterialProperty emissiveColorLDR = null; MaterialProperty emissiveColorHDR = null; MaterialProperty emissiveExposureWeight = null; /// /// Constructs a DecalSurfaceInputsUIBlock based on the parameters. /// /// Bit index used to store the foldout state public DecalSurfaceInputsUIBlock(ExpandableBit expandableBit) : base(expandableBit, Styles.header) { } /// /// Loads the material properties for the block. /// public override void LoadMaterialProperties() { baseColor = FindProperty(kBaseColor); baseColorMap = FindProperty(kBaseColorMap); normalMap = FindProperty(kNormalMap); maskMap = FindProperty(kMaskMap); decalBlend = FindProperty(kDecalBlend); normalBlendSrc = FindProperty(kNormalBlendSrc); maskBlendSrc = FindProperty(kMaskBlendSrc); maskmapMetal = FindProperty(kMaskmapMetal); maskmapAO = FindProperty(kMaskmapAO); maskmapSmoothness = FindProperty(kMaskmapSmoothness); metallicRemapMin = FindProperty(kMetallicRemapMin); metallicRemapMax = FindProperty(kMetallicRemapMax); AORemapMin = FindProperty(kAORemapMin); AORemapMax = FindProperty(kAORemapMax); smoothnessRemapMin = FindProperty(kSmoothnessRemapMin); smoothnessRemapMax = FindProperty(kSmoothnessRemapMax); AO = FindProperty(kAO); smoothness = FindProperty(kSmoothness); metallic = FindProperty(kMetallic); maskMapBlueScale = FindProperty(kMaskMapBlueScale); // TODO: move emission to the EmissionUIBlock ? emissiveColor = FindProperty(kEmissiveColor); emissiveColorMap = FindProperty(kEmissiveColorMap); affectEmission = FindProperty(kAffectEmission); useEmissiveIntensity = FindProperty(kUseEmissiveIntensity); emissiveIntensityUnit = FindProperty(kEmissiveIntensityUnit); emissiveIntensity = FindProperty(kEmissiveIntensity); emissiveColorLDR = FindProperty(kEmissiveColorLDR); emissiveColorHDR = FindProperty(kEmissiveColorHDR); emissiveExposureWeight = FindProperty(kEmissiveExposureWeight); // always instanced SerializedProperty instancing = materialEditor.serializedObject.FindProperty("m_EnableInstancingVariants"); instancing.boolValue = true; } /// /// Renders the properties in the block. /// protected override void OnGUIOpen() { var material = materials[0]; bool affectAlbedo = material.HasProperty(kAffectAlbedo) && material.GetFloat(kAffectAlbedo) == 1.0f; bool affectNormal = material.HasProperty(kAffectNormal) && material.GetFloat(kAffectNormal) == 1.0f; bool affectMetal = material.HasProperty(kAffectMetal) && material.GetFloat(kAffectMetal) == 1.0f; bool affectSmoothness = material.HasProperty(kAffectSmoothness) && material.GetFloat(kAffectSmoothness) == 1.0f; bool affectAO = material.HasProperty(kAffectAO) && material.GetFloat(kAffectAO) == 1.0f; bool affectEmission = material.HasProperty(kAffectEmission) && material.GetFloat(kAffectEmission) == 1.0f; bool affectMaskmap = affectMetal || affectAO || affectSmoothness; bool perChannelMask = false; HDRenderPipelineAsset hdrp = HDRenderPipeline.currentAsset; if (hdrp != null) { perChannelMask = hdrp.currentPlatformRenderPipelineSettings.decalSettings.perChannelMask; } bool allMaskMap = materials.All(m => m.GetTexture(kMaskMap)); blendSourceNames[0] = affectAlbedo ? "Base Color Map Alpha" : "Opacity"; blendSourceNames[1] = allMaskMap ? "Mask Map Blue Channel" : "Mask Opacity"; if (affectAlbedo) materialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap, baseColor); else { MaterialEditor.BeginProperty(baseColor); Color color = baseColor.colorValue; EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = baseColor.hasMixedValue; color.a = EditorGUILayout.Slider(Styles.baseOpacityText, color.a, 0.0f, 1.0f); EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck()) baseColor.colorValue = color; MaterialEditor.EndProperty(); EditorGUI.indentLevel++; materialEditor.TexturePropertySingleLine(Styles.baseColorAlphaOnlyText, baseColorMap); EditorGUI.indentLevel--; } using (new EditorGUI.DisabledScope(!affectNormal)) { materialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap); if (materials.All(m => m.GetTexture(kNormalMap))) { EditorGUI.indentLevel++; materialEditor.PopupShaderProperty(normalBlendSrc, Styles.normalOpacityChannelText, blendSourceNames); EditorGUI.indentLevel--; } } using (new EditorGUI.DisabledScope(!affectMaskmap)) { materialEditor.TexturePropertySingleLine(Styles.maskMapText, maskMap); EditorGUI.indentLevel++; if (allMaskMap) { if (perChannelMask) { using (new EditorGUI.DisabledScope(!affectMetal)) materialEditor.MinMaxShaderProperty(metallicRemapMin, metallicRemapMax, 0.0f, 1.0f, Styles.metallicRemappingText); using (new EditorGUI.DisabledScope(!affectAO)) materialEditor.MinMaxShaderProperty(AORemapMin, AORemapMax, 0.0f, 1.0f, Styles.aoRemappingText); } using (new EditorGUI.DisabledScope(!affectSmoothness)) materialEditor.MinMaxShaderProperty(smoothnessRemapMin, smoothnessRemapMax, 0.0f, 1.0f, Styles.smoothnessRemappingText); } else { if (perChannelMask) { using (new EditorGUI.DisabledScope(!affectMetal)) materialEditor.ShaderProperty(metallic, Styles.metallicText); using (new EditorGUI.DisabledScope(!affectAO)) materialEditor.ShaderProperty(AO, Styles.aoText); } using (new EditorGUI.DisabledScope(!affectSmoothness)) materialEditor.ShaderProperty(smoothness, Styles.smoothnessText); } materialEditor.PopupShaderProperty(maskBlendSrc, Styles.maskOpacityChannelText, blendSourceNames); EditorGUI.indentLevel--; } bool useBlueScale = (affectMaskmap && maskBlendSrc.floatValue == (float)BlendSource.MaskMapBlue) || (affectNormal && normalBlendSrc.floatValue == (float)BlendSource.MaskMapBlue); using (new EditorGUI.DisabledScope(!useBlueScale)) materialEditor.ShaderProperty(maskMapBlueScale, allMaskMap ? Styles.maskMapBlueScaleText : Styles.opacityBlueScaleText); materialEditor.ShaderProperty(decalBlend, Styles.decalBlendText); using (new EditorGUI.DisabledScope(!affectEmission)) { EditorGUI.BeginChangeCheck(); materialEditor.ShaderProperty(useEmissiveIntensity, Styles.useEmissionIntensityText); bool updateEmissiveColor = EditorGUI.EndChangeCheck(); if (useEmissiveIntensity.floatValue == 0.0f) { if (updateEmissiveColor) emissiveColorHDR.colorValue = emissiveColor.colorValue; EditorGUI.BeginChangeCheck(); EmissionUIBlock.DoEmissiveTextureProperty(materialEditor, emissiveColorMap, emissiveColorHDR); if (EditorGUI.EndChangeCheck()) emissiveColor.colorValue = emissiveColorHDR.colorValue; } else { if (updateEmissiveColor) EmissionUIBlock.UpdateEmissiveColorLDRAndIntensityFromEmissiveColor(emissiveColorLDR, emissiveIntensity, emissiveColor); EmissionUIBlock.DoEmissiveTextureProperty(materialEditor, emissiveColorMap, emissiveColorLDR); EmissionUIBlock.DoEmissiveIntensityGUI(materialEditor, emissiveIntensity, emissiveIntensityUnit); } materialEditor.ShaderProperty(emissiveExposureWeight, Styles.emissiveExposureWeightText); } } } }