Skip to content

Commit

Permalink
feat: MaskingShape components always use stencil mask
Browse files Browse the repository at this point in the history
  • Loading branch information
mob-sakai committed Nov 14, 2024
1 parent d9010bf commit a7b3bf6
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 22 deletions.
15 changes: 12 additions & 3 deletions Packages/src/Runtime/MaskingShape/MaskingShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,19 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
var colorMask = m_ShowMaskGraphic ? ColorWriteMask.All : 0;
{
Profiler.BeginSample("(SM4UI)[MaskingShape)] GetModifiedMaterial > StencilMaterial.Add");
var writeMask = Utils.GetHighestBit(_stencilBits);
var readMask = _stencilBits & ~writeMask;
switch (maskingMethod)
{
case MaskingMethod.Additive:
maskMat = StencilMaterial.Add(baseMaterial, _stencilBits, StencilOp.Replace,
CompareFunction.NotEqual, colorMask, _stencilBits, _stencilBits);
CompareFunction.Equal, colorMask, readMask, writeMask);
break;
case MaskingMethod.Subtract:
maskMat = StencilMaterial.Add(baseMaterial, _stencilBits, StencilOp.Invert,
CompareFunction.Equal, colorMask, _stencilBits, _stencilBits);
var op = SoftMaskEnabled() ? StencilOp.Keep : StencilOp.Zero;
var comp = writeMask == 1 ? CompareFunction.Always : CompareFunction.Equal;
maskMat = StencilMaterial.Add(baseMaterial, _stencilBits, op,
comp, colorMask, readMask, writeMask);
break;
}

Expand Down Expand Up @@ -331,6 +335,11 @@ internal bool AntiAliasingEnabled()
return isActiveAndEnabled && _mask is SoftMask softMask && softMask.AntiAliasingEnabled();
}

internal bool SoftMaskEnabled()
{
return isActiveAndEnabled && _mask is SoftMask softMask && softMask.SoftMaskingEnabled();
}

private void RecalculateStencilIfNeeded()
{
if (!isActiveAndEnabled)
Expand Down
2 changes: 1 addition & 1 deletion Packages/src/Runtime/MaskingShape/TerminalMaskingShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public override Material GetModifiedMaterial(Material baseMaterial)
}

var maskMat = StencilMaterial.Add(baseMaterial, _stencilBits, StencilOp.Zero, CompareFunction.Equal, 0,
_stencilBits, _stencilBits);
_stencilBits, Utils.GetHighestBit(_stencilBits));

StencilMaterial.Remove(m_MaskMaterial);
m_MaskMaterial = maskMat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class UISoftMaskProjectSettings : PreloadedProjectSettings<UISoftMaskProj
#if UNITY_EDITOR
instance.m_UseStencilOutsideScreen;
#else
false;
true;
#endif

#if UNITY_MODULE_VR
Expand Down
22 changes: 18 additions & 4 deletions Packages/src/Runtime/SoftMaskable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public float power
private MaskableGraphic _graphic;
private Material _maskableMaterial;
private bool _shouldRecalculateStencil;
private Mask _mask;
private SoftMask _softMask;
private int _softMaskDepth;
private int _stencilBits;
Expand Down Expand Up @@ -147,6 +148,7 @@ private void OnDisable()
}

_graphic = null;
_mask = null;
_softMask = null;
MaterialRepository.Release(ref _maskableMaterial);

Expand All @@ -160,6 +162,7 @@ private void OnDestroy()
{
_graphic = null;
_maskableMaterial = null;
_mask = null;
_softMask = null;
_checkGraphic = null;

Expand Down Expand Up @@ -199,14 +202,25 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
}

RecalculateStencilIfNeeded();
_softMaskDepth = _softMask ? _softMask.softMaskDepth : -1;

if (!_softMask || _softMaskDepth < 0 || 4 <= _softMaskDepth)
var softMaskDepth = _softMask ? _softMask.softMaskDepth : -1;
if (softMaskDepth < 0 || 4 <= softMaskDepth)
{
_softMaskDepth = -1;
MaterialRepository.Release(ref _maskableMaterial);
return baseMaterial;
}

_softMaskDepth = softMaskDepth;
if (0 <= _softMaskDepth
&& _softMask == _mask
&& _softMask.SoftMaskingEnabled()
&& TryGetComponent<MaskingShape>(out var shape)
&& shape.isActiveAndEnabled
&& shape.maskingMethod == MaskingShape.MaskingMethod.Subtract)
{
_softMaskDepth -= 1;
}

Profiler.BeginSample("(SM4UI)[SoftMaskable] GetModifiedMaterial");
var isStereo = UISoftMaskProjectSettings.stereoEnabled && _graphic.canvas.IsStereoCanvas();
var useStencil = UISoftMaskProjectSettings.useStencilOutsideScreen;
Expand Down Expand Up @@ -263,7 +277,7 @@ private void RecalculateStencilIfNeeded()
if (!_shouldRecalculateStencil) return;
_shouldRecalculateStencil = false;
var useStencil = UISoftMaskProjectSettings.useStencilOutsideScreen;
_stencilBits = Utils.GetStencilBits(transform, false, useStencil, out var _, out _softMask);
_stencilBits = Utils.GetStencilBits(transform, false, useStencil, out _mask, out _softMask);
}

private void CheckGraphic()
Expand Down
1 change: 0 additions & 1 deletion Packages/src/Runtime/Utilities/SoftMaskUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ public static Material CreateSoftMaskable(
mat.SetTexture(s_SoftMaskTex, softMaskBuffer);
mat.SetInt(s_SoftMaskableStereo, isStereo ? 1 : 0);
mat.SetInt(s_SoftMaskableEnable, 1);
mat.SetInt(s_StencilReadMask, stencilBits);
mat.SetVector(s_SoftMaskColor, new Vector4(
0 <= softMaskDepth ? 1 : 0,
1 <= softMaskDepth ? 1 : 0,
Expand Down
22 changes: 10 additions & 12 deletions Packages/src/Runtime/Utilities/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,6 @@ public static int GetStencilBits(Transform transform, bool includeSelf, bool use
if (!nearestMask)
{
nearestMask = mask;
if (FrameCache.TryGet(nearestMask, nameof(GetStencilBits), out stencilBits))
{
FrameCache.TryGet(nearestMask, nameof(GetStencilBits), out nearestSoftMask);

Profiler.EndSample();
return stencilBits;
}
}

stencilBits = 0 < depth++ ? stencilBits << 1 : 0;
Expand Down Expand Up @@ -98,11 +91,6 @@ public static int GetStencilBits(Transform transform, bool includeSelf, bool use

stencilBits = Mathf.Min(stencilBits, 255);
Profiler.EndSample();
if (nearestMask)
{
FrameCache.Set(nearestMask, nameof(GetStencilBits), stencilBits);
FrameCache.Set(nearestMask, nameof(GetStencilBits), nearestSoftMask);
}

return stencilBits;
}
Expand Down Expand Up @@ -181,6 +169,16 @@ private static bool AlphaHitTestValid(RawImage src, Vector2 sp, Camera eventCame
}
}

public static int GetHighestBit(int i)
{
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
// i |= (i >> 16);
return i - (i >> 1);
}

#if UNITY_EDITOR
private static string GetWarningMessage(Graphic src)
{
Expand Down

0 comments on commit a7b3bf6

Please sign in to comment.