sparcoon 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/emitter/FXEmitter.Internal.d.ts +50 -2
- package/dist/emitter/FXEmitter.Internal.js +1 -2
- package/dist/emitter/FXEmitter.d.ts +48 -1
- package/dist/emitter/FXEmitter.js +74 -11
- package/dist/emitter/behavior/FXBehavior.d.ts +12 -2
- package/dist/emitter/behavior/FXBehavior.js +3 -2
- package/dist/emitter/behavior/FXBehaviorDirectionalForce.d.ts +25 -0
- package/dist/emitter/behavior/FXBehaviorDirectionalForce.js +74 -0
- package/dist/emitter/behavior/FXBehaviorPointForce.d.ts +40 -0
- package/dist/emitter/behavior/FXBehaviorPointForce.js +98 -0
- package/dist/emitter/behavior/FXBehaviorScaleOverLife.d.ts +9 -8
- package/dist/emitter/behavior/FXBehaviorScaleOverLife.js +12 -29
- package/dist/emitter/behavior/FXBehaviorTorqueDamping.d.ts +4 -3
- package/dist/emitter/behavior/FXBehaviorTorqueDamping.js +3 -2
- package/dist/emitter/behavior/FXBehaviorTorqueNoise.d.ts +4 -3
- package/dist/emitter/behavior/FXBehaviorTorqueNoise.js +3 -2
- package/dist/emitter/behavior/FXBehaviorTorqueOverLife.d.ts +17 -0
- package/dist/emitter/behavior/FXBehaviorTorqueOverLife.js +34 -0
- package/dist/emitter/behavior/FXBehaviorVelocityDamping.d.ts +3 -2
- package/dist/emitter/behavior/FXBehaviorVelocityDamping.js +3 -2
- package/dist/emitter/behavior/FXBehaviorVelocityNoise.d.ts +6 -5
- package/dist/emitter/behavior/FXBehaviorVelocityNoise.js +6 -5
- package/dist/emitter/behavior/FXBehaviorVelocityOverLife.d.ts +20 -0
- package/dist/emitter/behavior/FXBehaviorVelocityOverLife.js +48 -0
- package/dist/emitter/spawn/FXSpawn.d.ts +4 -2
- package/dist/emitter/spawn/FXSpawn.js +3 -2
- package/dist/emitter/spawn/FXSpawnBox.d.ts +8 -16
- package/dist/emitter/spawn/FXSpawnBox.js +23 -39
- package/dist/emitter/spawn/{FXSpawnRandomLifetime.d.ts → FXSpawnLifetime.d.ts} +3 -5
- package/dist/emitter/spawn/{FXSpawnRandomLifetime.js → FXSpawnLifetime.js} +8 -10
- package/dist/emitter/spawn/FXSpawnOffset.d.ts +9 -0
- package/dist/emitter/spawn/FXSpawnOffset.js +9 -0
- package/dist/emitter/spawn/FXSpawnPoint.d.ts +8 -0
- package/dist/emitter/spawn/FXSpawnPoint.js +8 -0
- package/dist/emitter/spawn/{FXSpawnRandomRotation.d.ts → FXSpawnRotation.d.ts} +3 -5
- package/dist/emitter/spawn/{FXSpawnRandomRotation.js → FXSpawnRotation.js} +8 -10
- package/dist/emitter/spawn/{FXSpawnRandomScale.d.ts → FXSpawnScale.d.ts} +4 -6
- package/dist/emitter/spawn/{FXSpawnRandomScale.js → FXSpawnScale.js} +12 -14
- package/dist/emitter/spawn/FXSpawnSphere.d.ts +11 -6
- package/dist/emitter/spawn/FXSpawnSphere.js +11 -6
- package/dist/emitter/spawn/{FXSpawnRandomTorque.d.ts → FXSpawnTorque.d.ts} +3 -5
- package/dist/emitter/spawn/{FXSpawnRandomTorque.js → FXSpawnTorque.js} +8 -10
- package/dist/emitter/spawn/FXSpawnVelocity.d.ts +32 -0
- package/dist/emitter/spawn/{FXSpawnRandomVelocity.js → FXSpawnVelocity.js} +26 -11
- package/dist/index.d.ts +23 -16
- package/dist/index.js +20 -16
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.d.ts +4 -4
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js +2 -2
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.d.ts +55 -5
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.js +9 -2
- package/dist/materials/FXMaterial/FXDepthMaterial.Internal.d.ts +3 -3
- package/dist/materials/FXMaterial/FXDistanceMaterial.Internal.d.ts +3 -3
- package/dist/materials/FXMaterial/FXMaterial.d.ts +51 -5
- package/dist/materials/FXMaterial/FXMaterial.js +5 -0
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.d.ts +3 -3
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.d.ts +3 -3
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.js +3 -3
- package/dist/miscellaneous/curve/FXCurve1D.Internal.d.ts +20 -0
- package/dist/miscellaneous/curve/FXCurve1D.d.ts +17 -0
- package/dist/miscellaneous/curve/FXCurve1D.js +94 -0
- package/dist/miscellaneous/miscellaneous.d.ts +3 -1
- package/dist/miscellaneous/miscellaneous.js +8 -4
- package/dist/miscellaneous/texture/FXTextureView.Internal.js +6 -0
- package/dist/miscellaneous/texture/FXTextureView.js +234 -0
- package/dist/nodes/color/FXNodeColor.d.ts +7 -0
- package/dist/nodes/color/FXNodeColor.js +11 -0
- package/dist/nodes/color/FXNodeColorOverLife.d.ts +25 -0
- package/dist/nodes/color/FXNodeColorOverLife.js +60 -0
- package/dist/nodes/color/FXNodeSphericalClip.d.ts +18 -0
- package/dist/nodes/color/FXNodeSphericalClip.js +45 -0
- package/dist/nodes/normal/FXNodeFlatNormal.d.ts +7 -0
- package/dist/nodes/normal/FXNodeFlatNormal.js +17 -0
- package/dist/nodes/normal/FXNodeNormal.d.ts +7 -0
- package/dist/nodes/normal/FXNodeNormal.js +7 -0
- package/dist/nodes/normal/FXNodeSphericalNormal.d.ts +7 -0
- package/dist/nodes/normal/{FXSphericalNormalNode.js → FXNodeSphericalNormal.js} +7 -4
- package/dist/nodes/texture/FXNodeAnimatedTexture.d.ts +47 -0
- package/dist/nodes/texture/FXNodeAnimatedTexture.js +137 -0
- package/dist/nodes/texture/FXNodeStaticTexture.d.ts +18 -0
- package/dist/nodes/texture/FXNodeStaticTexture.js +60 -0
- package/dist/nodes/texture/FXNodeTexture.d.ts +7 -0
- package/dist/nodes/texture/FXNodeTexture.js +11 -0
- package/package.json +2 -4
- package/dist/emitter/behavior/FXBehaviorDirectionalGravity.d.ts +0 -21
- package/dist/emitter/behavior/FXBehaviorDirectionalGravity.js +0 -51
- package/dist/emitter/behavior/FXBehaviorPointGravity.d.ts +0 -39
- package/dist/emitter/behavior/FXBehaviorPointGravity.js +0 -116
- package/dist/emitter/spawn/FXSpawnRandomVelocity.d.ts +0 -17
- package/dist/nodes/color/FXColorNode.d.ts +0 -3
- package/dist/nodes/color/FXColorNode.js +0 -8
- package/dist/nodes/color/FXColorOverLifeNode.d.ts +0 -6
- package/dist/nodes/color/FXColorOverLifeNode.js +0 -44
- package/dist/nodes/color/FXSphericalClipNode.d.ts +0 -5
- package/dist/nodes/color/FXSphericalClipNode.js +0 -30
- package/dist/nodes/normal/FXFlatNormalNode.d.ts +0 -4
- package/dist/nodes/normal/FXFlatNormalNode.js +0 -14
- package/dist/nodes/normal/FXNormalNode.d.ts +0 -3
- package/dist/nodes/normal/FXNormalNode.js +0 -4
- package/dist/nodes/normal/FXSphericalNormalNode.d.ts +0 -4
- package/dist/nodes/texture/FXAnimatedTextureNode.d.ts +0 -12
- package/dist/nodes/texture/FXAnimatedTextureNode.js +0 -88
- package/dist/nodes/texture/FXStaticTextureNode.d.ts +0 -6
- package/dist/nodes/texture/FXStaticTextureNode.js +0 -34
- package/dist/nodes/texture/FXTextureNode.d.ts +0 -3
- package/dist/nodes/texture/FXTextureNode.js +0 -8
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FXTextureView } from "../../miscellaneous/texture/FXTextureView";
|
|
2
|
+
import type { FXTextureConfig } from "../../miscellaneous/texture/FXTextureView.Internal";
|
|
3
|
+
import { FXNodeTexture } from "./FXNodeTexture";
|
|
4
|
+
/**
|
|
5
|
+
* Texture node that applies a single static texture to every particle
|
|
6
|
+
*/
|
|
7
|
+
export declare class FXNodeStaticTexture extends FXNodeTexture {
|
|
8
|
+
private readonly uniformTexture;
|
|
9
|
+
private readonly uniformUVTransform;
|
|
10
|
+
private readonly textureViewInternal;
|
|
11
|
+
/**
|
|
12
|
+
* @param config - Texture or atlas configuration applied to every particle
|
|
13
|
+
*/
|
|
14
|
+
constructor(config: FXTextureConfig);
|
|
15
|
+
/** View describing the texture and its atlas region */
|
|
16
|
+
get textureView(): FXTextureView;
|
|
17
|
+
set textureView(config: FXTextureConfig);
|
|
18
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { getNextInstanceId } from '../../miscellaneous/miscellaneous.js';
|
|
2
|
+
import { FXTextureView } from '../../miscellaneous/texture/FXTextureView.js';
|
|
3
|
+
import { checkSRGBSupport } from '../../miscellaneous/webglCapabilities.js';
|
|
4
|
+
import { FXNodeTexture } from './FXNodeTexture.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Texture node that applies a single static texture to every particle
|
|
8
|
+
*/
|
|
9
|
+
class FXNodeStaticTexture extends FXNodeTexture {
|
|
10
|
+
/**
|
|
11
|
+
* @param config - Texture or atlas configuration applied to every particle
|
|
12
|
+
*/
|
|
13
|
+
constructor(config) {
|
|
14
|
+
super();
|
|
15
|
+
const id = getNextInstanceId();
|
|
16
|
+
this._private_uniformTexture = `u_StaticTexture_${id}`;
|
|
17
|
+
this._private_uniformUVTransform = `u_StaticTextureUVTransform_${id}`;
|
|
18
|
+
this._private_textureViewInternal = new FXTextureView(config);
|
|
19
|
+
const uvTransform = this._private_textureViewInternal.calculateUVTransform();
|
|
20
|
+
this._private_textureViewInternal.setTextureDirtyFalse();
|
|
21
|
+
this._private_textureViewInternal.setUVTransformDirtyFalse();
|
|
22
|
+
this.affectsDepth = true;
|
|
23
|
+
this.cacheKey = "static-texture";
|
|
24
|
+
this.uniformDeclarations = [
|
|
25
|
+
`uniform sampler2D ${this._private_uniformTexture};`,
|
|
26
|
+
`uniform mat3 ${this._private_uniformUVTransform};`,
|
|
27
|
+
];
|
|
28
|
+
this.uniforms = {
|
|
29
|
+
[this._private_uniformTexture]: { value: this._private_textureViewInternal.texture },
|
|
30
|
+
[this._private_uniformUVTransform]: { value: uvTransform },
|
|
31
|
+
};
|
|
32
|
+
this.helperFunctions = `
|
|
33
|
+
vec4 fxSampleStaticTexture(sampler2D colorTexture, mat3 uvTransform, vec2 uv) {
|
|
34
|
+
vec2 transformedUV = (uvTransform * vec3(uv, 1.0)).xy;
|
|
35
|
+
vec4 color = texture2D(colorTexture, transformedUV);
|
|
36
|
+
// Apply gamma correction when sRGB textures are not natively supported
|
|
37
|
+
${checkSRGBSupport() ? "" : "color = vec4(pow(color.rgb, vec3(2.2)), color.a);"}
|
|
38
|
+
return color;
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
this.colorExpression = `fxSampleStaticTexture(${this._private_uniformTexture}, ${this._private_uniformUVTransform}, p_uv)`;
|
|
42
|
+
}
|
|
43
|
+
/** View describing the texture and its atlas region */
|
|
44
|
+
get textureView() {
|
|
45
|
+
return this._private_textureViewInternal;
|
|
46
|
+
}
|
|
47
|
+
set textureView(config) {
|
|
48
|
+
this._private_textureViewInternal.set(config);
|
|
49
|
+
if (this._private_textureViewInternal.textureDirty) {
|
|
50
|
+
this.uniforms[this._private_uniformTexture].value = this._private_textureViewInternal.texture;
|
|
51
|
+
this._private_textureViewInternal.setTextureDirtyFalse();
|
|
52
|
+
}
|
|
53
|
+
if (this._private_textureViewInternal.uvTransformDirty) {
|
|
54
|
+
this._private_textureViewInternal.calculateUVTransform(this.uniforms[this._private_uniformUVTransform].value);
|
|
55
|
+
this._private_textureViewInternal.setUVTransformDirtyFalse();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { FXNodeStaticTexture };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sparcoon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Instanced-mesh particle system for Three.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"particles",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
48
|
+
"@rollup/plugin-commonjs": "^29.0.2",
|
|
48
49
|
"@types/node": "^25.0.2",
|
|
49
50
|
"@types/three": "^0.157.0",
|
|
50
51
|
"@typescript-eslint/eslint-plugin": "^8.32.0",
|
|
@@ -55,8 +56,5 @@
|
|
|
55
56
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
56
57
|
"ts-transformer-minify-privates": "^1.0.0",
|
|
57
58
|
"typescript": "^5.8.3"
|
|
58
|
-
},
|
|
59
|
-
"dependencies": {
|
|
60
|
-
"@rollup/plugin-commonjs": "^29.0.2"
|
|
61
59
|
}
|
|
62
60
|
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { Vector3Like } from "../../miscellaneous/math";
|
|
2
|
-
import type { FXVector3Config } from "../../miscellaneous/miscellaneous";
|
|
3
|
-
import { FXBehavior } from "./FXBehavior";
|
|
4
|
-
/**
|
|
5
|
-
* Applies constant acceleration to all particles.
|
|
6
|
-
*
|
|
7
|
-
* Adds the direction vector to particle velocity each frame.
|
|
8
|
-
*/
|
|
9
|
-
export declare class FXBehaviorDirectionalGravity extends FXBehavior<{
|
|
10
|
-
builtin: "Matrix4";
|
|
11
|
-
}> {
|
|
12
|
-
private directionInternal;
|
|
13
|
-
/**
|
|
14
|
-
* @param direction - Acceleration vector in units/second²
|
|
15
|
-
*/
|
|
16
|
-
constructor(direction: Vector3Like);
|
|
17
|
-
/** Acceleration vector in units/second² */
|
|
18
|
-
get direction(): Vector3Like;
|
|
19
|
-
/** Acceleration vector in units/second² */
|
|
20
|
-
set direction(value: FXVector3Config);
|
|
21
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { assertValidNumber } from '../../miscellaneous/asserts.js';
|
|
2
|
-
import { resolveFXVector3Config, BUILTIN_OFFSET_VELOCITY_X, BUILTIN_OFFSET_VELOCITY_Y, BUILTIN_OFFSET_VELOCITY_Z } from '../../miscellaneous/miscellaneous.js';
|
|
3
|
-
import { FXBehavior } from './FXBehavior.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Applies constant acceleration to all particles.
|
|
7
|
-
*
|
|
8
|
-
* Adds the direction vector to particle velocity each frame.
|
|
9
|
-
*/
|
|
10
|
-
class FXBehaviorDirectionalGravity extends FXBehavior {
|
|
11
|
-
/**
|
|
12
|
-
* @param direction - Acceleration vector in units/second²
|
|
13
|
-
*/
|
|
14
|
-
constructor(direction) {
|
|
15
|
-
super();
|
|
16
|
-
/** @internal */
|
|
17
|
-
this.requiredProperties = { builtin: "Matrix4" };
|
|
18
|
-
this._private_directionInternal = resolveFXVector3Config(direction);
|
|
19
|
-
assertValidNumber(this._private_directionInternal.x, "FXBehaviorDirectionalGravity.constructor.direction.x");
|
|
20
|
-
assertValidNumber(this._private_directionInternal.y, "FXBehaviorDirectionalGravity.constructor.direction.y");
|
|
21
|
-
assertValidNumber(this._private_directionInternal.z, "FXBehaviorDirectionalGravity.constructor.direction.z");
|
|
22
|
-
}
|
|
23
|
-
/** Acceleration vector in units/second² */
|
|
24
|
-
get direction() {
|
|
25
|
-
return this._private_directionInternal;
|
|
26
|
-
}
|
|
27
|
-
/** Acceleration vector in units/second² */
|
|
28
|
-
set direction(value) {
|
|
29
|
-
this._private_directionInternal = resolveFXVector3Config(value);
|
|
30
|
-
assertValidNumber(this._private_directionInternal.x, "FXBehaviorDirectionalGravity.direction.x");
|
|
31
|
-
assertValidNumber(this._private_directionInternal.y, "FXBehaviorDirectionalGravity.direction.y");
|
|
32
|
-
assertValidNumber(this._private_directionInternal.z, "FXBehaviorDirectionalGravity.direction.z");
|
|
33
|
-
}
|
|
34
|
-
/** @internal */
|
|
35
|
-
update(properties, instanceCount, deltaTime) {
|
|
36
|
-
const { builtin } = properties;
|
|
37
|
-
const { array, itemSize } = builtin;
|
|
38
|
-
const offsetX = this._private_directionInternal.x * deltaTime;
|
|
39
|
-
const offsetY = this._private_directionInternal.y * deltaTime;
|
|
40
|
-
const offsetZ = this._private_directionInternal.z * deltaTime;
|
|
41
|
-
for (let i = 0; i < instanceCount; i++) {
|
|
42
|
-
const itemOffset = i * itemSize;
|
|
43
|
-
array[itemOffset + BUILTIN_OFFSET_VELOCITY_X] += offsetX;
|
|
44
|
-
array[itemOffset + BUILTIN_OFFSET_VELOCITY_Y] += offsetY;
|
|
45
|
-
array[itemOffset + BUILTIN_OFFSET_VELOCITY_Z] += offsetZ;
|
|
46
|
-
}
|
|
47
|
-
builtin.needsUpdate = true;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export { FXBehaviorDirectionalGravity };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { Vector3Like } from "../../miscellaneous/math";
|
|
2
|
-
import { type FXRange, type FXRangeConfig, type FXVector3Config } from "../../miscellaneous/miscellaneous";
|
|
3
|
-
import { FXBehavior } from "./FXBehavior";
|
|
4
|
-
/**
|
|
5
|
-
* Applies gravity attraction toward a point.
|
|
6
|
-
*
|
|
7
|
-
* Force follows inverse power law: strength / distance^exponent. Particles closer than threshold are unaffected.
|
|
8
|
-
*/
|
|
9
|
-
export declare class FXBehaviorPointGravity extends FXBehavior<{
|
|
10
|
-
builtin: "Matrix4";
|
|
11
|
-
}> {
|
|
12
|
-
private centerInternal;
|
|
13
|
-
private strengthInternal;
|
|
14
|
-
private exponentInternal;
|
|
15
|
-
private thresholdInternal;
|
|
16
|
-
/**
|
|
17
|
-
* @param center - Gravity center position
|
|
18
|
-
* @param strength - Force multiplier range. Accepts number, tuple, or range object
|
|
19
|
-
* @param exponent - Distance power exponent range. Accepts number, tuple, or range object
|
|
20
|
-
* @param threshold - Minimum distance range. Accepts number, tuple, or range object
|
|
21
|
-
*/
|
|
22
|
-
constructor(center: Vector3Like, strength: FXRangeConfig, exponent?: FXRangeConfig, threshold?: FXRangeConfig);
|
|
23
|
-
/** Gravity center position */
|
|
24
|
-
get center(): Vector3Like;
|
|
25
|
-
/** Force multiplier range */
|
|
26
|
-
get strength(): FXRange;
|
|
27
|
-
/** Distance power exponent range */
|
|
28
|
-
get exponent(): FXRange;
|
|
29
|
-
/** Minimum distance range */
|
|
30
|
-
get threshold(): FXRange;
|
|
31
|
-
/** Gravity center position */
|
|
32
|
-
set center(value: FXVector3Config);
|
|
33
|
-
/** Force multiplier range */
|
|
34
|
-
set strength(value: FXRangeConfig);
|
|
35
|
-
/** Distance power exponent range */
|
|
36
|
-
set exponent(value: FXRangeConfig);
|
|
37
|
-
/** Minimum distance range */
|
|
38
|
-
set threshold(value: FXRangeConfig);
|
|
39
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { MathUtils } from 'three';
|
|
2
|
-
import { assertValidNumber } from '../../miscellaneous/asserts.js';
|
|
3
|
-
import { resolveFXVector3Config, resolveFXRangeConfig, BUILTIN_OFFSET_POSITION_X, BUILTIN_OFFSET_POSITION_Y, BUILTIN_OFFSET_POSITION_Z, BUILTIN_OFFSET_RANDOM_A, BUILTIN_OFFSET_RANDOM_B, BUILTIN_OFFSET_RANDOM_C, BUILTIN_OFFSET_VELOCITY_X, BUILTIN_OFFSET_VELOCITY_Y, BUILTIN_OFFSET_VELOCITY_Z } from '../../miscellaneous/miscellaneous.js';
|
|
4
|
-
import { FXBehavior } from './FXBehavior.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Applies gravity attraction toward a point.
|
|
8
|
-
*
|
|
9
|
-
* Force follows inverse power law: strength / distance^exponent. Particles closer than threshold are unaffected.
|
|
10
|
-
*/
|
|
11
|
-
class FXBehaviorPointGravity extends FXBehavior {
|
|
12
|
-
/**
|
|
13
|
-
* @param center - Gravity center position
|
|
14
|
-
* @param strength - Force multiplier range. Accepts number, tuple, or range object
|
|
15
|
-
* @param exponent - Distance power exponent range. Accepts number, tuple, or range object
|
|
16
|
-
* @param threshold - Minimum distance range. Accepts number, tuple, or range object
|
|
17
|
-
*/
|
|
18
|
-
constructor(center, strength, exponent = 2, threshold = 1) {
|
|
19
|
-
super();
|
|
20
|
-
/** @internal */
|
|
21
|
-
this.requiredProperties = { builtin: "Matrix4" };
|
|
22
|
-
this._private_centerInternal = resolveFXVector3Config(center);
|
|
23
|
-
assertValidNumber(this._private_centerInternal.x, "FXBehaviorPointGravity.constructor.center.x");
|
|
24
|
-
assertValidNumber(this._private_centerInternal.y, "FXBehaviorPointGravity.constructor.center.y");
|
|
25
|
-
assertValidNumber(this._private_centerInternal.z, "FXBehaviorPointGravity.constructor.center.z");
|
|
26
|
-
this._private_strengthInternal = resolveFXRangeConfig(strength);
|
|
27
|
-
assertValidNumber(this._private_strengthInternal.min, "FXBehaviorPointGravity.constructor.strength.min");
|
|
28
|
-
assertValidNumber(this._private_strengthInternal.max, "FXBehaviorPointGravity.constructor.strength.max");
|
|
29
|
-
this._private_exponentInternal = resolveFXRangeConfig(exponent);
|
|
30
|
-
assertValidNumber(this._private_exponentInternal.min, "FXBehaviorPointGravity.constructor.exponent.min");
|
|
31
|
-
assertValidNumber(this._private_exponentInternal.max, "FXBehaviorPointGravity.constructor.exponent.max");
|
|
32
|
-
this._private_thresholdInternal = resolveFXRangeConfig(threshold);
|
|
33
|
-
assertValidNumber(this._private_thresholdInternal.min, "FXBehaviorPointGravity.constructor.threshold.min");
|
|
34
|
-
assertValidNumber(this._private_thresholdInternal.max, "FXBehaviorPointGravity.constructor.threshold.max");
|
|
35
|
-
}
|
|
36
|
-
/** Gravity center position */
|
|
37
|
-
get center() {
|
|
38
|
-
return this._private_centerInternal;
|
|
39
|
-
}
|
|
40
|
-
/** Force multiplier range */
|
|
41
|
-
get strength() {
|
|
42
|
-
return this._private_strengthInternal;
|
|
43
|
-
}
|
|
44
|
-
/** Distance power exponent range */
|
|
45
|
-
get exponent() {
|
|
46
|
-
return this._private_exponentInternal;
|
|
47
|
-
}
|
|
48
|
-
/** Minimum distance range */
|
|
49
|
-
get threshold() {
|
|
50
|
-
return this._private_thresholdInternal;
|
|
51
|
-
}
|
|
52
|
-
/** Gravity center position */
|
|
53
|
-
set center(value) {
|
|
54
|
-
this._private_centerInternal = resolveFXVector3Config(value);
|
|
55
|
-
assertValidNumber(this._private_centerInternal.x, "FXBehaviorPointGravity.center.x");
|
|
56
|
-
assertValidNumber(this._private_centerInternal.y, "FXBehaviorPointGravity.center.y");
|
|
57
|
-
assertValidNumber(this._private_centerInternal.z, "FXBehaviorPointGravity.center.z");
|
|
58
|
-
}
|
|
59
|
-
/** Force multiplier range */
|
|
60
|
-
set strength(value) {
|
|
61
|
-
this._private_strengthInternal = resolveFXRangeConfig(value);
|
|
62
|
-
assertValidNumber(this._private_strengthInternal.min, "FXBehaviorPointGravity.strength.min");
|
|
63
|
-
assertValidNumber(this._private_strengthInternal.max, "FXBehaviorPointGravity.strength.max");
|
|
64
|
-
}
|
|
65
|
-
/** Distance power exponent range */
|
|
66
|
-
set exponent(value) {
|
|
67
|
-
this._private_exponentInternal = resolveFXRangeConfig(value);
|
|
68
|
-
assertValidNumber(this._private_exponentInternal.min, "FXBehaviorPointGravity.exponent.min");
|
|
69
|
-
assertValidNumber(this._private_exponentInternal.max, "FXBehaviorPointGravity.exponent.max");
|
|
70
|
-
}
|
|
71
|
-
/** Minimum distance range */
|
|
72
|
-
set threshold(value) {
|
|
73
|
-
this._private_thresholdInternal = resolveFXRangeConfig(value);
|
|
74
|
-
assertValidNumber(this._private_thresholdInternal.min, "FXBehaviorPointGravity.threshold.min");
|
|
75
|
-
assertValidNumber(this._private_thresholdInternal.max, "FXBehaviorPointGravity.threshold.max");
|
|
76
|
-
}
|
|
77
|
-
/** @internal */
|
|
78
|
-
update(properties, instanceCount, deltaTime) {
|
|
79
|
-
const { builtin } = properties;
|
|
80
|
-
const { array, itemSize } = builtin;
|
|
81
|
-
for (let i = 0; i < instanceCount; i++) {
|
|
82
|
-
const itemOffset = i * itemSize;
|
|
83
|
-
const dx = this._private_centerInternal.x - array[itemOffset + BUILTIN_OFFSET_POSITION_X];
|
|
84
|
-
const dy = this._private_centerInternal.y - array[itemOffset + BUILTIN_OFFSET_POSITION_Y];
|
|
85
|
-
const dz = this._private_centerInternal.z - array[itemOffset + BUILTIN_OFFSET_POSITION_Z];
|
|
86
|
-
// Constant over the life of a particle but different for each particle
|
|
87
|
-
const thresholdT = array[itemOffset + BUILTIN_OFFSET_RANDOM_A];
|
|
88
|
-
const threshold = MathUtils.lerp(this.threshold.min, this.threshold.max, thresholdT);
|
|
89
|
-
const thresholdSquared = threshold * threshold;
|
|
90
|
-
const distanceSquared = dx * dx + dy * dy + dz * dz;
|
|
91
|
-
if (distanceSquared < thresholdSquared) {
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
// Constant over the life of a particle but different for each particle
|
|
95
|
-
const strengthT = array[itemOffset + BUILTIN_OFFSET_RANDOM_B];
|
|
96
|
-
const strength = MathUtils.lerp(this._private_strengthInternal.min, this._private_strengthInternal.max, strengthT);
|
|
97
|
-
// Constant over the life of a particle but different for each particle
|
|
98
|
-
const exponentT = array[itemOffset + BUILTIN_OFFSET_RANDOM_C];
|
|
99
|
-
const exponent = MathUtils.lerp(this._private_exponentInternal.min, this._private_exponentInternal.max, exponentT);
|
|
100
|
-
const distance = Math.sqrt(distanceSquared);
|
|
101
|
-
const forceMagnitude = strength / Math.pow(distance, exponent);
|
|
102
|
-
const directionX = dx / distance;
|
|
103
|
-
const directionY = dy / distance;
|
|
104
|
-
const directionZ = dz / distance;
|
|
105
|
-
const accelerationX = directionX * forceMagnitude;
|
|
106
|
-
const accelerationY = directionY * forceMagnitude;
|
|
107
|
-
const accelerationZ = directionZ * forceMagnitude;
|
|
108
|
-
array[itemOffset + BUILTIN_OFFSET_VELOCITY_X] += accelerationX * deltaTime;
|
|
109
|
-
array[itemOffset + BUILTIN_OFFSET_VELOCITY_Y] += accelerationY * deltaTime;
|
|
110
|
-
array[itemOffset + BUILTIN_OFFSET_VELOCITY_Z] += accelerationZ * deltaTime;
|
|
111
|
-
}
|
|
112
|
-
builtin.needsUpdate = true;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export { FXBehaviorPointGravity };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Vector3 } from "three";
|
|
2
|
-
import type { FXRange, FXRangeConfig } from "../../miscellaneous/miscellaneous";
|
|
3
|
-
import { FXSpawn } from "./FXSpawn";
|
|
4
|
-
export declare class FXSpawnRandomVelocity extends FXSpawn<{
|
|
5
|
-
builtin: "Matrix4";
|
|
6
|
-
}> {
|
|
7
|
-
private angleInternal;
|
|
8
|
-
private magnitudeInternal;
|
|
9
|
-
private readonly directionInternal;
|
|
10
|
-
constructor(direction?: Vector3, angle?: FXRangeConfig, magnitude?: FXRangeConfig);
|
|
11
|
-
get angle(): FXRange;
|
|
12
|
-
get magnitude(): FXRange;
|
|
13
|
-
get direction(): Vector3;
|
|
14
|
-
set angle(value: FXRangeConfig);
|
|
15
|
-
set magnitude(value: FXRangeConfig);
|
|
16
|
-
set direction(value: Vector3);
|
|
17
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { buildGradientTexture } from '../../miscellaneous/miscellaneous.js';
|
|
2
|
-
import { checkSRGBSupport } from '../../miscellaneous/webglCapabilities.js';
|
|
3
|
-
import { FXColorNode } from './FXColorNode.js';
|
|
4
|
-
|
|
5
|
-
const INSTANCES = [];
|
|
6
|
-
class FXColorOverLifeNode extends FXColorNode {
|
|
7
|
-
constructor(colors) {
|
|
8
|
-
if (colors.length === 0) {
|
|
9
|
-
throw new Error("FXColorOverLifeNode: colors array cannot be empty");
|
|
10
|
-
}
|
|
11
|
-
super();
|
|
12
|
-
INSTANCES.push(this);
|
|
13
|
-
const uniformName = `u_ColorOverLife_${INSTANCES.length - 1}`;
|
|
14
|
-
this._private_gradientTexture = buildGradientTexture(colors);
|
|
15
|
-
this.affectsDepth = true;
|
|
16
|
-
this.cacheKey = "color-over-life";
|
|
17
|
-
this.uniformDeclarations = [`uniform sampler2D ${uniformName};`];
|
|
18
|
-
this.uniforms = {
|
|
19
|
-
[uniformName]: { value: this._private_gradientTexture },
|
|
20
|
-
};
|
|
21
|
-
this.helperFunctions = `
|
|
22
|
-
vec4 sampleColorOverLife(sampler2D gradientTexture) {
|
|
23
|
-
// Normalized particle age [0, 1] maps to the gradient texture's x-axis
|
|
24
|
-
float lifetimeRatio = clamp(PARTICLE_AGE / PARTICLE_LIFETIME, 0.0, 1.0);
|
|
25
|
-
vec4 color = texture2D(gradientTexture, vec2(lifetimeRatio, 0.5));
|
|
26
|
-
|
|
27
|
-
// Apply gamma correction when sRGB textures are not natively supported
|
|
28
|
-
${checkSRGBSupport() ? "" : "color = vec4(pow(color.rgb, vec3(2.2)), color.a);"}
|
|
29
|
-
|
|
30
|
-
return color;
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
33
|
-
this.colorExpression = `sampleColorOverLife(${uniformName})`;
|
|
34
|
-
}
|
|
35
|
-
destroy() {
|
|
36
|
-
this._private_gradientTexture.dispose();
|
|
37
|
-
const index = INSTANCES.indexOf(this);
|
|
38
|
-
if (index !== -1) {
|
|
39
|
-
INSTANCES.splice(index, 1);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export { FXColorOverLifeNode };
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { FXColorNode } from './FXColorNode.js';
|
|
2
|
-
|
|
3
|
-
const INSTANCES = [];
|
|
4
|
-
class FXSphericalClipNode extends FXColorNode {
|
|
5
|
-
constructor(innerRadius = 0.5) {
|
|
6
|
-
super();
|
|
7
|
-
INSTANCES.push(this);
|
|
8
|
-
const uniformName = `u_SphericalClip_${INSTANCES.length - 1}`;
|
|
9
|
-
this.cacheKey = "spherical-clip";
|
|
10
|
-
this.uniformDeclarations = [`uniform float ${uniformName};`];
|
|
11
|
-
this.uniforms = {
|
|
12
|
-
[uniformName]: { value: innerRadius },
|
|
13
|
-
};
|
|
14
|
-
this.helperFunctions = `
|
|
15
|
-
vec4 applySphericalClip(float innerRadius) {
|
|
16
|
-
float distanceToCenter = distance(p_uv, vec2(0.5, 0.5));
|
|
17
|
-
return vec4(1.0, 1.0, 1.0, 1.0 - smoothstep(innerRadius, 0.5, distanceToCenter));
|
|
18
|
-
}
|
|
19
|
-
`;
|
|
20
|
-
this.colorExpression = `applySphericalClip(${uniformName})`;
|
|
21
|
-
}
|
|
22
|
-
destroy() {
|
|
23
|
-
const index = INSTANCES.indexOf(this);
|
|
24
|
-
if (index !== -1) {
|
|
25
|
-
INSTANCES.splice(index, 1);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export { FXSphericalClipNode };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { FXNormalNode } from './FXNormalNode.js';
|
|
2
|
-
|
|
3
|
-
class FXFlatNormalNode extends FXNormalNode {
|
|
4
|
-
constructor() {
|
|
5
|
-
super();
|
|
6
|
-
this.cacheKey = "flat";
|
|
7
|
-
this.uniformDeclarations = [];
|
|
8
|
-
this.uniforms = {};
|
|
9
|
-
this.helperFunctions = "";
|
|
10
|
-
this.normalExpression = "vec3(0.0, 0.0, 1.0)";
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export { FXFlatNormalNode };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Texture } from "three";
|
|
2
|
-
import { FXTextureNode } from "./FXTextureNode";
|
|
3
|
-
export interface FXAnimatedTextureNodeOptions {
|
|
4
|
-
texture: Texture;
|
|
5
|
-
columns: number;
|
|
6
|
-
rows: number;
|
|
7
|
-
interpolate?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export declare class FXAnimatedTextureNode extends FXTextureNode {
|
|
10
|
-
constructor({ texture, columns, rows, interpolate }: FXAnimatedTextureNodeOptions);
|
|
11
|
-
destroy(): void;
|
|
12
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { checkSRGBSupport } from '../../miscellaneous/webglCapabilities.js';
|
|
2
|
-
import { FXTextureNode } from './FXTextureNode.js';
|
|
3
|
-
|
|
4
|
-
const INSTANCES = [];
|
|
5
|
-
class FXAnimatedTextureNode extends FXTextureNode {
|
|
6
|
-
constructor({ texture, columns, rows, interpolate = false }) {
|
|
7
|
-
super();
|
|
8
|
-
INSTANCES.push(this);
|
|
9
|
-
const idx = INSTANCES.length - 1;
|
|
10
|
-
const uniformTexture = `u_AnimatedTexture_${idx}`;
|
|
11
|
-
const uniformColumns = `u_AnimatedTextureColumns_${idx}`;
|
|
12
|
-
const uniformRows = `u_AnimatedTextureRows_${idx}`;
|
|
13
|
-
const gammaCorrection = checkSRGBSupport()
|
|
14
|
-
? ""
|
|
15
|
-
: "color = vec4(pow(color.rgb, vec3(2.2)), color.a);";
|
|
16
|
-
this.affectsDepth = true;
|
|
17
|
-
this.cacheKey = interpolate ? "animated-interpolated" : "animated";
|
|
18
|
-
this.uniformDeclarations = [
|
|
19
|
-
`uniform sampler2D ${uniformTexture};`,
|
|
20
|
-
`uniform float ${uniformColumns};`,
|
|
21
|
-
`uniform float ${uniformRows};`,
|
|
22
|
-
];
|
|
23
|
-
this.uniforms = {
|
|
24
|
-
[uniformTexture]: { value: texture },
|
|
25
|
-
[uniformColumns]: { value: columns },
|
|
26
|
-
[uniformRows]: { value: rows },
|
|
27
|
-
};
|
|
28
|
-
this.helperFunctions = interpolate
|
|
29
|
-
? `
|
|
30
|
-
vec2 frameToUV(vec2 uv, float frame, float columns, float rows) {
|
|
31
|
-
float column = mod(frame, columns);
|
|
32
|
-
float row = floor(frame / columns);
|
|
33
|
-
return vec2((column + uv.x) / columns, 1.0 - (row + 1.0 - uv.y) / rows);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
vec4 sampleAnimatedTexture(sampler2D spriteSheet, vec2 uv, float columns, float rows) {
|
|
37
|
-
float totalFrames = columns * rows;
|
|
38
|
-
|
|
39
|
-
// Fractional frame position drives both frame selection and blend weight
|
|
40
|
-
float exactFrame = PARTICLE_AGE / PARTICLE_LIFETIME * totalFrames;
|
|
41
|
-
float currentFrame = clamp(floor(exactFrame), 0.0, totalFrames - 1.0);
|
|
42
|
-
float nextFrame = clamp(currentFrame + 1.0, 0.0, totalFrames - 1.0);
|
|
43
|
-
float blendWeight = fract(exactFrame);
|
|
44
|
-
|
|
45
|
-
vec4 color = mix(
|
|
46
|
-
texture2D(spriteSheet, frameToUV(uv, currentFrame, columns, rows)),
|
|
47
|
-
texture2D(spriteSheet, frameToUV(uv, nextFrame, columns, rows)),
|
|
48
|
-
blendWeight
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
// Apply gamma correction when sRGB textures are not natively supported
|
|
52
|
-
${gammaCorrection}
|
|
53
|
-
|
|
54
|
-
return color;
|
|
55
|
-
}
|
|
56
|
-
`
|
|
57
|
-
: `
|
|
58
|
-
vec4 sampleAnimatedTexture(sampler2D spriteSheet, vec2 uv, float columns, float rows) {
|
|
59
|
-
// Determine which frame to display based on normalized particle age
|
|
60
|
-
float totalFrames = columns * rows;
|
|
61
|
-
float frame = floor(PARTICLE_AGE / PARTICLE_LIFETIME * totalFrames);
|
|
62
|
-
frame = clamp(frame, 0.0, totalFrames - 1.0);
|
|
63
|
-
|
|
64
|
-
// Locate the frame's column and row in the sprite sheet grid
|
|
65
|
-
float column = mod(frame, columns);
|
|
66
|
-
float row = floor(frame / columns);
|
|
67
|
-
|
|
68
|
-
// Remap UV to the frame's tile region within the sprite sheet
|
|
69
|
-
vec2 frameUV = vec2((column + uv.x) / columns, 1.0 - (row + 1.0 - uv.y) / rows);
|
|
70
|
-
vec4 color = texture2D(spriteSheet, frameUV);
|
|
71
|
-
|
|
72
|
-
// Apply gamma correction when sRGB textures are not natively supported
|
|
73
|
-
${gammaCorrection}
|
|
74
|
-
|
|
75
|
-
return color;
|
|
76
|
-
}
|
|
77
|
-
`;
|
|
78
|
-
this.colorExpression = `sampleAnimatedTexture(${uniformTexture}, p_uv, ${uniformColumns}, ${uniformRows})`;
|
|
79
|
-
}
|
|
80
|
-
destroy() {
|
|
81
|
-
const index = INSTANCES.indexOf(this);
|
|
82
|
-
if (index !== -1) {
|
|
83
|
-
INSTANCES.splice(index, 1);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export { FXAnimatedTextureNode };
|