creativelifeform / three-nebula Goto Github PK
View Code? Open in Web Editor NEWWebGL based particle system engine for three.js
Home Page: https://three-nebula.org/
License: MIT License
WebGL based particle system engine for three.js
Home Page: https://three-nebula.org/
License: MIT License
As highlighted here, there's too many draw calls happening, which causes a performance bottle neck.
We can have a look at the following examples to get this going
Use case: I have an emitter that runs for 10 seconds. I'd like to extend the life of it by another 10 seconds after it's already started. Not reset it but extend its lifespan after it's started. I've tried resetting age and totalEmitTimes to 0 but it doesn't seem to affect run time.
Not sure if this is exactly possible, but here is the suggestion #54 (comment)
Make sure that it is globalObject: 'this',
so that usage of window
doesn't cause node to explode
More a question than an Issue. How can I use fromJSONAsync in pure JS while three-nebula is added with HTML script tag?
I tried few different approach but everything fails:
1.
new System.fromJSONAsync(...
→ Uncaught ReferenceError: System is not defined
2.
new Nebula.fromJSONAsync(...
→ Uncaught TypeError: Nebula.fromJSONAsync is not a constructor
3.
system = new Nebula.default();
system.fromJSONAsync(...
→ Uncaught TypeError: system.fromJSONAsync is not a function
4.
const { System, Emitter, Rate, Span } = window.Nebula;
const system = new System();
system.fromJSONAsync(...
→ Uncaught TypeError: system.fromJSONAsync is not a function
.
Other functions works fine. I can create emitter with particles through code and it works perfectly.
BTW. this library is really awesome :)
Perhaps an unintended consequence of using var++
, but the way it is now, PUID._id
will always be 1 less than the current PUID_${id}
string
This will allow these to be easily toggled on and off
There isn't really any reason to have a separate class for an emitter that can have behaviours applied to itself, so to achieve this
emitterBehaviours
update
method of the base emitterAfter this you can remove the BehaviourEmitter
class completely
Currently if you attempt to destroy while animating, bad things can happen because there is no guard to stop updates when destroy is called.
Also need to check to see if the emitter you are attempting to destroy exists before performing this operation.
Better implementation:
update(delta = DEFAULT_PROTON_DELTA) {
if (!this.canUpdate) {
return Promise.resolve();
}
const d = delta || DEFAULT_PROTON_DELTA;
this.dispatch(PROTON_UPDATE);
if (d > 0) {
let i = this.emitters.length;
while (i--) {
this.emitters[i].update(d);
}
}
this.dispatch(PROTON_UPDATE_AFTER);
return Promise.resolve();
}
destroy() {
this.canUpdate = false;
const length = this.emitters.length;
for (let i = 0; i < length; i++) {
this.emitters[i] && this.emitters[i].destroy();
delete this.emitters[i];
}
this.emitters.length = 0;
this.pool.destroy();
this.canUpdate = true;
}
This is being thrown by three
when viewing the gravity example
I've been doing some performance analysis with chrome dev tools because fps was pretty low for my usage.
export default {
_id: 0,
_uids: new Map(), //maps objects to IDs
id: function (functionOrObject) {
if (this._uids.has(functionOrObject))
return this._uids.get(functionOrObject);
const nid = 'PUID_' + this._id++;
this._uids.set(functionOrObject, nid);
return nid;
}
};
constructor(container, THREE) {
[...]
this._THREE = THREE;
}
[...]
onParticleUpdate(particle) {
if (particle.target) {
particle.target.position.copy(particle.position);
if (!(particle.target instanceof this._THREE.Sprite))
particle.target.rotation.set(
particle.rotation.x,
particle.rotation.y,
particle.rotation.z
);
this.scale(particle);
if (particle.useAlpha) {
particle.target.material.opacity = particle.alpha;
particle.target.material.transparent = true;
}
if (particle.useColor) {
particle.target.material.color.copy(particle.color);
}
}
}
(alternatively, could override the whole function in SpriteRenderer)
Could you fix these or do you need a PR @rohan-deshpande ?
Floating point textures are not supported on iOS safari and other mobile browsers.
Hi,
First of all, thank you for this cool library. Now I am looking forward to make volumetric and realistic cloud with different shapes. Is possible to do this with Nebula?
Currently there is a mixture of US and correct English spellings in the lib, let's just settle on using the US spellings and deprecate the correct ones. I think the main offender here is behaviour
vs behavior
spe CODE:
` var particleGroup = new SPE.Group({
texture: {
value: Resources.Load("resource/img/star.png").data
}
});
var emitter = new SPE.Emitter({
// maxAge: {
// value: 2
// },
// position: {
// value: new Vector3(0, 0, -50),
// spread: new Vector3(0, 0, 0)
// },
// acceleration: {
// value: new Vector3(0, -10, 0),
// spread: new Vector3(10, 0, 10)
// },
velocity: {
value: new Vector3(0, 0, 0),
spread: new Vector3(100, 75, 100)
},
color: {
randomise:true,
// value: [new Color('white'), new Color('red')]
},
size: {
value: 100
},
alive:0.25,
particleCount: 10,
});
particleGroup.addEmitter(emitter);
scene.add(particleGroup.mesh);
render.proton = particleGroup;`
Nebula GPURender code:
` private createNormalNebula(render: SceneRenderGroup, scene: Scene) {
let proton = new Nebula.System();
render.proton = proton
proton.addEmitter(this.createNebulaEmitter());
// proton.addRenderer(new Nebula.SpriteRenderer(scene, THREE));
//@ts-ignore
proton.addRenderer(new Nebula.GPURenderer(scene, THREE));
}
private createNebulaEmitter() {
let emitter = new Nebula.Emitter();
emitter.rate = new Nebula.Rate(10, 0.25);
// emitter.addInitializer(new Nebula.Mass(1));
emitter.addInitializer(new Nebula.Radius(100));
emitter.addInitializer(new Nebula.Life(2));
emitter.addInitializer(new Nebula.Body(this.createSprite()));
emitter.addInitializer(new Nebula.Position(new Nebula.BoxZone(100)));
// emitter.addInitializer(new Nebula.RadialVelocity(200, new Nebula.Vector3D(0, 1, 1), 180));
// //emitter.addBehaviour(new Proton.RandomDrift(30, 30, 30, .05));
emitter.addBehaviour(new Nebula.Rotate("random", "random"));
emitter.addBehaviour(new Nebula.Scale(0.75));
// emitter.addBehaviour(new Nebula.Alpha(1));
//emitter.addBehaviour(new Proton.CrossZone(zone2, "bound"));
//emitter.addBehaviour(new Proton.Collision(emitter,true));
emitter.addBehaviour(new Nebula.Color(0xff0000, 'random', Infinity));
emitter.emit();
return emitter;
}
private createSprite() {
var map = Resources.Load("resource/img/dot.png").data
var material = new SpriteMaterial({
map: map,
color: 0xff0000,
});
return new Sprite(material);
}
`
result:
SPE faster
any idea to imporve it?
Normalise doc blocks and use esdoc to create API docs
Seems like only one texture will get rendered. Colours and everything else seem fine.
Horizontal window size changes seem to not affect the rendering of systems whereas vertical size changes do
Reproduced particle position even if System.update(delta) changes in a variable frame rate environment.
When System.update(delta) changes, the particle position not reproduced.
Here is the sample code.
Anyone can change the DELTA_COEFFICIENT
value.
delta
= 0.0167 (DEFAULT_SYSTEM_DELTA)delta
= 0.00551Nebula.Emitter.damping is not corrected by delta time.
Velocity and Acceleration corrected by delta time.
In the sample code, if you change FIX_DAMPING = true
, the particle positions will be reproduced.
Currently non transparent textures will be given background colours when the GPURenderer is used in a three WebGLRenderer alpha: true
context.
^ Notice how every texture other than the middle one has a black square background.
This can be "solved" in two ways. Firstly, turn alpha: true
off for the WebGLRenderer. Not ideal, as the user may want to have a transparent canvas.
Secondly, we could change the fragment shader gl_FragColor
calculation from
gl_FragColor = gl_FragColor * texture2D(uTexture, uv)
to
gl_FragColor = gl_FragColor * texture2D(uTexture, uv).rgbr
However this borks transparent textures
^ Notice how the middle texture looks completely different now to the first image.
We do need to support both, so for now, we will leave things as is and ask users to do alpha: false
if they are using non transparent textures, saying the alternative is not supported right now.
The GPURenderer
is breaking in [email protected] with the following error
THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog invalid shaders� THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:97: 'texture' : function name expected
�1: #version 300 es
2: #define varying in
3: out highp vec4 pc_fragColor;
4: #define gl_FragColor pc_fragColor
5: #define gl_FragDepthEXT gl_FragDepth
6: #define texture2D texture
7: #define textureCube texture
8: #define texture2DProj textureProj
9: #define texture2DLodEXT textureLod
10: #define texture2DProjLodEXT textureProjLod
11: #define textureCubeLodEXT textureLod
12: #define texture2DGradEXT textureGrad
13: #define texture2DProjGradEXT textureProjGrad
14: #define textureCubeGradEXT textureGrad
15: precision highp float;
16: precision highp int;
17: #define HIGH_PRECISION
18: #define SHADER_NAME ShaderMaterial
19: #define GAMMA_FACTOR 2
20: uniform mat4 viewMatrix;
21: uniform vec3 cameraPosition;
22: uniform bool isOrthographic;
23:
24: vec4 LinearToLinear( in vec4 value ) {
25: return value;
26: }
27: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
28: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
29: }
30: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
31: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
32: }
33: vec4 sRGBToLinear( in vec4 value ) {
34: return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );
35: }
36: vec4 LinearTosRGB( in vec4 value ) {
37: return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
38: }
39: vec4 RGBEToLinear( in vec4 value ) {
40: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
41: }
42: vec4 LinearToRGBE( in vec4 value ) {
43: float maxComponent = max( max( value.r, value.g ), value.b );
44: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
45: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
46: }
47: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
48: return vec4( value.rgb * value.a * maxRange, 1.0 );
49: }
50: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
51: float maxRGB = max( value.r, max( value.g, value.b ) );
52: float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
53: M = ceil( M * 255.0 ) / 255.0;
54: return vec4( value.rgb / ( M * maxRange ), M );
55: }
56: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
57: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
58: }
59: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
60: float maxRGB = max( value.r, max( value.g, value.b ) );
61: float D = max( maxRange / maxRGB, 1.0 );
62: D = clamp( floor( D ) / 255.0, 0.0, 1.0 );
63: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
64: }
65: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
66: vec4 LinearToLogLuv( in vec4 value ) {
67: vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
68: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
69: vec4 vResult;
70: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
71: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
72: vResult.w = fract( Le );
73: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
74: return vResult;
75: }
76: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
77: vec4 LogLuvToLinear( in vec4 value ) {
78: float Le = value.z * 255.0 + value.w;
79: vec3 Xp_Y_XYZp;
80: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
81: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
82: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
83: vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
84: return vec4( max( vRGB, 0.0 ), 1.0 );
85: }
86: vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); }
87:
88:
89: uniform vec3 baseColor;
90: uniform sampler2D texture;
91:
92: varying vec3 targetColor;
93: varying float targetAlpha;
94:
95: void main() {
96: gl_FragColor = vec4(baseColor * targetColor, targetAlpha);
97: gl_FragColor = gl_FragColor * texture2D(texture, gl_PointCoord);
98: }
99:
Is there any way to initialize and/or animate Sprite rotation?
Looks like the only way is changing the material.rotation property and Nebula.Rotate is changing the Sprite rotation which has no effect with three.js
For systems that are instantiated from JSON, all properties which can be Infinity
need to check if the input value is null
and if so, set it to Infinity
For behaviours, you can easily set a fallback in the abstract Behaviour
constructor:
/**
* @desc The life of the behaviour
* @type {number}
*/
this.life = life || Infinity;
For emitters, you can set a fallback within the emit
method
emit(totalEmitTimes = Infinity, life = Infinity) {
this.currentEmitTime = 0;
this.totalEmitTimes = totalEmitTimes || Infinity;
if (totalEmitTimes === 1) {
this.life = totalEmitTimes;
} else {
this.life = life || Infinity;
}
this.rate.init();
return this;
}
The particle system needs to load asynchronously so that textures can be readied before the system starts. Not doing so causes the following issue to occur
The square renders happen because the particle texture hasn't loaded yet. The fromJSONAsync method was an attempt to solve this, but using it causes a three
error to occur.
Plan of action should be
fromJSONAsync
method to the main branch and mark it as experimental, also exclude it from code coverage for nowVersion: 4.0.1.
Adding a Color behaviour to an emitter with 0
or 0x0
as a colour causes it to crash:
TypeError: Cannot read property 'getValue' of null
.
0x000001 works.
Reason:
In src/math/ColorSpan.js
Line 60 - you check if you have a colours object. 0 will return false therefore returning null.
The BodySprite.fromJSON
method currently isn't going to really work for changes to blending options as the blending
key requires a specific three constant (which is a number) to be set.
In order to achieve this, you'll need a way to map strings to these constant such as
withBlendingConstantSetFromString = materialProperties => ({ ...materialProperties, blending: THREE[materialProperties.blending] });
You should call this within the fromJSON
method but you should also create a new constant DEFAULT_JSON_MATERIAL_PROPERTIES
which has the blending key set to a string for consistency
Hey there,
trying to use the script tag as per the documentation at the bottom of the main github page of three-nebula (see minimum working example below), but it leads to this error:
Firefox: "Uncaught TypeError: window.System is undefined"
Edge: "Uncaught TypeError: Cannot destructure property 'System' of 'window.System' as it is undefined."
This is the example code I am testing:
<html>
<head><title>Test</title></head>
<body>
<script type='text/javascript' src="js/three.js"></script>
<script type='text/javascript' src='js/three-nebula.js'></script>
<script>
const { System, Emitter, Rate, Span } = window.System;
const system = new System();
</script>
</body>
I am a hobby programmer, so there is probably something obvious I am missing - however, I cant find it.
The three.js implementation works without issues, the script files are definitely accessible.
Any help would be appreciated :)
MeshZone
will currently break if a mesh's geometry is a BufferGeometry
due to these geoms not having a vertices
property which is accessed directly in the getPosition
method of the class
getPosition() {
var vertices = this.geometry.vertices;
var rVector = vertices[(vertices.length * Math.random()) >> 0];
this.vector.x = rVector.x * this.scale;
this.vector.y = rVector.y * this.scale;
this.vector.z = rVector.z * this.scale;
return this.vector;
}
Seems like BufferGeometry
stores its vertices in a different place ie., for the mesh it'll be at mesh.geometry.attributes.position.array
The examples are getting to be a real pain to manage in terms of development as we are duplicating code all over the place. Updating them and adding new ones is simply not going to scale.
Moving them to be managed inside a single app with a module like system will make things a great deal easier.
Very weird and hard to solve issue, it seems the latest version of babel is causing issues with the points renderer example where performance slows to a crawl while rendering. The issue arose in 28c9357 where babel was upgraded to 7.8.4
from 7.5.0
.
Currently, commenting out the following lines from the webpack config (ie., removing babel entirely) seems to resolve the issue
{
test: /(\.jsx|\.js)$/,
loader: 'babel-loader',
exclude: /(node_modules)/,
},
Doing this and then running
npm run build
cd website
rm -rf node_modules/three-nebula
npm run link-src
npm run dev
And navigating to http://localhost:3000/examples/point-zone will show that the example is working as normal. If you run it with babel-loader
the example grinds to a halt.
I've tried upgrading all babel dependencies to see if the issue has been subsequently fixed, but it seems it is still a problem.
Obviously I'd love to be able to solve this from the library's source code itself, but it's really hard right now to know exactly what is causing it. This could be related to babel/babel#11356
Right now there's a few options
preset-env
is causing the issueThe library has diverged from the fork quite a bit now, might be a good time to rename it as it is kind of its own beast.
Possible names
Will add more if I think of any
Reported by @davidpox here #65 (comment) there are currently depth sorting issues with the GPURenderer
, need to investigate possible solutions
Olical/EventEmitter
is pretty battle hardened at this point and has good test coverage. It’ll mean coverage for the internal class will be unnecessary.
The Behaviour class is not accessible from the public. And the Behaviour class cannot be extended.
The Behaviour class is accessible from the public.
Third party developers will be able to create custom behaviors.
Currently, the Color behavior in three-nebula has two variables, ColorA and ColorB.
I want to set the transparency to a more granular level. For this reason, I have prototyped a custom behavior with the color of the Canvas element as a variable.
https://github.com/MasatoMakino/three-nebula-behaviour-plugin
https://masatomakino.github.io/three-nebula-behaviour-plugin/demo/
This is a color behavior with canvas elements and png images as variables.
This prototype works in 5.1.0 and does not work in 5.1.1.
This prototype is a custom class that extends the Behavior class in the src directory.
From this commit, the src folder has been removed from the npm package.
That's why I can't extend the Behavior class from src/behaviour/Behaviour.js
.
If getEasingByName() and SUPPORTED_JSON_BEHAVIOUR_TYPES are public, third party developers can customize the fromJson()
function.
However, the public SUPPORTED_JSON_BEHAVIOUR_TYPES has a Side effects. If the behavior has a duplicate TYPE
, fromJson will not work. You can't limit what TYPE
to third party developers.
I've thought of several ideas. They are not the best, but I hope they will help you.
macOS 10.15.2
three-nebula 5.1.0 - 5.1.1
webpack 4.43.0
Thank you.
Hi, I have noticed that since three-nebula package has a dependency on three.js, bundling applications that also have root dependencies to three.js causes three.js library to be included twice in the final bundle, one for the depedency on three-nebula and one for root dependencies on three.js.
Considering for example the following package.json dependencies:
"dependencies": {
"three": "^0.104.0",
"three-nebula": "^4.0.3",
},
And the following js file:
import { Scene, PerspectiveCamera, Mesh } from "three"
import System, {
Emitter,
Rate,
Span,
Position,
Mass,
Radius,
Life,
Velocity,
PointZone,
Vector3D,
Alpha,
Scale,
Color,
} from 'three-nebula'
Building this file using WebPack results in a file of 1.4 MB (threejs library packed alone is about 650 KB).
To include three.js only once in the bundle, the thing that works for me was to modify the file three-nebula/src/core/three.js to point directly to the root package ./node_modules/three/build/three.module.js (instead of ./node_modules/three-nebula/node_modules/three) and make imports from ./node_modules/three-nebula/src/index.js instead.
In that case the final bundle size is around 800 KB.
should be DEFAULT_ATTRACTION_RADIUS
The core/Pool
class is pretty confusing. I don't really like the API. After having a look for other JavaScript object pool implementations, I found https://www.npmjs.com/package/deepool which has a nice, simple API.
Here's how the change would have to work
Proton
instance will need to have a particlePool
property set, this will be set like this.particlePool = deepool.create(() => new Particle())
you could also consider moving this to being a property of the Emitter
instancecreateParticle
method, you can then simply call this.parent
or this.particlePool.use()
expire
method, simply call this.particlePool.recycle(particle.reset())
This should really be all there is to it. There'll be similar changes to be done inside the zones/MeshRenderer
class and any others that use the core/Pool
class.
Here's a bunch of things that should be done as part of the v2.0.0
release
reset
methods and move logic to the constructors. I don't see a reason for these methods at all as they are not called internally anywhere and they are just making the API more confusing than it needs to beinitializer/Position
constructor and function doc blocks so they do not have argument mismatchesTODO
comments (Resolved by #26)Proton.fromJSON
static method that can create an entire system from JSON (Resolved by #21)initialize
suffix. These have been replaced by methods that use the initializer
suffix (Resolved by #20)renderer/*Render
compatibility classes, remove all methods which use the render
suffix. These have been replaced by methods that use the renderer
suffix (Resolved by #20)VectorVelocity
initializer and port tests (Resolved by #22)RadialVelocity
initializer and port tests (Resolved by #22)PolarVelocity
initializer and port tests (Resolved by #22)name
property on all classes to type
to align with three
. Create a utility method to set the type on the class to the constructor namep
, v
, and a
, props on the Particle
class to position
, velocity
, acceleration
in the interest of self documenting code (Resolved by #25)math/ArraySpan
to math/ColorSpan
, remove the color specific stuff from math/ArraySpan
, it simply returns a random item from its internal array, it shouldn't have specific color logic in it (Resolved by #23)core/Pool
with deePool
events/EventDispatcher
with EventEmitter
this.parent.integrator
(Resolved by #21)Is there a way for a emitter to pick between two or more THREE.Sprites randomly?
You need the following things to be ignored by npm, right now the package size is huge and codesandbox is complaining
docs/
scripts/
src/
test/
website/
Accept a rotation object with x, y & z properties, set these on the emitter after instantiation.
There seems to be an astonishing similarity between this project and three.proton, even some of the examples are the same.
I'd like to know if they are related
Shouldn't be too hard to do, but let's port this to a modern format. Let's add
eslint
config.babelrc
.editorconfig
core/Proton
core/Particle
core/Pool
emitter/Emitter
I think this makes more logical sense. The initializers are basically properties for the emitter and the behaviours control how the particles behave.
When creating new Sprite() particles with modified geometry (UV coordinates) the system seems to cache the geometry. Subsequent new particles will use the existing modified geometry. We're using a sprite sheet so need to modify UVs to apply the correct texture to the sprite.
Currently this is a bit of a mystery to me but when including three-nebula
in a create-react-app
app - performance seems to be significantly impacted. The issue can be rectified by including the lib in a script tag rather than as a dependency.
If included as a dependency via npm install three-nebula
, GPU rendered systems which clock in at a rock solid 60FPS normally are maxing out at 40FPS.
If the lib is included as a script tag in public/index.html
and Nebula is accessed via the window
everything is fine.
Perhaps this is related to #94. You can't modify the babel config in CRA apps without ejecting so that solution is not going to work.
Ideally what would have to happen would be to investigate what function in particular was causing the issue and fix it.
@manthrax has done some investigating and noticed that the performance profiles for an identical system look totally different in the different environments.
Note that this doesn't seem to be happening in the GPURenderer example for an app built with next
so it more than likely is something odd in the create-react-app
config.
As highlighted here, there needs to be some extra logic and steps in the Position
initialiser to detect if the intention is to instantiate a MeshZone
for this to work the following needs to happen in the Position.fromJSON
method
MeshZone
geometryType
prop from the provided JSONYou will need to choose a range of three geometries to support, there's a bunch of cool ones that could give some pretty cool shapes to the particle systems.
You can use https://github.com/siddharthkp/bundlesize to do this
Right now there is no way for a dependent application to know when a particle system has reached its end of life, that is, when all of its emitters’ particles are dead = true
.
This of course can never happen if any of the emitters have their life set to Infinity
so this needs to be considered when creating the API.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.