Skip to content

Commit

Permalink
feat: gradation feature
Browse files Browse the repository at this point in the history
close #277, close #66
  • Loading branch information
mob-sakai committed Dec 31, 2024
1 parent e9522d3 commit bbe57df
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 11 deletions.
36 changes: 36 additions & 0 deletions Packages/src/Editor/UIEffectEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ public class UIEffect2Editor : Editor
private SerializedProperty _shadowColor;
private SerializedProperty _shadowColorGlow;

private SerializedProperty _gradationMode;
private SerializedProperty _gradationColor1;
private SerializedProperty _gradationColor2;
private SerializedProperty _gradationGradient;
private SerializedProperty _gradationOffset;
private SerializedProperty _gradationScale;

private bool _expandOthers;
private SerializedProperty _allowExtendVertex;

Expand Down Expand Up @@ -115,6 +122,13 @@ private void OnEnable()
_shadowColor = serializedObject.FindProperty("m_ShadowColor");
_shadowColorGlow = serializedObject.FindProperty("m_ShadowColorGlow");

_gradationMode = serializedObject.FindProperty("m_GradationMode");
_gradationColor1 = serializedObject.FindProperty("m_GradationColor1");
_gradationColor2 = serializedObject.FindProperty("m_GradationColor2");
_gradationGradient = serializedObject.FindProperty("m_GradationGradient");
_gradationOffset = serializedObject.FindProperty("m_GradationOffset");
_gradationScale = serializedObject.FindProperty("m_GradationScale");

_allowExtendVertex = serializedObject.FindProperty("m_AllowExtendVertex");
}

Expand Down Expand Up @@ -260,6 +274,28 @@ public void DrawProperties()
EditorGUI.indentLevel--;
}

// Gradient
DrawSeparator();
if (DrawHeaderPopup(_gradationMode))
{
EditorGUI.indentLevel++;
switch ((GradationMode)_gradationMode.intValue)
{
case GradationMode.HorizontalGradient:
case GradationMode.VerticalGradient:
EditorGUILayout.PropertyField(_gradationGradient);
break;
default:
EditorGUILayout.PropertyField(_gradationColor1);
EditorGUILayout.PropertyField(_gradationColor2);
break;
}

EditorGUILayout.PropertyField(_gradationOffset);
EditorGUILayout.PropertyField(_gradationScale);
EditorGUI.indentLevel--;
}

DrawSeparator();
_expandOthers = EditorGUILayout.BeginFoldoutHeaderGroup(_expandOthers, "Others");
if (_expandOthers)
Expand Down
13 changes: 13 additions & 0 deletions Packages/src/Runtime/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ public enum ShadowMode
Mirror
}

public enum GradationMode
{
None = 0,
Horizontal,
HorizontalGradient,
Vertical,
VerticalGradient,
RadialFast,
RadialDetail,
DiagonalToRightBottom,
DiagonalToLeftBottom
}

internal static class BlendTypeConverter
{
public static (BlendMode, BlendMode) Convert(this (BlendType type, BlendMode src, BlendMode dst) self)
Expand Down
101 changes: 101 additions & 0 deletions Packages/src/Runtime/UIEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,26 @@ public class UIEffect : UIEffectBase
[SerializeField]
protected bool m_ShadowColorGlow = false;

[SerializeField]
protected GradationMode m_GradationMode = GradationMode.None;

[SerializeField]
protected Color m_GradationColor1 = Color.white;

[SerializeField]
protected Color m_GradationColor2 = Color.white;

[SerializeField]
private Gradient m_GradationGradient = new Gradient();

[Range(-1, 1)]
[SerializeField]
protected float m_GradationOffset = 0;

[PowerRange(0.01f, 10, 10)]
[SerializeField]
protected float m_GradationScale = 1;

[SerializeField]
protected bool m_AllowExtendVertex = true;

Expand Down Expand Up @@ -597,6 +617,61 @@ public bool shadowGlow
}
}

public GradationMode gradationMode
{
get => m_GradationMode;
set
{
if (m_GradationMode == value) return;
context.gradationMode = m_GradationMode = value;
SetVerticesDirty();
}
}

public Color gradationColor1
{
get => m_GradationColor1;
set
{
if (m_GradationColor1 == value) return;
context.gradationColor1 = m_GradationColor1 = value;
SetVerticesDirty();
}
}

