From 1362b1874b9d65bcd29e8ea013c296f2d1e29014 Mon Sep 17 00:00:00 2001
From: mob-sakai <12690315+mob-sakai@users.noreply.github.com>
Date: Thu, 31 Oct 2024 16:23:56 +0900
Subject: [PATCH] feat: add `power` option for SoftMaskable element
---
Packages/src/Editor/SoftMaskableEditor.cs | 3 ++
Packages/src/Runtime/SoftMaskable.cs | 36 +++++++++++++++++++++--
Packages/src/Shaders/SoftMask.cginc | 3 +-
3 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/Packages/src/Editor/SoftMaskableEditor.cs b/Packages/src/Editor/SoftMaskableEditor.cs
index 9663856..fadf8cd 100644
--- a/Packages/src/Editor/SoftMaskableEditor.cs
+++ b/Packages/src/Editor/SoftMaskableEditor.cs
@@ -10,11 +10,13 @@ public class SoftMaskableEditor : AutoGeneratedEditor
{
private SerializedProperty _ignoreSelf;
private SerializedProperty _ignoreChildren;
+ private SerializedProperty _power;
private void OnEnable()
{
_ignoreSelf = serializedObject.FindProperty("m_IgnoreSelf");
_ignoreChildren = serializedObject.FindProperty("m_IgnoreChildren");
+ _power = serializedObject.FindProperty("m_Power");
}
public override void OnInspectorGUI()
@@ -27,6 +29,7 @@ public override void OnInspectorGUI()
serializedObject.Update();
DrawProperty(_ignoreSelf, x => x.SetMaterialDirty());
DrawProperty(_ignoreChildren, x => x.SetMaterialDirtyForChildren());
+ DrawProperty(_power, x => x.SetMaterialDirty());
serializedObject.ApplyModifiedProperties();
if (targets.Length == 1 && target is SoftMaskable softMaskable && softMaskable.ignored)
diff --git a/Packages/src/Runtime/SoftMaskable.cs b/Packages/src/Runtime/SoftMaskable.cs
index 106c0e7..9867199 100755
--- a/Packages/src/Runtime/SoftMaskable.cs
+++ b/Packages/src/Runtime/SoftMaskable.cs
@@ -15,6 +15,9 @@ public class SoftMaskable : MonoBehaviour, IMaterialModifier, IMaskable
#endif
private static readonly int s_AllowDynamicResolution = Shader.PropertyToID("_AllowDynamicResolution");
private static readonly int s_AllowRenderScale = Shader.PropertyToID("_AllowRenderScale");
+ private static readonly int s_SoftMaskingPower = Shader.PropertyToID("_SoftMaskingPower");
+ private const float k_PowerMin = 1f;
+ private const float k_PowerMax = 5f;
[Tooltip("The graphic is ignored when soft-masking.")]
[SerializeField]
@@ -24,6 +27,13 @@ public class SoftMaskable : MonoBehaviour, IMaterialModifier, IMaskable
[SerializeField]
private bool m_IgnoreChildren;
+ [Tooltip("Soft masking power.\n" +
+ "The higher this value, the faster it becomes transparent.\n" +
+ "If overlapping objects appear see-through, please adjust this value.")]
+ [SerializeField]
+ [Range(k_PowerMin, k_PowerMax)]
+ private float m_Power = 1f;
+
///
/// The graphic is ignored when soft-masking.
///
@@ -81,6 +91,23 @@ public bool ignored
}
}
+ ///
+ /// Soft masking power.
+ /// The higher this value, the faster it becomes transparent.
+ /// If overlapping objects appear see-through, please adjust this value.
+ ///
+ public float power
+ {
+ get => m_Power;
+ set
+ {
+ value = Mathf.Clamp(value, k_PowerMin, k_PowerMax);
+ if (Mathf.Approximately(m_Power, value)) return;
+ m_Power = value;
+ SetMaterialDirty();
+ }
+ }
+
private Action _checkGraphic;
private MaskableGraphic _graphic;
private Material _maskableMaterial;
@@ -183,7 +210,7 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
Profiler.BeginSample("(SM4UI)[SoftMaskable] GetModifiedMaterial");
var isStereo = UISoftMaskProjectSettings.stereoEnabled && _graphic.canvas.IsStereoCanvas();
var useStencil = UISoftMaskProjectSettings.useStencilOutsideScreen;
- var localId = 0u;
+ var localId = (uint)(Mathf.InverseLerp(k_PowerMin, k_PowerMax, power) * (1 << 10));
#if UNITY_EDITOR
var threshold = 0f;
var subtract = false;
@@ -200,7 +227,7 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
}
}
- localId = (uint)(Mathf.Clamp01(threshold) * (1 << 8) + (subtract ? 1 << 9 : 0));
+ localId = (uint)(Mathf.Clamp01(threshold) * (1 << 8) + (subtract ? 1 << 9 : 0) + (localId << 10));
#endif
var hash = new Hash128(
@@ -220,6 +247,7 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
#endif
_maskableMaterial.SetInt(s_AllowDynamicResolution, _softMask.allowDynamicResolution ? 1 : 0);
_maskableMaterial.SetInt(s_AllowRenderScale, _softMask.allowRenderScale ? 1 : 0);
+ _maskableMaterial.SetFloat(s_SoftMaskingPower, power);
return _maskableMaterial;
}
@@ -270,7 +298,9 @@ public void SetMaterialDirtyForChildren()
private void UpdateHideFlags()
{
- hideFlags = ignoreSelf || ignoreChildren ? HideFlags.None : HideFlags.DontSave;
+ hideFlags = ignoreSelf || ignoreChildren || !Mathf.Approximately(power, 1f)
+ ? HideFlags.None
+ : HideFlags.DontSave;
}
#if UNITY_EDITOR
diff --git a/Packages/src/Shaders/SoftMask.cginc b/Packages/src/Shaders/SoftMask.cginc
index 81b375a..9a11c02 100644
--- a/Packages/src/Shaders/SoftMask.cginc
+++ b/Packages/src/Shaders/SoftMask.cginc
@@ -18,6 +18,7 @@ uniform float _RenderScale;
uniform float2 _DynamicResolutionScale;
uniform int _AllowRenderScale;
uniform int _AllowDynamicResolution;
+uniform float _SoftMaskingPower;
float Approximately(float4x4 a, float4x4 b)
{
@@ -116,7 +117,7 @@ float SoftMaskSample(float2 uv, float a)
#endif
#endif
- return alpha.x * alpha.y * alpha.z * alpha.w;
+ return pow(alpha.x * alpha.y * alpha.z * alpha.w, _SoftMaskingPower);
}
void SoftMaskForGraph_float(float4 ScreenPos, float4 WorldPos, float InAlpha, out float A)