Обещаю, еще несколько постов о частицах.
Эта статья является частью моей текущей серии руководств по ThreeJS средней сложности. Я давно хотел что-то среднее между уровнями вступления Как нарисовать куб и Давайте заполним экран шейдерным безумием. Итак, вот оно.
До сих пор мы использовали только одно изображение текстуры для каждого эффекта. "Вот этот":
Этот отлично подходит для множества эффектов, но мы можем сделать гораздо больше, используя разные текстуры. Я скачал этот удивительный набор изображений от мастера игрового арта Кенни. Вы только посмотрите на все крутые изображения!
Теперь мы можем дать волю нашему воображению. Вот пять различных примеров с использованием одного из изображений Кенни, а также настройки, которые я использовал для каждого из них.
Частицы магии
const options = { position: new THREE.Vector3(0,2,0), positionRandomness: 0.0, velocity: new THREE.Vector3(0.0, -0.5, 0.0), velocityRandomness: 1.0, acceleration: new THREE.Vector3(0.0,0.0,0.0), color: new THREE.Color(1.0,0.0,1.0), endColor: new THREE.Color(0.0,1.0,1.0), colorRandomness: 0.0, lifetime: 2.0, fadeIn:0.001, fadeOut:0.001, size: 60, sizeRandomness: 0.0, } parts = new GPUParticleSystem({ maxParticles: 10000, particleSpriteTex: texture, blending: THREE.AdditiveBlending, onTick:(system,time) => { for (let i = 0; i < 10; i++) { options.velocity.set(rand(-1,1),rand(-1,1), 0) system.spawnParticle(options); } }})
Радуга звезд
const options = { position: new THREE.Vector3(0,2,0), positionRandomness: 0.0, velocity: new THREE.Vector3(0.0, -0.5, 0.0), velocityRandomness: 1.0, acceleration: new THREE.Vector3(0.0,-1.0,0.0), color: new THREE.Color(1.0,0.0,1.0), endColor: new THREE.Color(0.0,1.0,1.0), lifetime: 20.0, fadeIn:0.001, fadeOut:0.001, size: 100, sizeRandomness: 0.0, } parts = new GPUParticleSystem({ maxParticles: 10000, particleSpriteTex: texture, blending: THREE.AdditiveBlending, onTick:(system,time) => { for (let i = 0; i < 1; i++) { options.color.setHSL(rand(0,1),1.0,0.5) options.endColor = options.color options.position.set(rand(-2.5,-2),2,0) options.velocity.set(rand(1.2,1.4),1, 0) system.spawnParticle(options); } }})
Периодические огненные шары
Этот немного отличается тем, что использует условие, чтобы решить, когда стрелять. Код (floor (time)% 6 === 0) означает, что каждые шесть секунд он будет срабатывать непрерывно в течение одной секунды.
const options = { position: new THREE.Vector3(0,2,0), positionRandomness: 0.0, velocity: new THREE.Vector3(0.0, 0, 0.0), velocityRandomness: 1.0, acceleration: new THREE.Vector3(0.0,0.0,0.0), color: new THREE.Color(1.0,0.0,1.0), endColor: new THREE.Color(0.0,1.0,1.0), lifetime: 2.0, fadeIn:0.001, fadeOut:3.0, size: 60, sizeRandomness: 0.0, } parts = new GPUParticleSystem({ maxParticles: 10000, particleSpriteTex: texture, blending: THREE.AdditiveBlending, onTick:(system,time) => { if(Math.floor(time) %6 == 0) for (let i = 0; i < 6; i++) { options.color.setHSL(0.1, 1.0, 0.5) options.endColor.setHSL(0.0, 0.0, 0.8) options.position.set(0,0,0) const s = 0.05 options.velocity.set(rand(-s,s), rand(-s,s), rand(-s,s)) system.spawnParticle(options); } }})
Эффект транспортера
const options = { position: new THREE.Vector3(0,2,0), positionRandomness: 0.0, velocity: new THREE.Vector3(0.0, 0, 0.0), velocityRandomness: 1.0, acceleration: new THREE.Vector3(0.0,0.0,0.0), color: new THREE.Color(1.0,0.0,1.0), endColor: new THREE.Color(0.0,1.0,1.0), lifetime: 2.0, fadeIn:0.001, fadeOut:3.0, size: 200, sizeRandomness: 0.0, } parts = new GPUParticleSystem({ maxParticles: 10000, particleSpriteTex: texture, blending: THREE.AdditiveBlending, onTick: (system, time) => { if(Math.floor(time/1) % 2 === 0) { options.color.setHSL(0.1, 1.0, 0.5) options.endColor.setHSL(0.0, 0.0, 0.8) options.position.set(0, 0, 0) const s = 0.05 options.velocity.set(rand(-s, s), rand(-s, s), rand(-s, s)) system.spawnParticle(options); } } })
Бенгальское кольцо
Обратите внимание, что приведенный ниже код вычисляет начальную позицию под случайным углом с использованием sin и cos. Это то, что создает форму круга. Так же просто сделать квадрат или другую форму.
const options = { position: new THREE.Vector3(0,2,0), positionRandomness: 0.0, velocity: new THREE.Vector3(0.0, 0, 0.0), velocityRandomness: 1.0, acceleration: new THREE.Vector3(0.0,0.0,0.0), color: new THREE.Color(1.0,0.0,1.0), endColor: new THREE.Color(0.0,1.0,1.0), lifetime: 2.0, fadeIn:0.001, fadeOut:3.0, size: 30, sizeRandomness: 0.0, } parts = new GPUParticleSystem({ maxParticles: 10000, particleSpriteTex: texture, blending: THREE.AdditiveBlending, onTick: (system, time) => { for(let i=0; i<10; i++) { options.color.setHSL(0.1, 1.0, 0.5) options.endColor.setHSL(0.0, 0.0, 0.8) const theta = rand(0,Math.PI*2) const size = 0.4 options.position.set(Math.sin(theta)*size,Math.cos(theta)*size, 0) const s = 0.02 options.velocity.set(rand(-s, s), rand(-s, s), rand(-s, s)) system.spawnParticle(options); } } })
До скорого
Помните, если вы работаете над классным интерфейсом WebVR, который вы хотели бы продемонстрировать прямо в Firefox Reality, дайте мне знать.