实现手势操控3D粒子动画?太好玩了!

184 阅读7分钟

1-前言

小编刷着公众号,发现我喜欢的博主发表了一篇手势操控3d粒子动画的文章,立马跟着去试了一下,发现确实挺不错的,也是开始研究其源码来了。

2-Github地址

stark-shapes Github 地址https://github.com/collidingScopes/stark-shapes/tree/main

stark-shapes 在线体验地址https://collidingscopes.github.io/stark-shapes/

2e79fd48680f3a287295e225e9873b2.png

3-项目运行

HTTP:git clone https://github.com/collidingScopes/stark-shapes.git

SSH:·git clone git@github.com:collidingScopes/stark-shapes.git

然后cd stark-shapes

然后运行npx --yes http-server .

image-20250502104448824.png

发现启动成功了,就可以去玩啦。

4-项目特点

  • 手势控制

    • 右手:通过捏合手势实现缩放控制
    • 左手:通过旋转手势实现相机轨道控制
    • 双手拍手:切换到下一个几何图案
  • 丰富的几何图案

    • 基础形状:立方体、球体
    • 数学曲线:螺旋线、螺旋桨
    • 复杂形状:星系、莫比乌斯带、克莱因瓶
    • 自然形态:花朵、分形树
    • 数学图案:Voronoi图
  • 视觉效果

    • 平滑的图案过渡动画
    • 粒子波动效果
    • 动态颜色变化
    • 景深效果
    • 粒子发光效果

5-技术实现

核心技术栈

  • Three.js:3D图形渲染
  • MediaPipe:手势识别
  • dat.GUI:调试界面

主要功能模块

  1. 粒子系统

    • 使用BufferGeometry优化性能
    • 支持15,000个粒子的实时渲染
    • 实现粒子大小、颜色、透明度等属性的动态控制
  2. 相机控制

    • 实现平滑的缩放过渡
    • 支持水平和垂直方向的轨道控制
    • 设置合理的视角限制,防止相机翻转
  3. 手势识别

    • 实时检测左右手位置
    • 计算手指捏合距离
    • 识别拍手动作
    • 平滑的手势响应
  4. 图案转换

    • 支持14种不同的几何图案
    • 实现平滑的形状过渡动画
    • 颜色渐变效果

6-使用说明

  1. 环境要求

    • 现代浏览器(支持WebGL)
    • 摄像头权限(用于手势识别)
  2. 操作指南

    • 允许浏览器访问摄像头
    • 右手捏合控制缩放
    • 左手旋转控制视角
    • 双手拍手切换图案
  3. 调试面板

    • 波动强度调节
    • 过渡速度控制
    • 粒子大小设置
    • 手动切换图案

7-开发者说明

项目结构:

  • main.js:主程序逻辑
  • geometry.js:几何图案生成
  • chromatic-shader.js:着色器效果
  • index.html:页面结构
  • styles.css:样式定义

www.instagram.com/stereo.drif…)

8- main.js 代码分析

核心功能模块

1. 手势控制系统

项目使用 MediaPipe 实现手势识别,主要变量包括:

let hands;
let handDetected = false;
let isLeftHandPresent = false;
let isRightHandPresent = false;
let leftHandLandmarks = null;
let rightHandLandmarks = null;

手势控制功能:

  • 右手捏合手势:控制场景缩放
  • 左手旋转:控制相机轨道运动
  • 双手拍手:切换几何图案

2. 相机控制系统

相机系统实现了平滑的缩放和旋转效果:

// 相机缩放参数
let targetCameraZ = 100;
const MIN_CAMERA_Z = 20;
const MAX_CAMERA_Z = 200;

// 相机旋转参数
let targetCameraAngleX = 0;
let currentCameraAngleX = 0;
let targetCameraAngleY = 0;
let currentCameraAngleY = 0;

3. 粒子系统

粒子系统是项目的核心视觉元素:

const params = {
    particleCount: 15000,
    transitionSpeed: 0.005,
    waveIntensity: 0.0,
    particleSize: 0.5
};

主要特点:

  • 支持 15000 个粒子的渲染
  • 实现了平滑的粒子过渡动画
  • 包含波浪效果动画
  • 使用 Three.js 的 PointsMaterial 实现粒子渲染

4. 几何图案系统

项目支持多种几何图案:

const patterns = [
    createGrid, createSphere, createSpiral,
    createHelix, createTorus, createVortex, 
    createGalaxy, createWave, createMobius, 
    createSupernova, createKleinBottle,
    createFlower, createVoronoi, createFractalTree
];

5. 颜色系统

项目定义了多组颜色配置:

const colorPalettes = [
    [ new THREE.Color(0x3399ff), new THREE.Color(0x44ccff), new THREE.Color(0x0055cc) ],
    [ new THREE.Color(0xff3399), new THREE.Color(0xcc00ff), new THREE.Color(0x660099) ],
    // ... 更多颜色配置
];

9-Geometry.js 代码分析

