From f33cc97eb9420e7d1cb03d1613fc6417642ce98c Mon Sep 17 00:00:00 2001 From: mob-sakai <12690315+mob-sakai@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:04:46 +0900 Subject: [PATCH] grad2 --- Packages/src/Editor/UIEffectEditor.cs | 6 + Packages/src/Runtime/UIEffect.cs | 39 ++++ Packages/src/Runtime/UIEffectContext.cs | 6 +- Packages/src/Runtime/UIEffectTweener.cs | 3 +- .../src/Runtime/Utilities/GradientUtil.cs | 172 +++++++++++++----- 5 files changed, 177 insertions(+), 49 deletions(-) diff --git a/Packages/src/Editor/UIEffectEditor.cs b/Packages/src/Editor/UIEffectEditor.cs index 83ff3498..ad018147 100644 --- a/Packages/src/Editor/UIEffectEditor.cs +++ b/Packages/src/Editor/UIEffectEditor.cs @@ -64,6 +64,8 @@ public class UIEffect2Editor : Editor private SerializedProperty _gradationColor1; private SerializedProperty _gradationColor2; private SerializedProperty _gradationGradient; + private SerializedProperty _gradationOffset; + private SerializedProperty _gradationScale; private bool _expandOthers; private SerializedProperty _allowExtendVertex; @@ -121,6 +123,8 @@ private void OnEnable() _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"); } @@ -280,6 +284,8 @@ public void DrawProperties() break; } + EditorGUILayout.PropertyField(_gradationOffset); + EditorGUILayout.PropertyField(_gradationScale); EditorGUI.indentLevel--; } diff --git a/Packages/src/Runtime/UIEffect.cs b/Packages/src/Runtime/UIEffect.cs index f13811a6..32dc3f04 100644 --- a/Packages/src/Runtime/UIEffect.cs +++ b/Packages/src/Runtime/UIEffect.cs @@ -147,6 +147,14 @@ public class UIEffect : UIEffectBase [SerializeField] private Gradient m_GradationGradient = new Gradient(); + [Range(-1, 1)] + [SerializeField] + protected float m_GradationOffset = 0; + + [Range(0.1f, 5)] + [SerializeField] + protected float m_GradationScale = 1; + [SerializeField] protected bool m_AllowExtendVertex = true; @@ -611,6 +619,28 @@ public Gradient gradationGradient } } + 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; @@ -711,6 +741,8 @@ protected override void UpdateContext(UIEffectContext c) c.gradationColor1 = m_GradationColor1; c.gradationColor2 = m_GradationColor2; c.gradationGradient = m_GradationGradient; + c.gradationOffset = m_GradationOffset; + c.gradationScale = m_GradationScale; c.allowExtendVertex = m_AllowExtendVertex; } @@ -745,6 +777,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) @@ -865,6 +902,8 @@ internal void CopyFrom(UIEffectContext c) m_GradationColor1 = c.gradationColor1; m_GradationColor2 = c.gradationColor2; m_GradationGradient = c.gradationGradient; + m_GradationOffset = c.gradationOffset; + m_GradationScale = c.gradationScale; m_AllowExtendVertex = c.allowExtendVertex; diff --git a/Packages/src/Runtime/UIEffectContext.cs b/Packages/src/Runtime/UIEffectContext.cs index 21b139f7..5f9e0b63 100644 --- a/Packages/src/Runtime/UIEffectContext.cs +++ b/Packages/src/Runtime/UIEffectContext.cs @@ -142,6 +142,8 @@ public class UIEffectContext public Color gradationColor2; public Gradient gradationGradient; public bool allowExtendVertex; + public float gradationOffset; + public float gradationScale; public bool willModifyMaterial => samplingFilter != SamplingFilter.None || transitionFilter != TransitionFilter.None @@ -203,6 +205,8 @@ public void CopyFrom(UIEffectContext preset) gradationColor1 = preset.gradationColor1; gradationColor2 = preset.gradationColor2; gradationGradient = preset.gradationGradient; + gradationOffset = preset.gradationOffset; + gradationScale = preset.gradationScale; allowExtendVertex = preset.allowExtendVertex; } @@ -423,7 +427,7 @@ public void ModifyMesh(Graphic graphic, RectTransform transitionRoot, VertexHelp // Apply gradation. GradientUtil.DoGradient(gradationMode, verts, gradationColor1, gradationColor2, gradationGradient, - transitionRoot.rect); + gradationOffset, gradationScale, transitionRoot.rect); // Apply shadow. switch (shadowMode) diff --git a/Packages/src/Runtime/UIEffectTweener.cs b/Packages/src/Runtime/UIEffectTweener.cs index fccd3b62..166ae2a3 100644 --- a/Packages/src/Runtime/UIEffectTweener.cs +++ b/Packages/src/Runtime/UIEffectTweener.cs @@ -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 diff --git a/Packages/src/Runtime/Utilities/GradientUtil.cs b/Packages/src/Runtime/Utilities/GradientUtil.cs index 385b94b0..ef8af694 100644 --- a/Packages/src/Runtime/Utilities/GradientUtil.cs +++ b/Packages/src/Runtime/Utilities/GradientUtil.cs @@ -9,111 +9,155 @@ public static class GradientUtil private static readonly List s_KeyTimes = new List(); public static void DoGradient(GradationMode mode, List verts, Color a, Color b, Gradient gradient, - Rect rect) + float offset, float scale, Rect rect) { switch (mode) { case GradationMode.Horizontal: - DoHorizontalGradient(verts, a, b, rect); + DoHorizontalGradient(verts, a, b, offset, scale, rect); break; case GradationMode.Vertical: - DoVerticalGradient(verts, a, b, rect); + DoVerticalGradient(verts, a, b, offset, scale, rect); break; case GradationMode.DiagonalLeftTopToRightBottom: - DoDiagonalGradientLeftTopToRightBottom(verts, a, b, rect); + DoDiagonalGradientLeftTopToRightBottom(verts, a, b, offset, scale, rect); break; case GradationMode.DiagonalRightTopToLeftBottom: - DoDiagonalGradientRightTopToLeftBottom(verts, a, b, rect); + DoDiagonalGradientRightTopToLeftBottom(verts, a, b, offset, scale, rect); break; case GradationMode.Radial: - DoRadialGradient(verts, a, b, rect); + DoRadialGradient(verts, a, b, offset, scale, rect); break; case GradationMode.HorizontalGradient: - DoHorizontalGradient(verts, gradient, rect); + DoHorizontalGradient(verts, gradient, offset, scale, rect); break; case GradationMode.VerticalGradient: - DoVerticalGradient(verts, gradient, rect); + DoVerticalGradient(verts, gradient, offset, scale, rect); break; } } - private static void DoHorizontalGradient(List verts, Color a, Color b, Rect rect) + private static void DoHorizontalGradient(List verts, Color a, Color b, float offset, float scale, + Rect rect) { - DoGradient(verts, a, b, rect, (x, y) => x); + DoGradient(verts, a, b, rect, + (x, y) => Mathf.Clamp01(offset + (x - 0.5f) * scale + 0.5f)); } - private static void DoHorizontalGradient(List verts, Gradient gradient, Rect rect) + private static void DoHorizontalGradient(List verts, Gradient gradient, float offset, float scale, + Rect rect) { - GetKeyTimes(gradient, s_KeyTimes); + GetKeyTimes(gradient, s_KeyTimes, offset, scale); var count = verts.Count; for (var i = 0; i < verts.Count; i += 6) { GetBundle(verts, i, out var lb, out var lt, out var rt, out var rb); - if (i + 5 < count) { SplitHorizontal(verts, lb, lt, ref rb, ref rt, rect, s_KeyTimes); } - lb.color *= gradient.Evaluate(Mathf.InverseLerp(rect.xMin, rect.xMax, lb.position.x + 0.0001f)); - lt.color *= gradient.Evaluate(Mathf.InverseLerp(rect.xMin, rect.xMax, lt.position.x + 0.0001f)); - rt.color *= gradient.Evaluate(Mathf.InverseLerp(rect.xMin, rect.xMax, rt.position.x - 0.0001f)); - rb.color *= gradient.Evaluate(Mathf.InverseLerp(rect.xMin, rect.xMax, rb.position.x - 0.0001f)); + lb.color *= EvaluateHorizontal(gradient, rect, lb.position.x + 0.0001f, offset, scale); + lt.color *= EvaluateHorizontal(gradient, rect, lt.position.x + 0.0001f, offset, scale); + rt.color *= EvaluateHorizontal(gradient, rect, rt.position.x - 0.0001f, offset, scale); + rb.color *= EvaluateHorizontal(gradient, rect, rb.position.x - 0.0001f, offset, scale); SetBundle(verts, i, lb, lt, rt, rb); } + + return; + + static Color EvaluateHorizontal(Gradient gradient, Rect rect, float t, float offset, float scale) + { + var t0 = t; + t = Mathf.InverseLerp(rect.xMin, rect.xMax, t); + var t1 = t; + t = Mathf.Repeat(t * scale - offset, 1); + var t2 = t; + Console.WriteLine($"{t0} -> {t1} -> {t2}"); + return gradient.Evaluate(t); + } } - private static void DoVerticalGradient(List verts, Color a, Color b, Rect rect) + private static void DoVerticalGradient(List verts, Color a, Color b, float offset, float scale, + Rect rect) { - DoGradient(verts, a, b, rect, (x, y) => 1 - y); + DoGradient(verts, a, b, rect, + (x, y) => Mathf.Clamp01(offset + (0.5f - y) * scale + 0.5f)); } - private static void DoVerticalGradient(List verts, Gradient gradient, Rect rect) + private static void DoVerticalGradient(List verts, Gradient gradient, float offset, float scale, + Rect rect) { - GetKeyTimes(gradient, s_KeyTimes); + GetKeyTimes(gradient, s_KeyTimes, offset, scale); var count = verts.Count; for (var i = 0; i < verts.Count; i += 6) { GetBundle(verts, i, out var lb, out var lt, out var rt, out var rb); - if (i + 5 < count) { SplitVertical(verts, lb, ref lt, rb, ref rt, rect, s_KeyTimes); } - lb.color *= gradient.Evaluate(Mathf.InverseLerp(rect.yMin, rect.yMax, lb.position.y + 0.0001f)); - lt.color *= gradient.Evaluate(Mathf.InverseLerp(rect.yMin, rect.yMax, lt.position.y - 0.0001f)); - rt.color *= gradient.Evaluate(Mathf.InverseLerp(rect.yMin, rect.yMax, rt.position.y - 0.0001f)); - rb.color *= gradient.Evaluate(Mathf.InverseLerp(rect.yMin, rect.yMax, rb.position.y + 0.0001f)); + lb.color *= EvaluateVertical(gradient, rect, lb.position.y + 0.0001f, offset, scale); + lt.color *= EvaluateVertical(gradient, rect, lt.position.y + 0.0001f, offset, scale); + rt.color *= EvaluateVertical(gradient, rect, rt.position.y - 0.0001f, offset, scale); + rb.color *= EvaluateVertical(gradient, rect, rb.position.y - 0.0001f, offset, scale); SetBundle(verts, i, lb, lt, rt, rb); } + + return; + + static Color EvaluateVertical(Gradient gradient, Rect rect, float t, float offset, float scale) + { + t = Mathf.InverseLerp(rect.yMin, rect.yMax, t); + t = Mathf.Repeat(t * scale + offset, 1); + return gradient.Evaluate(t); + } } - private static void DoDiagonalGradientLeftTopToRightBottom(List verts, Color a, Color b, Rect rect) + private static void DoDiagonalGradientLeftTopToRightBottom(List verts, Color a, Color b, float offset, + float scale, + Rect rect) { - DoGradient(verts, a, b, rect, (x, y) => 1 - (1 - x + y) / 2); + DoGradient(verts, a, b, rect, + (x, y) => Mathf.Clamp01(0.5f * scale + 0.5f + offset - (1 - x + y) * scale / 2)); } - private static void DoDiagonalGradientRightTopToLeftBottom(List verts, Color a, Color b, Rect rect) + private static void DoDiagonalGradientRightTopToLeftBottom(List verts, Color a, Color b, float offset, + float scale, + Rect rect) { - DoGradient(verts, a, b, rect, (x, y) => 1 - (x + y) / 2); + DoGradient(verts, a, b, rect, + (x, y) => Mathf.Clamp01(0.5f * scale + 0.5f + offset - (x + y) * scale / 2)); } - private static void DoRadialGradient(List verts, Color a, Color b, Rect rect) + private static void DoRadialGradient(List verts, Color a, Color b, float offset, float scale, + Rect rect) { + var d = 20; var count = verts.Count; + for (var i = 0; i < count; i += 6) + { + GetBundle(verts, i, out var lb, out var lt, out var rt, out var rb); + for (var j = 1; j < d; j++) + { + SplitHorizontal(verts, lb, lt, ref rb, ref rt, rect, 1f - (float)j / d); + } + + SetBundle(verts, i, lb, lt, rt, rb); + } + + count = verts.Count; for (var i = 0; i < verts.Count; i += 6) { GetBundle(verts, i, out var lb, out var lt, out var rt, out var rb); if (i + 5 < count) { - SplitHorizontal(verts, lb, lt, ref rb, ref rt, rect, 0.25f); - SplitHorizontal(verts, lb, lt, ref rb, ref rt, rect, 0.5f); - SplitHorizontal(verts, lb, lt, ref rb, ref rt, rect, 0.75f); - SplitVertical(verts, lb, ref lt, rb, ref rt, rect, 0.25f); - SplitVertical(verts, lb, ref lt, rb, ref rt, rect, 0.5f); - SplitVertical(verts, lb, ref lt, rb, ref rt, rect, 0.75f); + for (var j = 1; j < d; j++) + { + SplitVertical(verts, lb, ref lt, rb, ref rt, rect, 1f - (float)j / d); + } } lb.color *= DoGradient(lb, a, b, rect, Rad); @@ -127,7 +171,7 @@ float Rad(float x, float y) { x -= 0.5f; y -= 0.5f; - return Mathf.Sqrt(x * x + y * y) * 2; + return Mathf.Clamp01(offset + Mathf.Sqrt(x * x + y * y) * 2 * scale); } } } @@ -228,30 +272,64 @@ private static void SplitVertical(List verts, UIVertex lb, ref UIVerte rt = rm; } - private static void GetKeyTimes(Gradient gradient, List results) + private static void GetKeyTimes(Gradient gradient, List results, float offset, float scale) { results.Clear(); var colors = gradient.colorKeys; for (var i = 0; i < colors.Length; i++) { - var t = colors[i].time; - if (t <= 0 || 1 <= t) continue; - - results.Add(colors[i].time); + hogehoe(results, colors[i].time, offset, scale); } var alphas = gradient.alphaKeys; for (var i = 0; i < alphas.Length; i++) { - var t = alphas[i].time; - if (t <= 0 || 1 <= t || results.Contains(t)) continue; - - results.Add(t); + hogehoe(results, alphas[i].time, offset, scale); } + hogehoe(results, 0, offset, scale); + hogehoe(results, 1, offset, scale); results.Sort((a, b) => b.CompareTo(a)); } + static void hogehoe(List results, float value, float offset, float scale) + { + scale = 1f / scale; + value = value * scale + offset - 1; + while (value < 1f) + { + if (0 < value && results.FindIndex(x => Mathf.Abs(x - value) < 0.001f) < 0) + { + results.Add(value); + } + + value += scale; + } + } + + static List ApplyScaleOffsetAndRepeat(List aValues, double scale, double offset) + { + var result = new List(); + + foreach (var a in aValues) + { + // スケールとオフセットを適用 + double value = a / scale - offset; + + // 0〜1の範囲にラップ + value = (value % 1.0 + 1.0) % 1.0; + + // 出力をリストに追加し、1未満の間ループで追加 + while (value < 1.0) + { + result.Add(value); + value += scale; // スケール値を加算 + } + } + + return result; + } + private static void GetBundle(List verts, int i, out UIVertex lb, out UIVertex lt, out UIVertex rt, out UIVertex rb) {