CanvasMeshRenderer.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. namespace Rokid.UXR.Interaction
  2. {
  3. using UnityEngine;
  4. using UnityEngine.Profiling;
  5. using UnityEngine.Assertions;
  6. public enum RenderingMode
  7. {
  8. [InspectorName("Alpha-Blended")]
  9. AlphaBlended = 0,
  10. [InspectorName("Alpha-Cutout")]
  11. AlphaCutout,
  12. [InspectorName("Opaque")]
  13. Opaque,
  14. }
  15. public class CanvasMeshRenderer : MonoBehaviour
  16. {
  17. private static readonly int MainTexShaderID = Shader.PropertyToID("_MainTex");
  18. [SerializeField]
  19. protected CanvasRenderTexture _canvasRenderTexture;
  20. [SerializeField]
  21. protected MeshRenderer _meshRenderer;
  22. [SerializeField]
  23. protected int _renderingMode = (int)RenderingMode.AlphaCutout;
  24. [Tooltip("Requires MSAA. Provides limited transparency useful for " +
  25. "anti-aliasing soft edges of UI elements.")]
  26. [SerializeField]
  27. private bool _useAlphaToMask = true;
  28. [Tooltip("Select the alpha cutoff used for the cutout rendering.")]
  29. [Range(0, 1)]
  30. [SerializeField]
  31. private float _alphaCutoutThreshold = 0.5f;
  32. private RenderingMode RenderingMode => (RenderingMode)_renderingMode;
  33. protected virtual string GetShaderName()
  34. {
  35. switch (RenderingMode)
  36. {
  37. case RenderingMode.AlphaBlended:
  38. return "Hidden/Imposter_AlphaBlended";
  39. case RenderingMode.AlphaCutout:
  40. if (_useAlphaToMask)
  41. {
  42. return "Hidden/Imposter_AlphaToMask";
  43. }
  44. else
  45. {
  46. return "Hidden/Imposter_AlphaCutout";
  47. }
  48. default:
  49. case RenderingMode.Opaque:
  50. return "Hidden/Imposter_Opaque";
  51. }
  52. }
  53. protected virtual void SetAdditionalProperties(MaterialPropertyBlock block)
  54. {
  55. block.SetFloat("_Cutoff", GetAlphaCutoutThreshold());
  56. }
  57. protected virtual float GetAlphaCutoutThreshold()
  58. {
  59. if (RenderingMode == RenderingMode.AlphaCutout &&
  60. !_useAlphaToMask)
  61. {
  62. return _alphaCutoutThreshold;
  63. }
  64. return 1f;
  65. }
  66. protected Material _material;
  67. protected bool _started;
  68. protected virtual void HandleUpdateRenderTexture(Texture texture)
  69. {
  70. RKLog.Debug($"====CanvasMeshRenderer====:+ HandleUpdateRenderTexture");
  71. _meshRenderer.material = _material;
  72. var block = new MaterialPropertyBlock();
  73. _meshRenderer.GetPropertyBlock(block);
  74. block.SetTexture(MainTexShaderID, texture);
  75. SetAdditionalProperties(block);
  76. _meshRenderer.SetPropertyBlock(block);
  77. }
  78. protected virtual void Start()
  79. {
  80. this.BeginStart(ref _started);
  81. Assert.IsNotNull(_meshRenderer);
  82. Assert.IsNotNull(_canvasRenderTexture);
  83. this.EndStart(ref _started);
  84. }
  85. protected virtual void OnEnable()
  86. {
  87. if (_started)
  88. {
  89. Profiler.BeginSample("InterfaceRenderer.UpdateMaterial");
  90. try
  91. {
  92. _material = new Material(Shader.Find(GetShaderName()));
  93. }
  94. finally
  95. {
  96. Profiler.EndSample();
  97. }
  98. _canvasRenderTexture.OnUpdateRenderTexture += HandleUpdateRenderTexture;
  99. if (_canvasRenderTexture.Texture != null)
  100. {
  101. HandleUpdateRenderTexture(_canvasRenderTexture.Texture);
  102. }
  103. }
  104. }
  105. protected virtual void OnDisable()
  106. {
  107. if (_started)
  108. {
  109. if (_material != null)
  110. {
  111. Destroy(_material);
  112. _material = null;
  113. }
  114. _canvasRenderTexture.OnUpdateRenderTexture -= HandleUpdateRenderTexture;
  115. }
  116. }
  117. public static partial class Properties
  118. {
  119. public static readonly string RenderingMode = nameof(_renderingMode);
  120. public static readonly string UseAlphaToMask = nameof(_useAlphaToMask);
  121. public static readonly string AlphaCutoutThreshold = nameof(_alphaCutoutThreshold);
  122. }
  123. }
  124. }