|
|
@@ -0,0 +1,133 @@
|
|
|
+// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
|
|
|
+CCEffect %{
|
|
|
+ techniques:
|
|
|
+ - passes:
|
|
|
+ - vert: sprite-vs:vert
|
|
|
+ frag: sprite-fs:frag
|
|
|
+ depthStencilState:
|
|
|
+ depthTest: false
|
|
|
+ depthWrite: false
|
|
|
+ blendState:
|
|
|
+ targets:
|
|
|
+ - blend: true
|
|
|
+ blendSrc: src_alpha
|
|
|
+ blendDst: one_minus_src_alpha
|
|
|
+ blendDstAlpha: one_minus_src_alpha
|
|
|
+ rasterizerState:
|
|
|
+ cullMode: none
|
|
|
+ properties:
|
|
|
+ edgeColor: { value: [1.0, 1.0, 1.0, 1.0] }
|
|
|
+ textureSize: { value: [512.0, 512.0] }
|
|
|
+ edgeWidth: { value: 2.0 }
|
|
|
+ alphaThreshold: { value: 0.5 }
|
|
|
+}%
|
|
|
+
|
|
|
+CCProgram sprite-vs %{
|
|
|
+ precision highp float;
|
|
|
+ #include <builtin/uniforms/cc-global>
|
|
|
+ #if USE_LOCAL
|
|
|
+ #include <builtin/uniforms/cc-local>
|
|
|
+ #endif
|
|
|
+ #if SAMPLE_FROM_RT
|
|
|
+ #include <common/common-define>
|
|
|
+ #endif
|
|
|
+ in vec3 a_position;
|
|
|
+ in vec2 a_texCoord;
|
|
|
+ in vec4 a_color;
|
|
|
+
|
|
|
+ out vec4 color;
|
|
|
+ out vec2 uv0;
|
|
|
+
|
|
|
+ vec4 vert () {
|
|
|
+ vec4 pos = vec4(a_position, 1);
|
|
|
+
|
|
|
+ #if USE_LOCAL
|
|
|
+ pos = cc_matWorld * pos;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #if USE_PIXEL_ALIGNMENT
|
|
|
+ pos = cc_matView * pos;
|
|
|
+ pos.xyz = floor(pos.xyz);
|
|
|
+ pos = cc_matProj * pos;
|
|
|
+ #else
|
|
|
+ pos = cc_matViewProj * pos;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ uv0 = a_texCoord;
|
|
|
+ #if SAMPLE_FROM_RT
|
|
|
+ CC_HANDLE_RT_SAMPLE_FLIP(uv0);
|
|
|
+ #endif
|
|
|
+ color = a_color;
|
|
|
+
|
|
|
+ return pos;
|
|
|
+ }
|
|
|
+}%
|
|
|
+
|
|
|
+CCProgram sprite-fs %{
|
|
|
+ precision highp float;
|
|
|
+ #include <builtin/internal/embedded-alpha>
|
|
|
+ #include <builtin/internal/alpha-test>
|
|
|
+ #define MAX_EDGE_WIDTH 10.0 // 最大边缘宽度(可根据需求调整)
|
|
|
+ in vec4 color;
|
|
|
+
|
|
|
+ #if USE_TEXTURE
|
|
|
+ in vec2 uv0;
|
|
|
+ #pragma builtin(local)
|
|
|
+ layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ uniform EdgeUniforms {
|
|
|
+ vec4 edgeColor;
|
|
|
+ vec2 textureSize;
|
|
|
+ float edgeWidth;
|
|
|
+ };
|
|
|
+
|
|
|
+ vec4 frag () {
|
|
|
+ vec4 o = vec4(1, 1, 1, 1);
|
|
|
+
|
|
|
+ #if USE_TEXTURE
|
|
|
+ o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);
|
|
|
+
|
|
|
+ // Edge detection based on alpha channel
|
|
|
+ vec2 texelSize = 1.0 / textureSize;
|
|
|
+ float currentAlpha = o.a;
|
|
|
+
|
|
|
+ // Sample surrounding pixels to detect edge
|
|
|
+ float edgeDetected = 0.0;
|
|
|
+ if (currentAlpha > 0.01) {
|
|
|
+ // Check if we're at the edge by sampling neighboring pixels
|
|
|
+ for (float x = -MAX_EDGE_WIDTH; x <= MAX_EDGE_WIDTH; x += 1.0) {
|
|
|
+ for (float y = -MAX_EDGE_WIDTH; y <= MAX_EDGE_WIDTH; y += 1.0) {
|
|
|
+ if (x == 0.0 && y == 0.0) continue;
|
|
|
+
|
|
|
+ vec2 sampleUV = uv0 + vec2(x, y) * texelSize;
|
|
|
+ float sampleAlpha = CCSampleWithAlphaSeparated(cc_spriteTexture, sampleUV).a;
|
|
|
+
|
|
|
+ // If we find a transparent pixel nearby, we're at an edge
|
|
|
+ if (sampleAlpha < 0.01) {
|
|
|
+ float distance = length(vec2(x, y));
|
|
|
+ if (distance <= edgeWidth) {
|
|
|
+ float edgeStrength = 1.0 - (distance / edgeWidth);
|
|
|
+ edgeDetected = max(edgeDetected, edgeStrength);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Apply edge effect
|
|
|
+ if (edgeDetected > 0.0) {
|
|
|
+ o.rgb = mix(o.rgb, edgeColor.rgb, edgeDetected * edgeColor.a);
|
|
|
+ }
|
|
|
+
|
|
|
+ #if IS_GRAY
|
|
|
+ float gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
|
|
|
+ o.r = o.g = o.b = gray;
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
+ o *= color;
|
|
|
+ ALPHA_TEST(o);
|
|
|
+ return o;
|
|
|
+ }
|
|
|
+}%
|