Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
mob-sakai committed Dec 13, 2024
1 parent e370c41 commit ef18e70
Show file tree
Hide file tree
Showing 11 changed files with 264 additions and 222 deletions.
2 changes: 0 additions & 2 deletions Packages/src/Editor/UIEffectEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ public void DrawProperties()
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_toneIntensity);

EditorGUI.indentLevel--;
}

Expand Down Expand Up @@ -195,7 +194,6 @@ public void DrawProperties()
if (!DrawHeaderPopup(_blendType))
{
EditorGUI.indentLevel++;

EditorGUILayout.PropertyField(_srcBlendMode);
EditorGUILayout.PropertyField(_dstBlendMode);
EditorGUI.indentLevel--;
Expand Down
159 changes: 5 additions & 154 deletions Packages/src/Runtime/UIEffectContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using Coffee.UIEffectInternal;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
Expand All @@ -13,7 +11,6 @@ namespace Coffee.UIEffects
{
public class UIEffectContext
{
private const float k_MaxEffectDistance = 600f;
private static readonly UIEffectContext s_DefaultContext = new UIEffectContext();
private static readonly List<UIVertex> s_WorkingVertices = new List<UIVertex>();
private static readonly int s_SrcBlend = Shader.PropertyToID("_SrcBlend");
Expand Down Expand Up @@ -135,7 +132,6 @@ public class UIEffectContext
public float shadowFade = 0.9f;
public bool shadowEffectOnOrigin = false;
public float shadowMirrorScale = 0.5f;
// public RectTransform transitionRoot;

public bool willModifyMaterial => samplingFilter != SamplingFilter.None
|| transitionFilter != TransitionFilter.None
Expand Down Expand Up @@ -390,34 +386,12 @@ public void ModifyMesh(Graphic graphic, RectTransform transitionRoot, VertexHelp
}
}

// Apply shadow.
if (shadowMode != ShadowMode.None)
{
var start = 0;
var end = count;
if (shadowMode == ShadowMode.Mirror)
{
var rect2 = transitionRoot.rect;
var pivot = transitionRoot.pivot.y;
var height = rect2.height;
var rate = shadowDistance.x;
var scale = shadowMirrorScale;
var offset = shadowDistance.y - (scale + 1) * pivot * height;
var range = new Vector2(rect2.yMin, rect2.yMax);
ApplyMirror(s_WorkingVertices, count, rate, range, scale, offset, shadowFade);
}
else
{
var d = Vector2.zero;
var a = 1f;
var distance = new Vector2(Mathf.Clamp(shadowDistance.x, -k_MaxEffectDistance, k_MaxEffectDistance),
Mathf.Clamp(shadowDistance.y, -k_MaxEffectDistance, k_MaxEffectDistance));
for (var i = 0; i < shadowIteration; i++)
{
d += distance / (i + 1);
a *= shadowFade;
ApplyShadow(s_WorkingVertices, ref start, ref end, d, shadowMode, a);
}
}
count = s_WorkingVertices.Count;
ShadowUtil.DoShadow(shadowMode, s_WorkingVertices, shadowDistance, shadowIteration, shadowMirrorScale,
shadowFade, transitionRoot);

// Mark as origin vertices.
if (!shadowEffectOnOrigin)
Expand Down Expand Up @@ -556,128 +530,5 @@ private static void GetBounds(List<UIVertex> verts, int start, int count, out Re
maxPos.x - minPos.x - 0.002f, maxPos.y - minPos.y - 0.002f);
uvBounds = new Rect(minUV.x, minUV.y, maxUV.x - minUV.x, maxUV.y - minUV.y);
}

private static void ApplyMirror(List<UIVertex> verts, int count, float rate, Vector2 range, float scale,
float offset, float alpha)
{
rate = Mathf.Clamp01(rate);
var start = 0;
var end = count;
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, 0, alpha);

for (var i = 0; i < count; i += 6)
{
var lb = s_WorkingVertices[i];
var lbRate = Mathf.InverseLerp(range.x, range.y, lb.position.y);
var lt = s_WorkingVertices[i + 1];
var ltRate = Mathf.InverseLerp(range.x, range.y, lt.position.y);
var rt = s_WorkingVertices[i + 2];
var rtRate = Mathf.InverseLerp(range.x, range.y, rt.position.y);
var rb = s_WorkingVertices[i + 4];
var rbRate = Mathf.InverseLerp(range.x, range.y, rb.position.y);

lb.color.a = (byte)(Mathf.InverseLerp(rate, 0, lbRate) * lb.color.a);
lt.color.a = (byte)(Mathf.InverseLerp(rate, 0, ltRate) * lt.color.a);
rt.color.a = (byte)(Mathf.InverseLerp(rate, 0, rtRate) * rt.color.a);
rb.color.a = (byte)(Mathf.InverseLerp(rate, 0, rbRate) * rb.color.a);

if (lbRate < rate && rate < ltRate)
{
var t = (rate - lbRate) / (ltRate - lbRate);
lt.position = Vector3.Lerp(lb.position, lt.position, t);
lt.uv0 = Vector4.Lerp(lb.uv0, lt.uv0, t);
lt.uv1 = Vector4.Lerp(lb.uv1, lt.uv1, t);
lt.uv2 = Vector4.Lerp(lb.uv2, lt.uv2, t);
lt.color = Color.Lerp(lb.color, lt.color, t);
}

if (rbRate < rate && rate < rtRate)
{
var t = (rate - rbRate) / (rtRate - rbRate);
rt.position = Vector3.Lerp(rb.position, rt.position, t);
rt.uv0 = Vector4.Lerp(rb.uv0, rt.uv0, t);
rt.uv1 = Vector4.Lerp(rb.uv1, rt.uv1, t);
rt.uv2 = Vector4.Lerp(rb.uv2, rt.uv2, t);
rt.color = Color.Lerp(rb.color, rt.color, t);
}


lb.position.y = -lb.position.y * scale + offset;
lt.position.y = -lt.position.y * scale + offset;
rt.position.y = -rt.position.y * scale + offset;
rb.position.y = -rb.position.y * scale + offset;

s_WorkingVertices[i] = s_WorkingVertices[i + 5] = lb;
s_WorkingVertices[i + 1] = lt;
s_WorkingVertices[i + 2] = s_WorkingVertices[i + 3] = rt;
s_WorkingVertices[i + 4] = rb;
}
}

/// <summary>
/// Append shadow vertices.
/// * It is similar to Shadow component implementation.
/// </summary>
private static void ApplyShadow(List<UIVertex> verts, ref int start, ref int end, Vector2 distance,
ShadowMode mode, float alpha)
{
if (mode == ShadowMode.None) return;

var x = distance.x;
var y = distance.y;
switch (mode)
{
case ShadowMode.Shadow:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
break;
case ShadowMode.Shadow3:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, 0, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, y, alpha);
break;
case ShadowMode.Outline:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, -y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, -y, alpha);
break;
case ShadowMode.Outline8:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, -y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, -y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, 0, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, 0, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, -y, alpha);
break;
}
}

