UIHsvModifier.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.Serialization;
  4. using UnityEngine.UI;
  5. namespace Coffee.UIEffects
  6. {
  7. /// <summary>
  8. /// HSV Modifier.
  9. /// </summary>
  10. [AddComponentMenu("UI/UIEffects/UIHsvModifier", 4)]
  11. public class UIHsvModifier : BaseMaterialEffect
  12. {
  13. private const uint k_ShaderId = 6 << 3;
  14. private static readonly ParameterTexture s_ParamTex = new ParameterTexture(7, 128, "_ParamTex");
  15. [Header("Target")] [Tooltip("Target color to affect hsv shift.")] [SerializeField] [ColorUsage(false)]
  16. Color m_TargetColor = Color.red;
  17. [Tooltip("Color range to affect hsv shift [0 ~ 1].")] [SerializeField] [Range(0, 1)]
  18. float m_Range = 0.1f;
  19. [Header("Adjustment")] [Tooltip("Hue shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
  20. float m_Hue;
  21. [Tooltip("Saturation shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
  22. float m_Saturation;
  23. [Tooltip("Value shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
  24. float m_Value;
  25. /// <summary>
  26. /// Target color to affect hsv shift.
  27. /// </summary>
  28. public Color targetColor
  29. {
  30. get { return m_TargetColor; }
  31. set
  32. {
  33. if (m_TargetColor == value) return;
  34. m_TargetColor = value;
  35. SetEffectParamsDirty();
  36. }
  37. }
  38. /// <summary>
  39. /// Color range to affect hsv shift [0 ~ 1].
  40. /// </summary>
  41. public float range
  42. {
  43. get { return m_Range; }
  44. set
  45. {
  46. value = Mathf.Clamp(value, 0, 1);
  47. if (Mathf.Approximately(m_Range, value)) return;
  48. m_Range = value;
  49. SetEffectParamsDirty();
  50. }
  51. }
  52. /// <summary>
  53. /// Saturation shift [-0.5 ~ 0.5].
  54. /// </summary>
  55. public float saturation
  56. {
  57. get { return m_Saturation; }
  58. set
  59. {
  60. value = Mathf.Clamp(value, -0.5f, 0.5f);
  61. if (Mathf.Approximately(m_Saturation, value)) return;
  62. m_Saturation = value;
  63. SetEffectParamsDirty();
  64. }
  65. }
  66. /// <summary>
  67. /// Value shift [-0.5 ~ 0.5].
  68. /// </summary>
  69. public float value
  70. {
  71. get { return m_Value; }
  72. set
  73. {
  74. value = Mathf.Clamp(value, -0.5f, 0.5f);
  75. if (Mathf.Approximately(m_Value, value)) return;
  76. m_Value = value;
  77. SetEffectParamsDirty();
  78. }
  79. }
  80. /// <summary>
  81. /// Hue shift [-0.5 ~ 0.5].
  82. /// </summary>
  83. public float hue
  84. {
  85. get { return m_Hue; }
  86. set
  87. {
  88. value = Mathf.Clamp(value, -0.5f, 0.5f);
  89. if (Mathf.Approximately(m_Hue, value)) return;
  90. m_Hue = value;
  91. SetEffectParamsDirty();
  92. }
  93. }
  94. /// <summary>
  95. /// Gets the parameter texture.
  96. /// </summary>
  97. public override ParameterTexture paramTex
  98. {
  99. get { return s_ParamTex; }
  100. }
  101. public override Hash128 GetMaterialHash(Material material)
  102. {
  103. if (!isActiveAndEnabled || !material || !material.shader)
  104. return k_InvalidHash;
  105. return new Hash128(
  106. (uint) material.GetInstanceID(),
  107. k_ShaderId,
  108. 0,
  109. 0
  110. );
  111. }
  112. public override void ModifyMaterial(Material newMaterial, Graphic graphic)
  113. {
  114. var connector = GraphicConnector.FindConnector(graphic);
  115. newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIHsvModifier)", newMaterial.shader.name));
  116. paramTex.RegisterMaterial(newMaterial);
  117. }
  118. public override void ModifyMesh(VertexHelper vh, Graphic graphic)
  119. {
  120. if (!isActiveAndEnabled)
  121. return;
  122. var normalizedIndex = paramTex.GetNormalizedIndex(this);
  123. var vertex = default(UIVertex);
  124. var count = vh.currentVertCount;
  125. for (var i = 0; i < count; i++)
  126. {
  127. vh.PopulateUIVertex(ref vertex, i);
  128. vertex.uv0 = new Vector2(
  129. Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
  130. normalizedIndex
  131. );
  132. vh.SetUIVertex(vertex, i);
  133. }
  134. }
  135. protected override void SetEffectParamsDirty()
  136. {
  137. float h, s, v;
  138. Color.RGBToHSV(m_TargetColor, out h, out s, out v);
  139. paramTex.SetData(this, 0, h); // param1.x : target hue
  140. paramTex.SetData(this, 1, s); // param1.y : target saturation
  141. paramTex.SetData(this, 2, v); // param1.z : target value
  142. paramTex.SetData(this, 3, m_Range); // param1.w : target range
  143. paramTex.SetData(this, 4, m_Hue + 0.5f); // param2.x : hue shift
  144. paramTex.SetData(this, 5, m_Saturation + 0.5f); // param2.y : saturation shift
  145. paramTex.SetData(this, 6, m_Value + 0.5f); // param2.z : value shift
  146. }
  147. }
  148. }