main
Vinny 2026-02-28 17:24:32 +08:00
parent 6d84b2d967
commit f3ee42f13e
3 changed files with 50 additions and 36 deletions

View File

@ -23,6 +23,7 @@ namespace NLD.UI
private static readonly int ShadowSkewID = Shader.PropertyToID("_ShadowSkew");
private static readonly int ShadowSoftnessID = Shader.PropertyToID("_ShadowSoftness");
private static readonly int ShadowBlurID = Shader.PropertyToID("_ShadowBlur");
private static readonly int ShadowBlurIntensityID = Shader.PropertyToID("_ShadowBlurIntensity");
[Header("Shadow Settings")]
[Tooltip("Size/softness of the shadow (for Image only, TMP shadow is always sharp)")]
@ -48,9 +49,13 @@ namespace NLD.UI
[Header("Appearance")]
[SerializeField] private Color _color = new Color(0f, 0f, 0f, 0.5f);
[Tooltip("Blur amount of the shadow (0 = sharp)")]
[Range(0f, 20f)]
[SerializeField] private float _blur = 0f;
[Tooltip("Blur intensity: 0 = sharp, 1 = fully blurred")]
[Range(0f, 1f)]
[SerializeField] private float _blurIntensity = 0f;
[Tooltip("Blur range: spatial spread of the blur effect")]
[Min(0f)]
[SerializeField] private float _blurRange = 10f;
[SerializeField] private ShadowBlendMode _blendMode = ShadowBlendMode.Normal;
@ -126,10 +131,16 @@ namespace NLD.UI
set { _blendMode = value; MarkDirty(); UpdateShadow(); }
}
public float BlurAmount
public float BlurIntensity
{
get => _blur;
set { _blur = Mathf.Clamp(value, 0f, 20f); UpdateShadow(); }
get => _blurIntensity;
set { _blurIntensity = Mathf.Clamp01(value); UpdateShadow(); }
}
public float BlurRange
{
get => _blurRange;
set { _blurRange = Mathf.Max(0f, value); UpdateShadow(); }
}
#endregion
@ -295,7 +306,8 @@ namespace NLD.UI
mat.SetVector(ShadowOffsetID, new Vector4(offset.x, offset.y, 0, 0));
mat.SetVector(ShadowSkewID, new Vector4(_skewX, _skewY, 0, 0));
mat.SetFloat(ShadowSoftnessID, _size * 0.1f);
mat.SetFloat(ShadowBlurID, _blur);
mat.SetFloat(ShadowBlurID, _blurRange);
mat.SetFloat(ShadowBlurIntensityID, _blurIntensity);
}
private void CleanupShaderMode()
@ -436,7 +448,7 @@ namespace NLD.UI
_contentTMP.color = _originalColor;
_shadowTMP.color = GetProcessedColor();
ApplyTMPShadowBlur(_blur);
ApplyTMPShadowBlur();
Vector2 currentOffset = CalculateOffset();
if (_cachedOffset != currentOffset)
@ -472,13 +484,14 @@ namespace NLD.UI
target.overflowMode = _sourceTMP.overflowMode;
}
private void ApplyTMPShadowBlur(float blur)
private void ApplyTMPShadowBlur()
{
if (_shadowTMP == null) return;
float t = Mathf.Clamp01(blur / 20f);
Material mat = _shadowTMP.fontMaterial;
mat.SetFloat(ShaderUtilities.ID_FaceDilate, 0f);
mat.SetFloat(ShaderUtilities.ID_OutlineSoftness, t * 0.5f);
// Range: expand shadow outward via FaceDilate (only on shadow copy, content stays unchanged)
mat.SetFloat(ShaderUtilities.ID_FaceDilate, Mathf.Clamp01(_blurRange * 0.02f));
// Intensity: soften the expanded shadow edge
mat.SetFloat(ShaderUtilities.ID_OutlineSoftness, _blurIntensity);
}
#endif
@ -491,7 +504,7 @@ namespace NLD.UI
if (_shadowTMP != null)
{
_shadowTMP.color = GetProcessedColor();
ApplyTMPShadowBlur(_blur);
ApplyTMPShadowBlur();
}
#endif
}

View File

