CCEffect %{ techniques: - name: opaque passes: - vert: genie-vs:vs # 程序 genie-vs,入口 vs frag: genie-fs:fs # 程序 genie-fs,入口 fs blendState: targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha rasterizerState: cullMode: none properties: u_targetPos: { value: [0, -300] } u_progress: { value: 0.0, editor: { slide: true, range: [0, 1], step: 0.01 } } u_bendStrength: { value: 1.0, editor: { slide: true, range: [0, 3], step: 0.1 } } u_shrinkWidth: { value: 0.2, editor: { slide: true, range: [0, 1], step: 0.01 } } }% CCProgram genie-vs %{ precision highp float; #include #include in vec3 a_position; in vec2 a_uv0; in vec4 a_color; uniform MyConstants { vec2 u_targetPos; float u_progress; float u_bendStrength; float u_shrinkWidth; }; out vec2 v_uv; out vec4 v_color; vec2 quadBezier(vec2 p0, vec2 p1, vec2 p2, float t) { float u = 1.0 - t; return u * u * p0 + 2.0 * u * t * p1 + t * t * p2; } vec4 vs() { vec2 pos = a_position.xy; v_uv = a_uv0; v_color = a_color; float p = clamp(u_progress, 0.0, 1.0); float uvY = a_uv0.y; float uvX = a_uv0.x; vec2 topTarget = mix(pos, u_targetPos, p * 0.6); vec2 bottomTarget = u_targetPos; float bendDown = -80.0 * u_bendStrength * (1.0 - p); vec2 bottomControl = mix(pos, u_targetPos, 0.5) + vec2(0.0, bendDown); vec2 rowPos = quadBezier(topTarget, bottomControl, bottomTarget, uvY * p); float widthScale = 1.0 - (1.0 - u_shrinkWidth) * p * uvY; vec2 center = mix(topTarget, bottomTarget, uvY); rowPos.x = center.x + (rowPos.x - center.x) * widthScale; float bulge = -sin(uvY * 3.14159) * 30.0 * u_bendStrength * (1.0 - p); rowPos.y += bulge * sin((uvX - 0.5) * 3.14159); // 增强吸进效果 float depth = 1.0 - p * 0.8 * uvY; rowPos = mix(rowPos, u_targetPos, (1.0 - depth) * uvY * 1.0); // 最终阶段快速收缩到目标点 if (p > 0.8) { float finalT = (p - 0.8) / 0.2; rowPos = mix(rowPos, u_targetPos, finalT * 0.8); } return cc_matViewProj * vec4(rowPos, 0.0, 1.0); } }% CCProgram genie-fs %{ precision highp float; #include in vec2 v_uv; in vec4 v_color; uniform sampler2D texture; vec4 fs() { return texture(texture, v_uv) * v_color; } }%