157 lines
6.4 KiB
Diff
157 lines
6.4 KiB
Diff
diff --git a/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectBase.cs b/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectBase.cs
|
||
index c3ceb2fd..210257d0 100644
|
||
--- a/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectBase.cs
|
||
+++ b/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectBase.cs
|
||
@@ -196,8 +196,11 @@ namespace Coffee.UIEffects
|
||
|
||
Profiler.BeginSample("(UIE)[UIEffect] GetModifiedMaterial");
|
||
var samplingScaleId = (uint)(Mathf.InverseLerp(0.01f, 100, actualSamplingScale) * uint.MaxValue);
|
||
- var rootId = (uint)(transitionRoot != null ? transitionRoot.GetHashCode() : 0);
|
||
- var hash = new Hash128((uint)baseMaterial.GetHashCode(), effectId, samplingScaleId, rootId);
|
||
+ // 使用特效配置哈希作为材质共享 key,相同配置的特效共享同一材质,从而可以合批。
|
||
+ // root 仅在特效需要视图矩阵(transition/gradation/detail/shiny)时才影响材质。
|
||
+ var configId = context.configId;
|
||
+ var rootId = context.useViewMatrix && transitionRoot ? (uint)transitionRoot.GetInstanceID() : 0u;
|
||
+ var hash = new Hash128((uint)baseMaterial.GetInstanceID(), configId, samplingScaleId, rootId);
|
||
if (!MaterialRepository.Valid(hash, _material))
|
||
{
|
||
Profiler.BeginSample("(UIE)[UIEffect] GetModifiedMaterial > Get or create material");
|
||
diff --git a/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectContext.cs b/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectContext.cs
|
||
index c315f4cb..48b6ae4b 100644
|
||
--- a/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectContext.cs
|
||
+++ b/unity/my_libs/unityLib/UIEffect-main/Packages/src/Runtime/UIEffectContext.cs
|
||
@@ -1,5 +1,6 @@
|
||
using System;
|
||
using System.Collections.Generic;
|
||
+using System.Reflection;
|
||
using Coffee.UIEffectInternal;
|
||
using UnityEngine;
|
||
using UnityEngine.Profiling;
|
||
@@ -263,6 +264,126 @@ namespace Coffee.UIEffects
|
||
|| m_DetailFilter != DetailFilter.None
|
||
|| m_EdgeMode == EdgeMode.Shiny;
|
||
|
||
+ /// <summary>
|
||
+ /// 特效配置的稳定指纹。自动遍历所有序列化配置字段生成,因此插件新增属性时无需手动维护字段清单。
|
||
+ /// 相同配置会得到相同指纹,从而可以共享同一个材质并参与合批。
|
||
+ /// </summary>
|
||
+ public uint configId
|
||
+ {
|
||
+ get
|
||
+ {
|
||
+ unchecked
|
||
+ {
|
||
+ var h = (uint)2166136261;
|
||
+ var fields = s_ConfigFields;
|
||
+ for (var i = 0; i < fields.Length; i++)
|
||
+ {
|
||
+ var f = fields[i];
|
||
+ h = Mix(h, (uint)f.Name.GetHashCode());
|
||
+ h = Mix(h, HashValue(f.GetValue(this)));
|
||
+ }
|
||
+
|
||
+ // Avalanche 混淆(MurmurHash3 终混),让相近配置散列到不同指纹。
|
||
+ h ^= h >> 16;
|
||
+ h *= 0x85ebca6b;
|
||
+ h ^= h >> 13;
|
||
+ h *= 0xc2b2ae35;
|
||
+ h ^= h >> 16;
|
||
+ return h;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+ private static uint Mix(uint h, uint v)
|
||
+ {
|
||
+ h ^= v;
|
||
+ h *= 16777619;
|
||
+ return h;
|
||
+ }
|
||
+
|
||
+ /// <summary>
|
||
+ /// 对任意配置值做内容哈希。值类型会逐字段展开,嵌套结构体(Color、Vector2/3/4、MinMax01 等)
|
||
+ /// 无需单独写类型处理即可贡献全部数据。只有 UnityEngine.Object 和 Gradient 需要显式处理,
|
||
+ /// 因为它们的默认哈希基于引用而非内容。
|
||
+ /// </summary>
|
||
+ private static uint HashValue(object value)
|
||
+ {
|
||
+ if (value == null) return 0u;
|
||
+
|
||
+ if (value is UnityEngine.Object obj)
|
||
+ {
|
||
+ return obj ? (uint)obj.GetInstanceID() : 0u;
|
||
+ }
|
||
+
|
||
+ if (value is Gradient gradient)
|
||
+ {
|
||
+ return GradientHash(gradient);
|
||
+ }
|
||
+
|
||
+ var type = value.GetType();
|
||
+ if (type.IsPrimitive || type.IsEnum)
|
||
+ {
|
||
+ return unchecked((uint)value.GetHashCode());
|
||
+ }
|
||
+
|
||
+ if (type.IsValueType)
|
||
+ {
|
||
+ return HashFields(value, type);
|
||
+ }
|
||
+
|
||
+ return unchecked((uint)value.GetHashCode());
|
||
+ }
|
||
+
|
||
+ private static uint HashFields(object boxed, Type type)
|
||
+ {
|
||
+ unchecked
|
||
+ {
|
||
+ if (!s_FieldCache.TryGetValue(type, out var fields))
|
||
+ {
|
||
+ fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||
+ s_FieldCache[type] = fields;
|
||
+ }
|
||
+
|
||
+ var h = (uint)2166136261;
|
||
+ for (var i = 0; i < fields.Length; i++)
|
||
+ {
|
||
+ h = Mix(h, HashValue(fields[i].GetValue(boxed)));
|
||
+ }
|
||
+
|
||
+ return h;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ private static uint GradientHash(Gradient gradient)
|
||
+ {
|
||
+ unchecked
|
||
+ {
|
||
+ var h = (uint)2166136261;
|
||
+
|
||
+ var colorKeys = gradient.colorKeys;
|
||
+ for (var i = 0; i < colorKeys.Length; i++)
|
||
+ {
|
||
+ h = Mix(h, HashValue(colorKeys[i].color));
|
||
+ h = Mix(h, HashValue(colorKeys[i].time));
|
||
+ }
|
||
+
|
||
+ var alphaKeys = gradient.alphaKeys;
|
||
+ for (var i = 0; i < alphaKeys.Length; i++)
|
||
+ {
|
||
+ h = Mix(h, HashValue(alphaKeys[i].alpha));
|
||
+ h = Mix(h, HashValue(alphaKeys[i].time));
|
||
+ }
|
||
+
|
||
+ return h;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ private static readonly FieldInfo[] s_ConfigFields = typeof(UIEffectContext)
|
||
+ .GetFields(BindingFlags.Public | BindingFlags.Instance);
|
||
+
|
||
+ private static readonly Dictionary<Type, FieldInfo[]> s_FieldCache =
|
||
+ new Dictionary<Type, FieldInfo[]>();
|
||
+
|
||
private Texture2D _gradationRampTex;
|
||
private Texture2D _transitionRampTex;
|
||
private bool _isGradientDirty = true;
|