@ -9,36 +9,31 @@ namespace NLD.UI.Editor
[CanEditMultipleObjects]
public class CommonUIShadowEditor : UnityEditor.Editor
{
private SerializedProperty sizeProp;
private SerializedProperty offsetAngleProp;
private SerializedProperty offsetDistanceProp;
private SerializedProperty skewXProp;
private SerializedProperty skewYProp;
private SerializedProperty colorProp;
private SerializedProperty blurProp;
private SerializedProperty blurRangeProp;
private SerializedProperty blendModeProp;
private void OnEnable()
{
sizeProp = serializedObject.FindProperty("_size");
offsetAngleProp = serializedObject.FindProperty("_offsetAngle");
offsetDistanceProp = serializedObject.FindProperty("_offsetDistance");
skewXProp = serializedObject.FindProperty("_skewX");
skewYProp = serializedObject.FindProperty("_skewY");
colorProp = serializedObject.FindProperty("_color");
blurProp = serializedObject.FindProperty("_blur");
blurProp = serializedObject.FindProperty("_blurIntensity");
blurRangeProp = serializedObject.FindProperty("_blurRange");
blendModeProp = serializedObject.FindProperty("_blendMode");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// Size
EditorGUILayout.PropertyField(sizeProp, new GUIContent("Size", "Shadow blur size"));
EditorGUILayout.Space(4);
// Offset with angle knob
EditorGUILayout.BeginHorizontal();
DrawAngleKnob(offsetAngleProp);
@ -70,7 +65,8 @@ namespace NLD.UI.Editor
// Color and Blend Mode
EditorGUILayout.PropertyField(colorProp, new GUIContent("Color"));
EditorGUILayout.PropertyField(blurProp, new GUIContent("Blur", "Shadow blur amount (0 = sharp)"));
EditorGUILayout.PropertyField(blurProp, new GUIContent("Blur Intensity", "0 = sharp, 1 = fully blurred"));
EditorGUILayout.PropertyField(blurRangeProp, new GUIContent("Blur Range", "Spatial spread of blur"));
EditorGUILayout.PropertyField(blendModeProp, new GUIContent("Blend Mode"));
serializedObject.ApplyModifiedProperties();

View File

@ -9,7 +9,8 @@ Shader "NLD/UI/CommonUIShadow"
_ShadowOffset ("Shadow Offset (XY)", Vector) = (4, -4, 0, 0)
_ShadowSkew ("Shadow Skew (XY)", Vector) = (0, 0, 0, 0)
_ShadowSoftness ("Shadow Softness", Range(0, 1)) = 0.1
_ShadowBlur ("Shadow Blur", Range(0, 20)) = 0
_ShadowBlur ("Shadow Blur Range", Range(0, 50)) = 0
_ShadowBlurIntensity ("Shadow Blur Intensity", Range(0, 1)) = 1
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
@ -93,6 +94,7 @@ Shader "NLD/UI/CommonUIShadow"
float4 _ShadowSkew;
float _ShadowSoftness;
float _ShadowBlur;
float _ShadowBlurIntensity;
float4 _MainTex_TexelSize;
v2f vert(appdata_t v)
@ -123,18 +125,21 @@ Shader "NLD/UI/CommonUIShadow"
{
fixed4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
fixed sharpAlpha = (tex2D(_MainTex, IN.shadowUV) + _TextureSampleAdd).a;
float2 blurStep = _MainTex_TexelSize.xy * _ShadowBlur;
fixed totalAlpha = 0;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2(-blurStep.x, -blurStep.y)) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2( 0.0, -blurStep.y)) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2( blurStep.x, -blurStep.y)) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2(-blurStep.x, 0.0)) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV ) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2( blurStep.x, 0.0)) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2(-blurStep.x, blurStep.y)) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2( 0.0, blurStep.y)) + _TextureSampleAdd).a;
totalAlpha += (tex2D(_MainTex, IN.shadowUV + float2( blurStep.x, blurStep.y)) + _TextureSampleAdd).a;
fixed shadowAlpha = (totalAlpha / 9.0) * _ShadowColor.a;
fixed blurredAlpha = 0;
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2(-blurStep.x, -blurStep.y)) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2( 0.0, -blurStep.y)) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2( blurStep.x, -blurStep.y)) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2(-blurStep.x, 0.0)) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV ) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2( blurStep.x, 0.0)) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2(-blurStep.x, blurStep.y)) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2( 0.0, blurStep.y)) + _TextureSampleAdd).a);
blurredAlpha = max(blurredAlpha, (tex2D(_MainTex, IN.shadowUV + float2( blurStep.x, blurStep.y)) + _TextureSampleAdd).a);
fixed shadowAlpha = lerp(sharpAlpha, blurredAlpha, _ShadowBlurIntensity) * _ShadowColor.a;
fixed4 result;
result.rgb = lerp(_ShadowColor.rgb * shadowAlpha, color.rgb, color.a);