Files
2026-09-10 17:29:24 +08:00

157 lines
6.4 KiB
Diff
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;