From f83a647c30a4b8df8a1f1d80ddfef299dc123408 Mon Sep 17 00:00:00 2001 From: mob-sakai <12690315+mob-sakai@users.noreply.github.com> Date: Fri, 13 Sep 2024 20:40:44 +0900 Subject: [PATCH] fix: subtract mode `MaskingShape` does not display correctly in the editor --- Packages/src/Runtime/SoftMaskable.cs | 35 ++++++++++++++++++---------- Packages/src/Shaders/SoftMask.cginc | 16 +++++++++---- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Packages/src/Runtime/SoftMaskable.cs b/Packages/src/Runtime/SoftMaskable.cs index 3b0df72..5b3e8e5 100755 --- a/Packages/src/Runtime/SoftMaskable.cs +++ b/Packages/src/Runtime/SoftMaskable.cs @@ -9,7 +9,10 @@ namespace Coffee.UISoftMask [ExecuteAlways] public class SoftMaskable : MonoBehaviour, IMaterialModifier, IMaskable { +#if UNITY_EDITOR private static readonly int s_AlphaClipThreshold = Shader.PropertyToID("_AlphaClipThreshold"); + private static readonly int s_MaskingShapeSubtract = Shader.PropertyToID("_MaskingShapeSubtract"); +#endif private Action _checkGraphic; private MaskableGraphic _graphic; private Material _maskableMaterial; @@ -112,24 +115,16 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial) Profiler.BeginSample("(SM4UI)[SoftMaskable] GetModifiedMaterial"); var isStereo = UISoftMaskProjectSettings.stereoEnabled && _graphic.canvas.IsStereoCanvas(); var useStencil = UISoftMaskProjectSettings.useStencilOutsideScreen; - var hash = new Hash128( - (uint)baseMaterial.GetInstanceID(), - (uint)_softMask.softMaskBuffer.GetInstanceID(), - (uint)(_stencilBits + (isStereo ? 1 << 8 : 0) + (useStencil ? 1 << 9 : 0) + (_softMaskDepth << 10)), - 0); - MaterialRepository.Get(hash, ref _maskableMaterial, - x => SoftMaskUtils.CreateSoftMaskable(x.baseMaterial, x.softMaskBuffer, x._softMaskDepth, - x._stencilBits, x.isStereo, UISoftMaskProjectSettings.fallbackBehavior), - (baseMaterial, _softMask.softMaskBuffer, _softMaskDepth, _stencilBits, isStereo)); - Profiler.EndSample(); - + var localId = 0u; #if UNITY_EDITOR var threshold = 0f; - if (UISoftMaskProjectSettings.useStencilOutsideScreen) + var subtract = false; + if (useStencil) { if (TryGetComponent(out MaskingShape s) && s.maskingMethod == MaskingShape.MaskingMethod.Subtract) { threshold = s.softnessRange.average; + subtract = true; } else if (_softMask) { @@ -137,7 +132,23 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial) } } + localId = (uint)(Mathf.Clamp01(threshold) * (1 << 8) + (subtract ? 1 << 9 : 0)); +#endif + + var hash = new Hash128( + (uint)baseMaterial.GetInstanceID(), + (uint)_softMask.softMaskBuffer.GetInstanceID(), + (uint)(_stencilBits + (isStereo ? 1 << 8 : 0) + (useStencil ? 1 << 9 : 0) + (_softMaskDepth << 10)), + localId); + MaterialRepository.Get(hash, ref _maskableMaterial, + x => SoftMaskUtils.CreateSoftMaskable(x.baseMaterial, x.softMaskBuffer, x._softMaskDepth, + x._stencilBits, x.isStereo, UISoftMaskProjectSettings.fallbackBehavior), + (baseMaterial, _softMask.softMaskBuffer, _softMaskDepth, _stencilBits, isStereo)); + Profiler.EndSample(); + +#if UNITY_EDITOR _maskableMaterial.SetFloat(s_AlphaClipThreshold, threshold); + _maskableMaterial.SetInt(s_MaskingShapeSubtract, subtract ? 1 : 0); #endif return _maskableMaterial; diff --git a/Packages/src/Shaders/SoftMask.cginc b/Packages/src/Shaders/SoftMask.cginc index 17498bf..9e51a11 100644 --- a/Packages/src/Shaders/SoftMask.cginc +++ b/Packages/src/Shaders/SoftMask.cginc @@ -13,6 +13,7 @@ uniform float4x4 _GameVP_2; uniform float4x4 _GameTVP_2; uniform int _SoftMaskInGameView; uniform int _SoftMaskInSceneView; +uniform int _MaskingShapeSubtract; float Approximately(float4x4 a, float4x4 b) { @@ -87,12 +88,19 @@ float SoftMaskSample(float2 uv, float a) lerp(mask, half4(1, 1, 1, 1) - mask, _SoftMaskColor - half4(1, 1, 1, 1)), _SoftMaskColor)); #if SOFTMASK_EDITOR - int inScreen = step(0, uv.x) * step(uv.x, 1) * step(0, uv.y) * step(uv.y, 1); - alpha = lerp(_SoftMaskOutsideColor, alpha, inScreen); - if (inScreen == 0) + int inScreen = step(0, uv.x) * step(uv.x, 1) * step(0, uv.y) * step(uv.y, 1); + alpha = lerp(_SoftMaskOutsideColor, alpha, inScreen); + #ifdef UNITY_UI_ALPHACLIP + if (_MaskingShapeSubtract == 1) + { + if (_SoftMaskInSceneView == 1) { - clip (a * alpha.x * alpha.y * alpha.z * alpha.w - _AlphaClipThreshold - 0.001); + clip (a - _AlphaClipThreshold - 0.001); + return 1; } + clip (a * alpha.x * alpha.y * alpha.z * alpha.w - _AlphaClipThreshold - 0.001); + } + #endif #endif return alpha.x * alpha.y * alpha.z * alpha.w;