SoftMask.cginc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #ifndef SOFTMASK_INCLUDED
  2. #define SOFTMASK_INCLUDED
  3. #include "UnityUI.cginc"
  4. /* API Reference
  5. -------------
  6. #define SOFTMASK_COORDS(idx)
  7. Add it to the declaration of the structure that is passed from the vertex shader
  8. to the fragment shader.
  9. idx The number of interpolator to use. Specify the first free TEXCOORD index.
  10. #define SOFTMASK_CALCULATE_COORDS(OUT, pos)
  11. Use it in the vertex shader to calculate mask-related data.
  12. OUT An instance of the output structure that will be passed to the fragment
  13. shader. It should be of the type that contains a SOFTMASK_COORDS()
  14. declaration.
  15. pos A source vertex position that have been passed to the vertex shader.
  16. #define SOFTMASK_GET_MASK(IN)
  17. Use it in the fragment shader to finally compute the mask value.
  18. IN An instance of the vertex shader output structure. It should be of type
  19. that contains a SOFTMASK_COORDS() declaration.
  20. The following functions are defined only when one of SOFTMASK_SIMPLE, SOFTMASK_SLICED
  21. or SOFTMASK_TILED macro is defined. It's better to use the macros listed above when
  22. possible because they properly handle situation when Soft Mask is disabled.
  23. inline float SoftMask_GetMask(float2 maskPosition)
  24. Returns the mask value for a given pixel.
  25. maskPosition A position of the current pixel in mask's local space.
  26. To get this position use macro SOFTMASK_CALCULATE_COORDS().
  27. inline float4 SoftMask_GetMaskTexture(float2 maskPosition)
  28. Returns the color of the mask texture for a given pixel. maskPosition is the same
  29. as in SoftMask_GetMask(). This function returns the original pixel of the mask,
  30. which may be useful for debugging.
  31. */
  32. #if defined(SOFTMASK_SIMPLE) || defined(SOFTMASK_SLICED) || defined(SOFTMASK_TILED)
  33. # define __SOFTMASK_ENABLE
  34. # if defined(SOFTMASK_SLICED) || defined(SOFTMASK_TILED)
  35. # define __SOFTMASK_USE_BORDER
  36. # endif
  37. #endif
  38. #ifdef __SOFTMASK_ENABLE
  39. # define SOFTMASK_COORDS(idx) float4 maskPosition : TEXCOORD ## idx;
  40. # define SOFTMASK_CALCULATE_COORDS(OUT, pos) (OUT).maskPosition = mul(_SoftMask_WorldToMask, pos);
  41. # define SOFTMASK_GET_MASK(IN) SoftMask_GetMask((IN).maskPosition.xy)
  42. sampler2D _SoftMask;
  43. float4 _SoftMask_Rect;
  44. float4 _SoftMask_UVRect;
  45. float4x4 _SoftMask_WorldToMask;
  46. float4 _SoftMask_ChannelWeights;
  47. # ifdef __SOFTMASK_USE_BORDER
  48. float4 _SoftMask_BorderRect;
  49. float4 _SoftMask_UVBorderRect;
  50. # endif
  51. # ifdef SOFTMASK_TILED
  52. float2 _SoftMask_TileRepeat;
  53. # endif
  54. bool _SoftMask_InvertMask;
  55. bool _SoftMask_InvertOutsides;
  56. // On changing logic of the following functions, don't forget to update
  57. // according functions in SoftMask.MaterialParameters (C#).
  58. inline float2 __SoftMask_Inset(float2 a, float2 a1, float2 a2, float2 u1, float2 u2, float2 repeat) {
  59. float2 w = (a2 - a1);
  60. float2 d = (a - a1) / w;
  61. // use repeat only when both w and repeat are not zeroes
  62. return lerp(u1, u2, (w * repeat != 0.0f ? frac(d * repeat) : d));
  63. }
  64. inline float2 __SoftMask_Inset(float2 a, float2 a1, float2 a2, float2 u1, float2 u2) {
  65. float2 w = (a2 - a1);
  66. return lerp(u1, u2, (w != 0.0f ? (a - a1) / w : 0.0f));
  67. }
  68. # ifdef __SOFTMASK_USE_BORDER
  69. inline float2 __SoftMask_XY2UV(
  70. float2 a,
  71. float2 a1, float2 a2, float2 a3, float2 a4,
  72. float2 u1, float2 u2, float2 u3, float2 u4) {
  73. float2 s1 = step(a2, a);
  74. float2 s2 = step(a3, a);
  75. float2 s1i = 1 - s1;
  76. float2 s2i = 1 - s2;
  77. float2 s12 = s1 * s2;
  78. float2 s12i = s1 * s2i;
  79. float2 s1i2i = s1i * s2i;
  80. float2 aa1 = a1 * s1i2i + a2 * s12i + a3 * s12;
  81. float2 aa2 = a2 * s1i2i + a3 * s12i + a4 * s12;
  82. float2 uu1 = u1 * s1i2i + u2 * s12i + u3 * s12;
  83. float2 uu2 = u2 * s1i2i + u3 * s12i + u4 * s12;
  84. return
  85. __SoftMask_Inset(a, aa1, aa2, uu1, uu2
  86. # if SOFTMASK_TILED
  87. , s12i * _SoftMask_TileRepeat
  88. # endif
  89. );
  90. }
  91. inline float2 SoftMask_GetMaskUV(float2 maskPosition) {
  92. return
  93. __SoftMask_XY2UV(
  94. maskPosition,
  95. _SoftMask_Rect.xy, _SoftMask_BorderRect.xy, _SoftMask_BorderRect.zw, _SoftMask_Rect.zw,
  96. _SoftMask_UVRect.xy, _SoftMask_UVBorderRect.xy, _SoftMask_UVBorderRect.zw, _SoftMask_UVRect.zw);
  97. }
  98. # else
  99. inline float2 SoftMask_GetMaskUV(float2 maskPosition) {
  100. return
  101. __SoftMask_Inset(
  102. maskPosition,
  103. _SoftMask_Rect.xy, _SoftMask_Rect.zw, _SoftMask_UVRect.xy, _SoftMask_UVRect.zw);
  104. }
  105. # endif
  106. inline float4 SoftMask_GetMaskTexture(float2 maskPosition) {
  107. return tex2D(_SoftMask, SoftMask_GetMaskUV(maskPosition));
  108. }
  109. inline float SoftMask_GetMask(float2 maskPosition) {
  110. float2 uv = SoftMask_GetMaskUV(maskPosition);
  111. float4 sampledMask = tex2D(_SoftMask, uv);
  112. float weightedMask = dot(sampledMask * _SoftMask_ChannelWeights, 1);
  113. float maskInsideRect = _SoftMask_InvertMask ? 1 - weightedMask : weightedMask;
  114. float maskOutsideRect = _SoftMask_InvertOutsides;
  115. float isInsideRect = UnityGet2DClipping(maskPosition, _SoftMask_Rect);
  116. return lerp(maskOutsideRect, maskInsideRect, isInsideRect);
  117. }
  118. #else // __SOFTMASK_ENABLED
  119. # define SOFTMASK_COORDS(idx)
  120. # define SOFTMASK_CALCULATE_COORDS(OUT, pos)
  121. # define SOFTMASK_GET_MASK(IN) (1.0f)
  122. inline float4 SoftMask_GetMaskTexture(float2 maskPosition) { return 1.0f; }
  123. inline float SoftMask_GetMask(float2 maskPosition) { return 1.0f; }
  124. #endif
  125. #endif
  126. // UNITY_SHADER_NO_UPGRADE