diff --git a/Editor/MeterialEditor/Helpers.meta b/Editor/MeterialEditor/Helpers.meta new file mode 100644 index 0000000..7e28dc8 --- /dev/null +++ b/Editor/MeterialEditor/Helpers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f00671385fbbb674495b9f0b3d6dbe07 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/MeterialEditor/Helpers/UTSShaderGUIHelpers.cs b/Editor/MeterialEditor/Helpers/UTSShaderGUIHelpers.cs new file mode 100644 index 0000000..ff326ad --- /dev/null +++ b/Editor/MeterialEditor/Helpers/UTSShaderGUIHelpers.cs @@ -0,0 +1,20 @@ +namespace Misaki.HdrpToon.Editor +{ + internal static class UTSShaderGUIHelpers + { + public static ShadingMode GetShadingMode(this UTSShaderGUI shaderGUI) + { + return (ShadingMode)shaderGUI.GetUIScope().FindProperty("_Shading_Mode").floatValue; + } + + public static PBRMode GetPBRMode(this UTSShaderGUI shaderGUI) + { + return (PBRMode)shaderGUI.GetUIScope().FindProperty("_PBR_Mode").floatValue; + } + + public static bool HasFeature(this UTSShaderGUI shaderGUI, SurfaceFeatureFlags feature) + { + return ((SurfaceFeatureFlags)shaderGUI.GetUIScope().FindProperty("_Surface_Features").floatValue & feature) != 0; + } + } +} \ No newline at end of file diff --git a/Editor/MeterialEditor/Helpers/UTSShaderGUIHelpers.cs.meta b/Editor/MeterialEditor/Helpers/UTSShaderGUIHelpers.cs.meta new file mode 100644 index 0000000..b905bf6 --- /dev/null +++ b/Editor/MeterialEditor/Helpers/UTSShaderGUIHelpers.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4aa9e028e20a2014ab0e2a3ea6541f0e \ No newline at end of file diff --git a/Editor/MeterialEditor/ShaderGUIExpandable.cs b/Editor/MeterialEditor/ShaderGUIExpandable.cs index c12147c..7ac9d4e 100644 --- a/Editor/MeterialEditor/ShaderGUIExpandable.cs +++ b/Editor/MeterialEditor/ShaderGUIExpandable.cs @@ -4,9 +4,9 @@ namespace Misaki.HdrpToon.Editor { SurfaceOptions = 1 << 0, ShadingColor = 1 << 1, - ShadingGrade = 1 << 2, + Shadow = 1 << 2, MaterialFeature = 1 << 3, - PBR = 1 << 4, + SurfaceInputs = 1 << 4, AmbientMode = 1 << 5, Highlight = 1 << 6, Rimlight = 1 << 7, diff --git a/Editor/MeterialEditor/UIScopes/PBRScope.cs.meta b/Editor/MeterialEditor/UIScopes/PBRScope.cs.meta deleted file mode 100644 index cdd8ef9..0000000 --- a/Editor/MeterialEditor/UIScopes/PBRScope.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f611f3d462b5414f9241ed80e4f1d0bb -timeCreated: 1738325165 \ No newline at end of file diff --git a/Editor/MeterialEditor/UIScopes/ShadowScope.cs b/Editor/MeterialEditor/UIScopes/ShadowScope.cs new file mode 100644 index 0000000..9f07f62 --- /dev/null +++ b/Editor/MeterialEditor/UIScopes/ShadowScope.cs @@ -0,0 +1,57 @@ +using Misaki.ShaderGUI; +using UnityEditor; +using UnityEngine; + +namespace Misaki.HdrpToon.Editor +{ + internal class ShadowScope : MaterialUIScope + { + private static class Properties + { + public static MaterialProperty receiveLightShadow; + public static MaterialProperty receiveScreenSpaceShadow; + public static MaterialProperty receiveHairShadow; + + public static MaterialProperty shadowDistanceBias; + public static MaterialProperty shadowNormalBias; + } + + private static class Styles + { + public static readonly GUIContent receiveLightShadowText = new("Receive Light Shadow", "Enable to receive shadow from light."); + public static readonly GUIContent receiveHairShadowText = new("Receive Hair Shadow", "Enable to receive shadow from hair shadow caster"); + + public static readonly GUIContent receiveScreenSpaceShadowText = new("Receive Screen Space Shadow", "Enable to receive screen space shadow."); + public static readonly GUIContent lightShadowBiasText = new("Light Shadow Bias", "Specifies the bias of the light shadow."); + public static readonly GUIContent lightShadowNormalBiasText = new("Light Shadow Normal Bias", "Specifies the normal bias of the light shadow."); + } + + protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Shadow; + + protected override GUIContent Header => EditorGUIUtility.TrTextContent("Shadow Settings"); + + public override void LoadMaterialProperties() + { + Properties.receiveLightShadow = FindProperty("_Receive_Light_Shadow"); + Properties.receiveScreenSpaceShadow = FindProperty("_Receive_Screen_Space_Shadow"); + Properties.receiveHairShadow = FindProperty("_Receive_Hair_Shadow"); + + Properties.shadowDistanceBias = FindProperty("_ShadowDistanceBias"); + Properties.shadowNormalBias = FindProperty("_ShadowNormalBias"); + } + + protected override void DrawContent() + { + editor.ShaderProperty(Properties.receiveLightShadow, Styles.receiveLightShadowText); + if (Properties.receiveLightShadow.GetBooleanValue()) + { + editor.ShaderProperty(Properties.receiveScreenSpaceShadow, Styles.receiveScreenSpaceShadowText); + } + editor.ShaderProperty(Properties.receiveHairShadow, Styles.receiveHairShadowText); + + EditorGUILayout.Space(); + editor.ShaderProperty(Properties.shadowDistanceBias, Styles.lightShadowBiasText); + editor.ShaderProperty(Properties.shadowNormalBias, Styles.lightShadowNormalBiasText); + } + } +} \ No newline at end of file diff --git a/Editor/MeterialEditor/UIScopes/ShadowScope.cs.meta b/Editor/MeterialEditor/UIScopes/ShadowScope.cs.meta new file mode 100644 index 0000000..3c7c805 --- /dev/null +++ b/Editor/MeterialEditor/UIScopes/ShadowScope.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 8f9bb5393aec4e648a1c3b2ba0d566c3 \ No newline at end of file diff --git a/Editor/MeterialEditor/UIScopes/PBRScope.cs b/Editor/MeterialEditor/UIScopes/SurfaceInputsScope.cs similarity index 61% rename from Editor/MeterialEditor/UIScopes/PBRScope.cs rename to Editor/MeterialEditor/UIScopes/SurfaceInputsScope.cs index d7b2d8f..d13f539 100644 --- a/Editor/MeterialEditor/UIScopes/PBRScope.cs +++ b/Editor/MeterialEditor/UIScopes/SurfaceInputsScope.cs @@ -1,17 +1,14 @@ using Misaki.ShaderGUI; -using System.Linq; using UnityEditor; using UnityEditor.Rendering; using UnityEngine; -using UnityEngine.Rendering; namespace Misaki.HdrpToon.Editor { - public class PBRScope : MaterialUIScope + public class SurfaceInputsScope : MaterialUIScope { private static class Properties { - public static MaterialProperty PbrMode; public static MaterialProperty NormalMap; public static MaterialProperty NormalMapScale; public static MaterialProperty MaskMap; @@ -35,13 +32,11 @@ namespace Misaki.HdrpToon.Editor private static class Styles { - public static readonly GUIContent PbrModeText = new("PBR Mode", "PBR Mode"); - public static readonly GUIContent NormalMapText = new("Normal Map", "A texture that dictates the bumpiness of the material."); public static readonly GUIContent MaskMapText = new("Mask Map", - "A texture that dictates the physical properties of the material. R: Metallic, G: Occlusion, A: Smoothness"); + "A texture that dictates the physical properties of the material. R channel for metallic, G channel for ambient occlusion, A channel for smoothness"); public static readonly GUIContent MetallicText = @@ -75,21 +70,11 @@ namespace Misaki.HdrpToon.Editor "Feather and step value of Toon Specular"); } - private enum PBRMode - { - Off, - Standard, - Anisotropy, - KKHair, - Toon - } - - protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.PBR; - protected override GUIContent Header => new("PBR Settings"); + protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.SurfaceInputs; + protected override GUIContent Header => new("Surface Inputs"); public override void LoadMaterialProperties() { - Properties.PbrMode = FindProperty("_PBR_Mode"); Properties.NormalMap = FindProperty("_NormalMap"); Properties.NormalMapScale = FindProperty("_NormalScale"); Properties.MaskMap = FindProperty("_MaskMap"); @@ -113,62 +98,62 @@ namespace Misaki.HdrpToon.Editor protected override void DrawContent() { - editor.ShaderProperty(Properties.PbrMode, Styles.PbrModeText); - EditorGUILayout.Space(); - editor.TexturePropertySingleLine(Styles.NormalMapText, Properties.NormalMap, Properties.NormalMapScale); - var materials = editor.GetMaterials().ToList(); - foreach (var material in materials) - { - material.SetKeyword(new LocalKeyword(material.shader, "_NORMAL_MAP"), - Properties.NormalMap.textureValue != null); - } + editor.KeywordTexturePropertySingleLine(Styles.NormalMapText, Properties.NormalMap, Properties.NormalMapScale); + //var materials = editor.GetMaterials().ToList(); + //foreach (var material in materials) + //{ + // material.SetKeyword(new LocalKeyword(material.shader, "_NORMAL_MAP"), + // Properties.NormalMap.textureValue != null); + //} - var pbrMode = (PBRMode)Properties.PbrMode.floatValue; + var pbrMode = SurfaceOptionsScope.GetPBRMode(); if (pbrMode != PBRMode.Off) { - editor.TexturePropertySingleLine(Styles.MaskMapText, Properties.MaskMap); - - if (Properties.MaskMap.textureValue == null) + if (editor.KeywordTexturePropertySingleLine(Styles.MaskMapText, Properties.MaskMap)) { - foreach (var material in materials) - { - material.DisableKeyword(new LocalKeyword(material.shader, "_MASK_MAP")); - } + //foreach (var material in materials) + //{ + // material.EnableKeyword(new LocalKeyword(material.shader, "_MASKMAP")); + //} - if (pbrMode != PBRMode.KKHair) - editor.ShaderProperty(Properties.Metallic, Styles.MetallicText); - editor.ShaderProperty(Properties.Smoothness, Styles.SmoothnessText); + editor.MinMaxShaderProperty(Properties.MetallicRemapMin, Properties.MetallicRemapMax, 0, 1, Styles.MetallicRemap); + editor.MinMaxShaderProperty(Properties.AORemapMin, Properties.AORemapMax, 0, 1, Styles.AORemap); + editor.MinMaxShaderProperty(Properties.RoughnessRemapMin, Properties.RoughnessRemapMax, 0, 1, Styles.RoughnessRemap); } else { - foreach (var material in materials) + //foreach (var material in materials) + //{ + // material.DisableKeyword(new LocalKeyword(material.shader, "_MASKMAP")); + //} + + if (pbrMode != PBRMode.KKHair) { - material.EnableKeyword(new LocalKeyword(material.shader, "_MASK_MAP")); + editor.ShaderProperty(Properties.Metallic, Styles.MetallicText); } - editor.MinMaxShaderProperty(Properties.MetallicRemapMin, Properties.MetallicRemapMax, 0, 1, - Styles.MetallicRemap); - editor.MinMaxShaderProperty(Properties.AORemapMin, Properties.AORemapMax, 0, 1, Styles.AORemap); - editor.MinMaxShaderProperty(Properties.RoughnessRemapMin, Properties.RoughnessRemapMax, 0, 1, - Styles.RoughnessRemap); + editor.ShaderProperty(Properties.Smoothness, Styles.SmoothnessText); } } else { - foreach (var material in materials) - { - material.DisableKeyword(new LocalKeyword(material.shader, "_MASK_MAP")); - material.DisableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP")); - material.DisableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP")); - } + editor.SetKeyword("_MASKMAP", false); + editor.SetKeyword("_ANISOTROPY_MAP", false); + editor.SetKeyword("_SPECULAR_COLOR_MAP", false); + + //foreach (var material in materials) + //{ + // material.DisableKeyword(new LocalKeyword(material.shader, "_MASKMAP")); + // material.DisableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP")); + // material.DisableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP")); + //} } switch (pbrMode) { case PBRMode.Anisotropy or PBRMode.KKHair: { - editor.TexturePropertySingleLine(Styles.AnisotropyMapText, Properties.AnisotropyMap, - Properties.Anisotropy); + editor.KeywordTexturePropertySingleLine(Styles.AnisotropyMapText, Properties.AnisotropyMap, Properties.Anisotropy); if (pbrMode == PBRMode.KKHair) { editor.ShaderProperty(Properties.KKColor, Styles.KKColorText); @@ -178,44 +163,42 @@ namespace Misaki.HdrpToon.Editor EditorGUILayout.Space(); EditorGUILayout.LabelField("Anisotropy Map only ST"); editor.TextureScaleOffsetProperty(Properties.AnisotropyMap); - if (Properties.AnisotropyMap.textureValue == null) - { - foreach (var material in materials) - { - material.DisableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP")); - } - } - else - { - foreach (var material in materials) - { - material.EnableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP")); - } - } + //if (Properties.AnisotropyMap.textureValue == null) + //{ + // foreach (var material in materials) + // { + // material.DisableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP")); + // } + //} + //else + //{ + // foreach (var material in materials) + // { + // material.EnableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP")); + // } + //} break; } case PBRMode.Toon: { - editor.TexturePropertySingleLine(Styles.SpecularColorMapText, Properties.SpecularColorMap, - Properties.SpecularColor); - if (Properties.SpecularColorMap.textureValue == null) - { - foreach (var material in materials) - { - material.DisableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP")); - } - } - else - { - foreach (var material in materials) - { - material.EnableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP")); - } - } + editor.KeywordTexturePropertySingleLine(Styles.SpecularColorMapText, Properties.SpecularColorMap, Properties.SpecularColor); + //if (Properties.SpecularColorMap.textureValue == null) + //{ + // foreach (var material in materials) + // { + // material.DisableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP")); + // } + //} + //else + //{ + // foreach (var material in materials) + // { + // material.EnableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP")); + // } + //} - editor.MinMaxShaderProperty(Properties.SpecularFeather, Properties.SpecularStep, 0, 1, - Styles.SpecRemap); + editor.MinMaxShaderProperty(Properties.SpecularFeather, Properties.SpecularStep, 0, 1, Styles.SpecRemap); break; } } diff --git a/Editor/MeterialEditor/UIScopes/SurfaceInputsScope.cs.meta b/Editor/MeterialEditor/UIScopes/SurfaceInputsScope.cs.meta new file mode 100644 index 0000000..31938d6 --- /dev/null +++ b/Editor/MeterialEditor/UIScopes/SurfaceInputsScope.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 184fb730617fcf24592d8e6c49e2029a \ No newline at end of file diff --git a/Editor/MeterialEditor/UIScopes/SurfaceOptionsScope.cs b/Editor/MeterialEditor/UIScopes/SurfaceOptionsScope.cs index 0376e2c..1f19230 100644 --- a/Editor/MeterialEditor/UIScopes/SurfaceOptionsScope.cs +++ b/Editor/MeterialEditor/UIScopes/SurfaceOptionsScope.cs @@ -18,7 +18,6 @@ namespace Misaki.HdrpToon.Editor public static MaterialProperty materialType; public static MaterialProperty pbrMode; - public static MaterialProperty receiveHairShadow; public static MaterialProperty hairBlendingTarget; public static MaterialProperty surfaceFeatures; } @@ -35,7 +34,6 @@ namespace Misaki.HdrpToon.Editor public static readonly GUIContent materialTypeText = new("Material Type", "Specifies the material type."); public static readonly GUIContent pbrModeText = new("PBR Mode", "Specifies PBR model mode."); - public static readonly GUIContent receiveHairShadowText = new("Receive Hair Shadow", "Enable to receive shadow from hair shadow caster"); public static readonly GUIContent hairBlendingTargetText = new("Hair Blending Target", "Enable to be blended with hair"); public static readonly GUIContent surfaceFeaturesText = new("Surface Features", "Specifies the surface features."); } @@ -49,6 +47,11 @@ namespace Misaki.HdrpToon.Editor return (ShadingMode)Properties.shadingMode.floatValue; } + public static PBRMode GetPBRMode() + { + return (PBRMode)Properties.pbrMode.floatValue; + } + public static bool HasFeature(SurfaceFeatureFlags feature) { return ((SurfaceFeatureFlags)Properties.surfaceFeatures.floatValue & feature) != 0; @@ -66,7 +69,6 @@ namespace Misaki.HdrpToon.Editor Properties.materialType = FindProperty("_Material_Type"); Properties.pbrMode = FindProperty("_PBR_Mode"); - Properties.receiveHairShadow = FindProperty("_Receive_Hair_Shadow"); Properties.hairBlendingTarget = FindProperty("_HairBlendingTarget"); Properties.surfaceFeatures = FindProperty("_SurfaceFeatures"); } @@ -88,8 +90,6 @@ namespace Misaki.HdrpToon.Editor editor.ShaderProperty(Properties.materialType, Styles.materialTypeText); editor.ShaderProperty(Properties.pbrMode, Styles.pbrModeText); - editor.ShaderProperty(Properties.receiveHairShadow, Styles.receiveHairShadowText); - EditorGUI.BeginChangeCheck(); editor.ShaderProperty(Properties.hairBlendingTarget, Styles.hairBlendingTargetText); if (EditorGUI.EndChangeCheck()) diff --git a/Editor/MeterialEditor/UTSShaderGUI.cs b/Editor/MeterialEditor/UTSShaderGUI.cs index 6966a50..56958cd 100644 --- a/Editor/MeterialEditor/UTSShaderGUI.cs +++ b/Editor/MeterialEditor/UTSShaderGUI.cs @@ -26,7 +26,8 @@ namespace Misaki.HdrpToon.Editor { AddUIScope(new SurfaceOptionsScope()); AddUIScope(new ShadingColorScope()); - AddUIScope(new PBRScope()); + AddUIScope(new ShadowScope()); + AddUIScope(new SurfaceInputsScope()); AddUIScope(new RimLightScope()); AddUIScope(new AngelRingScope()); AddUIScope(new OutlineScope()); diff --git a/Runtime/Models/ShaderKeywordEnum.cs b/Runtime/Models/ShaderKeywordEnum.cs new file mode 100644 index 0000000..0c66a13 --- /dev/null +++ b/Runtime/Models/ShaderKeywordEnum.cs @@ -0,0 +1,17 @@ +namespace Misaki.HdrpToon +{ + internal enum ShadingMode + { + Standard, + SDF, + } + + internal enum PBRMode + { + Off, + Standard, + Anisotropy, + KKHair, + Toon + } +} \ No newline at end of file diff --git a/Runtime/Models/ShadingMode.cs.meta b/Runtime/Models/ShaderKeywordEnum.cs.meta similarity index 100% rename from Runtime/Models/ShadingMode.cs.meta rename to Runtime/Models/ShaderKeywordEnum.cs.meta diff --git a/Runtime/Models/ShadingMode.cs b/Runtime/Models/ShadingMode.cs deleted file mode 100644 index dcbaedc..0000000 --- a/Runtime/Models/ShadingMode.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Misaki.HdrpToon -{ - internal enum ShadingMode - { - Standard, - SDF, - } -} \ No newline at end of file diff --git a/Runtime/Models/SurfaceFeatureFlags.cs b/Runtime/Models/SurfaceFeatureFlags.cs index 2b8420d..d7307da 100644 --- a/Runtime/Models/SurfaceFeatureFlags.cs +++ b/Runtime/Models/SurfaceFeatureFlags.cs @@ -5,12 +5,12 @@ namespace Misaki.HdrpToon { [Flags] [GenerateHLSL(PackingRules.Exact)] - public enum SurfaceFeatureFlags : uint + public enum SurfaceFeatureFlags { None = 0, RimLight = 1 << 0, Stocking = 1 << 1, AngelRing = 1 << 2, - Outline = 1 << 3, + Outline = 1 << 3 } } \ No newline at end of file diff --git a/Runtime/Models/SurfaceFeatureFlags.cs.hlsl b/Runtime/Models/SurfaceFeatureFlags.cs.hlsl index 37d6e40..02d3c72 100644 --- a/Runtime/Models/SurfaceFeatureFlags.cs.hlsl +++ b/Runtime/Models/SurfaceFeatureFlags.cs.hlsl @@ -7,7 +7,6 @@ // // Misaki.HdrpToon.SurfaceFeatureFlags: static fields // -#define SURFACEFEATUREFLAGS_NONE (0) #define SURFACEFEATUREFLAGS_RIM_LIGHT (1) #define SURFACEFEATUREFLAGS_STOCKING (2) #define SURFACEFEATUREFLAGS_ANGEL_RING (4) diff --git a/Runtime/Shaders/HDRPToon.shader b/Runtime/Shaders/HDRPToon.shader index a6a6525..beedbe5 100644 --- a/Runtime/Shaders/HDRPToon.shader +++ b/Runtime/Shaders/HDRPToon.shader @@ -16,28 +16,6 @@ Shader "HDRP/Toon" [HideInInspector] _utsVersionY("VersionY", Float) = 7 [HideInInspector] _utsVersionZ("VersionZ", Float) = 6 - _HairBlendingMap("HairBlendingMap", 2D) = "black" {} - - _Metallic("_Metallic", Range(0.0, 1.0)) = 0 - _Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 - _MaskMap("MaskMap", 2D) = "white" {} - //[ToggleUI, HideInInspector] _Use_MaskMap("Use MaskMap", Int) = 0 - _MetallicRemapMin("MetalicRemapMin", Float) = 0.0 - _MetallicRemapMax("MetalicRemapMax", Float) = 1.0 - _SmoothnessRemapMin("RoughnessRemapMin", Float) = 0.0 - _SmoothnessRemapMax("RoughnessRemapMax", Float) = 1.0 - _AlphaRemapMin("AlphaRemapMin", Float) = 0.0 // HDRP 14 - _AlphaRemapMax("AlphaRemapMax", Float) = 1.0 // HDRP 14 - _AORemapMin("AORemapMin", Float) = 0.0 - _AORemapMax("AORemapMax", Float) = 1.0 - _SSSLutMap("SSSLutMap", 2D) = "white" {} - [ToggleUI, HideInInspector] _Use_SSSLut("Use SSSLut", Int) = 0 - _SSSIntensity("SSSIntensity", Range(0.0, 3.0)) = 1.0 - - _NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map - _NormalMapOS("NormalMapOS", 2D) = "white" {} // Object space normal map - no good default value - _NormalScale("_NormalScale", Range(0.0, 8.0)) = 1 - _BentNormalMap("_BentNormalMap", 2D) = "bump" {} _BentNormalMapOS("_BentNormalMapOS", 2D) = "white" {} @@ -268,7 +246,6 @@ Shader "HDRP/Toon" [KeywordEnum(Standard, SDF)] _Shading_Mode("Shade Grade mode", Float) = 0 [KeywordEnum(Standard, FrontHair, Face, Eye)] _Material_Type("Material Type", int) = 0 [KeywordEnum(Off, Standard, Anisotropy, KKHair, Toon)] _PBR_Mode("PBR Mode", int) = 0 - [Toggle] _Receive_Hair_Shadow("Receive HairS hadow", Float) = 0 [ToggleUI] _HairBlendingTarget("Hair Blending Target", Float) = 0 _SurfaceFeatures("Surface Features", Float) = 0 @@ -298,6 +275,37 @@ Shader "HDRP/Toon" _SDFShadowSmoothLevel("SDFShadowSmoothLevel", Range(0.0, 0.1)) = 0.02 _SDFHighlightStrength("SDFHighlightStrength", Range(0.0, 1.0)) = 0.75 + // Shadow + [Popup] _Receive_Light_Shadow("Receive Light Shadow", Integer) = 0 + [Popup] _Receive_Screen_Space_Shadow("Receive Screen Space Shadow", Float) = 0 + [Popup] _Receive_Hair_Shadow("Receive Hair Shadow", Float) = 0 + + _ShadowDistanceBias("ShadowBias", Range(0.0, 5.0)) = 0.0 + _ShadowNormalBias("ShadowNormalBias", Range(0.0, 5.0)) = 0.0 + //_Tweak_SystemShadowsLevel("Tweak_SystemShadowsLevel", Range(-0.5, 0.5)) = 0 + + // Surface Inputs + _NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map + _NormalScale("_NormalScale", Range(0.0, 8.0)) = 1 + //_NormalMapOS("NormalMapOS", 2D) = "white" {} // Object space normal map - no good default value + + _Metallic("_Metallic", Range(0.0, 1.0)) = 0 + _Smoothness("Smoothness", Range(0.0, 1.0)) = 0.0 + _MaskMap("MaskMap", 2D) = "white" {} + _MetallicRemapMin("MetalicRemapMin", Float) = 0.0 + _MetallicRemapMax("MetalicRemapMax", Float) = 1.0 + _SmoothnessRemapMin("RoughnessRemapMin", Float) = 0.0 + _SmoothnessRemapMax("RoughnessRemapMax", Float) = 1.0 + _AlphaRemapMin("AlphaRemapMin", Float) = 0.0 + _AlphaRemapMax("AlphaRemapMax", Float) = 1.0 + _AORemapMin("AORemapMin", Float) = 0.0 + _AORemapMax("AORemapMax", Float) = 1.0 + _SSSLutMap("SSSLutMap", 2D) = "white" {} + [ToggleUI, HideInInspector] _Use_SSSLut("Use SSSLut", Int) = 0 + _SSSIntensity("SSSIntensity", Range(0.0, 3.0)) = 1.0 + + _HairBlendingMap("HairBlendingMap", 2D) = "black" {} + // Angel Rings _AngelRingColor("Angel Ring Color", Color) = (1, 1, 1, 1) @@ -320,8 +328,10 @@ Shader "HDRP/Toon" + [Toggle(_)] _Cast_Hair_Shadow("CastHairShadow", Float) = 0 [HideInInspector] _utsTechnique("Technique", int) = 0 //DWF + [HideInInspector] _AutoRenderQueue("Automatic Render Queue ", int) = 1 [Enum(Off, 0, StencilOut, 1, StencilMask, 2)] _StencilMode("StencilMode", int) = 0 // these are set in UniversalToonGUI.cs in accordance with _StencilMode @@ -361,13 +371,6 @@ Shader "HDRP/Toon" _BumpScale("Normal Scale", Range(0, 1)) = 1 [Toggle(_)] _Is_NormalMapToBase("Is_NormalMapToBase", Float) = 0 - // Hair Shadow - [Toggle(_)] _Cast_Hair_Shadow("CastHairShadow", Float) = 0 - - _ShadowBias("ShadowBias", Range(0.0, 5.0)) = 0.0 - - [Toggle(_)] _Set_SystemShadowsToBase("Set_SystemShadowsToBase", Float) = 1 - _Tweak_SystemShadowsLevel("Tweak_SystemShadowsLevel", Range(-0.5, 0.5)) = 0 // Eye Parallax [Toggle(_)] _Is_EyeParallax("_Is_EyeParallax", Float) = 0 @@ -659,6 +662,8 @@ Shader "HDRP/Toon" #pragma multi_compile DECALS_OFF DECALS_3RT DECALS_4RT #pragma multi_compile _ LIGHT_LAYERS + #pragma shader_feature_local_fragment _MASKMAP + #ifndef DEBUG_DISPLAY // When we have alpha test, we will force a depth prepass so we always bypass the clip instruction in the GBuffer // Don't do it with debug display mode as it is possible there is no depth prepass in this case @@ -1001,10 +1006,14 @@ Shader "HDRP/Toon" #pragma shader_feature_local_fragment _USE_SHADING_RAMP_MAP_ON + #pragma shader_feature_local_fragment _RECEIVE_LIGHT_SHADOW_ON + #pragma shader_feature_local_fragment _RECEIVE_SCREEN_SPACE_SHADOW_ON + #pragma shader_feature_local_fragment _RECEIVE_HAIR_SHADOW_ON + #pragma shader_feature_local_fragment _INDIRECT_DIFFUSE_OFF _INDIRECT_DIFFUSE_IBL _INDIRECT_DIFFUSE_MATCAP _INDIRECT_DIFFUSE_RAMP #pragma shader_feature_local_fragment _INDIRECT_SPECULAR_OFF _INDIRECT_SPECULAR_IBL _INDIRECT_SPECULAR_MATCAP - #pragma shader_feature_local_fragment _MASK_MAP + #pragma shader_feature_local_fragment _MASKMAP #pragma shader_feature_local_fragment _NORMAL_MAP #pragma shader_feature_local_fragment _ANISOTROPY_MAP #pragma shader_feature_local_fragment _SPECULAR_COLOR_MAP @@ -1012,8 +1021,6 @@ Shader "HDRP/Toon" #pragma shader_feature_local_fragment _OUTLINE_COLOR_MAP - #pragma shader_feature_local_fragment _RECEIVE_HAIR_SHADOW_ON - #define PUNCTUAL_SHADOW_MEDIUM #define DIRECTIONAL_SHADOW_MEDIUM #define AREA_SHADOW_MEDIUM diff --git a/Runtime/Shaders/Includes/Common/UtsHead.hlsl b/Runtime/Shaders/Includes/Common/UtsHead.hlsl index f7e32d2..ebe4995 100644 --- a/Runtime/Shaders/Includes/Common/UtsHead.hlsl +++ b/Runtime/Shaders/Includes/Common/UtsHead.hlsl @@ -154,7 +154,7 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V) float3 specularColor = 1; float anisotropy = 0; - #ifdef _MASK_MAP + #ifdef _MASKMAP float4 _MaskMap_var = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)); metallic = _MaskMap_var.x; metallic = lerp(_MetallicRemapMin, _MetallicRemapMax, metallic); diff --git a/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl b/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl index 9d08264..c7157b1 100644 --- a/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl +++ b/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl @@ -171,7 +171,6 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr #if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW shadow *= GetHairShadow(posInput, L); #endif - shadow = saturate(lerp(1.0, shadow, _Set_SystemShadowsToBase)); #if _SHADING_MODE_SDF float angle; diff --git a/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl b/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl index d7adfe0..60bc43e 100644 --- a/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl +++ b/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl @@ -9,6 +9,9 @@ #define SATURATE_BASE_COLOR_IF_SDR(x) saturate(x) #endif +#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl" +#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl" + const float rateR = 0.299; const float rateG = 0.587; const float rateB = 0.114; @@ -44,7 +47,11 @@ DirectLighting UtsEvaluateBSDF_Directional(LightLoopContext lightLoopContext, Po ZERO_INITIALIZE(DirectLighting, lighting); float3 L = -lightData.forward; - SHADOW_TYPE shadow = EvaluateShadow_Directional(lightLoopContext, posInput, lightData, builtinData, bsdfData.geomNormalWS); + + SHADOW_TYPE shadow = 1.0; +#if _RECEIVE_LIGHT_SHADOW_ON + shadow = EvaluateShadow_Directional(lightLoopContext, posInput, lightData, builtinData, bsdfData.geomNormalWS); +#endif if (lightData.lightDimmer > 0.0) { @@ -70,10 +77,10 @@ DirectLighting UtsEvaluateBSDF_Punctual(LightLoopContext lightLoopContext, Posit float4 distances; // {d, d^2, 1/d, d_proj} GetPunctualLightVectors(posInput.positionWS, lightData, L, distances); - PositionInputs shadowPositionInputs = posInput; - shadowPositionInputs.positionWS = posInput.positionWS + L * _ShadowBias; - - SHADOW_TYPE shadow = EvaluateShadow_Punctual(lightLoopContext, shadowPositionInputs, lightData, builtinData, bsdfData.geomNormalWS, L, distances); + SHADOW_TYPE shadow = 1.0; +#if _RECEIVE_LIGHT_SHADOW_ON + shadow = UtsEvaluateShadow_Punctual(lightLoopContext, posInput, lightData, builtinData, UtsGetShadowNormal(bsdfData), L, distances); +#endif if (lightData.lightDimmer > 0.0) { @@ -123,19 +130,19 @@ void UtsEvaluateBSDF_BakeDiffuse(PositionInputs posInput, PreLightData preLightD else #endif { + #if defined(_PBR_MODE_OFF) || defined(_PBR_MODE_TOON) + float3 normalWS = float3(0.0, 0.0, 1.0); + #else + float3 normalWS = bsdfData.normalWS; + #endif + float3 backNormalWS = -normalWS; + #if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) if (_EnableProbeVolumes) { // Reflect normal to get lighting for reflection probe tinting float3 R = reflect(-V, bsdfData.normalWS); - #if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON) - float3 normalWS = 0.0; - float3 backNormalWS = 0.0; - #else - float3 normalWS = bsdfData.normalWS; - float3 backNormalWS = -bsdfData.normalWS; - #endif EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS), bsdfData.normalWS, -bsdfData.normalWS, R, V, @@ -144,8 +151,8 @@ void UtsEvaluateBSDF_BakeDiffuse(PositionInputs posInput, PreLightData preLightD } else // If probe volume is disabled we fallback on the ambient probes { - builtinData.bakeDiffuseLighting = EvaluateAmbientProbe(bsdfData.normalWS); - builtinData.backBakeDiffuseLighting = EvaluateAmbientProbe(-bsdfData.normalWS); + builtinData.bakeDiffuseLighting = EvaluateAmbientProbe(normalWS); + builtinData.backBakeDiffuseLighting = EvaluateAmbientProbe(backNormalWS); } #endif } @@ -193,11 +200,6 @@ IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, Position IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); - if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION) - { - return lighting; - } - float3 envLighting; float3 positionWS = posInput.positionWS; float weight = 1.0; diff --git a/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl b/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl index 45ee469..386ac63 100644 --- a/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl +++ b/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl @@ -3,7 +3,6 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/PhysicalCamera.hlsl" -#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl" #include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl" #include "Packages/com.misaki.hdrp-toon/Runtime/Models/SurfaceFeatureFlags.cs.hlsl" @@ -74,7 +73,7 @@ bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS) bool rayTracedShadow = (light.screenSpaceShadowIndex & RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG) != 0.0; return (validScreenSpaceShadow && ((rayTracedShadow && visibleLight) || !rayTracedShadow)); #else - return ( (light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW); + return ((light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW); #endif } @@ -91,7 +90,8 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs // Initialize the contactShadow and contactShadowFade fields InitContactShadow(posInput, context); - + +#if _RECEIVE_LIGHT_SHADOW_ON // First of all we compute the shadow value of the directional light to reduce the VGPR pressure if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL) { @@ -100,8 +100,8 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs { DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex]; - #if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) - if (UseScreenSpaceShadow(light, bsdfData.normalWS)) + #if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_RECEIVE_SCREEN_SPACE_SHADOW_ON) + if (UtsUseScreenSpaceShadow(light, bsdfData.normalWS)) { context.shadowValue = GetScreenSpaceColorShadow(posInput, light.screenSpaceShadowIndex).SHADOW_TYPE_SWIZZLE; } @@ -115,12 +115,13 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs dot(bsdfData.normalWS, L) > 0.0) { context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext, - posInput.positionSS, posInput.positionWS + L * _ShadowBias, bsdfData.normalWS, + posInput.positionSS, posInput.positionWS + L * _ShadowDistanceBias, UtsGetShadowNormal(bsdfData), light.shadowIndex, L); } } } } +#endif PreLightData preLightData = GetPreLightData_UTS(V, posInput, bsdfData); diff --git a/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl b/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl new file mode 100644 index 0000000..05d05db --- /dev/null +++ b/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl @@ -0,0 +1,77 @@ +#ifndef UTS_SHADOW_EVALUATION +#define UTS_SHADOW_EVALUATION + +float3 UtsGetShadowNormal(UtsBSDFData bsdfData) +{ +#if _MATERIAL_TYPE_FACE + return normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0))).xyz; +#else + return bsdfData.geomNormalWS * (1.0 + _ShadowNormalBias); +#endif +} + +// distances = {d, d^2, 1/d, d_proj}, where d_proj = dot(lightToSample, light.forward). +SHADOW_TYPE UtsEvaluateShadow_Punctual(LightLoopContext lightLoopContext, PositionInputs posInput, LightData light, BuiltinData builtinData, float3 N, float3 L, float4 distances) +{ + #ifndef LIGHT_EVALUATION_NO_SHADOWS + float shadow = 1.0; + float shadowMask = 1.0; + float NdotL = dot(N, L); // Disable contact shadow and shadow mask when facing away from light (i.e transmission) + + #ifdef SHADOWS_SHADOWMASK + // shadowMaskSelector.x is -1 if there is no shadow mask + // Note that we override shadow value (in case we don't have any dynamic shadow) + shadow = shadowMask = (light.shadowMaskSelector.x >= 0.0 && NdotL > 0.0) ? dot(BUILTIN_DATA_SHADOW_MASK, light.shadowMaskSelector) : 1.0; + #endif + + #if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_RECEIVE_SCREEN_SPACE_SHADOW_ON) + if ((light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW) + { + shadow = GetScreenSpaceShadow(posInput, light.screenSpaceShadowIndex); + shadow = lerp(shadowMask, shadow, light.shadowDimmer); + } + else + #endif + if ((light.shadowIndex >= 0) && (light.shadowDimmer > 0)) + { + shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, posInput.positionSS, posInput.positionWS + L * _ShadowDistanceBias, N, light.shadowIndex, L, distances.x, light.lightType == GPULIGHTTYPE_POINT, light.lightType != GPULIGHTTYPE_PROJECTOR_BOX); + + #ifdef SHADOWS_SHADOWMASK + // Note: Legacy Unity have two shadow mask mode. ShadowMask (ShadowMask contain static objects shadow and ShadowMap contain only dynamic objects shadow, final result is the minimun of both value) + // and ShadowMask_Distance (ShadowMask contain static objects shadow and ShadowMap contain everything and is blend with ShadowMask based on distance (Global distance setup in QualitySettigns)). + // HDRenderPipeline change this behavior. Only ShadowMask mode is supported but we support both blend with distance AND minimun of both value. Distance is control by light. + // The following code do this. + // The min handle the case of having only dynamic objects in the ShadowMap + // The second case for blend with distance is handled with ShadowDimmer. ShadowDimmer is define manually and by shadowDistance by light. + // With distance, ShadowDimmer become one and only the ShadowMask appear, we get the blend with distance behavior. + shadow = light.nonLightMappedOnly ? min(shadowMask, shadow) : shadow; + #endif + + shadow = lerp(shadowMask, shadow, light.shadowDimmer); + } + + // Transparents have no contact shadow information +#if !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(LIGHT_EVALUATION_NO_CONTACT_SHADOWS) + { + // In certain cases (like hair) we allow to force the contact shadow sample. + #ifdef LIGHT_EVALUATION_CONTACT_SHADOW_DISABLE_NDOTL + const bool allowContactShadow = true; + #else + const bool allowContactShadow = NdotL > 0.0; + #endif + + shadow = min(shadow, allowContactShadow ? GetContactShadow(lightLoopContext, light.contactShadowMask, light.isRayTracedContactShadow) : 1.0); + } + #endif + + #ifdef DEBUG_DISPLAY + if (_DebugShadowMapMode == SHADOWMAPDEBUGMODE_SINGLE_SHADOW && light.shadowIndex == _DebugSingleShadowIndex) + g_DebugShadowAttenuation = shadow; + #endif + return shadow; +#else // LIGHT_EVALUATION_NO_SHADOWS + return 1.0; +#endif +} + +#endif \ No newline at end of file diff --git a/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl.meta b/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl.meta new file mode 100644 index 0000000..ab809e2 --- /dev/null +++ b/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 58ed9f8b53f6c414991b5223756b2938 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shaders/Includes/Properties/UtsUnityPerMaterial.hlsl b/Runtime/Shaders/Includes/Properties/UtsUnityPerMaterial.hlsl index bcb4064..196c8d7 100644 --- a/Runtime/Shaders/Includes/Properties/UtsUnityPerMaterial.hlsl +++ b/Runtime/Shaders/Includes/Properties/UtsUnityPerMaterial.hlsl @@ -21,15 +21,16 @@ float _SDFShadowLevel; float _SDFShadowSmoothLevel; float _SDFHighlightStrength; +// Shadow +float _ShadowDistanceBias; +float _ShadowNormalBias; float _utsTechnique; float4 _Color; -fixed _Set_SystemShadowsToBase; float _SurfaceFeatures; float _Tweak_SystemShadowsLevel; -float _ShadowBias; float _EyeParallaxAmount; float _HairBlendingFactor; diff --git a/Runtime/Shaders/Includes/ShaderPass/ShaderPassForward.hlsl b/Runtime/Shaders/Includes/ShaderPass/ShaderPassForward.hlsl index f4e6369..12179bb 100644 --- a/Runtime/Shaders/Includes/ShaderPass/ShaderPassForward.hlsl +++ b/Runtime/Shaders/Includes/ShaderPass/ShaderPassForward.hlsl @@ -146,7 +146,7 @@ void Frag(PackedVaryingsToPS packedInput, ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer); #endif float4 Set_UV0 = input.texCoord0; - float4 _MainTex_var = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _MainTex)); + float4 _MainTex_var = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _BaseColorMap)); surfaceData.baseColor = _MainTex_var.xyz; diff --git a/package.json b/package.json index 20e123c..02ea6f0 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,6 @@ }, "dependencies": { "com.unity.render-pipelines.high-definition": "17.0.0", - "com.misaki.shader-gui": "1.1.0" + "com.misaki.shader-gui": "1.1.2" } } \ No newline at end of file