├── .npmignore ├── examples ├── capture.jpg ├── grass_diffuse.png └── basic.html ├── src ├── constants.js ├── three-particle-fire.js ├── install.js ├── geometry.js ├── material.js └── texture.js ├── .gitignore ├── .babelrc ├── package.json ├── rollup.config.js ├── readme.md └── dist ├── three-particle-fire.min.js ├── three-particle-fire.module.js └── three-particle-fire.js /.npmignore: -------------------------------------------------------------------------------- 1 | examples/* 2 | -------------------------------------------------------------------------------- /examples/capture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yomotsu/three-particle-fire/HEAD/examples/capture.jpg -------------------------------------------------------------------------------- /examples/grass_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yomotsu/three-particle-fire/HEAD/examples/grass_diffuse.png -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | export const SPRITE_ROW_LENGTH = 4; 2 | export const ONE_SPRITE_ROW_LENGTH = 1 / SPRITE_ROW_LENGTH; 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | Thumbs.db 3 | 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | *.map 9 | 10 | node_modules 11 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ "env", { 4 | "targets": { 5 | "browsers": [ 6 | "last 2 versions", 7 | "ie >= 11" 8 | ] 9 | }, 10 | "loose": true, 11 | "modules": false 12 | } ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/three-particle-fire.js: -------------------------------------------------------------------------------- 1 | import makeGeometryClass from './geometry.js'; 2 | import makeMaterialClass from './material.js'; 3 | import { install, onInstall } from './install.js'; 4 | 5 | const particleFire = { 6 | // Geometry, 7 | // Material, 8 | install 9 | }; 10 | 11 | onInstall( 'THREE', () => { 12 | 13 | particleFire.Geometry = makeGeometryClass(); 14 | particleFire.Material = makeMaterialClass(); 15 | 16 | } ); 17 | 18 | export default particleFire; 19 | -------------------------------------------------------------------------------- /src/install.js: -------------------------------------------------------------------------------- 1 | const libs = {}; 2 | const callbacks = {}; 3 | 4 | export function install( _libs ) { 5 | 6 | libs.THREE = _libs.THREE; 7 | 8 | for ( let i = 0, l = callbacks[ 'THREE' ].length; i < l; i ++ ) { 9 | 10 | callbacks[ 'THREE' ][ i ](); 11 | 12 | } 13 | 14 | delete callbacks[ 'THREE' ]; 15 | 16 | } 17 | 18 | export function getInstalled( key ) { 19 | 20 | return libs[ key ]; 21 | 22 | } 23 | 24 | export function onInstall( key, callback ) { 25 | 26 | if ( ! callbacks[ key ] ) callbacks[ key ] = []; 27 | 28 | callbacks[ key ].push( callback ); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "three-particle-fire", 3 | "version": "0.1.0", 4 | "author": "Yomotsu", 5 | "license": "MIT", 6 | "main": "dist/three-particle-fire.js", 7 | "repository": "yomotsu/three-particle-fire", 8 | "jsnext:main": "dist/three-particle-fire.module.js", 9 | "module": "dist/three-particle-fire.module.js", 10 | "devDependencies": { 11 | "babel-core": "^6.26.3", 12 | "babel-preset-env": "1.7.0", 13 | "rollup": "^2.77.3", 14 | "rollup-plugin-babel": "3.0.2", 15 | "rollup-plugin-commonjs": "8.2.6", 16 | "rollup-plugin-node-resolve": "^3.0.0", 17 | "rollup-watch": "^4.3.1", 18 | "uglify-js": "^3.16.3" 19 | }, 20 | "scripts": { 21 | "dev": "npm run watch", 22 | "watch": "rollup --config --watch", 23 | "build": "rollup --config", 24 | "release": "rollup -c && uglifyjs dist/three-particle-fire.js -cm --preamble \"/*!\n * three-particle-fire\n * (c) 2017 @yomotsu\n * Released under the MIT License.\n */\" > dist/three-particle-fire.min.js" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import nodeResolve from 'rollup-plugin-node-resolve'; 2 | import commonjs from 'rollup-plugin-commonjs'; 3 | import babel from 'rollup-plugin-babel'; 4 | import pkg from './package.json'; 5 | 6 | const license = `/*! 7 | * ${ pkg.name } 8 | * https://github.com/${ pkg.repository } 9 | * (c) 2017 @yomotsu 10 | * Released under the MIT License. 11 | */` 12 | 13 | export default { 14 | input: 'src/three-particle-fire.js', 15 | output: [ 16 | { 17 | format: 'umd', 18 | name: 'particleFire', 19 | file: 'dist/three-particle-fire.js', 20 | banner: license 21 | }, 22 | { 23 | format: 'es', 24 | file: 'dist/three-particle-fire.module.js', 25 | banner: license 26 | } 27 | ], 28 | indent: '\t', 29 | sourceMap: false, 30 | plugins: [ 31 | nodeResolve( { 32 | jsnext: true, 33 | browser: true, 34 | preferBuiltins: false 35 | } ), 36 | commonjs( { 37 | include: [ 'node_modules/**' ], 38 | exclude: [], 39 | sourceMap: true, 40 | } ), 41 | babel( { 42 | exclude: 'node_modules/**', 43 | presets: [ 44 | [ 'env', { 45 | targets: { 46 | browsers: [ 'last 2 versions' ] 47 | }, 48 | loose: true, 49 | modules: false 50 | } ] 51 | ] 52 | } ) 53 | ] 54 | }; 55 | -------------------------------------------------------------------------------- /src/geometry.js: -------------------------------------------------------------------------------- 1 | import { ONE_SPRITE_ROW_LENGTH } from './constants.js'; 2 | import { getInstalled } from './install.js'; 3 | 4 | export default function makeGeometryClass() { 5 | 6 | const THREE = getInstalled( 'THREE' ); 7 | 8 | return class Geometry { 9 | 10 | constructor( radius, height, particleCount ) { 11 | 12 | const geometry = new THREE.BufferGeometry(); 13 | 14 | const halfHeight = height * 0.5; 15 | const position = new Float32Array( particleCount * 3 ); 16 | const random = new Float32Array( particleCount ); 17 | const sprite = new Float32Array( particleCount ); 18 | 19 | for ( let i = 0; i < particleCount; i ++ ) { 20 | 21 | const r = Math.sqrt( Math.random() ) * radius; 22 | const angle = Math.random() * 2 * Math.PI; 23 | position[ i * 3 + 0 ] = Math.cos( angle ) * r; 24 | position[ i * 3 + 1 ] = ( radius - r ) / radius * halfHeight + halfHeight; 25 | position[ i * 3 + 2 ] = Math.sin( angle ) * r; 26 | sprite[ i ] = ONE_SPRITE_ROW_LENGTH * ( ( Math.random() * 4 )|0 ); 27 | random[ i ] = Math.random(); 28 | 29 | if ( i === 0 ) { 30 | 31 | // to avoid going out of Frustum 32 | position[ i * 3 + 0 ] = 0; 33 | position[ i * 3 + 1 ] = 0; 34 | position[ i * 3 + 2 ] = 0; 35 | 36 | } 37 | 38 | } 39 | 40 | geometry.setAttribute( 'position', new THREE.BufferAttribute( position, 3 ) ); 41 | geometry.setAttribute( 'random', new THREE.BufferAttribute( random, 1 ) ); 42 | geometry.setAttribute( 'sprite', new THREE.BufferAttribute( sprite, 1 ) ); 43 | return geometry; 44 | 45 | } 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # three-particle-fire 2 | 3 | Fire mesh object for three.js 4 | 5 | [![Latest NPM release](https://img.shields.io/npm/v/three-particle-fire.svg)](https://www.npmjs.com/package/three-particle-fire) 6 | ![MIT License](https://img.shields.io/npm/l/three-particle-fire.svg) 7 | [![dependencies Status](https://david-dm.org/yomotsu/three-particle-fire/status.svg)](https://david-dm.org/yomotsu/three-particle-fire) 8 | 9 | ![](https://yomotsu.github.io/three-particle-fire/examples/capture.jpg) 10 | 11 | [Demos can be seen here](https://yomotsu.github.io/three-particle-fire/examples/basic.html). 12 | 13 | ## Usage 14 | 15 | 1. Import your three.js and then prepare three-particle-fire to use. 16 | ```javascript 17 | import * as THREE from 'three'; 18 | import particleFire from 'three-particle-fire'; 19 | 20 | particleFire.install( { THREE: THREE } ); 21 | ``` 22 | 23 | 2. Now ready to use. particleFire will provide geometry and material for `THREE.Points` class. 24 | ```javascript 25 | var fireRadius = 0.5; 26 | var fireHeight = 3; 27 | var particleCount = 800; 28 | var height = window.innerHeight; 29 | 30 | var geometry0 = new particleFire.Geometry( fireRadius, fireHeight, particleCount ); 31 | var material0 = new particleFire.Material( { color: 0xff2200 } ); 32 | material0.setPerspective( camera.fov, height ); 33 | var particleFireMesh0 = new THREE.Points( geometry0, material0 ); 34 | scene.add( particleFireMesh0 ); 35 | ``` 36 | 37 | 3. Update on tick in your render loop. 38 | ```javascript 39 | function update () { 40 | 41 | var delta = clock.getDelta(); 42 | 43 | requestAnimationFrame( update ); 44 | 45 | particleFireMesh0.material.update( delta ); 46 | renderer.render( scene, camera ); 47 | 48 | } 49 | ``` 50 | 51 | 4. Sync on onresize event 52 | 53 | ```javascript 54 | window.addEventListener( 'resize', function () { 55 | 56 | var width = window.innerWidth; 57 | var height = window.innerHeight; 58 | 59 | camera.aspect = width / height; 60 | camera.updateProjectionMatrix(); 61 | renderer.setSize( width, height ); 62 | 63 | particleFireMesh0.material.setPerspective( camera.fov, height ); 64 | 65 | } ); 66 | ``` 67 | -------------------------------------------------------------------------------- /src/material.js: -------------------------------------------------------------------------------- 1 | import { ONE_SPRITE_ROW_LENGTH } from './constants.js'; 2 | import { getInstalled } from './install.js'; 3 | import { getTexture } from './texture.js'; 4 | 5 | export default function makeMaterialClass() { 6 | 7 | const THREE = getInstalled( 'THREE' ); 8 | 9 | return class Material { 10 | 11 | constructor( parameters ) { 12 | 13 | const uniforms = { 14 | color : { value: null }, 15 | size : { value: 0.0 }, 16 | map : { value: getTexture() }, 17 | time : { value: 0.0 }, 18 | heightOfNearPlane: { value: 0.0 } 19 | }; 20 | 21 | const material = new THREE.ShaderMaterial({ 22 | 23 | uniforms : uniforms, 24 | 25 | vertexShader : [ 26 | 'attribute float random;', 27 | 'attribute float sprite;', 28 | 'uniform float time;', 29 | 'uniform float size;', 30 | 'uniform float heightOfNearPlane;', 31 | 32 | 'varying float vSprite;', 33 | 'varying float vOpacity;', 34 | 35 | 'float PI = 3.14;', 36 | 37 | 'float quadraticIn( float t ) {', 38 | 39 | 'float tt = t * t;', 40 | 'return tt * tt;', 41 | 42 | '}', 43 | 44 | 'void main() {', 45 | 46 | 'float progress = fract( time + ( 2.0 * random - 1.0 ) );', 47 | 'float progressNeg = 1.0 - progress;', 48 | 'float ease = quadraticIn( progress );', 49 | 'float influence = sin( PI * ease );', 50 | 51 | 'vec3 newPosition = position * vec3( 1.0, ease, 1.0 );', 52 | 'gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );', 53 | 'gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;', 54 | 55 | 'vOpacity = min( influence * 4.0, 1.0 ) * progressNeg;', 56 | 'vSprite = sprite;', 57 | 58 | '}' 59 | ].join( '\n' ), 60 | 61 | fragmentShader: [ 62 | 'uniform vec3 color;', 63 | 'uniform sampler2D map;', 64 | 65 | 'varying float vSprite;', 66 | 'varying float vOpacity;', 67 | 68 | 'void main() {', 69 | 70 | 'vec2 texCoord = vec2(', 71 | 'gl_PointCoord.x * ' + ONE_SPRITE_ROW_LENGTH + ' + vSprite,', 72 | 'gl_PointCoord.y', 73 | ');', 74 | 75 | 'gl_FragColor = vec4( texture2D( map, texCoord ).xyz * color * vOpacity, 1.0 );', 76 | 77 | '}' 78 | ].join( '\n' ), 79 | 80 | blending : THREE.AdditiveBlending, 81 | depthTest : true, 82 | depthWrite : false, 83 | transparent: true, 84 | // fog : true 85 | 86 | } ); 87 | 88 | material.color = new THREE.Color( 0xff2200 ); 89 | material.size = 0.4; 90 | 91 | if ( parameters !== undefined ) { 92 | material.setValues( parameters ); 93 | } 94 | 95 | material.uniforms.color.value = material.color; 96 | material.uniforms.size.value = material.size; 97 | 98 | material.update = function( delta ) { 99 | 100 | material.uniforms.time.value = ( material.uniforms.time.value + delta ) % 1; 101 | 102 | } 103 | 104 | material.setPerspective = function( fov, height ) { 105 | 106 | material.uniforms.heightOfNearPlane.value = Math.abs( height / ( 2 * Math.tan( THREE.MathUtils.degToRad( fov * 0.5 ) ) ) ); 107 | 108 | } 109 | 110 | return material; 111 | 112 | } 113 | 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /examples/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | =^.^= 6 | 10 | 11 | 12 | 13 | 14 | 15 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /src/texture.js: -------------------------------------------------------------------------------- 1 | import { getInstalled } from './install.js'; 2 | 3 | let texture; 4 | 5 | export function getTexture() { 6 | 7 | if ( !! texture ) return texture; 8 | 9 | const THREE = getInstalled( 'THREE' ); 10 | const image = new Image(); 11 | 12 | texture = new THREE.Texture(); 13 | texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 14 | texture.image = image; 15 | 16 | image.onload = () => { 17 | 18 | texture.needsUpdate = true; 19 | 20 | }; 21 | 22 | image.src = 'data:image/png;base64,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'; 23 | 24 | return texture; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /dist/three-particle-fire.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.particleFire=e()}(this,function(){"use strict";function t(t){return A[t]}function e(){var e=t("THREE"),A=function(A){var o={color:{type:"c",value:null},size:{type:"f",value:0},texture:{type:"t",value:function(){if(n)return n;var e=t("THREE"),r=new Image;return n=new e.Texture,n.wrapS=n.wrapT=e.RepeatWrapping,n.image=r,r.onload=function(){n.needsUpdate=!0},r.src="data:image/png;base64,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",n}()},time:{type:"f",value:0},heightOfNearPlane:{type:"f",value:0}};e.ShaderMaterial.call(this,{uniforms:o,vertexShader:["attribute float randam;","attribute float sprite;","uniform float time;","uniform float size;","uniform float heightOfNearPlane;","varying float vSprite;","varying float vOpacity;","float PI = 3.14;","float quadraticIn( float t ) {","float tt = t * t;","return tt * tt;","}","void main() {","float progress = fract( time + ( 2.0 * randam - 1.0 ) );","float progressNeg = 1.0 - progress;","float ease = quadraticIn( progress );","float influence = sin( PI * ease );","vec3 newPosition = position * vec3( 1.0, ease, 1.0 );","gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );","gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;","vOpacity = min( influence * 4.0, 1.0 ) * progressNeg;","vSprite = sprite;","}"].join("\n"),fragmentShader:["uniform vec3 color;","uniform sampler2D texture;","varying float vSprite;","varying float vOpacity;","void main() {","vec2 texCoord = vec2(","gl_PointCoord.x * "+r+" + vSprite,","gl_PointCoord.y",");","gl_FragColor = vec4( texture2D( texture, vec2( texCoord ) ).xyz * color * vOpacity, 1.0 );","}"].join("\n"),blending:e.AdditiveBlending,depthTest:!0,depthWrite:!1,transparent:!0}),this.color=new e.Color(16720384),this.size=.4,this.setValues(A),this.uniforms.color.value=this.color,this.uniforms.size.value=this.size};return A.prototype=Object.create(e.ShaderMaterial.prototype),A.prototype.update=function(t){this.uniforms.time.value=(this.uniforms.time.value+t)%1},A.prototype.setPerspective=function(t,r){this.uniforms.heightOfNearPlane.value=Math.abs(r/(2*Math.tan(e.Math.degToRad(.5*t))))},A}var r=.25,A={},o={},n=void 0,i={install:function(t){A.THREE=t.THREE;for(var e=0,r=o.THREE.length;e