CCEffect %{ techniques: - name: normal passes: - vert: vs frag: fs blendState: targets: - blend: true rasterizerState: cullMode: back properties: texture: { value: white } center: { value: [0.5, 0.5] } time: { value: 0.0 } ringCount: { value: 5.0 } ringWidth: { value: 0.04 } waveSpeed: { value: 0.3 } // 扩散速度 shrink: { value: 2.0 } // 内缩强度 fadePow: { value= 2.0 } // 淡出速度 color: { value: [0.95, 0.95, 0.95, 0.45] } // 淡白 }% CCProgram vs %{ precision highp float; #include #include in vec3 a_position; in vec2 a_uv0; out vec2 v_uv0; void main () { vec4 pos = vec4(a_position, 1); #if CC_USE_MODEL pos = cc_matViewProj * cc_matWorld * pos; #else pos = cc_matViewProj * pos; #endif gl_Position = pos; v_uv0 = a_uv0; } }% CCProgram fs %{ precision highp float; #include #include in vec2 v_uv0; uniform sampler2D texture; uniform fs_uniforms { vec4 color; vec2 center; float time; float ringCount; float ringWidth; float waveSpeed; float shrink; float fadePow; }; void main () { vec4 tex = texture2D(texture, v_uv0); float dist = distance(v_uv0, center); float alpha = 0.0; // 计算从中心到边界的最大距离 vec2 lowerDist = center; vec2 upperDist = vec2(1.0 - center.x, 1.0 - center.y); float maxDist = max(max(lowerDist.x, lowerDist.y), max(upperDist.x, upperDist.y)); // 设置渐隐开始和结束位置 float fadeStartDist = maxDist * 0.25; // 从中心向外1/4位置开始渐隐 float fadeEndDist = maxDist * 0.95; // 外圈往里一些位置完全隐藏 // 生成5个独立的波纹环,每个间隔一定时间出现 for (int i = 0; i < 3; ++i) { // 每个波纹环间隔0.3秒出现 float ringStartTime = float(i) * 0.3; if (time < ringStartTime) continue; // 当前波纹环的时间 float ringTime = time - ringStartTime; // 波纹半径随时间增长 float radius = ringTime * waveSpeed; // 当波纹超出边界时不再显示 if (radius > maxDist) continue; if (radius > 1.5) continue; float inner = radius - ringWidth; float a = smoothstep(inner, radius, dist) * (1.0 - smoothstep(radius, radius + 0.01, dist)); // 涟漪效果 a *= sin(dist * shrink - ringTime * 6.0) * 0.5 + 0.5; a *= pow(1.0 - radius / 1.5, fadePow); // 添加边界渐隐效果:从1/4位置开始渐隐直到边界附近完全隐藏 if (radius > fadeStartDist) { float boundaryFade = 1.0 - smoothstep(fadeStartDist, fadeEndDist, radius); a *= boundaryFade; } alpha += a; } alpha = clamp(alpha, 0.0, 1.0); gl_FragColor = vec4(color.rgb, alpha * color.a); ALPHA_TEST(gl_FragColor); } }%