using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UI; namespace Coffee.UIExtensions { /// /// HSV Modifier. /// [AddComponentMenu("UI/UIEffect/UIHsvModifier", 4)] public class UIHsvModifier : UIEffectBase { //################################ // Constant or Static Members. //################################ public const string shaderName = "UI/Hidden/UI-Effect-HSV"; static readonly ParameterTexture _ptex = new ParameterTexture(7, 128, "_ParamTex"); //################################ // Serialize Members. //################################ [Header("Target")] [Tooltip("Target color to affect hsv shift.")] [SerializeField] [ColorUsage(false)] Color m_TargetColor = Color.red; [Tooltip("Color range to affect hsv shift [0 ~ 1].")] [SerializeField] [Range(0, 1)] float m_Range = 0.1f; [Header("Adjustment")] [Tooltip("Hue shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)] float m_Hue; [Tooltip("Saturation shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)] float m_Saturation; [Tooltip("Value shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)] float m_Value; //################################ // Public Members. //################################ /// /// Target color to affect hsv shift. /// public Color targetColor { get { return m_TargetColor; } set { if (m_TargetColor != value) { m_TargetColor = value; SetDirty(); } } } /// /// Color range to affect hsv shift [0 ~ 1]. /// public float range { get { return m_Range; } set { value = Mathf.Clamp(value, 0, 1); if (!Mathf.Approximately(m_Range, value)) { m_Range = value; SetDirty(); } } } /// /// Saturation shift [-0.5 ~ 0.5]. /// public float saturation { get { return m_Saturation; } set { value = Mathf.Clamp(value, -0.5f, 0.5f); if (!Mathf.Approximately(m_Saturation, value)) { m_Saturation = value; SetDirty(); } } } /// /// Value shift [-0.5 ~ 0.5]. /// public float value { get { return m_Value; } set { value = Mathf.Clamp(value, -0.5f, 0.5f); if (!Mathf.Approximately(m_Value, value)) { m_Value = value; SetDirty(); } } } /// /// Hue shift [-0.5 ~ 0.5]. /// public float hue { get { return m_Hue; } set { value = Mathf.Clamp(value, -0.5f, 0.5f); if (!Mathf.Approximately(m_Hue, value)) { m_Hue = value; SetDirty(); } } } /// /// Gets the parameter texture. /// public override ParameterTexture ptex { get { return _ptex; } } #if UNITY_EDITOR protected override Material GetMaterial() { if (isTMPro) { return null; } return MaterialResolver.GetOrGenerateMaterialVariant(Shader.Find(shaderName)); } #endif /// /// Modifies the mesh. /// public override void ModifyMesh(VertexHelper vh) { if (!isActiveAndEnabled) return; float normalizedIndex = ptex.GetNormalizedIndex(this); UIVertex vertex = default(UIVertex); int count = vh.currentVertCount; for (int i = 0; i < count; i++) { vh.PopulateUIVertex(ref vertex, i); vertex.uv0 = new Vector2( Packer.ToFloat(vertex.uv0.x, vertex.uv0.y), normalizedIndex ); vh.SetUIVertex(vertex, i); } } protected override void SetDirty() { float h, s, v; Color.RGBToHSV(m_TargetColor, out h, out s, out v); foreach (var m in materials) { ptex.RegisterMaterial (m); } ptex.SetData(this, 0, h); // param1.x : target hue ptex.SetData(this, 1, s); // param1.y : target saturation ptex.SetData(this, 2, v); // param1.z : target value ptex.SetData(this, 3, m_Range); // param1.w : target range ptex.SetData(this, 4, m_Hue + 0.5f); // param2.x : hue shift ptex.SetData(this, 5, m_Saturation + 0.5f); // param2.y : saturation shift ptex.SetData(this, 6, m_Value + 0.5f); // param2.z : value shift } //################################ // Private Members. //################################ } }