public Color gradationColor2
{
get => m_GradationColor2;
set
{
if (m_GradationColor2 == value) return;
context.gradationColor2 = m_GradationColor2 = value;
SetVerticesDirty();
}
}

public float gradationOffset
{
get => m_GradationOffset;
set
{
if (Mathf.Approximately(m_GradationOffset, value)) return;
context.gradationOffset = m_GradationOffset = value;
SetVerticesDirty();
}
}

public float gradationScale
{
get => m_GradationScale;
set
{
if (Mathf.Approximately(m_GradationScale, value)) return;
context.gradationScale = m_GradationScale = value;
SetVerticesDirty();
}
}

public bool allowExtendVertex
{
get => m_AllowExtendVertex;
Expand Down Expand Up @@ -633,6 +708,7 @@ protected override void OnDestroy()
protected override void OnValidate()
{
(m_SrcBlendMode, m_DstBlendMode) = (m_BlendType, m_SrcBlendMode, m_DstBlendMode).Convert();
context?.SetGradationDirty();
base.OnValidate();
}
#endif
Expand All @@ -657,6 +733,13 @@ public override void SetMaterialDirty()
});
}

public void SetGradientKeys(GradientColorKey[] colorKeys, GradientAlphaKey[] alphaKeys)
{
m_GradationGradient ??= new Gradient();
m_GradationGradient.SetKeys(colorKeys, alphaKeys);
context?.SetGradationDirty();
}

protected override void UpdateContext(UIEffectContext c)
{
c.toneFilter = m_ToneFilter;
Expand Down Expand Up @@ -696,6 +779,12 @@ protected override void UpdateContext(UIEffectContext c)
c.shadowColorFilter = m_ShadowColorFilter;
c.shadowColor = m_ShadowColor;
c.shadowColorGlow = m_ShadowColorGlow;
c.gradationMode = m_GradationMode;
c.gradationColor1 = m_GradationColor1;
c.gradationColor2 = m_GradationColor2;
c.gradationGradient = m_GradationGradient;
c.gradationOffset = m_GradationOffset;
c.gradationScale = m_GradationScale;
c.allowExtendVertex = m_AllowExtendVertex;
}

Expand Down Expand Up @@ -730,6 +819,11 @@ public override void SetRate(float rate, UIEffectTweener.CullingMask mask)
{
transitionRate = rate;
}

if (gradationMode != GradationMode.None && 0 < (mask & UIEffectTweener.CullingMask.Gradiation))
{
gradationOffset = Mathf.Lerp(-1f, 1f, rate);
}
}

public override bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
Expand Down Expand Up @@ -852,6 +946,13 @@ internal void CopyFrom(UIEffectContext c)
m_ShadowColor = c.shadowColor;
m_ShadowColorGlow = c.shadowColorGlow;

m_GradationMode = c.gradationMode;
m_GradationColor1 = c.gradationColor1;
m_GradationColor2 = c.gradationColor2;
m_GradationGradient = c.gradationGradient;
m_GradationOffset = c.gradationOffset;
m_GradationScale = c.gradationScale;

m_AllowExtendVertex = c.allowExtendVertex;

UpdateContext(context);
Expand Down
89 changes: 87 additions & 2 deletions Packages/src/Runtime/UIEffectContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ public class UIEffectContext
public Color shadowColor;
public bool shadowColorGlow;

public GradationMode gradationMode;
public Color gradationColor1;
public Color gradationColor2;
public Gradient gradationGradient;
public float gradationOffset;
public float gradationScale;
private List<float> _keyTimes;
private List<float> _splitTimes;

public bool allowExtendVertex;


Expand All @@ -188,6 +197,7 @@ public class UIEffectContext

public void Reset()
{
InternalListPool<float>.Return(ref _keyTimes);
CopyFrom(s_DefaultContext);
}

Expand Down Expand Up @@ -237,9 +247,21 @@ public void CopyFrom(UIEffectContext preset)
shadowColor = preset.shadowColor;
shadowColorGlow = preset.shadowColorGlow;

gradationMode = preset.gradationMode;
gradationColor1 = preset.gradationColor1;
gradationColor2 = preset.gradationColor2;
gradationGradient = preset.gradationGradient;
gradationOffset = preset.gradationOffset;
gradationScale = preset.gradationScale;

allowExtendVertex = preset.allowExtendVertex;
}

public void SetGradationDirty()
{
InternalListPool<float>.Return(ref _keyTimes);
}

