CubismCG.cginc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * Copyright(c) Live2D Inc. All rights reserved.
  3. *
  4. * Use of this source code is governed by the Live2D Open Software license
  5. * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
  6. */
  7. #ifndef CUBISM_CG_INCLUDED
  8. #define CUBISM_CG_INCLUDED
  9. #include "UnityCG.cginc"
  10. inline float4 CubismGetMaskChannel(float4 tile)
  11. {
  12. return tile.xxxx == float4(0, 1, 2, 3);
  13. }
  14. inline float4 CubismGetClippedMaskChannel(float2 coordinates, float4 tile)
  15. {
  16. float2 bound = tile.yz * tile.w;
  17. float isInside =
  18. step(bound.x, coordinates.x)
  19. * step(bound.y, coordinates.y)
  20. * step(coordinates.x, bound.x + tile.w)
  21. * step(coordinates.y, bound.y + tile.w);
  22. return CubismGetMaskChannel(tile) * isInside;
  23. }
  24. inline float2 CubismToMaskCoordinates(float2 vertex, float4 tile, float4 transform)
  25. {
  26. float2 result = vertex;
  27. float scale = tile.w * transform.z;
  28. float2 offset = transform.xy;
  29. float2 origin = (tile.yz + float2(0.5, 0.5)) * tile.ww;
  30. result.xy -= offset;
  31. result *= scale;
  32. result.xy += origin;
  33. return result;
  34. }
  35. inline float4 CubismToMaskClipPos(float2 vertex, float4 tile, float4 transform)
  36. {
  37. float2 result = CubismToMaskCoordinates(vertex, tile, transform);
  38. result *= 2;
  39. result.xy = float2(result.x, (result.y * _ProjectionParams.x));
  40. result.xy -= float2(1, _ProjectionParams.x);
  41. return float4(result.xy, 1, 1);
  42. }
  43. inline float CubismSampleMaskTexture(sampler2D tex, float4 channel, float2 coordinates)
  44. {
  45. float4 texel = tex2D(tex, coordinates.xy) * channel;
  46. return texel.r + texel.g + texel.b + texel.a;
  47. }
  48. #if defined (CUBISM_MASK_ON) || defined(CUBISM_INVERT_ON)
  49. #define CUBISM_MASK_SHADER_VARIABLES \
  50. sampler2D cubism_MaskTexture; \
  51. float4 cubism_MaskTile; \
  52. float4 cubism_MaskTransform;
  53. #define CUBISM_TO_MASK_CLIP_POS(IN, OUT) OUT.vertex = CubismToMaskClipPos(IN.vertex, cubism_MaskTile, cubism_MaskTransform);
  54. #define CUBISM_MASK_CHANNEL CubismGetMaskChannel(cubism_MaskTile)
  55. #define CUBISM_VERTEX_OUTPUT float2 cubism_MaskCoordinates : TEXCOORD3;
  56. #define CUBISM_INITIALIZE_VERTEX_OUTPUT(IN, OUT) OUT.cubism_MaskCoordinates = CubismToMaskCoordinates(IN.vertex, cubism_MaskTile, cubism_MaskTransform);
  57. #if defined(CUBISM_INVERT_ON)
  58. #define CUBISM_APPLY_MASK(IN, COLOR) \
  59. float4 cubism_maskChannel = CubismGetClippedMaskChannel(IN.cubism_MaskCoordinates, cubism_MaskTile); \
  60. float cubism_maskAlpha = CubismSampleMaskTexture(cubism_MaskTexture, cubism_maskChannel, IN.cubism_MaskCoordinates); \
  61. COLOR *= 1.0 - cubism_maskAlpha;
  62. #else
  63. #define CUBISM_APPLY_MASK(IN, COLOR) \
  64. float4 cubism_maskChannel = CubismGetClippedMaskChannel(IN.cubism_MaskCoordinates, cubism_MaskTile); \
  65. float cubism_maskAlpha = CubismSampleMaskTexture(cubism_MaskTexture, cubism_maskChannel, IN.cubism_MaskCoordinates); \
  66. COLOR *= cubism_maskAlpha;
  67. #endif
  68. #else
  69. #define CUBISM_MASK_SHADER_VARIABLES
  70. #define CUBISM_TO_MASK_CLIP_POS(IN, OUT)
  71. #define CUBISM_MASK_CHANNEL float4(1, 1, 1, 1)
  72. #define CUBISM_VERTEX_OUTPUT
  73. #define CUBISM_INITIALIZE_VERTEX_OUTPUT(IN, OUT)
  74. #define CUBISM_APPLY_MASK(IN, COLOR)
  75. #endif
  76. #define CUBISM_SHADER_VARIABLES \
  77. float cubism_ModelOpacity; \
  78. CUBISM_MASK_SHADER_VARIABLES
  79. #define CUBISM_APPLY_ALPHA(IN, COLOR) \
  80. COLOR.rgb *= COLOR.a; \
  81. CUBISM_APPLY_MASK(IN, COLOR); \
  82. COLOR *= cubism_ModelOpacity;
  83. #endif