MaskAAA.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.Rendering;
  5. using UnityEngine.Serialization;
  6. namespace UnityEngine.UI
  7. {
  8. [AddComponentMenu("UI/MaskAAA", 13)]
  9. [ExecuteAlways]
  10. [RequireComponent(typeof(RectTransform))]
  11. [DisallowMultipleComponent]
  12. /// <summary>
  13. /// A component for masking children elements.
  14. /// </summary>
  15. /// <remarks>
  16. /// By using this element any children elements that have masking enabled will mask where a sibling Graphic would write 0 to the stencil buffer.
  17. /// </remarks>
  18. public class MaskAAA : UnityEngine.UI.Mask
  19. {
  20. public bool m_ShowMaskGraphic
  21. {
  22. get { return showMaskGraphic; }
  23. }
  24. private Material m_MaskMaterial;
  25. private Material m_UnmaskMaterial;
  26. /// Stencil calculation time!
  27. public override Material GetModifiedMaterial(Material baseMaterial)
  28. {
  29. if (!MaskEnabled())
  30. return baseMaterial;
  31. var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);
  32. var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas);
  33. if (stencilDepth >= 8)
  34. {
  35. Debug.LogWarning("Attempting to use a stencil mask with depth > 8", gameObject);
  36. return baseMaterial;
  37. }
  38. int desiredStencilBit = 1 << stencilDepth;
  39. // if we are at the first level...
  40. // we want to destroy what is there
  41. if (desiredStencilBit == 1)
  42. {
  43. var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0);
  44. StencilMaterial.Remove(m_MaskMaterial);
  45. m_MaskMaterial = maskMaterial;
  46. // var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0);
  47. // StencilMaterial.Remove(m_UnmaskMaterial);
  48. // m_UnmaskMaterial = unmaskMaterial;
  49. // graphic.canvasRenderer.popMaterialCount = 1;
  50. // graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);
  51. return m_MaskMaterial;
  52. }
  53. //otherwise we need to be a bit smarter and set some read / write masks
  54. var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));
  55. StencilMaterial.Remove(m_MaskMaterial);
  56. m_MaskMaterial = maskMaterial2;
  57. graphic.canvasRenderer.hasPopInstruction = true;
  58. var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));
  59. StencilMaterial.Remove(m_UnmaskMaterial);
  60. m_UnmaskMaterial = unmaskMaterial2;
  61. graphic.canvasRenderer.popMaterialCount = 1;
  62. graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);
  63. return m_MaskMaterial;
  64. }
  65. }
  66. }