/// <summary>
/// Append shadow vertices.
/// * It is similar to Shadow component implementation.
/// </summary>
private static void ApplyShadowZeroAlloc(List<UIVertex> verts, ref int start, ref int end, float x, float y,
float alpha)
{
var count = end - start;
for (var i = 0; i < count; i++)
{
// The original vertices is pushed backward.
verts.Add(verts[end - count + i]);

// Set shadow vertex.
var vt = verts[start + i];
vt.position.x += x;
vt.position.y += y;
vt.color.a = (byte)(alpha * vt.color.a);
verts[start + i] = vt;
}

// Update next shadow offset.
start = end;
end = verts.Count;
}
}
}
8 changes: 8 additions & 0 deletions Packages/src/Runtime/Utilities.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

164 changes: 164 additions & 0 deletions Packages/src/Runtime/Utilities/ShadowUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
using System.Collections.Generic;
using UnityEngine;

namespace Coffee.UIEffects
{
public static class ShadowUtil
{
public static void DoShadow(ShadowMode mode, List<UIVertex> verts, Vector2 distance, int iteration,
float mirrorScale, float fade, RectTransform root)
{
if (mode == ShadowMode.None) return;

distance = new Vector2(Mathf.Clamp(distance.x, -600, 600), Mathf.Clamp(distance.y, -600, 600));
var count = verts.Count;
var start = 0;
var end = count;
if (mode == ShadowMode.Mirror)
{
var rect2 = root.rect;
var pivot = root.pivot.y;
var height = rect2.height;
var rate = distance.x;
var scale = mirrorScale;
var offset = distance.y - (scale + 1) * pivot * height;
var range = new Vector2(rect2.yMin, rect2.yMax);
ApplyMirror(verts, count, rate, range, scale, offset, fade);
}
else
{
var d = Vector2.zero;
var a = 1f;
for (var i = 0; i < iteration; i++)
{
d += distance / (i + 1);
a *= fade;
ApplyShadow(verts, ref start, ref end, d, mode, a);
}
}
}

private static void ApplyMirror(List<UIVertex> verts, int count, float rate, Vector2 range, float scale,
float offset, float alpha)
{
rate = Mathf.Clamp01(rate);
var start = 0;
var end = count;
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, 0, alpha);

for (var i = 0; i < count; i += 6)
{
var lb = verts[i];
var lbRate = Mathf.InverseLerp(range.x, range.y, lb.position.y);
var lt = verts[i + 1];
var ltRate = Mathf.InverseLerp(range.x, range.y, lt.position.y);
var rt = verts[i + 2];
var rtRate = Mathf.InverseLerp(range.x, range.y, rt.position.y);
var rb = verts[i + 4];
var rbRate = Mathf.InverseLerp(range.x, range.y, rb.position.y);

lb.color.a = (byte)(Mathf.InverseLerp(rate, 0, lbRate) * lb.color.a);
lt.color.a = (byte)(Mathf.InverseLerp(rate, 0, ltRate) * lt.color.a);
rt.color.a = (byte)(Mathf.InverseLerp(rate, 0, rtRate) * rt.color.a);
rb.color.a = (byte)(Mathf.InverseLerp(rate, 0, rbRate) * rb.color.a);

if (lbRate < rate && rate < ltRate)
{
var t = (rate - lbRate) / (ltRate - lbRate);
lt.position = Vector3.Lerp(lb.position, lt.position, t);
lt.uv0 = Vector4.Lerp(lb.uv0, lt.uv0, t);
lt.uv1 = Vector4.Lerp(lb.uv1, lt.uv1, t);
lt.uv2 = Vector4.Lerp(lb.uv2, lt.uv2, t);
lt.color = Color.Lerp(lb.color, lt.color, t);
}

if (rbRate < rate && rate < rtRate)
{
var t = (rate - rbRate) / (rtRate - rbRate);
rt.position = Vector3.Lerp(rb.position, rt.position, t);
rt.uv0 = Vector4.Lerp(rb.uv0, rt.uv0, t);
rt.uv1 = Vector4.Lerp(rb.uv1, rt.uv1, t);
rt.uv2 = Vector4.Lerp(rb.uv2, rt.uv2, t);
rt.color = Color.Lerp(rb.color, rt.color, t);
}


lb.position.y = -lb.position.y * scale + offset;
lt.position.y = -lt.position.y * scale + offset;
rt.position.y = -rt.position.y * scale + offset;
rb.position.y = -rb.position.y * scale + offset;

verts[i] = verts[i + 5] = lb;
verts[i + 1] = lt;
verts[i + 2] = verts[i + 3] = rt;
verts[i + 4] = rb;
}
}

/// <summary>
/// Append shadow vertices.
/// * It is similar to Shadow component implementation.
/// </summary>
private static void ApplyShadow(List<UIVertex> verts, ref int start, ref int end, Vector2 distance,
ShadowMode mode, float alpha)
{
if (mode == ShadowMode.None) return;

var x = distance.x;
var y = distance.y;
switch (mode)
{
case ShadowMode.Shadow:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
break;
case ShadowMode.Shadow3:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, 0, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, y, alpha);
break;
case ShadowMode.Outline:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, -y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, -y, alpha);
break;
case ShadowMode.Outline8:
ApplyShadowZeroAlloc(verts, ref start, ref end, x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, -y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, -y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, x, 0, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, y, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, -x, 0, alpha);
ApplyShadowZeroAlloc(verts, ref start, ref end, 0, -y, alpha);
break;
}
}

/// <summary>
/// Append shadow vertices.
/// * It is similar to Shadow component implementation.
/// </summary>
private static void ApplyShadowZeroAlloc(List<UIVertex> verts, ref int start, ref int end, float x, float y,
float alpha)
{
var count = end - start;
for (var i = 0; i < count; i++)
{
// The original vertices is pushed backward.
verts.Add(verts[end - count + i]);

// Set shadow vertex.
var vt = verts[start + i];
vt.position.x += x;
vt.position.y += y;
vt.color.a = (byte)(alpha * vt.color.a);
verts[start + i] = vt;
}

// Update next shadow offset.
start = end;
end = verts.Count;
}
}
}
11 changes: 11 additions & 0 deletions Packages/src/Runtime/Utilities/ShadowUtil.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ef18e70

Please sign in to comment.