sparcoon 0.0.8 → 0.2.0
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/dist/{elements → emitter}/FXEmitter.Internal.d.ts +2 -4
- package/dist/{elements → emitter}/FXEmitter.Internal.js +3 -1
- package/dist/{elements → emitter}/FXEmitter.d.ts +8 -8
- package/dist/{elements → emitter}/FXEmitter.js +21 -18
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorDirectionalGravity.d.ts +2 -2
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorDirectionalGravity.js +2 -2
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorModule.d.ts +1 -1
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorPointGravity.d.ts +2 -2
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorPointGravity.js +2 -2
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorScaleOverLife.d.ts +1 -1
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorScaleOverLife.js +2 -2
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueDamping.d.ts +1 -1
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueDamping.js +2 -2
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueNoise.d.ts +1 -1
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueNoise.js +3 -3
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityDamping.d.ts +1 -1
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityDamping.js +2 -2
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityNoise.d.ts +1 -1
- package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityNoise.js +3 -3
- package/dist/{spawnModules → emitter/spawn}/FXSpawnBox.d.ts +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnBox.js +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnModule.d.ts +1 -1
- package/dist/{spawnModules → emitter/spawn}/FXSpawnOffset.d.ts +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnOffset.js +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomLifetime.d.ts +1 -1
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomLifetime.js +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomRotation.d.ts +1 -1
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomRotation.js +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomScale.d.ts +1 -1
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomScale.js +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomTorque.d.ts +1 -1
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomTorque.js +2 -2
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomVelocity.d.ts +1 -1
- package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomVelocity.js +2 -2
- package/dist/emitter/spawn/FXSpawnSphere.d.ts +38 -0
- package/dist/emitter/spawn/FXSpawnSphere.js +89 -0
- package/dist/index.d.ts +24 -20
- package/dist/index.js +25 -20
- package/dist/instancedParticle/FXInstancedParticle.Internal.d.ts +2 -9
- package/dist/instancedParticle/FXInstancedParticle.Internal.js +2 -187
- package/dist/instancedParticle/FXInstancedParticle.d.ts +4 -4
- package/dist/instancedParticle/FXInstancedParticle.js +5 -6
- package/dist/instancedParticle/shared.d.ts +1 -1
- package/dist/instancedParticle/shared.js +1 -1
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.d.ts +9 -0
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js +108 -0
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.d.ts +15 -0
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.js +18 -0
- package/dist/materials/FXMaterial.Internal.d.ts +4 -0
- package/dist/materials/FXMaterial.Internal.js +106 -0
- package/dist/materials/FXMaterial.d.ts +14 -0
- package/dist/materials/FXMaterial.js +21 -0
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.d.ts +4 -0
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.js +80 -0
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.d.ts +11 -0
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.js +17 -0
- package/dist/materials/color-nodes/FXAnimatedTextureNode.d.ts +10 -0
- package/dist/materials/color-nodes/FXAnimatedTextureNode.js +41 -0
- package/dist/materials/color-nodes/FXColorNode.d.ts +3 -0
- package/dist/materials/color-nodes/FXColorNode.js +8 -0
- package/dist/materials/color-nodes/FXColorOverLifeNode.d.ts +7 -0
- package/dist/materials/color-nodes/FXColorOverLifeNode.js +38 -0
- package/dist/materials/color-nodes/FXStaticTextureNode.d.ts +5 -0
- package/dist/materials/color-nodes/FXStaticTextureNode.js +23 -0
- package/dist/materials/miscellaneous.d.ts +1 -0
- package/dist/materials/miscellaneous.js +25 -0
- package/dist/{color → miscellaneous/color}/FXColor.js +2 -2
- package/dist/miscellaneous/miscellaneous.d.ts +1 -1
- package/package.json +1 -1
- package/dist/miscellaneous/texture/FXTextureView.Internal.js +0 -6
- package/dist/miscellaneous/texture/FXTextureView.js +0 -234
- package/dist/renderingModules/FXRenderingAnimatedTexture.d.ts +0 -5
- package/dist/renderingModules/FXRenderingAnimatedTexture.js +0 -14
- package/dist/renderingModules/FXRenderingColorOverLife.d.ts +0 -14
- package/dist/renderingModules/FXRenderingColorOverLife.js +0 -32
- package/dist/renderingModules/FXRenderingColorOverVelocity.d.ts +0 -15
- package/dist/renderingModules/FXRenderingColorOverVelocity.js +0 -37
- package/dist/renderingModules/FXRenderingModule.d.ts +0 -8
- package/dist/renderingModules/FXRenderingModule.js +0 -9
- package/dist/renderingModules/FXRenderingTexture.d.ts +0 -14
- package/dist/renderingModules/FXRenderingTexture.js +0 -26
- package/dist/shaders/FXRenderingAnimatedTexture.glsl.js +0 -3
- package/dist/shaders/FXRenderingColorOverLife.glsl.js +0 -3
- package/dist/shaders/FXRenderingColorOverVelocity.glsl.js +0 -3
- package/dist/shaders/FXRenderingTexture.glsl.js +0 -3
- /package/dist/{behaviorModules → emitter/behavior}/FXBehaviorModule.js +0 -0
- /package/dist/{spawnModules → emitter/spawn}/FXSpawnModule.js +0 -0
- /package/dist/{color → miscellaneous/color}/FXColor.Internal.d.ts +0 -0
- /package/dist/{color → miscellaneous/color}/FXColor.Internal.js +0 -0
- /package/dist/{color → miscellaneous/color}/FXColor.d.ts +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { MeshBasicMaterial, DoubleSide } from 'three';
|
|
2
|
+
import { PARTICLE_DEFINES } from '../miscellaneous.js';
|
|
3
|
+
|
|
4
|
+
function buildFXUnlitMaterial(varyings, blending, useAlphaHashing, colorNodes) {
|
|
5
|
+
const attributeDeclarations = [];
|
|
6
|
+
const varyingDeclarations = [];
|
|
7
|
+
const vertexAssignments = [];
|
|
8
|
+
for (const name in varyings) {
|
|
9
|
+
const { glslTypeName } = varyings[name];
|
|
10
|
+
attributeDeclarations.push(`attribute ${glslTypeName} a_${name};`);
|
|
11
|
+
varyingDeclarations.push(`varying ${glslTypeName} p_${name};`);
|
|
12
|
+
vertexAssignments.push(`p_${name} = a_${name};`);
|
|
13
|
+
}
|
|
14
|
+
const material = new MeshBasicMaterial({
|
|
15
|
+
transparent: !useAlphaHashing,
|
|
16
|
+
depthWrite: useAlphaHashing,
|
|
17
|
+
depthTest: true,
|
|
18
|
+
alphaHash: useAlphaHashing,
|
|
19
|
+
blending,
|
|
20
|
+
side: DoubleSide,
|
|
21
|
+
forceSinglePass: true,
|
|
22
|
+
alphaTest: 1 / 255,
|
|
23
|
+
});
|
|
24
|
+
material.onBeforeCompile = (shader) => {
|
|
25
|
+
const vertexPreamble = [
|
|
26
|
+
PARTICLE_DEFINES,
|
|
27
|
+
attributeDeclarations.join("\n"),
|
|
28
|
+
"varying vec2 p_uv;",
|
|
29
|
+
varyingDeclarations.join("\n"),
|
|
30
|
+
].join("\n");
|
|
31
|
+
shader.vertexShader =
|
|
32
|
+
vertexPreamble +
|
|
33
|
+
"\n" +
|
|
34
|
+
shader.vertexShader
|
|
35
|
+
.replace("#include <begin_vertex>", [
|
|
36
|
+
"p_uv = uv;",
|
|
37
|
+
vertexAssignments.join("\n"),
|
|
38
|
+
"vec3 transformed = position;",
|
|
39
|
+
"#ifdef USE_ALPHAHASH",
|
|
40
|
+
" vPosition = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z) + vec3(position.xy, 0.0);",
|
|
41
|
+
"#endif",
|
|
42
|
+
].join("\n"))
|
|
43
|
+
.replace("#include <project_vertex>", `
|
|
44
|
+
vec2 p_bp = position.xy;
|
|
45
|
+
p_bp.x *= PARTICLE_SCALE_X;
|
|
46
|
+
p_bp.y *= PARTICLE_SCALE_Y;
|
|
47
|
+
float p_cosR = cos(PARTICLE_ROTATION);
|
|
48
|
+
float p_sinR = sin(PARTICLE_ROTATION);
|
|
49
|
+
p_bp = vec2(
|
|
50
|
+
p_bp.x * p_cosR - p_bp.y * p_sinR,
|
|
51
|
+
p_bp.x * p_sinR + p_bp.y * p_cosR
|
|
52
|
+
);
|
|
53
|
+
vec3 p_c = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);
|
|
54
|
+
vec4 mvPosition = modelViewMatrix * vec4(p_c, 1.0);
|
|
55
|
+
mvPosition.xy += p_bp;
|
|
56
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
57
|
+
`);
|
|
58
|
+
const fragmentPreamble = [
|
|
59
|
+
PARTICLE_DEFINES,
|
|
60
|
+
"varying vec2 p_uv;",
|
|
61
|
+
varyingDeclarations.join("\n"),
|
|
62
|
+
colorNodes.flatMap((n) => n.uniformDeclarations).join("\n"),
|
|
63
|
+
colorNodes.map((n) => n.helperFunctions).join("\n"),
|
|
64
|
+
].join("\n");
|
|
65
|
+
for (const node of colorNodes) {
|
|
66
|
+
Object.assign(shader.uniforms, node.uniforms);
|
|
67
|
+
}
|
|
68
|
+
let fragmentShader = shader.fragmentShader;
|
|
69
|
+
if (colorNodes.length > 0) {
|
|
70
|
+
const combinedExpression = colorNodes.map((n) => n.colorExpression).join(" * ");
|
|
71
|
+
const discardLine = useAlphaHashing ? "" : "if (diffuseColor.a < 0.0035) discard;";
|
|
72
|
+
fragmentShader = fragmentShader.replace("#include <map_fragment>", `diffuseColor = ${combinedExpression}; ${discardLine}`);
|
|
73
|
+
}
|
|
74
|
+
shader.fragmentShader = fragmentPreamble + "\n" + fragmentShader;
|
|
75
|
+
};
|
|
76
|
+
material.customProgramCacheKey = () => `fx-unlit-${colorNodes.map((n) => n.cacheKey).join("-") || "none"}`;
|
|
77
|
+
return material;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export { buildFXUnlitMaterial };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Blending } from "three";
|
|
2
|
+
import { FXMaterial, type FXMaterialOptions } from "../FXMaterial";
|
|
3
|
+
export interface FXUnlitMaterialOptions extends FXMaterialOptions {
|
|
4
|
+
blending: Blending;
|
|
5
|
+
useAlphaHashing: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class FXUnlitMaterial extends FXMaterial {
|
|
8
|
+
private readonly blending;
|
|
9
|
+
private readonly useAlphaHashing;
|
|
10
|
+
constructor(options?: Partial<FXUnlitMaterialOptions>);
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NormalBlending } from 'three';
|
|
2
|
+
import { FXMaterial } from '../FXMaterial.js';
|
|
3
|
+
import { buildFXUnlitMaterial } from './FXUnlitMaterial.Internal.js';
|
|
4
|
+
|
|
5
|
+
class FXUnlitMaterial extends FXMaterial {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
super(options);
|
|
8
|
+
this._private_blending = options.blending ?? NormalBlending;
|
|
9
|
+
this._private_useAlphaHashing = options.useAlphaHashing ?? false;
|
|
10
|
+
}
|
|
11
|
+
/** @internal */
|
|
12
|
+
buildThreeMaterial(varyings) {
|
|
13
|
+
return buildFXUnlitMaterial(varyings, this._private_blending, this._private_useAlphaHashing, this.colorNodes);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { FXUnlitMaterial };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Texture } from "three";
|
|
2
|
+
import { FXColorNode } from "./FXColorNode";
|
|
3
|
+
export interface FXAnimatedTextureNodeOptions {
|
|
4
|
+
texture: Texture;
|
|
5
|
+
cols: number;
|
|
6
|
+
rows: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class FXAnimatedTextureNode extends FXColorNode {
|
|
9
|
+
constructor({ texture, cols, rows }: FXAnimatedTextureNodeOptions);
|
|
10
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FXColorNode } from './FXColorNode.js';
|
|
2
|
+
|
|
3
|
+
class FXAnimatedTextureNode extends FXColorNode {
|
|
4
|
+
constructor({ texture, cols, rows }) {
|
|
5
|
+
super();
|
|
6
|
+
/** @internal */
|
|
7
|
+
this.cacheKey = "animated";
|
|
8
|
+
/** @internal */
|
|
9
|
+
this.uniformDeclarations = [
|
|
10
|
+
"uniform sampler2D u_AnimatedTexture;",
|
|
11
|
+
"uniform float u_AnimatedTextureCols;",
|
|
12
|
+
"uniform float u_AnimatedTextureRows;",
|
|
13
|
+
];
|
|
14
|
+
/** @internal */
|
|
15
|
+
this.helperFunctions = `
|
|
16
|
+
vec4 _fx_sampleAnimated(sampler2D tex, vec2 uv, float cols, float rows) {
|
|
17
|
+
float totalFrames = cols * rows;
|
|
18
|
+
float frame = floor(PARTICLE_AGE / PARTICLE_LIFETIME * totalFrames);
|
|
19
|
+
frame = clamp(frame, 0.0, totalFrames - 1.0);
|
|
20
|
+
float col = mod(frame, cols);
|
|
21
|
+
float row = floor(frame / cols);
|
|
22
|
+
vec2 frameUV = vec2((col + uv.x) / cols, 1.0 - (row + 1.0 - uv.y) / rows);
|
|
23
|
+
return texture2D(tex, frameUV);
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
/** @internal */
|
|
27
|
+
this.colorExpression = "_fx_sampleAnimated(u_AnimatedTexture, p_uv, u_AnimatedTextureCols, u_AnimatedTextureRows)";
|
|
28
|
+
/** @internal */
|
|
29
|
+
this.affectsDepth = true;
|
|
30
|
+
this.uniforms = {
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
32
|
+
u_AnimatedTexture: { value: texture },
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
34
|
+
u_AnimatedTextureCols: { value: cols },
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
36
|
+
u_AnimatedTextureRows: { value: rows },
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { FXAnimatedTextureNode };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FXColor } from "../../miscellaneous/color/FXColor";
|
|
2
|
+
import { FXColorNode } from "./FXColorNode";
|
|
3
|
+
export declare class FXColorOverLifeNode extends FXColorNode {
|
|
4
|
+
private readonly gradientTexture;
|
|
5
|
+
constructor(colors: FXColor[]);
|
|
6
|
+
destroy(): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { buildGradientTexture } from '../../miscellaneous/miscellaneous.js';
|
|
2
|
+
import { checkSRGBSupport } from '../../miscellaneous/webglCapabilities.js';
|
|
3
|
+
import { FXColorNode } from './FXColorNode.js';
|
|
4
|
+
|
|
5
|
+
class FXColorOverLifeNode extends FXColorNode {
|
|
6
|
+
constructor(colors) {
|
|
7
|
+
if (colors.length === 0) {
|
|
8
|
+
throw new Error("FXColorOverLifeNode: colors array cannot be empty");
|
|
9
|
+
}
|
|
10
|
+
super();
|
|
11
|
+
/** @internal */
|
|
12
|
+
this.affectsDepth = true;
|
|
13
|
+
/** @internal */
|
|
14
|
+
this.cacheKey = "color-over-life";
|
|
15
|
+
/** @internal */
|
|
16
|
+
this.uniformDeclarations = ["uniform sampler2D u_ColorOverLife;"];
|
|
17
|
+
/** @internal */
|
|
18
|
+
this.colorExpression = "_fx_sampleColorOverLife(u_ColorOverLife)";
|
|
19
|
+
this._private_gradientTexture = buildGradientTexture(colors);
|
|
20
|
+
this.uniforms = {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
22
|
+
u_ColorOverLife: { value: this._private_gradientTexture },
|
|
23
|
+
};
|
|
24
|
+
this.helperFunctions = `
|
|
25
|
+
vec4 _fx_sampleColorOverLife(sampler2D tex) {
|
|
26
|
+
float t = clamp(PARTICLE_AGE / PARTICLE_LIFETIME, 0.0, 1.0);
|
|
27
|
+
vec4 c = texture2D(tex, vec2(t, 0.5));
|
|
28
|
+
${checkSRGBSupport() ? "" : "c = vec4(pow(c.rgb, vec3(2.2)), c.a);"}
|
|
29
|
+
return c;
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
destroy() {
|
|
34
|
+
this._private_gradientTexture.dispose();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { FXColorOverLifeNode };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FXColorNode } from './FXColorNode.js';
|
|
2
|
+
|
|
3
|
+
class FXStaticTextureNode extends FXColorNode {
|
|
4
|
+
constructor(texture) {
|
|
5
|
+
super();
|
|
6
|
+
/** @internal */
|
|
7
|
+
this.cacheKey = "static";
|
|
8
|
+
/** @internal */
|
|
9
|
+
this.uniformDeclarations = ["uniform sampler2D u_StaticTexture;"];
|
|
10
|
+
/** @internal */
|
|
11
|
+
this.helperFunctions = "";
|
|
12
|
+
/** @internal */
|
|
13
|
+
this.colorExpression = "texture2D(u_StaticTexture, p_uv)";
|
|
14
|
+
/** @internal */
|
|
15
|
+
this.affectsDepth = true;
|
|
16
|
+
this.uniforms = {
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
18
|
+
u_StaticTexture: { value: texture },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { FXStaticTextureNode };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PARTICLE_DEFINES = "\n #define PARTICLE_POSITION_X p_builtin[0][0]\n #define PARTICLE_POSITION_Y p_builtin[0][1]\n #define PARTICLE_POSITION_Z p_builtin[0][2]\n\n #define PARTICLE_VELOCITY_X p_builtin[0][3]\n #define PARTICLE_VELOCITY_Y p_builtin[1][0]\n #define PARTICLE_VELOCITY_Z p_builtin[1][1]\n\n #define PARTICLE_SCALE_X p_builtin[1][2]\n #define PARTICLE_SCALE_Y p_builtin[1][3]\n #define PARTICLE_SCALE_Z p_builtin[2][0]\n\n #define PARTICLE_ROTATION p_builtin[2][1]\n #define PARTICLE_TORQUE p_builtin[2][2]\n\n #define PARTICLE_LIFETIME p_builtin[2][3]\n #define PARTICLE_AGE p_builtin[3][0]\n\n #define PARTICLE_RANDOM_A p_builtin[3][1]\n #define PARTICLE_RANDOM_B p_builtin[3][2]\n #define PARTICLE_RANDOM_C p_builtin[3][3]\n";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const PARTICLE_DEFINES = `
|
|
2
|
+
#define PARTICLE_POSITION_X p_builtin[0][0]
|
|
3
|
+
#define PARTICLE_POSITION_Y p_builtin[0][1]
|
|
4
|
+
#define PARTICLE_POSITION_Z p_builtin[0][2]
|
|
5
|
+
|
|
6
|
+
#define PARTICLE_VELOCITY_X p_builtin[0][3]
|
|
7
|
+
#define PARTICLE_VELOCITY_Y p_builtin[1][0]
|
|
8
|
+
#define PARTICLE_VELOCITY_Z p_builtin[1][1]
|
|
9
|
+
|
|
10
|
+
#define PARTICLE_SCALE_X p_builtin[1][2]
|
|
11
|
+
#define PARTICLE_SCALE_Y p_builtin[1][3]
|
|
12
|
+
#define PARTICLE_SCALE_Z p_builtin[2][0]
|
|
13
|
+
|
|
14
|
+
#define PARTICLE_ROTATION p_builtin[2][1]
|
|
15
|
+
#define PARTICLE_TORQUE p_builtin[2][2]
|
|
16
|
+
|
|
17
|
+
#define PARTICLE_LIFETIME p_builtin[2][3]
|
|
18
|
+
#define PARTICLE_AGE p_builtin[3][0]
|
|
19
|
+
|
|
20
|
+
#define PARTICLE_RANDOM_A p_builtin[3][1]
|
|
21
|
+
#define PARTICLE_RANDOM_B p_builtin[3][2]
|
|
22
|
+
#define PARTICLE_RANDOM_C p_builtin[3][3]
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
export { PARTICLE_DEFINES };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MathUtils, Color, Vector4 } from 'three';
|
|
2
|
-
import { assertValidNumber } from '../
|
|
3
|
-
import { srgbToLinear, linearToSRGB } from '../
|
|
2
|
+
import { assertValidNumber } from '../asserts.js';
|
|
3
|
+
import { srgbToLinear, linearToSRGB } from '../math.js';
|
|
4
4
|
import { COLORS } from './FXColor.Internal.js';
|
|
5
5
|
|
|
6
6
|
/** RGBA color with RGB, HSL, hex, and named color support */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Vector3Tuple } from "three";
|
|
2
2
|
import { DataTexture } from "three";
|
|
3
|
-
import type { FXColor } from "../color/FXColor";
|
|
4
3
|
import type { Vector3Like } from "../miscellaneous/math";
|
|
5
4
|
import type { FXTextureConfig } from "../miscellaneous/texture/FXTextureView.Internal";
|
|
5
|
+
import type { FXColor } from "./color/FXColor";
|
|
6
6
|
export interface FXRange {
|
|
7
7
|
min: number;
|
|
8
8
|
max: number;
|
package/package.json
CHANGED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { Ferrsign3 } from 'ferrsign';
|
|
2
|
-
import { Matrix3, Vector2, Texture } from 'three';
|
|
3
|
-
import { assertValidPositiveNumber, assertValidNonNegativeNumber } from '../asserts.js';
|
|
4
|
-
import { TEXTURE_DEFAULT_TEXTURE, TEXTURE_DEFAULT_SIZE } from './FXTextureView.Internal.js';
|
|
5
|
-
|
|
6
|
-
/** Wrapper for Three.js texture with atlas and trim support. Does not own the underlying texture; user must dispose it. */
|
|
7
|
-
class FXTextureView {
|
|
8
|
-
/** @param config Texture or atlas configuration */
|
|
9
|
-
constructor(config) {
|
|
10
|
-
this._private_textureInternal = TEXTURE_DEFAULT_TEXTURE;
|
|
11
|
-
this._private_sourceWidth = TEXTURE_DEFAULT_SIZE;
|
|
12
|
-
this._private_sourceHeight = TEXTURE_DEFAULT_SIZE;
|
|
13
|
-
this._private_frameX = 0;
|
|
14
|
-
this._private_frameY = 0;
|
|
15
|
-
this._private_frameWidth = TEXTURE_DEFAULT_SIZE;
|
|
16
|
-
this._private_frameHeight = TEXTURE_DEFAULT_SIZE;
|
|
17
|
-
this._private_rotatedInternal = false;
|
|
18
|
-
this._private_scaleInternal = 1;
|
|
19
|
-
this._private_trimLeft = 0;
|
|
20
|
-
this._private_trimRight = 0;
|
|
21
|
-
this._private_trimTop = 0;
|
|
22
|
-
this._private_trimBottom = 0;
|
|
23
|
-
this._private_textureDirtyInternal = false;
|
|
24
|
-
this._private_uvTransformDirtyInternal = false;
|
|
25
|
-
this._private_trimDirtyInternal = false;
|
|
26
|
-
this._private_signalDiminsionsChangedInternal = new Ferrsign3();
|
|
27
|
-
if (config !== undefined) {
|
|
28
|
-
this.set(config);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
/** Original width before trimming in world units */
|
|
32
|
-
get width() {
|
|
33
|
-
return this._private_sourceWidth / this._private_scaleInternal;
|
|
34
|
-
}
|
|
35
|
-
/** Original height before trimming in world units */
|
|
36
|
-
get height() {
|
|
37
|
-
return this._private_sourceHeight / this._private_scaleInternal;
|
|
38
|
-
}
|
|
39
|
-
/** Visible width after trimming in world units */
|
|
40
|
-
get trimmedWidth() {
|
|
41
|
-
const frameSize = this._private_rotatedInternal ? this._private_frameHeight : this._private_frameWidth;
|
|
42
|
-
return frameSize / this._private_scaleInternal;
|
|
43
|
-
}
|
|
44
|
-
/** Visible height after trimming in world units */
|
|
45
|
-
get trimmedHeight() {
|
|
46
|
-
const frameSize = this._private_rotatedInternal ? this._private_frameWidth : this._private_frameHeight;
|
|
47
|
-
return frameSize / this._private_scaleInternal;
|
|
48
|
-
}
|
|
49
|
-
/** Underlying Three.js texture */
|
|
50
|
-
get texture() {
|
|
51
|
-
return this._private_textureInternal;
|
|
52
|
-
}
|
|
53
|
-
/** Whether sprite is rotated in atlas */
|
|
54
|
-
get rotated() {
|
|
55
|
-
return this._private_rotatedInternal;
|
|
56
|
-
}
|
|
57
|
-
/** Scale factor for resolution independence */
|
|
58
|
-
get scale() {
|
|
59
|
-
return this._private_scaleInternal;
|
|
60
|
-
}
|
|
61
|
-
/** Transparent padding around visible content */
|
|
62
|
-
get trim() {
|
|
63
|
-
const scale = this._private_scaleInternal;
|
|
64
|
-
return {
|
|
65
|
-
left: this._private_trimLeft / scale,
|
|
66
|
-
right: this._private_trimRight / scale,
|
|
67
|
-
top: this._private_trimTop / scale,
|
|
68
|
-
bottom: this._private_trimBottom / scale,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
get textureDirty() {
|
|
72
|
-
return this._private_textureDirtyInternal;
|
|
73
|
-
}
|
|
74
|
-
/** Whether UV transform inputs changed since last check */
|
|
75
|
-
get uvTransformDirty() {
|
|
76
|
-
return this._private_uvTransformDirtyInternal;
|
|
77
|
-
}
|
|
78
|
-
/** Whether trim values changed since last check */
|
|
79
|
-
get trimDirty() {
|
|
80
|
-
return this._private_trimDirtyInternal;
|
|
81
|
-
}
|
|
82
|
-
get signalDiminsionsChanged() {
|
|
83
|
-
return this._private_signalDiminsionsChangedInternal;
|
|
84
|
-
}
|
|
85
|
-
setTextureDirtyFalse() {
|
|
86
|
-
this._private_textureDirtyInternal = false;
|
|
87
|
-
}
|
|
88
|
-
/** Marks UV transform as clean. @internal */
|
|
89
|
-
setUVTransformDirtyFalse() {
|
|
90
|
-
this._private_uvTransformDirtyInternal = false;
|
|
91
|
-
}
|
|
92
|
-
/** Marks trim as clean. @internal */
|
|
93
|
-
setTrimDirtyFalse() {
|
|
94
|
-
this._private_trimDirtyInternal = false;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Calculates UV transform matrix for shader sampling.
|
|
98
|
-
* @param result Matrix to store result in
|
|
99
|
-
* @returns UV transform matrix
|
|
100
|
-
*/
|
|
101
|
-
calculateUVTransform(result = new Matrix3()) {
|
|
102
|
-
const atlasWidth = this._private_textureInternal.image?.naturalWidth ?? TEXTURE_DEFAULT_SIZE;
|
|
103
|
-
const atlasHeight = this._private_textureInternal.image?.naturalHeight ?? TEXTURE_DEFAULT_SIZE;
|
|
104
|
-
if (this._private_rotatedInternal) {
|
|
105
|
-
const physicalWidth = this._private_frameHeight;
|
|
106
|
-
const physicalHeight = this._private_frameWidth;
|
|
107
|
-
const u0 = this._private_frameX / atlasWidth;
|
|
108
|
-
const v0 = (atlasHeight - this._private_frameY - physicalHeight) / atlasHeight;
|
|
109
|
-
const uSize = physicalWidth / atlasWidth;
|
|
110
|
-
const vSize = physicalHeight / atlasHeight;
|
|
111
|
-
result.set(0, uSize, u0, -vSize, 0, v0 + vSize, 0, 0, 1);
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
const u0 = this._private_frameX / atlasWidth;
|
|
115
|
-
const v0 = (atlasHeight - this._private_frameY - this._private_frameHeight) / atlasHeight;
|
|
116
|
-
const uSize = this._private_frameWidth / atlasWidth;
|
|
117
|
-
const vSize = this._private_frameHeight / atlasHeight;
|
|
118
|
-
result.set(uSize, 0, u0, 0, vSize, v0, 0, 0, 1);
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Gets original dimensions before trimming.
|
|
124
|
-
* @param result Vector to store result in
|
|
125
|
-
* @returns Width and height in world units
|
|
126
|
-
*/
|
|
127
|
-
getResolution(result = new Vector2()) {
|
|
128
|
-
return result.set(this.width, this.height);
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Replaces texture with new configuration.
|
|
132
|
-
* @param config Texture or atlas configuration
|
|
133
|
-
*/
|
|
134
|
-
set(config) {
|
|
135
|
-
const lastWidth = this.width;
|
|
136
|
-
const lastHeight = this.height;
|
|
137
|
-
if (config instanceof Texture) {
|
|
138
|
-
this._private_setFromTexture(config);
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
this._private_setFromAtlasConfig(config);
|
|
142
|
-
}
|
|
143
|
-
if (this.width !== lastWidth || this.height !== lastHeight) {
|
|
144
|
-
this._private_signalDiminsionsChangedInternal.emit(this.width, this.height, this);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
_private_setFromTexture(texture) {
|
|
148
|
-
const width = texture.image?.naturalWidth ?? TEXTURE_DEFAULT_SIZE;
|
|
149
|
-
const height = texture.image?.naturalHeight ?? TEXTURE_DEFAULT_SIZE;
|
|
150
|
-
this._private_sourceWidth = width;
|
|
151
|
-
this._private_sourceHeight = height;
|
|
152
|
-
if (this.texture !== texture) {
|
|
153
|
-
this._private_textureInternal = texture;
|
|
154
|
-
this._private_textureDirtyInternal = true;
|
|
155
|
-
}
|
|
156
|
-
if (this._private_frameX !== 0 ||
|
|
157
|
-
this._private_frameY !== 0 ||
|
|
158
|
-
this._private_frameWidth !== width ||
|
|
159
|
-
this._private_frameHeight !== height ||
|
|
160
|
-
this._private_scaleInternal !== 1 || this._private_rotatedInternal) {
|
|
161
|
-
this._private_frameX = 0;
|
|
162
|
-
this._private_frameY = 0;
|
|
163
|
-
this._private_frameWidth = width;
|
|
164
|
-
this._private_frameHeight = height;
|
|
165
|
-
this._private_rotatedInternal = false;
|
|
166
|
-
this._private_scaleInternal = 1;
|
|
167
|
-
this._private_uvTransformDirtyInternal = true;
|
|
168
|
-
}
|
|
169
|
-
if (this._private_trimLeft !== 0 ||
|
|
170
|
-
this._private_trimRight !== 0 ||
|
|
171
|
-
this._private_trimTop !== 0 ||
|
|
172
|
-
this._private_trimBottom !== 0) {
|
|
173
|
-
this._private_trimLeft = 0;
|
|
174
|
-
this._private_trimRight = 0;
|
|
175
|
-
this._private_trimTop = 0;
|
|
176
|
-
this._private_trimBottom = 0;
|
|
177
|
-
this._private_trimDirtyInternal = true;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
_private_setFromAtlasConfig(config) {
|
|
181
|
-
assertValidPositiveNumber(config.sourceSize.w, "FXTextureView.setFromAtlasConfig.config.sourceSize.w");
|
|
182
|
-
assertValidPositiveNumber(config.sourceSize.h, "FXTextureView.setFromAtlasConfig.config.sourceSize.h");
|
|
183
|
-
assertValidNonNegativeNumber(config.frame.x, "FXTextureView.setFromAtlasConfig.config.frame.x");
|
|
184
|
-
assertValidNonNegativeNumber(config.frame.y, "FXTextureView.setFromAtlasConfig.config.frame.y");
|
|
185
|
-
assertValidPositiveNumber(config.frame.w, "FXTextureView.setFromAtlasConfig.config.frame.w");
|
|
186
|
-
assertValidPositiveNumber(config.frame.h, "FXTextureView.setFromAtlasConfig.config.frame.h");
|
|
187
|
-
assertValidNonNegativeNumber(config.spriteSourceSize.x, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.x");
|
|
188
|
-
assertValidNonNegativeNumber(config.spriteSourceSize.y, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.y");
|
|
189
|
-
assertValidPositiveNumber(config.spriteSourceSize.w, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.w");
|
|
190
|
-
assertValidPositiveNumber(config.spriteSourceSize.h, "FXTextureView.setFromAtlasConfig.config.spriteSourceSize.h");
|
|
191
|
-
if (config.scale !== undefined) {
|
|
192
|
-
assertValidPositiveNumber(config.scale, "FXTextureView.setFromAtlasConfig.config.scale");
|
|
193
|
-
}
|
|
194
|
-
this._private_sourceWidth = config.sourceSize.w;
|
|
195
|
-
this._private_sourceHeight = config.sourceSize.h;
|
|
196
|
-
if (this.texture !== config.texture) {
|
|
197
|
-
this._private_textureInternal = config.texture;
|
|
198
|
-
this._private_textureDirtyInternal = true;
|
|
199
|
-
}
|
|
200
|
-
const scale = config.scale ?? 1;
|
|
201
|
-
const rotated = config.rotated ?? false;
|
|
202
|
-
if (this._private_frameX !== 0 ||
|
|
203
|
-
this._private_frameY !== 0 ||
|
|
204
|
-
this._private_frameWidth !== config.frame.w ||
|
|
205
|
-
this._private_frameHeight !== config.frame.h ||
|
|
206
|
-
this._private_scaleInternal !== scale ||
|
|
207
|
-
this._private_rotatedInternal !== rotated) {
|
|
208
|
-
this._private_frameX = config.frame.x;
|
|
209
|
-
this._private_frameY = config.frame.y;
|
|
210
|
-
this._private_frameWidth = config.frame.w;
|
|
211
|
-
this._private_frameHeight = config.frame.h;
|
|
212
|
-
this._private_scaleInternal = scale;
|
|
213
|
-
this._private_rotatedInternal = rotated;
|
|
214
|
-
this._private_uvTransformDirtyInternal = true;
|
|
215
|
-
}
|
|
216
|
-
const spriteSource = config.spriteSourceSize;
|
|
217
|
-
const trimLeft = spriteSource.x;
|
|
218
|
-
const trimTop = spriteSource.y;
|
|
219
|
-
const trimRight = this._private_sourceWidth - spriteSource.x - spriteSource.w;
|
|
220
|
-
const trimBottom = this._private_sourceHeight - spriteSource.y - spriteSource.h;
|
|
221
|
-
if (this._private_trimLeft !== trimLeft ||
|
|
222
|
-
this._private_trimRight !== trimRight ||
|
|
223
|
-
this._private_trimTop !== trimTop ||
|
|
224
|
-
this._private_trimBottom !== trimBottom) {
|
|
225
|
-
this._private_trimLeft = trimLeft;
|
|
226
|
-
this._private_trimRight = trimRight;
|
|
227
|
-
this._private_trimTop = trimTop;
|
|
228
|
-
this._private_trimBottom = trimBottom;
|
|
229
|
-
this._private_trimDirtyInternal = true;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export { FXTextureView };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Vector2 } from 'three';
|
|
2
|
-
import source from '../shaders/FXRenderingAnimatedTexture.glsl.js';
|
|
3
|
-
import { FXRenderingModule } from './FXRenderingModule.js';
|
|
4
|
-
|
|
5
|
-
class FXRenderingAnimatedTexture extends FXRenderingModule {
|
|
6
|
-
constructor(texture, horizontalCount, verticalCount) {
|
|
7
|
-
super();
|
|
8
|
-
/** @internal */
|
|
9
|
-
this.source = source;
|
|
10
|
-
this.requiredUniforms = { texture, count: new Vector2(horizontalCount, verticalCount) };
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export { FXRenderingAnimatedTexture };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { FXColor } from "../color/FXColor";
|
|
2
|
-
import { FXRenderingModule } from "./FXRenderingModule";
|
|
3
|
-
/**
|
|
4
|
-
* Colors particles based on lifetime progression.
|
|
5
|
-
*
|
|
6
|
-
* Interpolates through color gradient as particles age from birth to death.
|
|
7
|
-
*/
|
|
8
|
-
export declare class FXRenderingColorOverLife extends FXRenderingModule {
|
|
9
|
-
/**
|
|
10
|
-
* @param colors - Color gradient stops from birth to death
|
|
11
|
-
*/
|
|
12
|
-
constructor(colors: FXColor[]);
|
|
13
|
-
destroy(): void;
|
|
14
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { buildGradientTexture } from '../miscellaneous/miscellaneous.js';
|
|
2
|
-
import source from '../shaders/FXRenderingColorOverLife.glsl.js';
|
|
3
|
-
import { FXRenderingModule } from './FXRenderingModule.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Colors particles based on lifetime progression.
|
|
7
|
-
*
|
|
8
|
-
* Interpolates through color gradient as particles age from birth to death.
|
|
9
|
-
*/
|
|
10
|
-
class FXRenderingColorOverLife extends FXRenderingModule {
|
|
11
|
-
/**
|
|
12
|
-
* @param colors - Color gradient stops from birth to death
|
|
13
|
-
*/
|
|
14
|
-
constructor(colors) {
|
|
15
|
-
super();
|
|
16
|
-
/** @internal */
|
|
17
|
-
this.requiredProperties = {
|
|
18
|
-
builtin: "Matrix4",
|
|
19
|
-
};
|
|
20
|
-
/** @internal */
|
|
21
|
-
this.source = source;
|
|
22
|
-
if (colors.length === 0) {
|
|
23
|
-
throw new Error("FXRenderingColorOverLife: colors array cannot be empty");
|
|
24
|
-
}
|
|
25
|
-
this.requiredUniforms = { colorOverLifeTexture: buildGradientTexture(colors) };
|
|
26
|
-
}
|
|
27
|
-
destroy() {
|
|
28
|
-
this.requiredUniforms.colorOverLifeTexture.dispose();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export { FXRenderingColorOverLife };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { FXColor } from "../color/FXColor";
|
|
2
|
-
import { FXRenderingModule } from "./FXRenderingModule";
|
|
3
|
-
/**
|
|
4
|
-
* Colors particles based on velocity magnitude.
|
|
5
|
-
*
|
|
6
|
-
* Maps velocity from 0 to maxVelocity across the color gradient.
|
|
7
|
-
*/
|
|
8
|
-
export declare class FXRenderingColorOverVelocity extends FXRenderingModule {
|
|
9
|
-
/**
|
|
10
|
-
* @param colors - Color gradient from slow to fast
|
|
11
|
-
* @param maxVelocity - Velocity mapped to final color
|
|
12
|
-
*/
|
|
13
|
-
constructor(colors: FXColor[], maxVelocity: number);
|
|
14
|
-
destroy(): void;
|
|
15
|
-
}
|