// 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: alphaThreshold: { value: 0.5 } glowColor: { value: [1, 1, 1, 1], editor: { type: color } } glowWidth: { value: 0.05, editor: { slide: true, range: [0, 0.3], step: 0.001 } } glowThreshold: { value: 1, editor: { slide: true, range: [0, 0.99], step: 0.001 } } }% CCProgram sprite-vs %{ precision highp float; #include #if USE_LOCAL #include #endif #if SAMPLE_FROM_RT #include #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 #include in vec4 color; uniform FSConstants { vec4 glowColor; float glowWidth; float glowThreshold; }; #if USE_TEXTURE in vec2 uv0; #pragma builtin(local) layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; #endif vec4 getTextureColor (sampler2D mainTexture, vec2 uv) { if (uv.x > 1.0 || uv.x < 0.0 || uv.y > 1.0 || uv.y < 0.0) { return vec4(0.0, 0.0, 0.0, 0.0); } return texture(mainTexture, uv); } float getColorAlpha (float angle, float dist) { // 角度转弧度,公式为:弧度 = 角度 * (pi / 180) float radian = angle * 3.14 / 180.0; vec2 newUV = uv0 + vec2(dist * cos(radian), dist * sin(radian)); vec4 color = getTextureColor(cc_spriteTexture, newUV); return color.a; } float getAverageAlpha (float dist) { float totalAlpha = 0.0; totalAlpha += getColorAlpha(0.0, dist); totalAlpha += getColorAlpha(30.0, dist); totalAlpha += getColorAlpha(60.0, dist); totalAlpha += getColorAlpha(90.0, dist); totalAlpha += getColorAlpha(120.0, dist); totalAlpha += getColorAlpha(150.0, dist); totalAlpha += getColorAlpha(180.0, dist); totalAlpha += getColorAlpha(210.0, dist); totalAlpha += getColorAlpha(240.0, dist); totalAlpha += getColorAlpha(270.0, dist); totalAlpha += getColorAlpha(300.0, dist); totalAlpha += getColorAlpha(330.0, dist); return totalAlpha * 0.0833; } float getGlowAlpha () { if (glowWidth == 0.0 ) { return 0.0; } vec4 srcColor = getTextureColor(cc_spriteTexture, uv0); if (srcColor.a <= glowThreshold) { return srcColor.a; } float totalAlpha = 0.0; totalAlpha += getAverageAlpha(glowWidth * 0.1); totalAlpha += getAverageAlpha(glowWidth * 0.2); totalAlpha += getAverageAlpha(glowWidth * 0.3); totalAlpha += getAverageAlpha(glowWidth * 0.4); totalAlpha += getAverageAlpha(glowWidth * 0.5); totalAlpha += getAverageAlpha(glowWidth * 0.6); totalAlpha += getAverageAlpha(glowWidth * 0.7); totalAlpha += getAverageAlpha(glowWidth * 0.8); totalAlpha += getAverageAlpha(glowWidth * 0.9); totalAlpha += getAverageAlpha(glowWidth * 1.0); return totalAlpha * 0.1; } vec4 frag () { vec4 o = vec4(1, 1, 1, 1); #if USE_TEXTURE o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0); #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 float alpha = getGlowAlpha(); if (alpha > glowThreshold) { alpha = 1.0 - alpha; alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0; } vec4 dstColor = glowColor * alpha; vec4 scrColor = o; o = scrColor * scrColor.a + dstColor * 1.0; o *= color; ALPHA_TEST(o); return o; } }%