public void ApplyToMaterial(Material material, float actualSamplingScale = 1f)
{
if (!material) return;
Expand Down Expand Up @@ -353,6 +375,7 @@ public void ModifyMesh(Graphic graphic, RectTransform transitionRoot, VertexHelp
// Get the rectangle to calculate the normalized position.
vh.GetUIVertexStream(verts);
var bundleSize = isText ? 6 : count;
var rectMatrix = Matrix4x4.identity;
var rot = Matrix4x4.Rotate(Quaternion.Euler(0, 0, transitionRotation));
var v1 = rot.MultiplyPoint3x4(new Vector3(1, 1, 0));
var multiplier = Mathf.Max(Mathf.Abs(v1.x), Mathf.Abs(v1.y));
Expand All @@ -361,9 +384,10 @@ public void ModifyMesh(Graphic graphic, RectTransform transitionRoot, VertexHelp
if (transitionRoot)
{
rect = transitionRoot.rect;
rectMatrix = transitionRoot.worldToLocalMatrix
* graphic.transform.localToWorldMatrix;
rot *= Matrix4x4.Scale(new Vector3(1 / multiplier, 1 / multiplier, 1))
* transitionRoot.worldToLocalMatrix
* graphic.rectTransform.localToWorldMatrix;
* rectMatrix;
}
else
{
Expand Down Expand Up @@ -401,13 +425,74 @@ public void ModifyMesh(Graphic graphic, RectTransform transitionRoot, VertexHelp
}
}

// Apply gradation.
ApplyGradation(verts, transitionRoot.rect, rectMatrix);

// Apply shadow.
ApplyShadow(transitionRoot, verts);

vh.Clear();
vh.AddUIVertexTriangleStream(verts);
}

private void ApplyGradation(List<UIVertex> verts, Rect rect, Matrix4x4 m)
{
var a = gradationColor1;
var b = gradationColor2;
var offset = gradationOffset;
var scale = gradationScale;
var grad = gradationGradient;
switch (gradationMode)
{
case GradationMode.Horizontal:
GradientUtil.DoHorizontalGradient(verts, a, b, offset, scale, rect, m);
break;
case GradationMode.Vertical:
GradientUtil.DoVerticalGradient(verts, a, b, offset, scale, rect, m);
break;
case GradationMode.DiagonalToRightBottom:
GradientUtil.DoDiagonalGradientToRightBottom(verts, a, b, offset, scale, rect, m);
break;
case GradationMode.DiagonalToLeftBottom:
GradientUtil.DoDiagonalGradientToLeftBottom(verts, a, b, offset, scale, rect, m);
break;
case GradationMode.RadialFast:
GradientUtil.DoRadialGradient(verts, a, b, offset, scale, rect, m, 4);
break;
case GradationMode.RadialDetail:
GradientUtil.DoRadialGradient(verts, a, b, offset, scale, rect, m, 12);
break;
case GradationMode.HorizontalGradient:
{
if (_keyTimes == null)
{
_keyTimes = InternalListPool<float>.Rent();
GradientUtil.GetKeyTimes(grad, _keyTimes);
}

var splitTimes = InternalListPool<float>.Rent();
GradientUtil.SplitKeyTimes(_keyTimes, splitTimes, offset, scale);
GradientUtil.DoHorizontalGradient(verts, grad, splitTimes, offset, scale, rect, m);
InternalListPool<float>.Return(ref splitTimes);
break;
}
case GradationMode.VerticalGradient:
{
if (_keyTimes == null)
{
_keyTimes = InternalListPool<float>.Rent();
GradientUtil.GetKeyTimes(grad, _keyTimes);
}

var splitTimes = InternalListPool<float>.Rent();
GradientUtil.SplitKeyTimes(_keyTimes, splitTimes, offset, scale);
GradientUtil.DoVerticalGradient(verts, grad, splitTimes, offset, scale, rect, m);
InternalListPool<float>.Return(ref splitTimes);
break;
}
}
}

private void ApplyShadow(RectTransform transitionRoot, List<UIVertex> verts)
{
switch (shadowMode)
Expand Down
3 changes: 2 additions & 1 deletion Packages/src/Runtime/UIEffectTweener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public enum CullingMask
Tone = 1 << 0,
Color = 1 << 1,
Sampling = 1 << 2,
Transition = 1 << 3
Transition = 1 << 3,
Gradiation = 1 << 5
}

public enum UpdateMode
Expand Down
Loading

0 comments on commit bbe57df

Please sign in to comment.