Example #1
0
        public static void Override(BlendMode blendMode, UnityEngine.Rendering.BlendMode srcFactor, UnityEngine.Rendering.BlendMode dstFactor)
        {
            int index = (int)blendMode * 2;

            Factors[index]     = (float)srcFactor;
            Factors[index + 1] = (float)dstFactor;
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="blendMode"></param>
        /// <param name="srcFactor"></param>
        /// <param name="dstFactor"></param>
        public static void Override(BlendMode blendMode, NativeBlendMode srcFactor, NativeBlendMode dstFactor)
        {
            BlendFactor bf = Factors[(int)blendMode];

            bf.srcFactor = srcFactor;
            bf.dstFactor = dstFactor;
        }
        /// <summary>
        /// Initialises a new LineCirclePattern which is the interpolation of two other LineCirclePatterns
        /// </summary>
        /// <param name="PatternA"></param>
        /// <param name="PatternB"></param>
        /// <param name="LerpFactor"></param>
        public LineCirclePattern(LineCirclePattern PatternA, LineCirclePattern PatternB, float LerpFactor)
        {
            Count                  = Mathf.RoundToInt(Mathf.Lerp(PatternA.Count, PatternB.Count, LerpFactor));
            LineCount              = Mathf.RoundToInt(Mathf.Lerp(PatternA.LineCount, PatternB.LineCount, LerpFactor));
            LineScaleMultiplier    = Mathf.Lerp(PatternA.LineScaleMultiplier, PatternB.LineScaleMultiplier, LerpFactor);
            LineRotationMultiplier = Mathf.Lerp(PatternA.LineRotationMultiplier, PatternB.LineRotationMultiplier, LerpFactor);
            SphericalCoordinates   = LerpFactor < 0.5f ? PatternA.SphericalCoordinates : PatternB.SphericalCoordinates;
            LineInterval           = Mathf.RoundToInt(Mathf.Lerp(PatternA.LineInterval, PatternB.LineInterval, LerpFactor));
            AutoScaleLines         = LerpFactor < 0.5f ? PatternA.AutoScaleLines : PatternB.AutoScaleLines;

            TimeStep   = Mathf.Lerp(PatternA.TimeStep, PatternB.TimeStep, LerpFactor);
            TimeSpan   = Mathf.Lerp(PatternA.TimeSpan, PatternB.TimeSpan, LerpFactor);
            TimeOffset = Mathf.Lerp(PatternA.TimeOffset, PatternB.TimeOffset, LerpFactor);

            DrawLines = LerpFactor < 0.5f ? PatternA.DrawLines : PatternB.DrawLines;
            DrawFill  = LerpFactor < 0.5f ? PatternA.DrawFill : PatternB.DrawFill;
            LineColor = Color.Lerp(PatternA.LineColor, PatternB.LineColor, LerpFactor);
            FillColor = Color.Lerp(PatternA.FillColor, PatternB.FillColor, LerpFactor);

            SrcMode = LerpFactor < 0.5f ? PatternA.SrcMode : PatternB.SrcMode;
            DstMode = LerpFactor < 0.5f ? PatternA.DstMode : PatternB.DstMode;

            Oscillators = new Oscillator[PatternA.Oscillators.Length];
            for (int i = 0; i < Oscillators.Length; i++)
            {
                Oscillators[i] = new Oscillator(PatternA.Oscillators[i], PatternB.Oscillators[i], LerpFactor);
            }

            TimeToZ = LerpFactor < 0.5f ? PatternA.TimeToZ : PatternB.TimeToZ;
            ZFade   = LerpFactor < 0.5f ? PatternA.ZFade : PatternB.ZFade;
        }
        /// <summary>
        /// Creates a new LineCirclePattern, duplicating an existing one
        /// </summary>
        /// <param name="CopyTarget">The LineCirclePattern to duplicate</param>
        public LineCirclePattern(LineCirclePattern CopyTarget)
        {
            Count                  = CopyTarget.Count;
            LineCount              = CopyTarget.LineCount;
            LineScaleMultiplier    = CopyTarget.LineScaleMultiplier;
            LineRotationMultiplier = CopyTarget.LineRotationMultiplier;
            SphericalCoordinates   = CopyTarget.SphericalCoordinates;
            LineInterval           = CopyTarget.LineInterval;
            AutoScaleLines         = CopyTarget.AutoScaleLines;

            TimeStep   = CopyTarget.TimeStep;
            TimeSpan   = CopyTarget.TimeSpan;
            TimeOffset = CopyTarget.TimeOffset;

            DrawLines = CopyTarget.DrawLines;
            DrawFill  = CopyTarget.DrawFill;
            LineColor = CopyTarget.LineColor;
            FillColor = CopyTarget.FillColor;

            SrcMode = CopyTarget.SrcMode;
            DstMode = CopyTarget.DstMode;

            Oscillators = new Oscillator[CopyTarget.Oscillators.Length];
            for (int i = 0; i < Oscillators.Length; i++)
            {
                Oscillators[i] = new Oscillator(CopyTarget.Oscillators[i]);
            }

            TimeToZ = CopyTarget.TimeToZ;
            ZFade   = CopyTarget.ZFade;
        }
        public BlendingScope(BlendMode srcMode, BlendMode dstMode)
        {
            m_srcMode = (int)HandleUtility.handleMaterial.GetFloat("_BlendSrcMode");
            HandleUtility.handleMaterial.SetFloat("_BlendSrcMode", (int)srcMode);

            m_dstMode = (int)HandleUtility.handleMaterial.GetFloat("_BlendDstMode");
            HandleUtility.handleMaterial.SetFloat("_BlendDstMode", (int)dstMode);
        }
Example #6
0
 private static void TransparencySetup(Material material, UnityEngine.Rendering.BlendMode from, UnityEngine.Rendering.BlendMode to)
 {
     material.SetOverrideTag("RenderType", "Transparent");
     material.SetInt("_SrcBlend", (int)from);
     material.SetInt("_DstBlend", (int)to);
     material.SetInt("_ZWrite", 0);
     material.DisableKeyword("_ALPHATEST_ON");
     material.EnableKeyword("_ALPHABLEND_ON");
     // material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
     material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
 }
        public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
        {
            base.AssignNewShaderToMaterial(material, oldShader, newShader);

            if (oldShader == null)
            {
                SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_blendMode"));
                return;
            }

            if (newShader.name.Contains("vrc"))
            {
                BlendMode blendMode = BlendMode.Opaque;
                UnityEngine.Rendering.BlendMode SrcBlend = UnityEngine.Rendering.BlendMode.One;
                UnityEngine.Rendering.BlendMode DstBlend = UnityEngine.Rendering.BlendMode.Zero;

                if (newShader.name.Contains("Cutout") || newShader.name.Contains("cutout"))
                {
                    blendMode = BlendMode.Cutout;
                    SrcBlend  = UnityEngine.Rendering.BlendMode.SrcAlpha;
                    DstBlend  = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                    material.SetFloat("_ColorMask", 14);
                    material.SetFloat("_AlphaToMask", 1);
                }
                else if (newShader.name.Contains("Fade") || newShader.name.Contains("fade"))
                {
                    blendMode = BlendMode.Fade;
                    SrcBlend  = UnityEngine.Rendering.BlendMode.SrcAlpha;
                    DstBlend  = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                }
                else if (newShader.name.Contains("Transparent") || newShader.name.Contains("transparent"))
                {
                    blendMode = BlendMode.Transparent;
                    SrcBlend  = UnityEngine.Rendering.BlendMode.SrcAlpha;
                    DstBlend  = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                }
                material.SetFloat("_blendMode", (float)blendMode);
                material.SetFloat("_SrcBlend", (float)SrcBlend);
                material.SetFloat("_DstBlend", (float)DstBlend);

                MaterialChanged(material, keyModes);

                material.renderQueue = -1;
            }
            else
            {
                MaterialChanged(material, keyModes);
            }
        }
Example #8
0
        private void SetMatBlend(UnityEngine.Rendering.BlendMode src, UnityEngine.Rendering.BlendMode dst, AlphaMode alp, int zwrite)
        {
            if (material.HasProperty("_SrcBlend"))
            {
                material.SetInt("_SrcBlend", (int)src);
            }
            if (material.HasProperty("_DstBlend"))
            {
                material.SetInt("_DstBlend", (int)dst);
            }
            if (material.HasProperty("_ZWrite"))
            {
                material.SetInt("_ZWrite", zwrite);
            }

            EnableMatKeyword(KEY_ALPHA_TEST, (alp & AlphaMode.AlphaTest) != 0);
            EnableMatKeyword(KEY_ALPHA_PREMULT, (alp & AlphaMode.AlphaPrume) != 0);
        }
Example #9
0
        internal static Material Create_LineMat(UnityEngine.Rendering.BlendMode SrcBlend, UnityEngine.Rendering.BlendMode DstBlend)
        {
            // Unity has a built-in shader that is useful for drawing
            // simple colored things.
            var shader = Shader.Find("Hidden/Internal-Colored");
            var mat    = new Material(shader)
            {
                hideFlags = HideFlags.HideAndDontSave
            };

            mat.SetInt(Blend, (int)SrcBlend);
            mat.SetInt(DstBlend1, (int)DstBlend);

            mat.SetInt(Cull, (int)UnityEngine.Rendering.CullMode.Off); // Turn backface culling off
            mat.SetInt(ZWrite, 1);                                     // Turn on depth writes

            return(mat);
        }
    private void Blending(MaterialEditor materialEditor, MaterialProperty[] properties, GUIStyle style, bool toggle, string inspector, string flag)
    {
        MaterialProperty srcM = ShaderGUI.FindProperty("_MySrcMode", properties);
        MaterialProperty dstM = ShaderGUI.FindProperty("_MyDstMode", properties);

        if (srcM.floatValue == 0 && dstM.floatValue == 0)
        {
            srcM.floatValue = 5;
            dstM.floatValue = 10;
        }
        bool ini = toggle;

        toggle = EditorGUILayout.BeginToggleGroup(inspector, toggle);
        if (ini != toggle && !Application.isPlaying)
        {
            EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
        }
        if (toggle)
        {
            targetMat.EnableKeyword(flag);
            EditorGUILayout.BeginVertical(style);
            {
                GUILayout.Label("Look for 'ShaderLab: Blending' if you don't know what this is", style);
                if (GUILayout.Button("Back To Default Blending"))
                {
                    srcM.floatValue = 5;
                    dstM.floatValue = 10;
                }
                srcMode         = (UnityEngine.Rendering.BlendMode)srcM.floatValue;
                dstMode         = (UnityEngine.Rendering.BlendMode)dstM.floatValue;
                srcMode         = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("SrcMode", srcMode);
                dstMode         = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("DstMode", dstMode);
                srcM.floatValue = (float)(srcMode);
                dstM.floatValue = (float)(dstMode);
            }
            EditorGUILayout.EndVertical();
        }
        else
        {
            targetMat.DisableKeyword(flag);
        }
        EditorGUILayout.EndToggleGroup();
    }
        /// <summary>
        /// Creates a new LineCirclePattern
        /// </summary>
        public LineCirclePattern()
        {
            Count                  = 10000;
            LineCount              = 12;
            LineScaleMultiplier    = 0f;
            LineRotationMultiplier = 0f;
            SphericalCoordinates   = true;
            AutoScaleLines         = true;
            LineInterval           = 4;

            TimeStep   = 0.01f;
            TimeSpan   = 0;
            TimeOffset = 0;

            DrawLines = true;
            DrawFill  = true;
            LineColor = new Color(1f, 1f, 1f, 0.1f);
            FillColor = new Color(1f, 1f, 1f, 0.1f);

            SrcMode = UnityEngine.Rendering.BlendMode.SrcAlpha;
            DstMode = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;

            Oscillators = new Oscillator[ID.Count];
            Oscillators[ID.CirclePosX]  = new Oscillator("CirclePosX", 1, 0, 1, 1, 0);
            Oscillators[ID.CirclePosY]  = new Oscillator("CirclePosY", 1, 0, 1, 3.1f, 0);
            Oscillators[ID.CirclePosZ]  = new Oscillator("CirclePosZ", 0, 0, 1, 1, 0);
            Oscillators[ID.CircleRotX]  = new Oscillator("CircleRotX", 0, 0, 1, 1, 0);
            Oscillators[ID.CircleRotY]  = new Oscillator("CircleRotY", 0, 0, 1, 1, 0);
            Oscillators[ID.CircleRotZ]  = new Oscillator("CircleRotZ", 0, 0, 1, 1, 0);
            Oscillators[ID.CircleRad]   = new Oscillator("CircleRad", 0, 0, 1, 1, 0);
            Oscillators[ID.LineRotX]    = new Oscillator("LineRotX", 0, 0, 1, 1, 0);
            Oscillators[ID.LineRotY]    = new Oscillator("LineRotY", 0, 0, 1, 1, 0);
            Oscillators[ID.LineRotZ]    = new Oscillator("LineRotZ", 0, 0, 1, 1, 0);
            Oscillators[ID.LineLength]  = new Oscillator("LineLength", 0, 0, 1, 1, 0);
            Oscillators[ID.ColorOffset] = new Oscillator("ColorOffset", 0, 0, 1, 1, 0);
            Oscillators[ID.ColorRange]  = new Oscillator("ColorRange", 0, 0, 1, 1, 0);

            TimeToZ = 0f;
            ZFade   = float.MaxValue;
        }
    public override void OnInspectorGUI()
    {
        if (!this.isVisible)
        {
            return;
        }

#if SHOW_DEFAULT_INSPECTOR
        base.OnInspectorGUI();
        return;
#else
        //Detect if Shader has changed
        if (targetMaterial.shader != mCurrentShader)
        {
            mCurrentShader = targetMaterial.shader;
        }

        UpdateFeaturesFromShader();

        //Get material keywords
        List <string> keywordsList   = new List <string>(targetMaterial.shaderKeywords);
        bool          updateKeywords = false;

        //Header
        TCP2_GUI.HeaderBig("TOONY COLORS PRO 2 - Outlines Only");
        TCP2_GUI.Separator();

        //Iterate Shader properties
        serializedObject.Update();
        SerializedProperty mShader = serializedObject.FindProperty("m_Shader");
        if (isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null)
        {
            EditorGUIUtility.labelWidth = TCP2_Utils.ScreenWidthRetina - 120f;
            EditorGUIUtility.fieldWidth = 64f;

            EditorGUI.BeginChangeCheck();

            MaterialProperty[] props = GetMaterialProperties(this.targets);

            //UNFILTERED PARAMETERS ==============================================================

            if (ShowFilteredProperties(null, props, false))
            {
                TCP2_GUI.Separator();
            }

            //FILTERED PARAMETERS ================================================================

            //Outline Type ---------------------------------------------------------------------------
            ShowFilteredProperties("#OUTLINE#", props, false);
            if (!mShaderModel2)
            {
                bool texturedOutline = TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_TEXTURED", "Outline Color from Texture", "If enabled, outline will take an averaged color from the main texture multiplied by Outline Color", keywordsList, ref updateKeywords);
                if (texturedOutline)
                {
                    ShowFilteredProperties("#OUTLINETEX#", props);
                }
            }

            TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_CONST_SIZE", "Constant Size Outline", "If enabled, outline will have a constant size independently from camera distance", keywordsList, ref updateKeywords);
            if (TCP2_Utils.ShaderKeywordToggle("TCP2_ZSMOOTH_ON", "Correct Z Artefacts", "Enable the outline z-correction to try to hide artefacts from complex models", keywordsList, ref updateKeywords))
            {
                ShowFilteredProperties("#OUTLINEZ#", props);
            }

            //Smoothed Normals -----------------------------------------------------------------------
            TCP2_GUI.Header("OUTLINE NORMALS", "Defines where to take the vertex normals from to draw the outline.\nChange this when using a smoothed mesh to fill the gaps shown in hard-edged meshes.");
            TCP2_Utils.ShaderKeywordRadio(null, new string[] { "TCP2_NONE", "TCP2_COLORS_AS_NORMALS", "TCP2_TANGENT_AS_NORMALS", "TCP2_UV2_AS_NORMALS" }, new GUIContent[]
            {
                new GUIContent("Regular", "Use regular vertex normals"),
                new GUIContent("Vertex Colors", "Use vertex colors as normals (with smoothed mesh)"),
                new GUIContent("Tangents", "Use tangents as normals (with smoothed mesh)"),
                new GUIContent("UV2", "Use second texture coordinates as normals (with smoothed mesh)"),
            },
                                          keywordsList, ref updateKeywords);

            //Outline Blending -----------------------------------------------------------------------

            if (mIsOutlineBlending)
            {
                MaterialProperty[] blendProps = GetFilteredProperties("#BLEND#", props);

                if (blendProps.Length != 2)
                {
                    EditorGUILayout.HelpBox("Couldn't find Blending properties!", MessageType.Error);
                }
                else
                {
                    TCP2_GUI.Header("OUTLINE BLENDING", "BLENDING EXAMPLES:\nAlpha Transparency: SrcAlpha / OneMinusSrcAlpha\nMultiply: DstColor / Zero\nAdd: One / One\nSoft Add: OneMinusDstColor / One");

                    UnityEngine.Rendering.BlendMode blendSrc = (UnityEngine.Rendering.BlendMode)blendProps[0].floatValue;
                    UnityEngine.Rendering.BlendMode blendDst = (UnityEngine.Rendering.BlendMode)blendProps[1].floatValue;

                    EditorGUI.BeginChangeCheck();
                    float f = EditorGUIUtility.fieldWidth;
                    float l = EditorGUIUtility.labelWidth;
                    EditorGUIUtility.fieldWidth  = 110f;
                    EditorGUIUtility.labelWidth -= Mathf.Abs(f - EditorGUIUtility.fieldWidth);
                    blendSrc = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Source Factor", blendSrc);
                    blendDst = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Destination Factor", blendDst);
                    EditorGUIUtility.fieldWidth = f;
                    EditorGUIUtility.labelWidth = l;
                    if (EditorGUI.EndChangeCheck())
                    {
                        blendProps[0].floatValue = (float)blendSrc;
                        blendProps[1].floatValue = (float)blendDst;
                    }
                }
            }

            TCP2_GUI.Separator();

            //--------------------------------------------------------------------------------------

            if (EditorGUI.EndChangeCheck())
            {
                PropertiesChanged();
            }
        }

        //Update Keywords
        if (updateKeywords)
        {
            if (targets != null && targets.Length > 0)
            {
                foreach (Object t in targets)
                {
                    (t as Material).shaderKeywords = keywordsList.ToArray();
                    EditorUtility.SetDirty(t);
                }
            }
            else
            {
                targetMaterial.shaderKeywords = keywordsList.ToArray();
                EditorUtility.SetDirty(targetMaterial);
            }
        }
#endif
    }
Example #13
0
    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        mMaterialEditor = materialEditor;

#if SHOW_DEFAULT_INSPECTOR
        base.OnGUI();
        return;
#else
        if (mJustChangedShader)
        {
            mJustChangedShader = false;
            mVariantError      = null;
            Event.current.Use();                        //Avoid layout mismatch error
            SceneView.RepaintAll();
        }

        UpdateFeaturesFromShader();

        //Get material keywords
        List <string> keywordsList   = new List <string>(targetMaterial.shaderKeywords);
        bool          updateKeywords = false;
        bool          updateVariant  = false;

        //Header
        EditorGUILayout.BeginHorizontal();
        TCP2_GUI.HeaderBig("TOONY COLORS PRO 2 - INSPECTOR");
        if (isGeneratedShader && TCP2_GUI.Button(TCP2_GUI.CogIcon, "O", "Open in Shader Generator"))
        {
            if (targetMaterial.shader != null)
            {
                TCP2_ShaderGenerator.OpenWithShader(targetMaterial.shader);
            }
        }
        TCP2_GUI.HelpButton("Unified Shader");
        EditorGUILayout.EndHorizontal();
        TCP2_GUI.Separator();

        if (!string.IsNullOrEmpty(mVariantError))
        {
            EditorGUILayout.HelpBox(mVariantError, MessageType.Error);

            EditorGUILayout.HelpBox("Some of the shaders are packed to avoid super long loading times when you import Toony Colors Pro 2 into Unity.\n\n" +
                                    "You can unpack them by category in the menu:\n\"Tools > Toony Colors Pro 2 > Unpack Shaders > ...\"",
                                    MessageType.Info);
        }

        //Iterate Shader properties
        materialEditor.serializedObject.Update();
        SerializedProperty mShader = materialEditor.serializedObject.FindProperty("m_Shader");
        if (materialEditor.isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null)
        {
            //Retina display fix
            EditorGUIUtility.labelWidth = TCP2_Utils.ScreenWidthRetina - 120f;
            EditorGUIUtility.fieldWidth = 64f;

            EditorGUI.BeginChangeCheck();

            MaterialProperty[] props = properties;

            //UNFILTERED PARAMETERS ==============================================================

            TCP2_GUI.HeaderAndHelp("BASE", "Base Properties");
            if (ShowFilteredProperties(null, props))
            {
                if (!isGeneratedShader)
                {
                    TCP2_Utils.ShaderKeywordToggle("TCP2_DISABLE_WRAPPED_LIGHT", "Disable Wrapped Lighting", "Disable wrapped lighting, reducing intensity received from lights", keywordsList, ref updateKeywords, "Disable Wrapped Lighting");
                }

                TCP2_GUI.Separator();
            }

            //FILTERED PARAMETERS ================================================================

            //RAMP TYPE --------------------------------------------------------------------------

            if (CategoryFilter("TEXTURE_RAMP"))
            {
                if (isGeneratedShader)
                {
                    ShowFilteredProperties("#RAMPT#", props);
                }
                else
                {
                    if (TCP2_Utils.ShaderKeywordToggle("TCP2_RAMPTEXT", "Texture Toon Ramp", "Make the toon ramp based on a texture", keywordsList, ref updateKeywords, "Ramp Style"))
                    {
                        ShowFilteredProperties("#RAMPT#", props);
                    }
                    else
                    {
                        ShowFilteredProperties("#RAMPF#", props);
                    }
                }
            }
            else
            {
                ShowFilteredProperties("#RAMPF#", props);
            }

            TCP2_GUI.Separator();

            //BUMP/NORMAL MAPPING ----------------------------------------------------------------

            if (CategoryFilter("BUMP"))
            {
                if (isGeneratedShader)
                {
                    TCP2_GUI.HeaderAndHelp("BUMP/NORMAL MAPPING", "Normal/Bump map");

                    ShowFilteredProperties("#NORM#", props);
                    ShowFilteredProperties("#PLLX#", props);
                }
                else
                {
                    if (TCP2_Utils.ShaderKeywordToggle("TCP2_BUMP", "BUMP/NORMAL MAPPING", "Enable bump mapping using normal maps", keywordsList, ref updateKeywords, "Normal/Bump map"))
                    {
                        ShowFilteredProperties("#NORM#", props);
                    }
                }

                TCP2_GUI.Separator();
            }

            //SPECULAR ---------------------------------------------------------------------------

            if (CategoryFilter("SPECULAR", "SPECULAR_ANISOTROPIC"))
            {
                if (isGeneratedShader)
                {
                    TCP2_GUI.HeaderAndHelp("SPECULAR", "Specular");
                    ShowFilteredProperties("#SPEC#", props);
                    if (HasFlags("SPECULAR_ANISOTROPIC"))
                    {
                        ShowFilteredProperties("#SPECA#", props);
                    }
                    if (HasFlags("SPECULAR_TOON"))
                    {
                        ShowFilteredProperties("#SPECT#", props);
                    }
                }
                else
                {
                    bool specular = TCP2_Utils.HasKeywords(keywordsList, "TCP2_SPEC", "TCP2_SPEC_TOON");
                    TCP2_Utils.ShaderVariantUpdate("Specular", ShaderVariants, ShaderVariantsEnabled, specular, ref updateVariant);

                    specular |= TCP2_Utils.ShaderKeywordRadio("SPECULAR", new string[] { "TCP2_SPEC_OFF", "TCP2_SPEC", "TCP2_SPEC_TOON" }, new GUIContent[]
                    {
                        new GUIContent("Off", "No Specular"),
                        new GUIContent("Regular", "Default Blinn-Phong Specular"),
                        new GUIContent("Cartoon", "Specular with smoothness control")
                    },
                                                              keywordsList, ref updateKeywords);

                    if (specular)
                    {
                        ShowFilteredProperties("#SPEC#", props);

                        bool specr = TCP2_Utils.HasKeywords(keywordsList, "TCP2_SPEC_TOON");
                        if (specr)
                        {
                            ShowFilteredProperties("#SPECT#", props);
                        }
                    }
                }

                TCP2_GUI.Separator();
            }

            //REFLECTION -------------------------------------------------------------------------

            if (CategoryFilter("REFLECTION") && !isMobileShader)
            {
                if (isGeneratedShader)
                {
                    TCP2_GUI.HeaderAndHelp("REFLECTION", "Reflection");

                    ShowFilteredProperties("#REFL#", props);
#if UNITY_5
                    if (HasFlags("U5_REFLPROBE"))
                    {
                        ShowFilteredProperties("#REFL_U5#", props);
                    }
#endif
                    if (HasFlags("REFL_COLOR"))
                    {
                        ShowFilteredProperties("#REFLC#", props);
                    }
                    if (HasFlags("REFL_ROUGH"))
                    {
                        ShowFilteredProperties("#REFLR#", props);
                        EditorGUILayout.HelpBox("Cubemap Texture needs to have MipMaps enabled for Roughness to work!", MessageType.Info);
                    }
                }
                else
                {
                    bool reflection = TCP2_Utils.HasKeywords(keywordsList, "TCP2_REFLECTION", "TCP2_REFLECTION_MASKED");
                    TCP2_Utils.ShaderVariantUpdate("Reflection", ShaderVariants, ShaderVariantsEnabled, reflection, ref updateVariant);

                    reflection |= TCP2_Utils.ShaderKeywordRadio("REFLECTION", new string[] { "TCP2_REFLECTION_OFF", "TCP2_REFLECTION", "TCP2_REFLECTION_MASKED" }, new GUIContent[]
                    {
                        new GUIContent("Off", "No Cubemap Reflection"),
                        new GUIContent("Global", "Global Cubemap Reflection"),
                        new GUIContent("Masked", "Masked Cubemap Reflection (using the main texture's alpha channel)")
                    },
                                                                keywordsList, ref updateKeywords);

                    if (reflection)
                    {
#if UNITY_5
                        //Reflection Probes toggle
                        if (TCP2_Utils.ShaderKeywordToggle("TCP2_U5_REFLPROBE", "Use Reflection Probes", "Use Unity 5's Reflection Probes", keywordsList, ref updateKeywords))
                        {
                            ShowFilteredProperties("#REFL_U5#", props);
                        }
#endif
                        ShowFilteredProperties("#REFL#", props);
                    }
                }

                TCP2_GUI.Separator();
            }

            //MATCAP -----------------------------------------------------------------------------

            if (CategoryFilter("MATCAP"))
            {
                if (isGeneratedShader)
                {
                    TCP2_GUI.Header("MATCAP");
                    ShowFilteredProperties("#MC#", props);

                    TCP2_GUI.Separator();
                }
                else if (isMobileShader)
                {
                    bool matcap = TCP2_Utils.HasKeywords(keywordsList, "TCP2_MC", "TCP2_MCMASK");
                    TCP2_Utils.ShaderVariantUpdate("Matcap", ShaderVariants, ShaderVariantsEnabled, matcap, ref updateVariant);

                    matcap |= TCP2_Utils.ShaderKeywordRadio("MATCAP", new string[] { "TCP2_MC_OFF", "TCP2_MC", "TCP2_MCMASK" }, new GUIContent[]
                    {
                        new GUIContent("Off", "No MatCap reflection"),
                        new GUIContent("Global", "Global additive MatCap"),
                        new GUIContent("Masked", "Masked additive MatCap (using the main texture's alpha channel)")
                    },
                                                            keywordsList, ref updateKeywords);

                    if (matcap)
                    {
                        ShowFilteredProperties("#MC#", props);
                    }

                    TCP2_GUI.Separator();
                }
            }

            //SUBSURFACE SCATTERING --------------------------------------------------------------------------------

            if (CategoryFilter("SUBSURFACE_SCATTERING") && isGeneratedShader)
            {
                TCP2_GUI.HeaderAndHelp("SUBSURFACE SCATTERING", "Subsurface Scattering");
                ShowFilteredProperties("#SUBS#", props);
                TCP2_GUI.Separator();
            }

            //RIM --------------------------------------------------------------------------------

            if (CategoryFilter("RIM", "RIM_OUTLINE"))
            {
                if (isGeneratedShader)
                {
                    TCP2_GUI.HeaderAndHelp("RIM", "Rim");

                    ShowFilteredProperties("#RIM#", props);

                    if (HasFlags("RIMDIR"))
                    {
                        ShowFilteredProperties("#RIMDIR#", props);

                        if (HasFlags("PARALLAX"))
                        {
                            EditorGUILayout.HelpBox("Because it affects the view direction vector, Rim Direction may distort Parallax effect.", MessageType.Warning);
                        }
                    }
                }
                else
                {
                    bool rim        = TCP2_Utils.HasKeywords(keywordsList, "TCP2_RIM");
                    bool rimOutline = TCP2_Utils.HasKeywords(keywordsList, "TCP2_RIMO");

                    TCP2_Utils.ShaderVariantUpdate("Rim", ShaderVariants, ShaderVariantsEnabled, rim, ref updateVariant);
                    TCP2_Utils.ShaderVariantUpdate("RimOutline", ShaderVariants, ShaderVariantsEnabled, rimOutline, ref updateVariant);

                    rim |= rimOutline |= TCP2_Utils.ShaderKeywordRadio("RIM", new string[] { "TCP2_RIM_OFF", "TCP2_RIM", "TCP2_RIMO" }, new GUIContent[]
                    {
                        new GUIContent("Off", "No Rim effect"),
                        new GUIContent("Lighting", "Rim lighting (additive)"),
                        new GUIContent("Outline", "Rim outline (blended)")
                    },
                                                                       keywordsList, ref updateKeywords);

                    if (rim || rimOutline)
                    {
                        ShowFilteredProperties("#RIM#", props);

                        if (CategoryFilter("RIMDIR"))
                        {
                            if (TCP2_Utils.ShaderKeywordToggle("TCP2_RIMDIR", "Directional Rim", "Enable directional rim control (rim calculation is approximated if enabled)", keywordsList, ref updateKeywords))
                            {
                                ShowFilteredProperties("#RIMDIR#", props);
                            }
                        }
                    }
                }

                TCP2_GUI.Separator();
            }

            //CUBEMAP AMBIENT --------------------------------------------------------------------

            if (CategoryFilter("CUBE_AMBIENT") && isGeneratedShader)
            {
                TCP2_GUI.HeaderAndHelp("CUBEMAP AMBIENT", "Cubemap Ambient");
                ShowFilteredProperties("#CUBEAMB#", props);
                TCP2_GUI.Separator();
            }

            //DIRECTIONAL AMBIENT --------------------------------------------------------------------

            if (CategoryFilter("DIRAMBIENT") && isGeneratedShader)
            {
                TCP2_GUI.HeaderAndHelp("DIRECTIONAL AMBIENT", "Directional Ambient");
                DirectionalAmbientGUI("#DAMB#", props);
                TCP2_GUI.Separator();
            }

            //SKETCH --------------------------------------------------------------------------------

            if (CategoryFilter("SKETCH", "SKETCH_GRADIENT") && isGeneratedShader)
            {
                TCP2_GUI.HeaderAndHelp("SKETCH", "Sketch");

                bool sketch  = HasFlags("SKETCH");
                bool sketchG = HasFlags("SKETCH_GRADIENT");

                if (sketch || sketchG)
                {
                    ShowFilteredProperties("#SKETCH#", props);
                }

                if (sketchG)
                {
                    ShowFilteredProperties("#SKETCHG#", props);
                }

                TCP2_GUI.Separator();
            }

            //OUTLINE --------------------------------------------------------------------------------

            if (CategoryFilter("OUTLINE", "OUTLINE_BLENDING"))
            {
                bool hasOutlineOpaque   = false;
                bool hasOutlineBlending = false;
                bool hasOutline         = false;

                if (isGeneratedShader)
                {
                    TCP2_GUI.HeaderAndHelp("OUTLINE", "Outline");

                    hasOutlineOpaque   = HasFlags("OUTLINE");
                    hasOutlineBlending = HasFlags("OUTLINE_BLENDING");
                    hasOutline         = hasOutlineOpaque || hasOutlineBlending;
                }
                else
                {
                    hasOutlineOpaque   = TCP2_Utils.HasKeywords(keywordsList, "OUTLINES");
                    hasOutlineBlending = TCP2_Utils.HasKeywords(keywordsList, "OUTLINE_BLENDING");
                    hasOutline         = hasOutlineOpaque || hasOutlineBlending;

                    TCP2_Utils.ShaderVariantUpdate("Outline", ShaderVariants, ShaderVariantsEnabled, hasOutlineOpaque, ref updateVariant);
                    TCP2_Utils.ShaderVariantUpdate("OutlineBlending", ShaderVariants, ShaderVariantsEnabled, hasOutlineBlending, ref updateVariant);

                    hasOutline |= TCP2_Utils.ShaderKeywordRadio("OUTLINE", new string[] { "OUTLINE_OFF", "OUTLINES", "OUTLINE_BLENDING" }, new GUIContent[]
                    {
                        new GUIContent("Off", "No Outline"),
                        new GUIContent("Opaque", "Opaque Outline"),
                        new GUIContent("Blended", "Allows transparent Outline and other effects")
                    },
                                                                keywordsList, ref updateKeywords);
                }

                if (hasOutline)
                {
                    EditorGUI.indentLevel++;

                    //Outline Type ---------------------------------------------------------------------------
                    ShowFilteredProperties("#OUTLINE#", props, false);
                    if (!isMobileShader && !HasFlags("FORCE_SM2"))
                    {
                        bool outlineTextured = TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_TEXTURED", "Outline Color from Texture", "If enabled, outline will take an averaged color from the main texture multiplied by Outline Color", keywordsList, ref updateKeywords);
                        if (outlineTextured)
                        {
                            ShowFilteredProperties("#OUTLINETEX#", props);
                        }
                    }
                    TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_CONST_SIZE", "Constant Size Outline", "If enabled, outline will have a constant size independently from camera distance", keywordsList, ref updateKeywords);
                    if (TCP2_Utils.ShaderKeywordToggle("TCP2_ZSMOOTH_ON", "Correct Z Artefacts", "Enable the outline z-correction to try to hide artefacts from complex models", keywordsList, ref updateKeywords))
                    {
                        ShowFilteredProperties("#OUTLINEZ#", props);
                    }

                    //Smoothed Normals -----------------------------------------------------------------------
                    EditorGUI.indentLevel--;
                    TCP2_GUI.Header("OUTLINE NORMALS", "Defines where to take the vertex normals from to draw the outline.\nChange this when using a smoothed mesh to fill the gaps shown in hard-edged meshes.");
                    EditorGUI.indentLevel++;
                    TCP2_Utils.ShaderKeywordRadio(null, new string[] { "TCP2_NONE", "TCP2_COLORS_AS_NORMALS", "TCP2_TANGENT_AS_NORMALS", "TCP2_UV2_AS_NORMALS" }, new GUIContent[]
                    {
                        new GUIContent("Regular", "Use regular vertex normals"),
                        new GUIContent("Vertex Colors", "Use vertex colors as normals (with smoothed mesh)"),
                        new GUIContent("Tangents", "Use tangents as normals (with smoothed mesh)"),
                        new GUIContent("UV2", "Use second texture coordinates as normals (with smoothed mesh)"),
                    },
                                                  keywordsList, ref updateKeywords);
                    EditorGUI.indentLevel--;

                    //Outline Blending -----------------------------------------------------------------------

                    if (hasOutlineBlending)
                    {
                        MaterialProperty[] blendProps = GetFilteredProperties("#BLEND#", props);

                        if (blendProps.Length != 2)
                        {
                            EditorGUILayout.HelpBox("Couldn't find Blending properties!", MessageType.Error);
                        }
                        else
                        {
                            TCP2_GUI.Header("OUTLINE BLENDING", "BLENDING EXAMPLES:\nAlpha Transparency: SrcAlpha / OneMinusSrcAlpha\nMultiply: DstColor / Zero\nAdd: One / One\nSoft Add: OneMinusDstColor / One");

                            UnityEngine.Rendering.BlendMode blendSrc = (UnityEngine.Rendering.BlendMode)blendProps[0].floatValue;
                            UnityEngine.Rendering.BlendMode blendDst = (UnityEngine.Rendering.BlendMode)blendProps[1].floatValue;

                            EditorGUI.BeginChangeCheck();
                            float f = EditorGUIUtility.fieldWidth;
                            float l = EditorGUIUtility.labelWidth;
                            EditorGUIUtility.fieldWidth  = 110f;
                            EditorGUIUtility.labelWidth -= Mathf.Abs(f - EditorGUIUtility.fieldWidth);
                            blendSrc = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Source Factor", blendSrc);
                            blendDst = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Destination Factor", blendDst);
                            EditorGUIUtility.fieldWidth = f;
                            EditorGUIUtility.labelWidth = l;
                            if (EditorGUI.EndChangeCheck())
                            {
                                blendProps[0].floatValue = (float)blendSrc;
                                blendProps[1].floatValue = (float)blendDst;
                            }
                        }
                    }
                }

                TCP2_GUI.Separator();
            }

            //LIGHTMAP --------------------------------------------------------------------------------

#if UNITY_4_5
            if (CategoryFilter("LIGHTMAP") && !isGeneratedShader)
            {
                TCP2_Utils.ShaderKeywordRadio("LIGHTMAP", new string[] { "TCP2_LIGHTMAP_OFF", "TCP2_LIGHTMAP" }, new GUIContent[] {
                    new GUIContent("Unity", "Use Unity's built-in lightmap decoding"),
                    new GUIContent("Toony Colors Pro 2", "Use TCP2's lightmap decoding (lightmaps will be affected by ramp and color settings)")
                }, keywordsList, ref updateKeywords);
            }
#endif

            //TRANSPARENCY --------------------------------------------------------------------------------

            if (CategoryFilter("ALPHA", "CUTOUT") && isGeneratedShader)
            {
                bool alpha  = false;
                bool cutout = false;

                if (isGeneratedShader)
                {
                    TCP2_GUI.Header("TRANSPARENCY");

                    alpha  = HasFlags("ALPHA");
                    cutout = HasFlags("CUTOUT");
                }

                if (alpha)
                {
                    MaterialProperty[] blendProps = GetFilteredProperties("#ALPHA#", props);
                    if (blendProps.Length != 2)
                    {
                        EditorGUILayout.HelpBox("Couldn't find Blending properties!", MessageType.Error);
                    }
                    else
                    {
                        TCP2_GUI.Header("BLENDING", "BLENDING EXAMPLES:\nAlpha Transparency: SrcAlpha / OneMinusSrcAlpha\nMultiply: DstColor / Zero\nAdd: One / One\nSoft Add: OneMinusDstColor / One");

                        UnityEngine.Rendering.BlendMode blendSrc = (UnityEngine.Rendering.BlendMode)blendProps[0].floatValue;
                        UnityEngine.Rendering.BlendMode blendDst = (UnityEngine.Rendering.BlendMode)blendProps[1].floatValue;

                        EditorGUI.BeginChangeCheck();
                        float f = EditorGUIUtility.fieldWidth;
                        float l = EditorGUIUtility.labelWidth;
                        EditorGUIUtility.fieldWidth  = 110f;
                        EditorGUIUtility.labelWidth -= Mathf.Abs(f - EditorGUIUtility.fieldWidth);
                        blendSrc = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Source Factor", blendSrc);
                        blendDst = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Destination Factor", blendDst);
                        EditorGUIUtility.fieldWidth = f;
                        EditorGUIUtility.labelWidth = l;
                        if (EditorGUI.EndChangeCheck())
                        {
                            blendProps[0].floatValue = (float)blendSrc;
                            blendProps[1].floatValue = (float)blendDst;
                        }
                    }
                }

                if (cutout)
                {
                    ShowFilteredProperties("#CUTOUT#", props);
                }
            }

#if DEBUG_INFO
            //--------------------------------------------------------------------------------------
            //DEBUG --------------------------------------------------------------------------------

            TCP2_GUI.SeparatorBig();

            TCP2_GUI.Header("DEBUG");

            //Clear Keywords
            if (GUILayout.Button("Clear Keywords", EditorStyles.miniButton))
            {
                keywordsList.Clear();
                updateKeywords = true;
            }

            //Shader Flags
            GUILayout.Label("Features", EditorStyles.boldLabel);
            string features = "";
            if (mShaderFeatures != null)
            {
                foreach (string flag in mShaderFeatures)
                {
                    features += flag + ", ";
                }
            }
            if (features.Length > 0)
            {
                features = features.Substring(0, features.Length - 2);
            }

            GUILayout.Label(features, EditorStyles.wordWrappedMiniLabel);

            //Shader Keywords
            GUILayout.Label("Keywords", EditorStyles.boldLabel);
            string keywords = "";
            foreach (string keyword in keywordsList)
            {
                keywords += keyword + ", ";
            }
            if (keywords.Length > 0)
            {
                keywords = keywords.Substring(0, keywords.Length - 2);
            }

            GUILayout.Label(keywords, EditorStyles.wordWrappedMiniLabel);
#endif
            //--------------------------------------------------------------------------------------

            if (EditorGUI.EndChangeCheck())
            {
                materialEditor.PropertiesChanged();
            }
        }

        //Update Keywords
        if (updateKeywords)
        {
            if (materialEditor.targets != null && materialEditor.targets.Length > 0)
            {
                foreach (Object t in materialEditor.targets)
                {
                    (t as Material).shaderKeywords = keywordsList.ToArray();
                    EditorUtility.SetDirty(t);
                }
            }
            else
            {
                targetMaterial.shaderKeywords = keywordsList.ToArray();
                EditorUtility.SetDirty(targetMaterial);
            }
        }

        //Update Variant
        if (updateVariant && !isGeneratedShader)
        {
            string baseName = isMobileShader ? BASE_SHADER_NAME_MOB : BASE_SHADER_NAME;

            string newShader = baseName;
            for (int i = 0; i < ShaderVariants.Count; i++)
            {
                if (ShaderVariantsEnabled[i])
                {
                    newShader += " " + ShaderVariants[i];
                }
            }
            newShader = newShader.TrimEnd();

            //If variant shader
            string basePath = BASE_SHADER_PATH;
            if (newShader != baseName)
            {
                basePath = VARIANT_SHADER_PATH;
            }

            Shader shader = Shader.Find(basePath + newShader);
            if (shader != null)
            {
                materialEditor.SetShader(shader, false);

                mJustChangedShader = true;
            }
            else
            {
                if (Event.current.type != EventType.Layout)
                {
                    mVariantError = "Can't find shader variant:\n" + basePath + newShader;
                }
                materialEditor.Repaint();
            }
        }
        else if (!string.IsNullOrEmpty(mVariantError) && Event.current.type != EventType.Layout)
        {
            mVariantError = null;
            materialEditor.Repaint();
        }
#endif

#if UNITY_5_5_OR_NEWER
        materialEditor.RenderQueueField();
#endif
    }
    public void ShaderPropertiesGUI(Material material)
    {
        // Use default labelWidth
        EditorGUIUtility.labelWidth = 0f;

        // Detect any changes to the material
        EditorGUI.BeginChangeCheck();
        {
            BlendModePopup();

            GUILayout.Space(8f);
            expandStandardProperties = GUILayout.Toggle(expandStandardProperties, "STANDARD PROPERTIES", EditorStyles.toolbarButton);
            if (expandStandardProperties)
            {
                //Background
                Rect vertRect = EditorGUILayout.BeginVertical();
                vertRect.xMax += 2;
                vertRect.xMin--;
                GUI.Box(vertRect, "", (GUIStyle)"RL Background");
                GUILayout.Space(4f);

                // Primary properties
                GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel);
                DoAlbedoArea(material);
                DoSpecularMetallicArea();
                m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap,
                                                           bumpMap.textureValue != null ? bumpScale : null);
                m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap,
                                                           heightMap.textureValue != null ? heigtMapScale : null);
                m_MaterialEditor.TexturePropertySingleLine(Styles.occlusionText, occlusionMap,
                                                           occlusionMap.textureValue != null ? occlusionStrength : null);
                DoEmissionArea(material);
                m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
                EditorGUI.BeginChangeCheck();
                m_MaterialEditor.TextureScaleOffsetProperty(albedoMap);
                if (EditorGUI.EndChangeCheck())
                {
                    emissionMap.textureScaleAndOffset = albedoMap.textureScaleAndOffset;
                }
                // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake

                EditorGUILayout.Space();

                // Secondary properties
                GUILayout.Label(Styles.secondaryMapsText, EditorStyles.boldLabel);
                m_MaterialEditor.TexturePropertySingleLine(Styles.detailAlbedoText, detailAlbedoMap);
                m_MaterialEditor.TexturePropertySingleLine(Styles.detailNormalMapText, detailNormalMap, detailNormalMapScale);
                m_MaterialEditor.TextureScaleOffsetProperty(detailAlbedoMap);
                m_MaterialEditor.ShaderProperty(uvSetSecondary, Styles.uvSetLabel.text);

                // Third properties
                GUILayout.Label(Styles.forwardText, EditorStyles.boldLabel);
                if (highlights != null)
                {
                    m_MaterialEditor.ShaderProperty(highlights, Styles.highlightsText);
                }
                if (reflections != null)
                {
                    m_MaterialEditor.ShaderProperty(reflections, Styles.reflectionsText);
                }

                GUILayout.Space(8f);
                EditorGUILayout.EndVertical();
            }

            EditorGUILayout.Space();

            //----------------------------------------------------------------
            //    TOONY COLORS PRO 2

            bool useOutline        = (m_MaterialEditor.target as Material).shaderKeywords.Contains("OUTLINES");
            bool useOutlineBlended = (m_MaterialEditor.target as Material).shaderKeywords.Contains("OUTLINE_BLENDING");

            bool hasOutlineShader        = tcp2_outlineWidth != null;
            bool hasOutlineBlendedShader = tcp2_srcBlendOutline != null;

            bool useOutlineNew        = useOutline;
            bool useOutlineBlendedNew = useOutlineBlended;

            expandTCP2Properties = GUILayout.Toggle(expandTCP2Properties, "TOONY COLORS PRO 2", EditorStyles.toolbarButton);
            if (expandTCP2Properties)
            {
                //Background
                Rect vertRect = EditorGUILayout.BeginVertical();
                vertRect.xMax += 2;
                vertRect.xMin--;
                GUI.Box(vertRect, "", (GUIStyle)"RL Background");
                GUILayout.Space(4f);

                GUILayout.Label("Base Properties", EditorStyles.boldLabel);
                m_MaterialEditor.ColorProperty(tcp2_highlightColor, Styles.tcp2_highlightColorText);
                m_MaterialEditor.ColorProperty(tcp2_shadowColor, Styles.tcp2_shadowColorText);

                // Wrapped Lighting
                m_MaterialEditor.ShaderProperty(tcp2_TCP2_DISABLE_WRAPPED_LIGHT, "Disable Wrapped Lighting");

                // Ramp Texture / Threshold
                m_MaterialEditor.ShaderProperty(tcp2_TCP2_RAMPTEXT, "Use Ramp Texture");
                if (tcp2_TCP2_RAMPTEXT.floatValue > 0)
                {
                    EditorGUI.indentLevel++;
                    m_MaterialEditor.ShaderProperty(tcp2_ramp, Styles.tcp2_rampText);
                    //m_MaterialEditor.TexturePropertySingleLine(Styles.tcp2_rampText, tcp2_ramp);
                    EditorGUI.indentLevel--;
                }
                else
                {
                    m_MaterialEditor.ShaderProperty(tcp2_rampThreshold, Styles.tcp2_rampThresholdText.text, 1);
                    m_MaterialEditor.ShaderProperty(tcp2_rampSmooth, Styles.tcp2_rampSmoothText.text, 1);
                    m_MaterialEditor.ShaderProperty(tcp2_rampSmoothAdd, Styles.tcp2_rampSmoothAddText.text, 1);
                }

                EditorGUILayout.Space();
                GUILayout.Label("Stylization Options", EditorStyles.boldLabel);

                // Stylized Specular
                m_MaterialEditor.ShaderProperty(tcp2_SPEC_TOON, "Stylized Specular");
                if (tcp2_SPEC_TOON.floatValue > 0)
                {
                    m_MaterialEditor.ShaderProperty(tcp2_specSmooth, Styles.tcp2_specSmoothText.text, 1);
                    m_MaterialEditor.ShaderProperty(tcp2_SpecBlend, Styles.tcp2_SpecBlendText.text, 1);

                    EditorGUILayout.Space();
                }

                //Stylized Fresnel
                m_MaterialEditor.ShaderProperty(tcp2_STYLIZED_FRESNEL, "Stylized Fresnel");
                if (tcp2_STYLIZED_FRESNEL.floatValue > 0)
                {
                    m_MaterialEditor.ShaderProperty(tcp2_rimStrength, Styles.tcp2_rimStrengthText.text, 1);
                    m_MaterialEditor.ShaderProperty(tcp2_rimMin, Styles.tcp2_rimMinText.text, 1);
                    m_MaterialEditor.ShaderProperty(tcp2_rimMax, Styles.tcp2_rimMaxText.text, 1);

                    EditorGUILayout.Space();
                }

                //Outline
                useOutlineNew = EditorGUILayout.Toggle(new GUIContent("Outline", "Enable mesh-based outline"), useOutline);
                if (useOutline && hasOutlineShader)
                {
                    //Outline base props
                    m_MaterialEditor.ShaderProperty(tcp2_outlineColor, Styles.tcp2_outlineColorText.text, 1);
                    m_MaterialEditor.ShaderProperty(tcp2_outlineWidth, Styles.tcp2_outlineWidthText.text, 1);

                    m_MaterialEditor.ShaderProperty(tcp2_TCP2_OUTLINE_TEXTURED, "Textured Outline", 1);
                    if (tcp2_TCP2_OUTLINE_TEXTURED.floatValue > 0)
                    {
                        m_MaterialEditor.ShaderProperty(tcp2_TexLod, Styles.tcp2_TexLodText, 1);
                    }

                    m_MaterialEditor.ShaderProperty(tcp2_TCP2_OUTLINE_CONST_SIZE, "Constant Screen Size", 1);
                    m_MaterialEditor.ShaderProperty(tcp2_TCP2_ZSMOOTH_ON, "Z Smooth", 1);
                    if (tcp2_TCP2_ZSMOOTH_ON.floatValue > 0)
                    {
                        m_MaterialEditor.ShaderProperty(tcp2_ZSmooth, Styles.tcp2_ZSmoothText, 2);
                        m_MaterialEditor.ShaderProperty(tcp2_Offset1, Styles.tcp2_Offset1Text, 2);
                        m_MaterialEditor.ShaderProperty(tcp2_Offset2, Styles.tcp2_Offset2Text, 2);
                    }

                    //Blended Outline
                    EditorGUI.indentLevel++;
                    useOutlineBlendedNew = EditorGUILayout.Toggle(new GUIContent("Blended Outline", "Enable blended outline rather than opaque"), useOutlineBlended);
                    if (useOutlineBlended && hasOutlineBlendedShader)
                    {
                        EditorGUI.indentLevel++;
                        UnityEngine.Rendering.BlendMode blendSrc = (UnityEngine.Rendering.BlendMode)tcp2_srcBlendOutline.floatValue;
                        UnityEngine.Rendering.BlendMode blendDst = (UnityEngine.Rendering.BlendMode)tcp2_dstBlendOutline.floatValue;
                        EditorGUI.BeginChangeCheck();
                        blendSrc = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup(Styles.tcp2_srcBlendOutlineText, blendSrc);
                        blendDst = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup(Styles.tcp2_dstBlendOutlineText, blendDst);
                        if (EditorGUI.EndChangeCheck())
                        {
                            tcp2_srcBlendOutline.floatValue = (float)blendSrc;
                            tcp2_dstBlendOutline.floatValue = (float)blendDst;
                        }
                        EditorGUI.indentLevel--;
                    }
                    EditorGUI.indentLevel--;

                    //Outline Normals
                    int onIndex  = GetOutlineNormalsIndex();
                    int newIndex = onIndex;
                    EditorGUI.indentLevel++;
                    if (TCP2_Utils.ScreenWidthRetina < 390f)
                    {
                        newIndex = TCP2_Utils.ShaderKeywordRadioGeneric("Outline Normals", newIndex, new GUIContent[]
                        {
                            new GUIContent("R", "Use regular vertex normals"),
                            new GUIContent("VC", "Use vertex colors as normals (with smoothed mesh)"),
                            new GUIContent("T", "Use tangents as normals (with smoothed mesh)"),
                            new GUIContent("UV2", "Use second texture coordinates as normals (with smoothed mesh)"),
                        });
                    }
                    else if (TCP2_Utils.ScreenWidthRetina < 560f)
                    {
                        newIndex = TCP2_Utils.ShaderKeywordRadioGeneric("Outline Normals", newIndex, new GUIContent[]
                        {
                            new GUIContent("Regular", "Use regular vertex normals"),
                            new GUIContent("VColors", "Use vertex colors as normals (with smoothed mesh)"),
                            new GUIContent("Tangents", "Use tangents as normals (with smoothed mesh)"),
                            new GUIContent("UV2", "Use second texture coordinates as normals (with smoothed mesh)"),
                        });
                    }
                    else
                    {
                        newIndex = TCP2_Utils.ShaderKeywordRadioGeneric("Outline Normals", newIndex, new GUIContent[]
                        {
                            new GUIContent("Regular", "Use regular vertex normals"),
                            new GUIContent("Vertex Colors", "Use vertex colors as normals (with smoothed mesh)"),
                            new GUIContent("Tangents", "Use tangents as normals (with smoothed mesh)"),
                            new GUIContent("UV2", "Use second texture coordinates as normals (with smoothed mesh)"),
                        });
                    }
                    EditorGUI.indentLevel--;
                    if (newIndex != onIndex)
                    {
                        UpdateOutlineNormalsKeyword(newIndex);
                    }
                }

                GUILayout.Space(8f);
                GUILayout.EndVertical();

                // TCP2 End
                //----------------------------------------------------------------
            }

            GUILayout.Space(10f);

            //TCP2: set correct shader based on outline properties
            if (useOutline != useOutlineNew || useOutlineBlended != useOutlineBlendedNew)
            {
                SetTCP2Shader(useOutlineNew, useOutlineBlendedNew);
            }
            else if (useOutline != hasOutlineShader || useOutlineBlended != hasOutlineBlendedShader)
            {
                SetTCP2Shader(useOutline, useOutlineBlended);
            }
        }
        if (EditorGUI.EndChangeCheck())
        {
            foreach (var obj in blendMode.targets)
            {
                MaterialChanged((Material)obj, m_WorkflowMode);
            }
        }
    }
