Three.js - 利用 JS 进行图片处理并生成对应粒子图
栏目: JavaScript · 发布时间: 5年前
内容简介:平时需要实现几个的动效来改善无聊的中后台业务带来的负面情绪。概述:利用 JS 以及 Three.js 对下图进行处理来生成对应的粒子图,
平时需要实现几个的动效来改善无聊的中后台业务带来的负面情绪。
概述:利用 JS 以及 Three.js 对下图进行处理
来生成对应的粒子图, 实例代码 。
主要分为以下几个步骤
1. 获取对应图像信息
首先读取图片,可以利用 document.images
获取页面中 img
的信息。
再将 img
绘制到 canvas
画布,利用 getImageData
获取图像的像素信息,具体如下 getImgData
const getImgData = img => { // 宽、高 const { width, height } = img const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') // 像素数 const numPixels = width * height canvas.width = width canvas.height = height ctx.scale(1, -1) ctx.drawImage(img, 0, 0, width, height * -1) // 用来描述canvas区域隐含的像素数据 const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height) return { width, numPixels, originalColors: Float32Array.from(imgData.data), } } 复制代码
imgData.data
包含着图片的像素数据的数组,即 RGBA 值:
- R - 红色 (0-255);
- G - 绿色 (0-255);
- B - 蓝色 (0-255);
- A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)。
在 imgData.data
排列顺序是每个像素点的 [R, G, B, A, R, G, B, A, ...]
,如图
2. 图像处理
上一步中获取到相关图像的像素信息,然后处理四个通道的信息 originalColors
由于图像的背景为黑色,也就是说可以利用 R 通道 的数据来进行阈值分割
设定一个阈值 threshold
,如果满足 originalColors[i * 4 + 0] > threshold
的条件,则统计该像素点可见,然后遍历 originalColors
得到可见像素点的位置的坐标。
const getParticleData = (img, threshold) => { const { width, numPixels, originalColors } = getImgData(img) let numVisible = 0 // 统计大于阈值的像素点 for (let i = 0; i < numPixels; i++) { if (originalColors[i * 4 + 0] > threshold) numVisible++ } const offsets = new Float32Array(numVisible * 3) // 获取像素点的位置 for (let i = 0, j = 0; i < numPixels; i++) { if (originalColors[i * 4 + 0] > threshold) { // 获取 x 方向的坐标 offsets[j * 3 + 0] = i % width // 获取 y 方向的坐标 offsets[j * 3 + 1] = Math.floor(i / width) j++ } } return { offsets } } 复制代码
3. 生成粒子图
这一步比较简单,就是利用得到的像素位置来生成对应的粒子图,首先初始化场景、相机等要素
// init webGL const scene = new THREE.Scene() const group = new THREE.Group() scene.add(group) const camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 10, 10000 ) camera.position.z = 300 const fovHeight = 2 * Math.tan(camera.fov * Math.PI / 180 / 2) * camera.position.z const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('canvas'), antialias: true, alpha: true, }) renderer.setClearColor(0x000000, 1) 复制代码
然后,在 offsets
的位置数据上,生成对应的粒子
设定每个粒子的 material
,然后利用 TweenMax.to
使得粒子过渡至对应位置。
const textureLoader = new THREE.TextureLoader() const map = textureLoader.load('./assets/images/circle.png') const material = new THREE.SpriteMaterial({ map, color: 0xffffff, fog: true }) const positions = offsets for (let index = 0; index < positions.length; index += 2) { const particleMaterial = material const particle = new THREE.Sprite(particleMaterial) // 粒子目标位置 const targetX = positions[index] const targetY = positions[index + 1] const targetZ = positions[index + 2] if (targetX && targetY) { // 粒子的初始位置 particle.position.x = 0 particle.position.y = 0 particle.position.z = 0 // 粒子从初始位置过渡到目标位置 TweenMax.to(particle.position, 1, { x: targetX, y: targetY, z: targetZ, delay: Math.random() * 0.1 }) group.add(particle) } } 复制代码
4. 总结
简单的阈值分割结合粒子特效对图像进行处理,如果需要其他特效,可以处理粒子的 material
,例如 RawShaderMaterial
,可以实现如下效果
以上所述就是小编给大家介绍的《Three.js - 利用 JS 进行图片处理并生成对应粒子图》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 深度高能粒子对撞追踪:Kaggle TrackML粒子追踪挑战赛亚军访谈
- 粒子滤波Matlab示例
- 粒子滤波Matlab示例
- 粒子系统的设计
- CAEmitterLayer 粒子动画
- 学习 PixiJS — 粒子效果
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。