Geometry.js 文件包含了多个几何图案生成函数,用于创建不同的3D粒子分布模式。每个函数都通过数学算法精确控制粒子在三维空间中的分布,实现了丰富的视觉效果。

主要函数

1. createGrid(i, count)

  • 创建立方体网格结构
  • 将粒子均匀分布在立方体的六个面上
  • 参数:
    • i: 当前粒子索引
    • count: 总粒子数
  • 实现细节:
    • 计算立方体边长和间距
    • 将粒子均匀分布在六个面上
    • 每个面的粒子按照二维网格排列

2. createSphere(i, count)

  • 生成球形分布
  • 使用球面坐标系实现均匀分布
  • 特点:
    • 使用黄金分割比进行分布优化
    • 固定半径的表面分布

3. createSpiral(i, count)

  • 创建螺旋形状
  • 特点:
    • 支持多臂螺旋(默认3臂)
    • 使用数学公式控制螺旋展开角度
    • 粒子沿螺旋线均匀分布

4. createHelix(i, count)

  • 生成双螺旋结构
  • 特点:
    • 两条平行螺旋线
    • 可调节螺旋半径和高度
    • 粒子均匀分布在螺旋线上

5. createTorus(i, count)

  • 创建圆环体
  • 参数控制:
    • 主半径:圆环中心到管壁中心的距离
    • 次半径:管壁的半径
  • 使用参数方程实现均匀分布

6. createVortex(i, count)

  • 生成漩涡效果
  • 特点:
    • 从底部到顶部逐渐扩大的半径
    • 可控制旋转圈数
    • 添加随机偏移实现自然效果

7. createGalaxy(i, count)

  • 创建星系形态
  • 特点:
    • 支持多条旋臂(默认4臂)
    • 扭曲因子控制旋臂弯曲程度
    • 垂直方向的厚度随距离变化
    • 包含随机偏移实现自然分布

8. createWave(i, count)

  • 生成波浪效果
  • 特点:
    • 二维平面上的波动分布
    • 可调节波浪高度和密度
    • 支持多重波叠加

技术特点

  1. 使用Three.js的Vector3对象表示三维坐标
  2. 通过数学公式精确控制粒子分布
  3. 支持参数化调节几何形状
  4. 添加随机性实现自然效果
  5. 优化的粒子分布算法确保视觉效果

使用方式

每个函数都接收两个参数:

  • i: 当前粒子的索引
  • count: 总粒子数量

返回值:

  • 返回THREE.Vector3对象,表示粒子的三维坐标

9-Chromatic Shader 代码分析

Chromatic-shader.js 实现了色差(色像差)后期处理效果,这是一种模拟相机镜头色差的视觉效果,使图像的RGB通道产生细微的位移,创造出独特的视觉效果。

核心组件

1. 着色器配置

const ChromaticAberrationShader = {
    uniforms: {
        "tDiffuse": { value: null },
        "resolution": { value: new THREE.Vector2(1, 1) },
        "strength": { value: 0.5 }
    }
    // ...
}
  • tDiffuse: 输入纹理,存储渲染的场景
  • resolution: 屏幕分辨率
  • strength: 色差效果强度

2. 顶点着色器

vertexShader: /* glsl */`
    varying vec2 vUv;
    void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`
  • 实现基础的顶点变换
  • 传递UV坐标到片段着色器

3. 片段着色器

fragmentShader: /* glsl */`
    uniform sampler2D tDiffuse;
    uniform vec2 resolution;
    uniform float strength;
    varying vec2 vUv;

    void main() {
        // 计算到中心的距离
        vec2 uv = vUv - 0.5;
        float dist = length(uv);
        
        // 平滑过渡
        float factor = smoothstep(0.0, 0.4, dist);
        
        // 计算偏移
        vec2 direction = normalize(uv);
        vec2 redOffset = direction * strength * factor * dist;
        vec2 greenOffset = direction * strength * 0.6 * factor * dist;
        vec2 blueOffset = direction * strength * 0.3 * factor * dist;
        
        // 采样各个颜色通道
        float r = texture2D(tDiffuse, vUv - redOffset).r;
        float g = texture2D(tDiffuse, vUv - greenOffset).g;
        float b = texture2D(tDiffuse, vUv - blueOffset).b;
        
        gl_FragColor = vec4(r, g, b, 1.0);
    }
`

实现细节

1. 距离计算

  • 计算每个像素到屏幕中心的距离
  • 使用该距离来控制色差效果的强度

2. 平滑过渡

  • 使用smoothstep实现从中心到边缘的平滑过渡
  • 中心区域保持清晰,边缘区域色差效果更强

3. 颜色通道偏移

  • 红色通道:最大偏移
  • 绿色通道:中等偏移(0.6倍)
  • 蓝色通道:最小偏移(0.3倍)

使用效果

  • 在场景边缘产生RGB通道分离效果
  • 中心区域保持清晰
  • 可通过strength参数调节效果强度

性能考虑

  • 使用向量运算优化性能
  • 避免复杂的数学计算
  • 使用smoothstep实现平滑过渡,避免硬边界