void DoEmissiveTextureProperty(MaterialProperty color)
        {
            materialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, color);

            // TODO: does not support multi-selection
            if (materials[0].GetTexture(kEmissiveColorMap))
            {
                EditorGUI.indentLevel++;
                materialEditor.ShaderProperty(UVEmissive, Styles.UVEmissiveMappingText);
                UVBaseMapping uvEmissiveMapping = (UVBaseMapping)UVEmissive.floatValue;

                float X, Y, Z, W;
                X = (uvEmissiveMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
                Y = (uvEmissiveMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
                Z = (uvEmissiveMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
                W = (uvEmissiveMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;

                UVMappingMaskEmissive.colorValue = new Color(X, Y, Z, W);

                if ((uvEmissiveMapping == UVBaseMapping.Planar) || (uvEmissiveMapping == UVBaseMapping.Triplanar))
                {
                    materialEditor.ShaderProperty(TexWorldScaleEmissive, Styles.texWorldScaleText);
                }

                materialEditor.TextureScaleOffsetProperty(emissiveColorMap);
                EditorGUI.indentLevel--;
            }
        }
        protected void EmissiveInputGUI(Material material)
        {
            using (var header = new HeaderScope(Styles.emissiveLabelText, (uint)Expendable.Emissive, this))
            {
                if (header.expended)
                {
                    m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);

                    if (material.GetTexture(kEmissiveColorMap))
                    {
                        EditorGUI.indentLevel++;
                        m_MaterialEditor.ShaderProperty(UVEmissive, Styles.UVMappingEmissiveText);
                        UVBaseMapping uvEmissiveMapping = (UVBaseMapping)UVEmissive.floatValue;

                        float X, Y, Z, W;
                        X = (uvEmissiveMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
                        Y = (uvEmissiveMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
                        Z = (uvEmissiveMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
                        W = (uvEmissiveMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;

                        UVMappingMaskEmissive.colorValue = new Color(X, Y, Z, W);


                        m_MaterialEditor.TextureScaleOffsetProperty(emissiveColorMap);
                        EditorGUI.indentLevel--;
                    }
                }
            }
        }
        protected void EmissiveInputGUI(Material material)
        {
            EditorGUILayout.Space();
            EditorGUILayout.LabelField(Styles.emissiveLabelText, EditorStyles.boldLabel);
            EditorGUI.indentLevel++;
            m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);

            if (material.GetTexture(kEmissiveColorMap))
            {
                EditorGUI.indentLevel++;
                m_MaterialEditor.ShaderProperty(UVEmissive, Styles.UVMappingEmissiveText);
                UVBaseMapping uvEmissiveMapping = (UVBaseMapping)UVEmissive.floatValue;

                float X, Y, Z, W;
                X = (uvEmissiveMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
                Y = (uvEmissiveMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
                Z = (uvEmissiveMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
                W = (uvEmissiveMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;

                UVMappingMaskEmissive.colorValue = new Color(X, Y, Z, W);


                m_MaterialEditor.TextureScaleOffsetProperty(emissiveColorMap);
                EditorGUI.indentLevel--;
            }

            EditorGUI.indentLevel--;
        }
Exemple #4
0
        void DrawDetailsGUI()
        {
            UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase[m_LayerIndex].floatValue;
            float         X, Y, Z, W;

            materialEditor.TexturePropertySingleLine(Styles.detailMapNormalText, detailMap[m_LayerIndex]);

            // TODO: does not work with multi-selection
            if (materials[0].GetTexture(isLayeredLit ? kDetailMap + m_LayerIndex : kDetailMap))
            {
                EditorGUI.indentLevel++;

                // When Planar or Triplanar is enable the UVDetail use the same mode, so we disable the choice on UVDetail
                if (uvBaseMapping == UVBaseMapping.Planar)
                {
                    EditorGUILayout.LabelField(Styles.UVDetailMappingText.text + ": Planar");
                }
                else if (uvBaseMapping == UVBaseMapping.Triplanar)
                {
                    EditorGUILayout.LabelField(Styles.UVDetailMappingText.text + ": Triplanar");
                }
                else
                {
                    materialEditor.ShaderProperty(UVDetail[m_LayerIndex], Styles.UVDetailMappingText);
                }

                // Setup the UVSet for detail, if planar/triplanar is use for base, it will override the mapping of detail (See shader code)
                X = ((UVDetailMapping)UVDetail[m_LayerIndex].floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
                Y = ((UVDetailMapping)UVDetail[m_LayerIndex].floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
                Z = ((UVDetailMapping)UVDetail[m_LayerIndex].floatValue == UVDetailMapping.UV2) ? 1.0f : 0.0f;
                W = ((UVDetailMapping)UVDetail[m_LayerIndex].floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
                UVDetailsMappingMask[m_LayerIndex].colorValue = new Color(X, Y, Z, W);

                EditorGUI.indentLevel++;
                materialEditor.ShaderProperty(linkDetailsWithBase[m_LayerIndex], Styles.linkDetailsWithBaseText);
                EditorGUI.indentLevel--;

                materialEditor.TextureScaleOffsetProperty(detailMap[m_LayerIndex]);
                if ((DisplacementMode)displacementMode.floatValue == DisplacementMode.Pixel && (UVDetail[m_LayerIndex].floatValue != UVBase[m_LayerIndex].floatValue))
                {
                    if (materials[0].GetTexture(isLayeredLit ? kDetailMap + m_LayerIndex : kDetailMap))
                    {
                        EditorGUILayout.HelpBox(Styles.perPixelDisplacementDetailsWarning.text, MessageType.Warning);
                    }
                }
                materialEditor.ShaderProperty(detailAlbedoScale[m_LayerIndex], Styles.detailAlbedoScaleText);
                materialEditor.ShaderProperty(detailNormalScale[m_LayerIndex], Styles.detailNormalScaleText);
                materialEditor.ShaderProperty(detailSmoothnessScale[m_LayerIndex], Styles.detailSmoothnessScaleText);
                EditorGUI.indentLevel--;
            }
        }
        static public void SetupLayersMappingKeywords(Material material)
        {
            const string kLayerMappingPlanar    = "_LAYER_MAPPING_PLANAR";
            const string kLayerMappingTriplanar = "_LAYER_MAPPING_TRIPLANAR";

            for (int i = 0; i < kMaxLayerCount; ++i)
            {
                string        layerUVBaseParam          = string.Format("{0}{1}", kUVBase, i);
                UVBaseMapping layerUVBaseMapping        = (UVBaseMapping)material.GetFloat(layerUVBaseParam);
                string        currentLayerMappingPlanar = string.Format("{0}{1}", kLayerMappingPlanar, i);
                CoreUtils.SetKeyword(material, currentLayerMappingPlanar, layerUVBaseMapping == UVBaseMapping.Planar);
                string currentLayerMappingTriplanar = string.Format("{0}{1}", kLayerMappingTriplanar, i);
                CoreUtils.SetKeyword(material, currentLayerMappingTriplanar, layerUVBaseMapping == UVBaseMapping.Triplanar);
            }
        }
        protected void BaseUVMappingInputGUI()
        {
            m_MaterialEditor.ShaderProperty(UVBase, Styles.UVBaseMappingText);

            UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase.floatValue;

            float X, Y, Z, W;

            X = (uvBaseMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
            Y = (uvBaseMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
            Z = (uvBaseMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
            W = (uvBaseMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;

            UVMappingMask.colorValue = new Color(X, Y, Z, W);

            m_MaterialEditor.TextureScaleOffsetProperty(baseColorMap);
        }
Exemple #7
0
        void DrawLayerOptionsGUI()
        {
            IntSliderShaderProperty(layerCount, 2, 4, Styles.layerCountText);

            materialEditor.TexturePropertySingleLine(Styles.layerMapMaskText, layerMaskMap);

            EditorGUI.indentLevel++;
            materialEditor.ShaderProperty(UVBlendMask, Styles.UVBlendMaskText);
            UVBaseMapping uvBlendMask = (UVBaseMapping)UVBlendMask.floatValue;

            float X, Y, Z, W;

            X = (uvBlendMask == UVBaseMapping.UV0) ? 1.0f : 0.0f;
            Y = (uvBlendMask == UVBaseMapping.UV1) ? 1.0f : 0.0f;
            Z = (uvBlendMask == UVBaseMapping.UV2) ? 1.0f : 0.0f;
            W = (uvBlendMask == UVBaseMapping.UV3) ? 1.0f : 0.0f;

            UVMappingMaskBlendMask.colorValue = new Color(X, Y, Z, W);

            if (((UVBaseMapping)UVBlendMask.floatValue == UVBaseMapping.Planar) ||
                ((UVBaseMapping)UVBlendMask.floatValue == UVBaseMapping.Triplanar))
            {
                materialEditor.ShaderProperty(texWorldScaleBlendMask, Styles.layerTexWorldScaleText);
            }
            materialEditor.TextureScaleOffsetProperty(layerMaskMap);
            EditorGUI.indentLevel--;

            materialEditor.ShaderProperty(vertexColorMode, Styles.vertexColorModeText);
            materialEditor.ShaderProperty(useMainLayerInfluence, Styles.useMainLayerInfluenceModeText);
            materialEditor.ShaderProperty(useHeightBasedBlend, Styles.useHeightBasedBlendText);

            if (m_UseHeightBasedBlend)
            {
                EditorGUI.indentLevel++;
                materialEditor.ShaderProperty(heightTransition, Styles.heightTransition);
                EditorGUI.indentLevel--;
            }

            bool mainLayerModeInfluenceEnable = useMainLayerInfluence.floatValue > 0.0f;

            materialEditor.ShaderProperty(objectScaleAffectTile, mainLayerModeInfluenceEnable ? Styles.objectScaleAffectTileText2 : Styles.objectScaleAffectTileText);
        }
        void DrawSurfaceInputsGUI()
        {
            UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase[m_LayerIndex].floatValue;
            float X, Y, Z, W;

            materialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap[m_LayerIndex], baseColor[m_LayerIndex]);

            bool hasMetallic = materials.All(m =>
                m.GetMaterialId() == MaterialId.LitStandard ||
                m.GetMaterialId() == MaterialId.LitAniso ||
                m.GetMaterialId() == MaterialId.LitIridescence);

            if (maskMap[m_LayerIndex].textureValue == null)
            {
                if (hasMetallic)
                    materialEditor.ShaderProperty(metallic[m_LayerIndex], Styles.metallicText);
                materialEditor.ShaderProperty(smoothness[m_LayerIndex], Styles.smoothnessText);
            }
            else
            {
                if (hasMetallic)
                    materialEditor.MinMaxShaderProperty(metallicRemapMin[m_LayerIndex], metallicRemapMax[m_LayerIndex], 0.0f, 1.0f, Styles.metallicRemappingText);

                materialEditor.MinMaxShaderProperty(smoothnessRemapMin[m_LayerIndex], smoothnessRemapMax[m_LayerIndex], 0.0f, 1.0f, Styles.smoothnessRemappingText);
                materialEditor.MinMaxShaderProperty(aoRemapMin[m_LayerIndex], aoRemapMax[m_LayerIndex], 0.0f, 1.0f, Styles.aoRemappingText);
            }

            materialEditor.TexturePropertySingleLine((materials.All(m => m.GetMaterialId() == MaterialId.LitSpecular)) ? Styles.maskMapSpecularText : Styles.maskMapSText, maskMap[m_LayerIndex]);

            materialEditor.ShaderProperty(normalMapSpace[m_LayerIndex], Styles.normalMapSpaceText);

            // Triplanar only work with tangent space normal
            if ((NormalMapSpace)normalMapSpace[m_LayerIndex].floatValue == NormalMapSpace.ObjectSpace && ((UVBaseMapping)UVBase[m_LayerIndex].floatValue == UVBaseMapping.Triplanar))
            {
                EditorGUILayout.HelpBox(Styles.normalMapSpaceWarning.text, MessageType.Error);
            }

            // We have two different property for object space and tangent space normal map to allow
            // 1. to go back and forth
            // 2. to avoid the warning that ask to fix the object normal map texture (normalOS are just linear RGB texture
            if ((NormalMapSpace)normalMapSpace[m_LayerIndex].floatValue == NormalMapSpace.TangentSpace)
            {
                materialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap[m_LayerIndex], normalScale[m_LayerIndex]);
                materialEditor.TexturePropertySingleLine(Styles.bentNormalMapText, bentNormalMap[m_LayerIndex]);
            }
            else
            {
                // No scaling in object space
                materialEditor.TexturePropertySingleLine(Styles.normalMapOSText, normalMapOS[m_LayerIndex]);
                materialEditor.TexturePropertySingleLine(Styles.bentNormalMapOSText, bentNormalMapOS[m_LayerIndex]);
            }

            DisplacementMode displaceMode = (DisplacementMode)displacementMode.floatValue;
            if (displaceMode != DisplacementMode.None || (m_Features & Features.HeightMap) != 0)
            {
                EditorGUI.BeginChangeCheck();
                materialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap[m_LayerIndex]);
                if (!heightMap[m_LayerIndex].hasMixedValue && heightMap[m_LayerIndex].textureValue != null && !displacementMode.hasMixedValue)
                {
                    EditorGUI.indentLevel++;
                    if (displaceMode == DisplacementMode.Pixel)
                    {
                        materialEditor.ShaderProperty(heightPoMAmplitude[m_LayerIndex], Styles.heightMapAmplitudeText);
                    }
                    else
                    {
                        materialEditor.ShaderProperty(heightParametrization[m_LayerIndex], Styles.heightMapParametrization);
                        if (!heightParametrization[m_LayerIndex].hasMixedValue)
                        {
                            HeightmapParametrization parametrization = (HeightmapParametrization)heightParametrization[m_LayerIndex].floatValue;
                            if (parametrization == HeightmapParametrization.MinMax)
                            {
                                EditorGUI.BeginChangeCheck();
                                materialEditor.ShaderProperty(heightMin[m_LayerIndex], Styles.heightMapMinText);
                                if (EditorGUI.EndChangeCheck())
                                    heightMin[m_LayerIndex].floatValue = Mathf.Min(heightMin[m_LayerIndex].floatValue, heightMax[m_LayerIndex].floatValue);
                                EditorGUI.BeginChangeCheck();
                                materialEditor.ShaderProperty(heightMax[m_LayerIndex], Styles.heightMapMaxText);
                                if (EditorGUI.EndChangeCheck())
                                    heightMax[m_LayerIndex].floatValue = Mathf.Max(heightMin[m_LayerIndex].floatValue, heightMax[m_LayerIndex].floatValue);
                            }
                            else
                            {
                                EditorGUI.BeginChangeCheck();
                                materialEditor.ShaderProperty(heightTessAmplitude[m_LayerIndex], Styles.heightMapAmplitudeText);
                                if (EditorGUI.EndChangeCheck())
                                    heightTessAmplitude[m_LayerIndex].floatValue = Mathf.Max(0f, heightTessAmplitude[m_LayerIndex].floatValue);
                                materialEditor.ShaderProperty(heightTessCenter[m_LayerIndex], Styles.heightMapCenterText);
                            }

                            materialEditor.ShaderProperty(heightOffset[m_LayerIndex], Styles.heightMapOffsetText);
                        }
                    }
                    EditorGUI.indentLevel--;
                }

                // UI only updates intermediate values, this will update the values actually used by the shader.
                if (EditorGUI.EndChangeCheck())
                {
                    SurfaceOptionUIBlock    surfaceOption;

                    // Fetch the surface option block which contains the function to update the displacement datas
                    if (m_LayerCount == 1)
                        surfaceOption = parent.FetchUIBlock<SurfaceOptionUIBlock>();
                    else
                        surfaceOption = parent.parent.FetchUIBlock<SurfaceOptionUIBlock>();

                    surfaceOption.UpdateDisplacement(m_LayerIndex);
                }
            }

            if (materials.All(m => m.GetMaterialId() == materials[0].GetMaterialId()))
            {
                // We can use materials[0] because all the material IDs have the same value
                switch (materials[0].GetMaterialId())
                {
                    case MaterialId.LitSSS:
                    case MaterialId.LitTranslucent:
                        ShaderSSSAndTransmissionInputGUI();
                        break;
                    case MaterialId.LitStandard:
                        // Nothing
                        break;

                    // Following mode are not supported by layered lit and will not be call by it
                    // as the MaterialId enum don't define it
                    case MaterialId.LitAniso:
                        ShaderAnisoInputGUI();
                        break;
                    case MaterialId.LitSpecular:
                        ShaderSpecularColorInputGUI();
                        break;
                    case MaterialId.LitIridescence:
                        ShaderIridescenceInputGUI();
                        break;

                    default:
                        Debug.Assert(false, "Encountered an unsupported MaterialID.");
                        break;
                }
            }

            if (!isLayeredLit)
            {
                ShaderClearCoatInputGUI();
            }

            EditorGUILayout.Space();

            EditorGUI.BeginChangeCheck();
            materialEditor.ShaderProperty(UVBase[m_LayerIndex], Styles.UVBaseMappingText);
            uvBaseMapping = (UVBaseMapping)UVBase[m_LayerIndex].floatValue;

            X = (uvBaseMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
            Y = (uvBaseMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
            Z = (uvBaseMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
            W = (uvBaseMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;

            UVMappingMask[m_LayerIndex].colorValue = new Color(X, Y, Z, W);

            if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar))
            {
                materialEditor.ShaderProperty(TexWorldScale[m_LayerIndex], Styles.texWorldScaleText);
            }
            materialEditor.TextureScaleOffsetProperty(baseColorMap[m_LayerIndex]);
            if (EditorGUI.EndChangeCheck())
            {
                // Precompute.
                InvTilingScale[m_LayerIndex].floatValue = 2.0f / (Mathf.Abs(baseColorMap[m_LayerIndex].textureScaleAndOffset.x) + Mathf.Abs(baseColorMap[m_LayerIndex].textureScaleAndOffset.y));
                if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar))
                {
                    InvTilingScale[m_LayerIndex].floatValue = InvTilingScale[m_LayerIndex].floatValue / TexWorldScale[m_LayerIndex].floatValue;
                }
            }
        }
        static public void SetupLayersMappingKeywords(Material material)
        {
            // object scale affect tile
            SetKeyword(material, "_LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE", material.GetFloat(kObjectScaleAffectTile) > 0.0f);

            // Blend mask
            UVBaseMapping UVBlendMaskMapping = (UVBaseMapping)material.GetFloat(kUVBlendMask);

            SetKeyword(material, "_LAYER_MAPPING_PLANAR_BLENDMASK", UVBlendMaskMapping == UVBaseMapping.Planar);
            SetKeyword(material, "_LAYER_MAPPING_TRIPLANAR_BLENDMASK", UVBlendMaskMapping == UVBaseMapping.Triplanar);

            int numLayer = (int)material.GetFloat(kLayerCount);

            // Layer
            if (numLayer == 4)
            {
                SetKeyword(material, "_LAYEREDLIT_4_LAYERS", true);
                SetKeyword(material, "_LAYEREDLIT_3_LAYERS", false);
            }
            else if (numLayer == 3)
            {
                SetKeyword(material, "_LAYEREDLIT_4_LAYERS", false);
                SetKeyword(material, "_LAYEREDLIT_3_LAYERS", true);
            }
            else
            {
                SetKeyword(material, "_LAYEREDLIT_4_LAYERS", false);
                SetKeyword(material, "_LAYEREDLIT_3_LAYERS", false);
            }

            const string kLayerMappingPlanar    = "_LAYER_MAPPING_PLANAR";
            const string kLayerMappingTriplanar = "_LAYER_MAPPING_TRIPLANAR";

            // We have to check for each layer if the UV2 or UV3 is needed.
            bool needUV3 = false;
            bool needUV2 = false;

            for (int i = 0; i < numLayer; ++i)
            {
                string        layerUVBaseParam          = string.Format("{0}{1}", kUVBase, i);
                UVBaseMapping layerUVBaseMapping        = (UVBaseMapping)material.GetFloat(layerUVBaseParam);
                string        currentLayerMappingPlanar = string.Format("{0}{1}", kLayerMappingPlanar, i);
                SetKeyword(material, currentLayerMappingPlanar, layerUVBaseMapping == UVBaseMapping.Planar);
                string currentLayerMappingTriplanar = string.Format("{0}{1}", kLayerMappingTriplanar, i);
                SetKeyword(material, currentLayerMappingTriplanar, layerUVBaseMapping == UVBaseMapping.Triplanar);

                string uvBase   = string.Format("{0}{1}", kUVBase, i);
                string uvDetail = string.Format("{0}{1}", kUVDetail, i);

                if (((UVDetailMapping)material.GetFloat(uvDetail) == UVDetailMapping.UV2) ||
                    ((UVBaseMapping)material.GetFloat(uvBase) == UVBaseMapping.UV2))
                {
                    needUV2 = true;
                }

                if (((UVDetailMapping)material.GetFloat(uvDetail) == UVDetailMapping.UV3) ||
                    ((UVBaseMapping)material.GetFloat(uvBase) == UVBaseMapping.UV3))
                {
                    needUV3 = true;
                    break; // If we find it UV3 let's early out
                }
            }

            if (needUV3)
            {
                material.DisableKeyword("_REQUIRE_UV2");
                material.EnableKeyword("_REQUIRE_UV3");
            }
            else if (needUV2)
            {
                material.EnableKeyword("_REQUIRE_UV2");
                material.DisableKeyword("_REQUIRE_UV3");
            }
            else
            {
                material.DisableKeyword("_REQUIRE_UV2");
                material.DisableKeyword("_REQUIRE_UV3");
            }
        }
        void DoLayeringInputGUI()
        {
            EditorGUI.indentLevel++;
            GUILayout.Label(styles.layersText, EditorStyles.boldLabel);

            EditorGUI.showMixedValue = layerCount.hasMixedValue;
            EditorGUI.BeginChangeCheck();
            int newLayerCount = EditorGUILayout.IntSlider(styles.layerCountText, (int)layerCount.floatValue, 2, 4);

            if (EditorGUI.EndChangeCheck())
            {
                Material material = m_MaterialEditor.target as Material;
                Undo.RecordObject(material, "Change layer count");
                layerCount.floatValue = (float)newLayerCount;
            }

            m_MaterialEditor.TexturePropertySingleLine(styles.layerMapMaskText, layerMaskMap);

            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(UVBlendMask, styles.UVBlendMaskText);
            UVBaseMapping uvBlendMask = (UVBaseMapping)UVBlendMask.floatValue;

            float X, Y, Z, W;

            X = (uvBlendMask == UVBaseMapping.UV0) ? 1.0f : 0.0f;
            Y = (uvBlendMask == UVBaseMapping.UV1) ? 1.0f : 0.0f;
            Z = (uvBlendMask == UVBaseMapping.UV2) ? 1.0f : 0.0f;
            W = (uvBlendMask == UVBaseMapping.UV3) ? 1.0f : 0.0f;

            UVMappingMaskBlendMask.colorValue = new Color(X, Y, Z, W);

            if (((UVBaseMapping)UVBlendMask.floatValue == UVBaseMapping.Planar) ||
                ((UVBaseMapping)UVBlendMask.floatValue == UVBaseMapping.Triplanar))
            {
                m_MaterialEditor.ShaderProperty(texWorldScaleBlendMask, styles.layerTexWorldScaleText);
            }
            m_MaterialEditor.TextureScaleOffsetProperty(layerMaskMap);
            EditorGUI.indentLevel--;

            m_MaterialEditor.ShaderProperty(vertexColorMode, styles.vertexColorModeText);

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = useMainLayerInfluence.hasMixedValue;
            bool mainLayerModeInfluenceEnable = EditorGUILayout.Toggle(styles.useMainLayerInfluenceModeText, useMainLayerInfluence.floatValue > 0.0f);

            if (EditorGUI.EndChangeCheck())
            {
                useMainLayerInfluence.floatValue = mainLayerModeInfluenceEnable ? 1.0f : 0.0f;
            }

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = useHeightBasedBlend.hasMixedValue;
            bool enabled = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend.floatValue > 0.0f);

            if (EditorGUI.EndChangeCheck())
            {
                useHeightBasedBlend.floatValue = enabled ? 1.0f : 0.0f;
            }

            if (enabled)
            {
                EditorGUI.indentLevel++;
                m_MaterialEditor.ShaderProperty(heightTransition, styles.heightTransition);
                EditorGUI.indentLevel--;
            }

            m_MaterialEditor.ShaderProperty(objectScaleAffectTile, mainLayerModeInfluenceEnable ? styles.objectScaleAffectTileText2 : styles.objectScaleAffectTileText);
            EditorGUI.indentLevel--;
        }
        protected override void MaterialPropertiesGUI(Material material)
        {
            EditorGUILayout.LabelField(Styles.InputsText, EditorStyles.boldLabel);

            EditorGUI.indentLevel++;

            m_MaterialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap, baseColor);

            m_MaterialEditor.ShaderProperty(metallic, Styles.metallicText);

            // maskMaps and smoothness rescaling controls:
            if (maskMapA.textureValue == null)
            {
                m_MaterialEditor.ShaderProperty(smoothnessA, Styles.smoothnessAText);
            }
            else
            {
                float remapMin = smoothnessARemapMin.floatValue;
                float remapMax = smoothnessARemapMax.floatValue;
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.MinMaxSlider(Styles.smoothnessARemappingText, ref remapMin, ref remapMax, 0.0f, 1.0f);
                if (EditorGUI.EndChangeCheck())
                {
                    smoothnessARemapMin.floatValue = remapMin;
                    smoothnessARemapMax.floatValue = remapMax;
                }
            }
            if (maskMapB.textureValue == null)
            {
                m_MaterialEditor.ShaderProperty(smoothnessB, Styles.smoothnessBText);
            }
            else
            {
                float remapMin = smoothnessBRemapMin.floatValue;
                float remapMax = smoothnessBRemapMax.floatValue;
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.MinMaxSlider(Styles.smoothnessBRemappingText, ref remapMin, ref remapMax, 0.0f, 1.0f);
                if (EditorGUI.EndChangeCheck())
                {
                    smoothnessBRemapMin.floatValue = remapMin;
                    smoothnessBRemapMax.floatValue = remapMax;
                }
            }
            m_MaterialEditor.ShaderProperty(lobeMix, Styles.lobeMixText);
            m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapASText, maskMapA);
            m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapBSText, maskMapB);


            // Normal map:
            m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);

            // UV Mapping:
            EditorGUILayout.Space();

            EditorGUI.BeginChangeCheck(); // UV mapping selection
            m_MaterialEditor.ShaderProperty(UVBase, Styles.UVBaseMappingText);

            UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase.floatValue;

            float X, Y, Z, W;

            X = (uvBaseMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
            Y = (uvBaseMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
            Z = (uvBaseMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
            W = (uvBaseMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;

            UVMappingMask.colorValue = new Color(X, Y, Z, W);


            //TODO:
            //if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar))
            //{
            //    m_MaterialEditor.ShaderProperty(TexWorldScale, Styles.texWorldScaleText);
            //}
            m_MaterialEditor.TextureScaleOffsetProperty(baseColorMap);
            if (EditorGUI.EndChangeCheck()) // ...UV mapping selection
            {
            }

            EditorGUI.indentLevel--; // inputs
            EditorGUILayout.Space();

            // Surface type:
            var surfaceTypeValue = (SurfaceType)surfaceType.floatValue;

            if (surfaceTypeValue == SurfaceType.Transparent)
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField(StylesBaseUnlit.TransparencyInputsText, EditorStyles.boldLabel);
                ++EditorGUI.indentLevel;

                DoDistortionInputsGUI();

                --EditorGUI.indentLevel;
            }


            // TODO: see DoEmissiveGUI( ) in LitUI.cs: custom uvmapping for emissive
            EditorGUILayout.Space();
            EditorGUILayout.LabelField(Styles.emissiveLabelText, EditorStyles.boldLabel);
            EditorGUI.indentLevel++;
            m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);
            m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
            m_MaterialEditor.ShaderProperty(albedoAffectEmissive, Styles.albedoAffectEmissiveText);
            EditorGUI.indentLevel--;
        }
        protected void DoLayerGUI(Material material, int layerIndex)
        {
            EditorGUILayout.LabelField(Styles.InputsText, EditorStyles.boldLabel);

            EditorGUI.indentLevel++;

            m_MaterialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap[layerIndex], baseColor[layerIndex]);

            if ((Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitStandard || (Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitAniso)
            {
                m_MaterialEditor.ShaderProperty(metallic[layerIndex], Styles.metallicText);
            }

            if (maskMap[layerIndex].textureValue == null)
            {
                m_MaterialEditor.ShaderProperty(smoothness[layerIndex], Styles.smoothnessText);
            }
            else
            {
                float remapMin = smoothnessRemapMin[layerIndex].floatValue;
                float remapMax = smoothnessRemapMax[layerIndex].floatValue;
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.MinMaxSlider(Styles.smoothnessRemappingText, ref remapMin, ref remapMax, 0.0f, 1.0f);
                if (EditorGUI.EndChangeCheck())
                {
                    smoothnessRemapMin[layerIndex].floatValue = remapMin;
                    smoothnessRemapMax[layerIndex].floatValue = remapMax;
                }

                float aoMin = aoRemapMin[layerIndex].floatValue;
                float aoMax = aoRemapMax[layerIndex].floatValue;
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.MinMaxSlider(Styles.aoRemappingText, ref aoMin, ref aoMax, 0.0f, 1.0f);
                if (EditorGUI.EndChangeCheck())
                {
                    aoRemapMin[layerIndex].floatValue = aoMin;
                    aoRemapMax[layerIndex].floatValue = aoMax;
                }
            }

            m_MaterialEditor.TexturePropertySingleLine(((Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitSpecular) ? Styles.maskMapSpecularText : Styles.maskMapSText, maskMap[layerIndex]);

            m_MaterialEditor.ShaderProperty(normalMapSpace[layerIndex], Styles.normalMapSpaceText);

            // Triplanar only work with tangent space normal
            if ((NormalMapSpace)normalMapSpace[layerIndex].floatValue == NormalMapSpace.ObjectSpace && ((UVBaseMapping)UVBase[layerIndex].floatValue == UVBaseMapping.Triplanar))
            {
                EditorGUILayout.HelpBox(Styles.normalMapSpaceWarning.text, MessageType.Error);
            }

            // We have two different property for object space and tangent space normal map to allow
            // 1. to go back and forth
            // 2. to avoid the warning that ask to fix the object normal map texture (normalOS are just linear RGB texture
            if ((NormalMapSpace)normalMapSpace[layerIndex].floatValue == NormalMapSpace.TangentSpace)
            {
                m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap[layerIndex], normalScale[layerIndex]);
                m_MaterialEditor.TexturePropertySingleLine(Styles.bentNormalMapText, bentNormalMap[layerIndex]);
            }
            else
            {
                // No scaling in object space
                m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapOSText, normalMapOS[layerIndex]);
                m_MaterialEditor.TexturePropertySingleLine(Styles.bentNormalMapOSText, bentNormalMapOS[layerIndex]);
            }

            EditorGUI.BeginChangeCheck();
            m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap[layerIndex]);
            if (!heightMap[layerIndex].hasMixedValue && heightMap[layerIndex].textureValue != null)
            {
                EditorGUI.indentLevel++;
                m_MaterialEditor.ShaderProperty(heightMin[layerIndex], Styles.heightMapMinText);
                m_MaterialEditor.ShaderProperty(heightMax[layerIndex], Styles.heightMapMaxText);
                m_MaterialEditor.ShaderProperty(heightCenter[layerIndex], Styles.heightMapCenterText);
                EditorGUI.showMixedValue = false;
                EditorGUI.indentLevel--;
            }
            // Note: We should only enclose min/max property here for change detection. However heightAmplitude may not be correctly initialize if default value was not correct
            // force a refresh when the user setup a heightmap, so we are sure it is correct
            if (EditorGUI.EndChangeCheck())
            {
                heightAmplitude[layerIndex].floatValue = (heightMax[layerIndex].floatValue - heightMin[layerIndex].floatValue) * 0.01f; // Conversion centimeters to meters.
            }

            switch ((Lit.MaterialId)materialID.floatValue)
            {
            case Lit.MaterialId.LitSSS:
                ShaderSSSInputGUI(material, layerIndex);
                break;

            case Lit.MaterialId.LitStandard:
                // Nothing
                break;

            // Following mode are not supported by layered lit and will not be call by it
            // as the MaterialId enum don't define it
            case Lit.MaterialId.LitAniso:
                ShaderAnisoInputGUI();
                break;

            case Lit.MaterialId.LitSpecular:
                m_MaterialEditor.TexturePropertySingleLine(Styles.specularColorText, specularColorMap, specularColor);
                break;

            case Lit.MaterialId.LitClearCoat:
                ShaderClearCoatInputGUI();
                break;

            default:
                Debug.Assert(false, "Encountered an unsupported MaterialID.");
                break;
            }

            EditorGUILayout.Space();

            EditorGUI.BeginChangeCheck();
            m_MaterialEditor.ShaderProperty(UVBase[layerIndex], Styles.UVBaseMappingText);

            UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase[layerIndex].floatValue;

            float X, Y, Z, W;

            X = (uvBaseMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
            Y = (uvBaseMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
            Z = (uvBaseMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
            W = (uvBaseMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;

            UVMappingMask[layerIndex].colorValue = new Color(X, Y, Z, W);

            if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar))
            {
                m_MaterialEditor.ShaderProperty(TexWorldScale[layerIndex], Styles.texWorldScaleText);
            }
            m_MaterialEditor.TextureScaleOffsetProperty(baseColorMap[layerIndex]);
            if (EditorGUI.EndChangeCheck())
            {
                // Precompute.
                InvTilingScale[layerIndex].floatValue = 2.0f / (Mathf.Abs(baseColorMap[layerIndex].textureScaleAndOffset.x) + Mathf.Abs(baseColorMap[layerIndex].textureScaleAndOffset.y));
                if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar))
                {
                    InvTilingScale[layerIndex].floatValue = InvTilingScale[layerIndex].floatValue / TexWorldScale[layerIndex].floatValue;
                }
            }

            EditorGUI.indentLevel--;
            EditorGUILayout.Space();
            EditorGUILayout.LabelField(Styles.detailText, EditorStyles.boldLabel);

            EditorGUI.indentLevel++;
            m_MaterialEditor.TexturePropertySingleLine(Styles.detailMapNormalText, detailMap[layerIndex]);

            // When Planar or Triplanar is enable the UVDetail use the same mode, so we disable the choice on UVDetail
            if (uvBaseMapping == UVBaseMapping.Planar)
            {
                EditorGUILayout.LabelField(Styles.UVDetailMappingText.text + ": Planar");
            }
            else if (uvBaseMapping == UVBaseMapping.Triplanar)
            {
                EditorGUILayout.LabelField(Styles.UVDetailMappingText.text + ": Triplanar");
            }
            else
            {
                m_MaterialEditor.ShaderProperty(UVDetail[layerIndex], Styles.UVDetailMappingText);
            }

            // Setup the UVSet for detail, if planar/triplanar is use for base, it will override the mapping of detail (See shader code)
            X = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
            Y = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
            Z = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV2) ? 1.0f : 0.0f;
            W = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
            UVDetailsMappingMask[layerIndex].colorValue = new Color(X, Y, Z, W);

            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(linkDetailsWithBase[layerIndex], Styles.linkDetailsWithBaseText);
            EditorGUI.indentLevel--;
            m_MaterialEditor.TextureScaleOffsetProperty(detailMap[layerIndex]);
            if ((DisplacementMode)displacementMode.floatValue == DisplacementMode.Pixel && (UVDetail[layerIndex].floatValue != UVBase[layerIndex].floatValue))
            {
                if (material.GetTexture(kDetailMap + m_PropertySuffixes[layerIndex]))
                {
                    EditorGUILayout.HelpBox(Styles.perPixelDisplacementDetailsWarning.text, MessageType.Warning);
                }
            }
            m_MaterialEditor.ShaderProperty(detailAlbedoScale[layerIndex], Styles.detailAlbedoScaleText);
            m_MaterialEditor.ShaderProperty(detailNormalScale[layerIndex], Styles.detailNormalScaleText);
            m_MaterialEditor.ShaderProperty(detailSmoothnessScale[layerIndex], Styles.detailSmoothnessScaleText);

            EditorGUI.indentLevel--;

            var surfaceTypeValue = (SurfaceType)surfaceType.floatValue;

            if (surfaceTypeValue == SurfaceType.Transparent &&
                refractionMode != null)
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField(StylesBaseUnlit.TransparencyInputsText, EditorStyles.boldLabel);
                ++EditorGUI.indentLevel;

                var isPrePass = material.HasProperty(kPreRefractionPass) && material.GetFloat(kPreRefractionPass) > 0.0;
                if (refractionMode != null
                    // Refraction is not available for pre-refraction objects
                    && !isPrePass)
                {
                    m_MaterialEditor.ShaderProperty(refractionMode, Styles.refractionModeText);
                    var mode = (Lit.RefractionMode)refractionMode.floatValue;
                    if (mode != Lit.RefractionMode.None)
                    {
                        m_MaterialEditor.ShaderProperty(ior, Styles.refractionIORText);

                        blendMode.floatValue = (float)BlendMode.Alpha;

                        if (thicknessMap[0].textureValue == null)
                        {
                            m_MaterialEditor.ShaderProperty(thickness[0], Styles.refractionThicknessText);
                        }
                        m_MaterialEditor.TexturePropertySingleLine(Styles.refractionThicknessMapText, thicknessMap[0]);

                        ++EditorGUI.indentLevel;
                        m_MaterialEditor.ShaderProperty(thicknessMultiplier, Styles.refractionThicknessMultiplierText);
                        --EditorGUI.indentLevel;

                        m_MaterialEditor.TexturePropertySingleLine(Styles.transmittanceColorText, transmittanceColorMap, transmittanceColor);
                        ++EditorGUI.indentLevel;
                        m_MaterialEditor.ShaderProperty(atDistance, Styles.atDistanceText);
                        atDistance.floatValue = Mathf.Max(atDistance.floatValue, 0);
                        --EditorGUI.indentLevel;
                    }
                }

                DoDistortionInputsGUI();

                --EditorGUI.indentLevel;
            }
        }