Example #15
0
 public BlendFactor(NativeBlendMode srcFactor, NativeBlendMode dstFactor, bool pma = false)
 {
     this.srcFactor = srcFactor;
     this.dstFactor = dstFactor;
     this.pma       = pma;
 }
Example #16
0
        public void CreateWMOObject()
        {
            if (terrainHandler.working)
            {
                WMO.WMOStruct data        = WMO.AllWMOData.Dequeue();
                GameObject    WMOinstance = new GameObject();

                terrainHandler.LoadedWMOIds[data.fileDataId] = WMOinstance;

                int nGroups = data.Info.nGroups;
                for (int g = 0; g < nGroups; g++)
                {
                    // group object //
                    GameObject GroupInstance = new GameObject();
                    GroupInstance.isStatic = true;
                    GroupInstance.transform.SetParent(terrainHandler.LoadedWMOIds[data.fileDataId].transform);
                    GroupInstance.name = data.groupsData[g].groupName;

                    LODGroup   Lodgroup  = GroupInstance.AddComponent <LODGroup>();
                    LOD[]      lods      = new LOD[1];
                    Renderer[] renderers = new Renderer[data.groupsData[g].nBatches];

                    // Batches //
                    for (int bn = 0; bn < data.groupsData[g].nBatches; bn++)
                    {
                        ////////////////////////////////
                        #region object

                        GameObject BatchInstance = new GameObject();
                        BatchInstance.isStatic = true;
                        BatchInstance.transform.SetParent(GroupInstance.transform);
                        BatchInstance.name = bn.ToString();
                        BatchInstance.transform.transform.eulerAngles = new Vector3(BatchInstance.transform.transform.eulerAngles.x, BatchInstance.transform.transform.eulerAngles.y - 180, GroupInstance.transform.transform.eulerAngles.z);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region mesh

                        BatchInstance.AddComponent <MeshRenderer>();
                        BatchInstance.GetComponent <MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
                        renderers[bn] = BatchInstance.GetComponent <MeshRenderer>();
                        BatchInstance.AddComponent <MeshFilter>();
                        Mesh bmesh = new Mesh();

                        uint batchVertSize = data.groupsData[g].batch_MaxIndex[bn] - data.groupsData[g].batch_MinIndex[bn] + 1;

                        Vector3[]  batchVertices      = new Vector3[batchVertSize];
                        Vector2[]  batchUVs           = new Vector2[batchVertSize];
                        Vector3[]  batchNormals       = new Vector3[batchVertSize];
                        Color32[]  batchVertexColors  = new Color32[batchVertSize];
                        List <int> batchTrianglesList = new List <int>();
                        int[]      batchTriangles;

                        int  arrayPosition     = 0;
                        uint batch_startVertex = data.groupsData[g].batch_MinIndex[bn];
                        uint batch_endVertex   = data.groupsData[g].batch_MaxIndex[bn];
                        for (uint v = batch_startVertex; v <= batch_endVertex; v++)
                        {
                            batchVertices[arrayPosition] = data.groupsData[g].vertices[v];
                            batchUVs[arrayPosition]      = data.groupsData[g].UVs[v];
                            batchNormals[arrayPosition]  = data.groupsData[g].normals[v];
                            if (!data.groupsData[g].flags.Hasvertexolors)
                            {
                                batchVertexColors[arrayPosition] = new Color32(127, 127, 127, 127);
                            }
                            else
                            {
                                batchVertexColors[arrayPosition] = data.groupsData[g].vertexColors[(int)v];
                            }
                            arrayPosition++;
                        }

                        uint batch_startIndex = data.groupsData[g].batch_StartIndex[bn];
                        uint batch_nIndices   = data.groupsData[g].batch_Count[bn];
                        for (uint idx = batch_startIndex; idx <= batch_startIndex + batch_nIndices - 2; idx = idx + 3)
                        {
                            uint in1 = data.groupsData[g].triangles[idx + 0];
                            uint in2 = data.groupsData[g].triangles[idx + 1];
                            uint in3 = data.groupsData[g].triangles[idx + 2];
                            int  a   = (int)(in1 - batch_startVertex);
                            int  b   = (int)(in2 - batch_startVertex);
                            int  c   = (int)(in3 - batch_startVertex);

                            batchTrianglesList.Add(a);
                            batchTrianglesList.Add(b);
                            batchTrianglesList.Add(c);
                        }
                        batchTrianglesList.Reverse();
                        batchTriangles = batchTrianglesList.ToArray();

                        bmesh.vertices  = batchVertices;
                        bmesh.uv        = batchUVs;
                        bmesh.normals   = batchNormals;
                        bmesh.triangles = batchTriangles;
                        bmesh.colors32  = batchVertexColors;
                        BatchInstance.GetComponent <MeshFilter>().mesh             = bmesh;
                        BatchInstance.GetComponent <MeshRenderer>().sharedMaterial = missingMaterial;

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region material

                        uint TextureFileDataId = data.texturePaths[data.materials[data.groupsData[g].batchMaterialIDs[bn]].TextureId1];
                        BatchInstance.GetComponent <Renderer>().material = WMOmaterials[(int)data.materials[data.groupsData[g].batchMaterialIDs[bn]].ShaderType];

                        ////////////////////////////////
                        #region Set Fragment Shader

                        WMOFragmentShader shader = data.materials[data.groupsData[g].batchMaterialIDs[bn]].ShaderType;
                        switch (shader)
                        {
                        case WMOFragmentShader.Diffuse:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderDiffuse", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Specular:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderSpecular", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Metal:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderMetal", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Env:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderEnv", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Opaque:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderOpaque", 1.0f);
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_AlphaToMask", 1.0f);
                            break;
                        }

                        default:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderDiffuse", 1.0f);
                            break;
                        }
                        }


                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Set Material Flags

                        // F_UNCULLED //
                        int Culling = 2; // on (only front)
                        if (data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNCULLED)
                        {
                            Culling = 0; // off (both sides_
                        }
                        BatchInstance.GetComponent <Renderer>().material.SetFloat("F_UNCULLED", Culling);
                        // F_UNLIT //
                        if (data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNLIT)
                        {
                            BatchInstance.GetComponent <Renderer>().material.EnableKeyword("F_UNLIT");
                        }
                        //BatchInstance.GetComponent<Renderer>().material.SetFloat("_F_UNLIT", data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNLIT ? 1 : 0);
                        // F_UNFOGGED //
                        BatchInstance.GetComponent <Renderer>().material.SetFloat("_F_UNFOGGED", data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNFOGGED ? 1 : 0);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Set Blending Mode

                        // set default blend: One Zero, basicly off
                        UnityEngine.Rendering.BlendMode source      = UnityEngine.Rendering.BlendMode.One;
                        UnityEngine.Rendering.BlendMode destination = UnityEngine.Rendering.BlendMode.Zero;

                        BlendingMode blending = data.materials[data.groupsData[g].batchMaterialIDs[bn]].BlendMode;

                        switch (blending)
                        {
                        case BlendingMode.Opaque:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.AlphaKey:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.Alpha:
                        {
                            source      = UnityEngine.Rendering.BlendMode.SrcAlpha;
                            destination = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                            break;
                        }

                        case BlendingMode.Additive:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.One;
                            break;
                        }

                        case BlendingMode.Modulate:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.Modulate2x:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.SrcColor;
                            break;
                        }

                        case BlendingMode.ModulateAdditive:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.One;
                            break;
                        }

                        default:
                        {
                            Debug.Log("BlendMode To Add: " + blending.ToString() + " Texture Used: " + TextureFileDataId);
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }
                        }
                        BatchInstance.GetComponent <Renderer>().material.SetInt("MySrcMode", (int)source);
                        BatchInstance.GetComponent <Renderer>().material.SetInt("MyDstMode", (int)destination);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Assign Textures

                        if (LoadedWMOTextures.ContainsKey(TextureFileDataId))
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetTexture("_MainTex", LoadedWMOTextures[TextureFileDataId]);
                        }
                        else
                        {
                            try
                            {
                                Texture2Ddata tdata = data.textureData[TextureFileDataId];
                                Texture2D     tex   = new Texture2D(tdata.width, tdata.height, tdata.textureFormat, tdata.hasMipmaps);
                                tex.LoadRawTextureData(tdata.TextureData);
                                tex.Apply();
                                LoadedWMOTextures[TextureFileDataId] = tex;
                                BatchInstance.GetComponent <Renderer>().material.SetTexture("_MainTex", tex);
                            }
                            catch (Exception ex)
                            {
                                Debug.Log("Error: Loading RawTextureData @ WMOhandler");
                                Debug.LogException(ex);
                            }
                        }
                        #endregion
                        ////////////////////////////////

                        #endregion
                        ////////////////////////////////
                    }

                    lods[0] = new LOD(.1f, renderers);
                    Lodgroup.SetLODs(lods);
                    Lodgroup.animateCrossFading = true;
                    Lodgroup.fadeMode           = LODFadeMode.SpeedTree;
                    Lodgroup.RecalculateBounds();
                }

                terrainHandler.LoadedWMOIds[data.fileDataId].transform.position   = data.position;
                terrainHandler.LoadedWMOIds[data.fileDataId].transform.rotation   = data.rotation;
                terrainHandler.LoadedWMOIds[data.fileDataId].transform.localScale = data.scale;
                if (data.uniqueID != -1)
                {
                    if (terrainHandler.ADTBlockWMOParents[data.uniqueID] != null)
                    {
                        terrainHandler.LoadedWMOIds[data.fileDataId].transform.SetParent(terrainHandler.ADTBlockWMOParents[data.uniqueID].transform);
                    }
                    else
                    {
                        Destroy(terrainHandler.LoadedWMOIds[data.fileDataId]);
                    }
                }
                terrainHandler.LoadedWMOIds[data.fileDataId].name = data.Info.wmoID.ToString();

                terrainHandler.frameBusy = false;
            }
        }