sprite-cover.effect 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. CCEffect %{
  2. techniques:
  3. - passes:
  4. - vert: cover-vs:vert
  5. frag: cover-fs:frag
  6. depthStencilState:
  7. depthTest: false
  8. depthWrite: false
  9. blendState:
  10. targets:
  11. - blend: true
  12. blendSrc: src_alpha
  13. blendDst: one_minus_src_alpha
  14. blendDstAlpha: one_minus_src_alpha
  15. rasterizerState:
  16. cullMode: none
  17. properties:
  18. uvTransform: { value: [1, 1, 0.5, 0.5] }
  19. cornerRadii: { value: [20, 20, 20, 20], editor: { tooltip: "圆角半径(节点单位):x左上、y右上、z右下、w左下;0为直角" } }
  20. nodeInfo: { value: [207, 412, 1, 0], editor: { tooltip: "xy节点宽高(脚本同步),z边缘柔化宽度" } }
  21. nodeUVRowX: { value: [1, 0, 0, 0], editor: { visible: false } }
  22. nodeUVRowY: { value: [0, -1, 1, 0], editor: { visible: false } }
  23. }%
  24. CCProgram cover-vs %{
  25. precision highp float;
  26. #include <builtin/uniforms/cc-global>
  27. #if USE_LOCAL
  28. #include <builtin/uniforms/cc-local>
  29. #endif
  30. in vec3 a_position;
  31. in vec2 a_texCoord;
  32. in vec4 a_color;
  33. out vec2 v_uv;
  34. out vec4 v_color;
  35. vec4 vert () {
  36. vec4 pos = vec4(a_position, 1.0);
  37. #if USE_LOCAL
  38. pos = cc_matWorld * pos;
  39. #endif
  40. v_uv = a_texCoord;
  41. v_color = a_color;
  42. return cc_matViewProj * pos;
  43. }
  44. }%
  45. CCProgram cover-fs %{
  46. precision highp float;
  47. #include <builtin/internal/embedded-alpha>
  48. in vec2 v_uv;
  49. in vec4 v_color;
  50. #pragma builtin(local)
  51. layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture;
  52. uniform CoverParams {
  53. vec4 uvTransform;
  54. vec4 cornerRadii;
  55. vec4 nodeInfo;
  56. vec4 nodeUVRowX;
  57. vec4 nodeUVRowY;
  58. };
  59. vec4 frag () {
  60. // Geometry stays inside the node rectangle; only the sampled region shrinks.
  61. vec2 uv = (v_uv - uvTransform.zw) * uvTransform.xy + uvTransform.zw;
  62. vec4 color = CCSampleWithAlphaSeparated(cc_spriteTexture, uv) * v_color;
  63. // Use the original, uncropped UV to recover node coordinates. The two
  64. // rows also account for SpriteFrames stored in a rotated atlas rectangle.
  65. vec3 sourceUV = vec3(v_uv, 1.0);
  66. vec2 nodeUV = vec2(dot(nodeUVRowX.xyz, sourceUV), dot(nodeUVRowY.xyz, sourceUV));
  67. vec2 halfSize = max(nodeInfo.xy, vec2(0.001)) * 0.5;
  68. vec2 p = (nodeUV - 0.5) * nodeInfo.xy;
  69. float radius = p.y >= 0.0
  70. ? (p.x < 0.0 ? cornerRadii.x : cornerRadii.y)
  71. : (p.x < 0.0 ? cornerRadii.w : cornerRadii.z);
  72. radius = clamp(radius, 0.0, min(halfSize.x, halfSize.y));
  73. vec2 q = abs(p) - halfSize + vec2(radius);
  74. float distanceToEdge = length(max(q, vec2(0.0)))
  75. + min(max(q.x, q.y), 0.0) - radius;
  76. color.a *= 1.0 - smoothstep(-max(nodeInfo.z, 0.001), 0.0, distanceToEdge);
  77. return color;
  78. }
  79. }%