一、效果展示

在这里插入图片描述

扩散波纹动画是一种以场景中心为起点,向外不断扩散的圆形波纹效果,常用于地图中心点、雷达扫描等场景。波纹呈现出柔和的发光效果,由中心向外不断循环扩散。

二、实现原理

2.1 整体架构

扩散波纹动画的实现分为三个核心部分:

  1. 平面载体:使用 PlaneGeometry 创建一个足够大的平面,作为波纹的渲染载体
  2. 自定义着色器:通过 onBeforeCompile 钩子注入 GLSL 代码,实现波纹的计算与渲染
  3. 动画驱动:使用 GSAP 动画库驱动 uniform 变量,实现波纹的循环扩散

2.2 着色器实现

2.2.1 顶点着色器修改

在顶点着色器中添加 vPosition 变量,将片元的位置信息传递到片元着色器:

// 在 void main() 之前声明 varying 变量
varying vec3 vPosition;

void main(){
    vPosition = position;  // 将顶点位置传递给片元着色器
    // ... 原有代码
}

2.2.2 片元着色器修改

片元着色器是波纹计算的核心,主要逻辑包括:

  1. 计算波纹半径r = uTime * uSpeed(当前波纹的前沿半径)
  2. 计算片元距离rDistance = distance(vPosition.xy, center)(片元到中心的距离)
  3. 判断波纹范围rDistance > r && rDistance < r + 2.0 * w
  4. 平滑过渡:使用 smoothstep 函数实现波纹前后沿的渐隐效果
  5. 颜色混合:使用 mix 函数在原色和波纹色之间平滑过渡
// 声明 uniform 变量
uniform float uTime;    // 时间控制
uniform float uSpeed;   // 扩散速度
uniform float uWidth;   // 波纹宽度
uniform vec3 uColor;    // 波纹颜色
varying vec3 vPosition; // 顶点位置

void main(){
    // 计算当前波纹前沿位置
    float r = uTime * uSpeed;
    
    // 波纹半宽
    float w = uWidth;
    
    // 波纹中心坐标
    vec2 center = vec2(0.0, 0.0);
    
    // 计算片元到中心的距离
    float rDistance = distance(vPosition.xy, center);
    
    // 判断是否在波纹范围内
    if(rDistance > r && rDistance < r + 2.0 * w) {
        float per = 0.0;
        
        // 波纹前沿(从外向内过渡)
        if(rDistance < r + w) {
            float p = smoothstep(0.0, 1.0, (rDistance - r) / w);
            p *= p;  // 增强渐隐效果
            outgoingLight = mix(outgoingLight, uColor, p);
        } 
        // 波纹后沿(从内向外过渡)
        else {
            float p = smoothstep(0.0, 1.0, (rDistance - r - w) / w);
            outgoingLight = mix(uColor, outgoingLight, p);
        }
        gl_FragColor = vec4(outgoingLight, diffuseColor.a);
    } 
    // 不在波纹范围内,完全透明
    else {
        gl_FragColor = vec4(outgoingLight, 0.0);
    }
}

2.3 混合模式配置

为了实现发光叠加效果,需要配置自定义混合模式:

material.blending = THREE.CustomBlending
material.blendEquation = THREE.AddEquation
material.blendSrc = THREE.DstColorFactor
material.blendDst = THREE.OneFactor

混合公式result = src_color * DstColorFactor + dst_color * OneFactor

这种混合模式让波纹颜色与背景颜色产生叠加发光效果。

2.4 动画驱动

使用 GSAP 驱动 uTime uniform 变量,实现波纹循环扩散:

gsap.to(shader.uniforms.uTime, {
    value: 4,       // 从 0 动画到 4
    repeat: -1,     // 无限循环
    duration: 6,    // 每次循环 6 秒
    ease: 'power1.easeIn',  // 缓动函数
})

三、完整 HTML 实现

以下是一个可独立运行的扩散波纹动画示例:




    
    扩散波纹动画
    


    
    
    


四、参数说明

参数 类型 默认值 说明
uTime float 0 → 4 时间控制变量,通过 GSAP 驱动
uSpeed float 8.0 波纹扩散速度,值越大波纹扩散越快
uWidth float 2.0 波纹宽度,影响波纹的厚度
uColor Color 0x71918e 波纹颜色
duration float 6 单次循环时长(秒)
value float 4 uTime 动画的目标值,影响扩散范围

五、扩展应用

  1. 多波纹叠加:可以创建多个平面,使用不同的 uTime 初始值实现多层波纹
  2. 自定义形状:修改 distance 函数,实现矩形、三角形等形状的波纹
  3. 多颜色渐变:在 mix 中加入更多颜色,实现彩虹波纹效果
  4. 波纹衰减:根据 rDistance 添加衰减因子,实现远处波纹变暗的效果

原文地址: https://www.cveoy.top/t/topic/qHfZ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录