// Cocos Creator 2.x 兼容的纸牌翻转Shader CCEffect %{ techniques: - passes: - vert: card-flip-vs frag: card-flip-fs blendState: targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha rasterizerState: cullMode: none depthStencilState: depthTest: false depthWrite: false properties: texture: { value: white } flipProgress: { value: 0, editor: { type: slider, min: 0, max: 1 } } bendStrength: { value: 0.2, editor: { type: slider, min: 0, max: 1 } } enableShadow: { value: 1, editor: { type: boolean } } }% CCProgram card-flip-vs %{ precision highp float; #include in vec3 a_position; in vec4 a_color; out vec4 v_color; #if USE_TEXTURE in vec2 a_uv0; out vec2 v_uv0; uniform sampler2D texture; #endif uniform Properties { float flipProgress; float bendStrength; float enableShadow; }; void main () { vec4 pos = vec4(a_position, 1); // 计算翻转角度 (从对应30%展示状态的角度到0度,实现从30%展示到完全展示的翻转) // 30%展示状态对应的角度约为π * 0.7 float adjustedProgress = (flipProgress - 0.1) / 0.7; // 将0.1-1.0范围映射到0-1 adjustedProgress = clamp(adjustedProgress, 0.0, 1.0); float flipAngle = (1.0 - adjustedProgress) * 3.14159; // 从π到0 // 计算当前y坐标相对于中心的位置 (-0.5到0.5) float relativeY = pos.y - 0.5; // 应用弯曲效果,使卡片看起来有厚度 float bend = sin(flipAngle) * bendStrength * relativeY; // 应用X轴旋转 pos.y = 0.5 + relativeY * cos(flipAngle); pos.z = relativeY * sin(flipAngle) + bend; // 限制Z轴范围,防止卡片在父节点移动时消失 pos.z = clamp(pos.z, -0.5, 0.5); // 应用阴影效果 if (enableShadow > 0.5 && flipProgress > 0.1 && flipProgress < 0.9) { float shadowIntensity = sin(flipAngle) * 0.5; v_color = vec4(a_color.rgb * (1.0 - shadowIntensity * 0.5), a_color.a); } else { v_color = a_color; } #if USE_TEXTURE v_uv0 = a_uv0; #endif gl_Position = cc_matViewProj * pos; } }% CCProgram card-flip-fs %{ precision highp float; #include in vec4 v_color; #if USE_TEXTURE in vec2 v_uv0; uniform sampler2D texture; #endif uniform Properties { float flipProgress; float bendStrength; float enableShadow; }; void main () { vec4 o = vec4(1, 1, 1, 1); #if USE_TEXTURE o *= texture2D(texture, v_uv0); #endif o *= v_color; // 当卡片背面朝向相机时,使其透明(翻转开始时30%展示,结束时完全展示) // 计算调整后的进度,将0.1-1.0范围映射到0-1 float adjustedProgress = (flipProgress - 0.1) / 0.7; adjustedProgress = clamp(adjustedProgress, 0.0, 1.0); if (adjustedProgress < 0.3) { float backFaceAlpha = (0.5 - adjustedProgress) * 2.0; o.a *= (1.0 - backFaceAlpha * 0.7); // 调整透明度,使初始状态为30%展示 } gl_FragColor = o; } }%