小编刷着公众号,发现我喜欢的博主发表了一篇手势操控3d粒子动画的文章,立马去试了一下,发现确实挺不错的,也是开始研究其源码来了。
stark-shapes Github 地址:https://github.com/collidingScopes/stark-shapes/tree/main
stark-shapes 在线体验地址:https://collidingscopes.github.io/stark-shapes/
HTTP:git clone https://github.com/collidingScopes/stark-shapes.git
SSH:·git clone [email protected]:collidingScopes/stark-shapes.git
然后cd stark-shapes
然后运行npx --yes http-server .
发现启动成功了,就可以去玩啦。
手势控制
丰富的几何图案
视觉效果
粒子系统
相机控制
手势识别
图案转换
环境要求
操作指南
调试面板
项目结构:
main.js
:主程序逻辑geometry.js
:几何图案生成chromatic-shader.js
:着色器效果index.html
:页面结构styles.css
:样式定义https://www.instagram.com/stereo.drift/)
项目使用 MediaPipe 实现手势识别,主要变量包括:
let hands;
let handDetected = false;
let isLeftHandPresent = false;
let isRightHandPresent = false;
let leftHandLandmarks = null;
let rightHandLandmarks = null;
手势控制功能:
相机系统实现了平滑的缩放和旋转效果:
// 相机缩放参数
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;
粒子系统是项目的核心视觉元素:
const params = {
particleCount: 15000,
transitionSpeed: 0.005,
waveIntensity: 0.0,
particleSize: 0.5
};
主要特点:
项目支持多种几何图案:
const patterns = [
createGrid, createSphere, createSpiral,
createHelix, createTorus, createVortex,
createGalaxy, createWave, createMobius,
createSupernova, createKleinBottle,
createFlower, createVoronoi, createFractalTree
];
项目定义了多组颜色配置:
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) ],
// ... 更多颜色配置
];
Geometry.js 文件包含了多个几何图案生成函数,用于创建不同的3D粒子分布模式。每个函数都通过数学算法精确控制粒子在三维空间中的分布,实现了丰富的视觉效果。
每个函数都接收两个参数:
返回值:
Chromatic-shader.js 实现了色差(色像差)后期处理效果,这是一种模拟相机镜头色差的视觉效果,使图像的RGB通道产生细微的位移,创造出独特的视觉效果。
const ChromaticAberrationShader = {
uniforms: {
"tDiffuse": { value: null },
"resolution": { value: new THREE.Vector2(1, 1) },
"strength": { value: 0.5 }
}
// ...
}
tDiffuse
: 输入纹理,存储渲染的场景resolution
: 屏幕分辨率strength
: 色差效果强度vertexShader: /* glsl */`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`
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实现平滑过渡,避免硬边界