diff --git a/com.unity.toonshader/Editor/Scripts/GUI/UnityToon3Das2DGUI.cs b/com.unity.toonshader/Editor/Scripts/GUI/UnityToon3Das2DGUI.cs index e316c6433..8f15cf96f 100644 --- a/com.unity.toonshader/Editor/Scripts/GUI/UnityToon3Das2DGUI.cs +++ b/com.unity.toonshader/Editor/Scripts/GUI/UnityToon3Das2DGUI.cs @@ -25,6 +25,7 @@ public override void OnGUI(MaterialEditor mEditor, MaterialProperty[] props) { } EditorGUI.BeginChangeCheck(); + DrawShaderSettingsGUI(mEditor, mats, m_materialPropertyUIElements, ref m_shaderSettingsFoldout, ref m_stencilFoldout); DrawThreeColorsGUI(mEditor, mats, m_materialPropertyUIElements, ref m_colorsFoldout); DrawShadingGUI(mEditor, mats, m_materialPropertyUIElements, ref m_shadingFoldout); DrawLightingGUI(mEditor, mats, m_materialPropertyUIElements, ref m_lightingFoldout); @@ -49,6 +50,8 @@ public override void OnGUI(MaterialEditor mEditor, MaterialProperty[] props) { void RefreshFoldouts(Material mat, Dictionary uiElements) { + m_shaderSettingsFoldout = false; + m_stencilFoldout = true; m_colorsFoldout = true; m_shadingFoldout = true; @@ -236,6 +239,34 @@ static void DrawOutlineGUI(MaterialEditor mEditor, Material[] mats, Dictionary uiElements, ref bool foldout, ref bool stencilFoldout) { + + ToonEditorGUIUtility.DrawFoldoutGUI(ref foldout, SHADER_SETTINGS_FOLDOUT); + if (!foldout) + return; + + Rect rect = ToonEditorGUIUtility.GetIndentedHeaderRect(INDENT_SIZE); + stencilFoldout = EditorGUI.BeginFoldoutHeaderGroup(rect, stencilFoldout, "Stencil"); + if (stencilFoldout) { + const int INDENT_DEPTH = 2; + EditorGUI.indentLevel += (INDENT_SIZE * INDENT_DEPTH); + ToonEditorGUIUtility.DrawRangePropertyGUI(mEditor, uiElements[ToonConstants.SHADER_PROP_STENCIL_REF]); + ToonEditorGUIUtility.DrawIntPopupGUI(mEditor, mats, uiElements[ToonConstants.SHADER_PROP_STENCIL_COMP], + ToonEditorConstants.STENCIL_COMP_ENUMS, ToonEditorConstants.STENCIL_COMP_VALUES, out int _); + ToonEditorGUIUtility.DrawIntPopupGUI(mEditor, mats, uiElements[ToonConstants.SHADER_PROP_STENCIL_OP_PASS], + ToonEditorConstants.STENCIL_OP_ENUMS, ToonEditorConstants.STENCIL_OP_VALUES, out int _); + ToonEditorGUIUtility.DrawIntPopupGUI(mEditor, mats, uiElements[ToonConstants.SHADER_PROP_STENCIL_OP_FAIL], + ToonEditorConstants.STENCIL_OP_ENUMS, ToonEditorConstants.STENCIL_OP_VALUES, out int _); + EditorGUI.indentLevel -= (INDENT_SIZE * INDENT_DEPTH); + } + EditorGUI.EndFoldoutHeaderGroup(); + + EditorGUILayout.Space(); + } + //---------------------------------------------------------------------------------------------------------------------- void InitMaterialPropertyUIElements(MaterialProperty[] allProps) { @@ -537,6 +568,24 @@ public override void AssignNewShaderToMaterial( }, //Outline End + // Shader Settings + new MaterialUIElement { + mainPropertyName = new MaterialName(ToonConstants.SHADER_PROP_STENCIL_REF), + label = new GUIContent("Stencil Ref", "Stencil reference value (0–255)."), + }, + new MaterialUIElement { + mainPropertyName = new MaterialName(ToonConstants.SHADER_PROP_STENCIL_COMP), + label = new GUIContent("Stencil Compare", "Stencil comparison function."), + }, + new MaterialUIElement { + mainPropertyName = new MaterialName(ToonConstants.SHADER_PROP_STENCIL_OP_PASS), + label = new GUIContent("Pass Op", "What to do when stencil test passes."), + }, + new MaterialUIElement { + mainPropertyName = new MaterialName(ToonConstants.SHADER_PROP_STENCIL_OP_FAIL), + label = new GUIContent("Fail Op", "What to do when stencil test fails."), + }, + }; @@ -551,6 +600,10 @@ internal enum HighlightMode { private static readonly GUIContent[] m_highlightModeEnums = ToonEnumUtility.ToInspectorNamesAsGUIContent(typeof(HighlightMode)); private static readonly int[] m_highlightModeValues = ToonEnumUtility.ToIntValues(typeof(HighlightMode)); + + static readonly GUIContent SHADER_SETTINGS_FOLDOUT = + EditorGUIUtility.TrTextContent("Shader Settings", "Low-level shader settings such as stencil."); + static readonly GUIContent COLORS_FOLDOUT = EditorGUIUtility.TrTextContent("Colors", "Colors for basic cel-shading settings in Unity Toon Shader."); @@ -559,6 +612,8 @@ internal enum HighlightMode { static readonly GUIContent LIGHTING_FOLDOUT = EditorGUIUtility.TrTextContent("Lighting", "Lighting settings."); + bool m_shaderSettingsFoldout = false; + bool m_stencilFoldout = true; bool m_colorsFoldout = true; bool m_shadingFoldout = true; bool m_normalMapFoldout = false; diff --git a/com.unity.toonshader/Editor/Scripts/ToonEditorConstants.cs b/com.unity.toonshader/Editor/Scripts/ToonEditorConstants.cs index a367ca2e5..8eb1ff75a 100644 --- a/com.unity.toonshader/Editor/Scripts/ToonEditorConstants.cs +++ b/com.unity.toonshader/Editor/Scripts/ToonEditorConstants.cs @@ -1,6 +1,7 @@ using System.IO; using Unity.Rendering.Toon; +using UnityEngine; namespace UnityEditor.Rendering.Toon { @@ -13,9 +14,14 @@ internal static class ToonEditorConstants { internal static readonly string TOON_SHADER_PATH = Path.Combine(PACKAGE_PATH,"Runtime/Shaders/UnityToon.shader").Replace('\\','/'); - internal static readonly string TOON_TESS_SHADER_PATH = + internal static readonly string TOON_TESS_SHADER_PATH = Path.Combine(PACKAGE_PATH,"Runtime/Shaders/UnityToonTessellation.shader").Replace('\\','/'); - + + internal static readonly GUIContent[] STENCIL_COMP_ENUMS = ToonEnumUtility.ToInspectorNamesAsGUIContent(typeof(UnityEngine.Rendering.CompareFunction)); + internal static readonly int[] STENCIL_COMP_VALUES = ToonEnumUtility.ToIntValues(typeof(UnityEngine.Rendering.CompareFunction)); + internal static readonly GUIContent[] STENCIL_OP_ENUMS = ToonEnumUtility.ToInspectorNamesAsGUIContent(typeof(UnityEngine.Rendering.StencilOp)); + internal static readonly int[] STENCIL_OP_VALUES = ToonEnumUtility.ToIntValues(typeof(UnityEngine.Rendering.StencilOp)); + } diff --git a/com.unity.toonshader/Editor/Scripts/Utilities/ToonEditorGUIUtility.cs b/com.unity.toonshader/Editor/Scripts/Utilities/ToonEditorGUIUtility.cs index 8b7f1cd75..f908c4542 100644 --- a/com.unity.toonshader/Editor/Scripts/Utilities/ToonEditorGUIUtility.cs +++ b/com.unity.toonshader/Editor/Scripts/Utilities/ToonEditorGUIUtility.cs @@ -141,6 +141,13 @@ internal static bool DrawFoldoutWithToggleGUI(MaterialEditor mEditor, Material[] } + internal static Rect GetIndentedHeaderRect(int indentLevel, bool hasLabel = false) { + EditorGUI.indentLevel += indentLevel; + Rect rect = EditorGUI.IndentedRect(EditorGUILayout.GetControlRect(hasLabel, EditorGUIUtility.singleLineHeight)); + EditorGUI.indentLevel -= indentLevel; + return rect; + } + static void DrawBGRect(Rect lineRect) { float initialPadding = lineRect.x; diff --git a/com.unity.toonshader/Runtime/Scripts/ToonConstants.cs b/com.unity.toonshader/Runtime/Scripts/ToonConstants.cs index 3d9ca26e3..0ce2463c4 100644 --- a/com.unity.toonshader/Runtime/Scripts/ToonConstants.cs +++ b/com.unity.toonshader/Runtime/Scripts/ToonConstants.cs @@ -79,7 +79,12 @@ internal static class ToonConstants { internal const string SHADER_PROP_OUTLINE_FAR = "_OutlineFar"; internal const string SHADER_PROP_OUTLINE_USE_NORMAL_MAP = "_Outline_UseNormalMap"; internal const string SHADER_PROP_OUTLINE_NORMAL_MAP = "_Outline_NormalMap"; - + + internal const string SHADER_PROP_STENCIL_REF = "_StencilRef"; + internal const string SHADER_PROP_STENCIL_COMP = "_StencilComp"; + internal const string SHADER_PROP_STENCIL_OP_PASS = "_StencilOpPass"; + internal const string SHADER_PROP_STENCIL_OP_FAIL = "_StencilOpFail"; + internal static readonly int SHADER_PROPERTY_MATERIAL_VERSION = Shader.PropertyToID("_ToonMaterialVersion"); internal const string SHADER_PROP_DIRECTIONAL_LIGHT_DIRECTION = "_DirectionalLight_Direction"; diff --git a/com.unity.toonshader/Runtime/Shaders/URP/ToonURP_3Das2D.shader b/com.unity.toonshader/Runtime/Shaders/URP/ToonURP_3Das2D.shader index db9d6e907..bdffc899a 100644 --- a/com.unity.toonshader/Runtime/Shaders/URP/ToonURP_3Das2D.shader +++ b/com.unity.toonshader/Runtime/Shaders/URP/ToonURP_3Das2D.shader @@ -54,7 +54,16 @@ Shader "Toon/Toon 3D as 2D (URP)"{ _Outline_UseNormalMap ("Outline: Use Outline Normal Map", Integer ) = 0 _Outline_NormalMap ("Outline Normal Map", 2D) = "bump" {} [HideInInspector] _ToonMaterialVersion ("Toon Material Version", Integer ) = 0 + + // Stencil Properties + + // Put this in the last bit of our stencil value for maximum compatibility with sprite mask + [IntRange] _StencilRef ("Stencil Reference", Range(0, 255)) = 128 + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Stencil Compare", Integer) = 8 // Always + [Enum(UnityEngine.Rendering.StencilOp)] _StencilOpPass ("Stencil Pass Op", Integer) = 2 // Replace + [Enum(UnityEngine.Rendering.StencilOp)] _StencilOpFail ("Stencil Fail Op", Integer) = 0 // Keep + } SubShader{ @@ -70,9 +79,10 @@ Shader "Toon/Toon 3D as 2D (URP)"{ ZWrite On Stencil{ - Ref 128 // Put this in the last bit of our stencil value for maximum compatibility with sprite mask - Comp always - Pass replace + Ref[_StencilRef] + Comp[_StencilComp] + Pass[_StencilOpPass] + Fail[_StencilOpFail] } Pass{ @@ -317,15 +327,6 @@ Shader "Toon/Toon 3D as 2D (URP)"{ // Cull [_SRPDefaultUnlitColMode] // ColorMask [_SPRDefaultUnlitColorMask] Blend SrcAlpha OneMinusSrcAlpha -// Stencil -// { -// Ref[_StencilNo] -// Comp[_StencilComp] -// Pass[_StencilOpPass] -// Fail[_StencilOpFail] -// -// } - HLSLPROGRAM #pragma target 3.0