Seven is the number.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.3 KiB

3 years ago
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.Rendering;
  4. using UnityEngine.UI;
  5. namespace LeTai.TrueShadow
  6. {
  7. public partial class ShadowRenderer
  8. {
  9. // TODO: cleanup unused mask materials
  10. static readonly Dictionary<(bool, Material), Material> MASK_MATERIALS_CACHE =
  11. new Dictionary<(bool, Material), Material>();
  12. internal static void ClearMaskMaterialCache()
  13. {
  14. foreach (var keyValuePair in MASK_MATERIALS_CACHE)
  15. {
  16. if(Application.isPlaying)
  17. Destroy(keyValuePair.Value);
  18. else
  19. DestroyImmediate(keyValuePair.Value);
  20. }
  21. MASK_MATERIALS_CACHE.Clear();
  22. }
  23. public Material GetModifiedMaterial(Material baseMaterial)
  24. {
  25. if (!shadow)
  26. return baseMaterial;
  27. shadow.ModifyShadowRendererMaterial(baseMaterial);
  28. if (!baseMaterial.HasProperty(ShaderId.COLOR_MASK) ||
  29. !baseMaterial.HasProperty(ShaderId.STENCIL_OP))
  30. return baseMaterial;
  31. bool casterIsMask = shadow.GetComponent<Mask>() != null;
  32. MASK_MATERIALS_CACHE.TryGetValue((casterIsMask, baseMaterial), out var mat);
  33. if (!mat)
  34. {
  35. mat = new Material(baseMaterial);
  36. if (shadow.ShadowAsSibling)
  37. {
  38. // Prevent shadow from writing to stencil mask
  39. mat.SetInt(ShaderId.COLOR_MASK, (int) ColorWriteMask.All);
  40. mat.SetInt(ShaderId.STENCIL_OP, (int) StencilOp.Keep);
  41. }
  42. else if (casterIsMask)
  43. {
  44. // Escape mask if we have one
  45. var baseStencilId = mat.GetInt(ShaderId.STENCIL_ID) + 1;
  46. int stencilDepth = 0;
  47. for (; stencilDepth < 8; stencilDepth++)
  48. {
  49. if (((baseStencilId >> stencilDepth) & 1) == 1)
  50. break;
  51. }
  52. stencilDepth = Mathf.Max(0, stencilDepth - 1);
  53. var stencilId = (1 << stencilDepth) - 1;
  54. mat.SetInt(ShaderId.STENCIL_ID, stencilId);
  55. mat.SetInt(ShaderId.STENCIL_READ_MASK, stencilId);
  56. }
  57. MASK_MATERIALS_CACHE[(casterIsMask, baseMaterial)] = mat;
  58. }
  59. return mat;
  60. }
  61. }
  62. }