Three.js 图片抖动粒子特效
🎯 提示词
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
使用 Three.js 实现图片抖动粒子特效,具体要求:
**核心特效**
- 将图片解析为像素数据
- 根据像素亮度生成粒子深度分布
- 粒子系统沿 Z 轴周期性抖动
- 保留原图色彩信息
**场景与光照**
- 黑色背景
- 坐标轴辅助线辅助调试
- AmbientLight 环境光
**交互与控制**
- TrackballControls 自由旋转缩放
- 相机距离 3000 单位
**技术要求**
- Three.js 版本 (ES Module)
- TrackballControls 控制器
- Canvas 2D Context 解析图片
- 自定义 ShaderMaterial 处理粒子颜色和抖动
📖 效果拆解
| 层次 |
视觉效果 |
技术实现 |
| 基础 |
像素粒子化 |
ImageData 遍历 + BufferGeometry |
| 核心特效 |
Z 轴亮度分布 |
亮度权重映射到 zRange 范围 |
| 动态效果 |
正弦波抖动 |
amplitude = sin(animationTime) |
| 色彩保留 |
逐像素颜色 |
customColor attribute |
🔧 核心技术点
1. 图片像素数据读取
为什么需要这个技术:需要获取每个像素的 RGB 值来生成有颜色的粒子系统。
function createPixelData() {
var image = document.createElement("img");
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
image.onload = function () {
canvas.width = image.width;
canvas.height = image.height;
context.fillStyle = context.createPattern(image, 'no-repeat');
context.fillRect(0, 0, imageWidth, imageHeight);
imageData = context.getImageData(0, 0, imageWidth, imageHeight).data;
createPaticles();
};
image.src = "https://img1.baidu.com/it/u=232967222,3421933282...";
}
2. 亮度计算与 Z 轴映射
为什么需要这个技术:根据像素亮度决定粒子在 Z 轴上的位置,明亮像素靠近观察者。
var weights = [0.2126, 0.7152, 0.0722];
for (var i = 0; i < imageHeight; i++) {
for (var j = 0; j < imageWidth; j++) {
var color = new THREE.Color();
color.setRGB(imageData[c] / 255, imageData[c + 1] / 255, imageData[c + 2] / 255);
var weight = color.r * weights[0] + color.g * weights[1] + color.b * weights[2];
vertex.z = (zRange * -0.5) + (zRange * weight);
}
}
3. 粒子 Shader
为什么需要这个技术:自定义顶点着色器实现 Z 轴抖动效果。
uniform float amplitude;
attribute vec3 customColor;
varying vec3 vColor;
void main() {
vColor = customColor;
vec4 pos = vec4(position, 1.0);
pos.z *= amplitude;
vec4 mvPosition = modelViewMatrix * pos;
gl_PointSize = 2.0 * (300.0 / -mvPosition.z);
gl_Position = projectionMatrix * mvPosition;
}
4. 动画循环
为什么需要这个技术:持续更新 amplitude 参数实现周期性抖动。
function update() {
shaderUniforms.amplitude.value = Math.sin(animationTime);
animationTime += animationDelta;
controls.update();
}
💡 调试与优化
| 问题类型 |
表现形式 |
解决方案 |
| 图片跨域失败 |
CORS 错误或空白 |
使用同源图片或配置 CORS 头部 |
| 粒子过于密集 |
性能下降 |
降低图片分辨率或采样间隔 |
| 抖动不自然 |
运动僵硬 |
调整 animationDelta 或改用其他波形 |
🚀 扩展思路
| 变体效果 |
核心改动 |
难度 |
| 粒子聚合 |
鼠标点击聚合/散开 |
⭐⭐ |
| 颜色渐变 |
粒子颜色随时间变化 |
⭐ |
| 3D 漂浮 |
添加 X/Y 轴随机运动 |
⭐ |
| 马赛克效果 |
用 BoxGeometry 替代 Points |
⭐⭐ |
| 粒子消散 |
alpha 随时间衰减 |
⭐⭐ |
| 图片切换 |
过渡动画切换多张图片 |
⭐⭐⭐ |
本文档由 ThreeLab 编辑整理,如需转载,请注明出处。
💬 评论区
评论功能即将上线,敬请期待!