sparcoon 0.5.0 → 0.6.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.
Files changed (105) hide show
  1. package/README.md +6 -6
  2. package/dist/emitter/FXEmitter.Internal.d.ts +55 -0
  3. package/dist/emitter/FXEmitter.d.ts +49 -0
  4. package/dist/emitter/FXEmitter.js +64 -0
  5. package/dist/emitter/behavior/FXBehavior.d.ts +12 -2
  6. package/dist/emitter/behavior/FXBehavior.js +3 -2
  7. package/dist/emitter/behavior/FXBehaviorDirectionalForce.d.ts +25 -0
  8. package/dist/emitter/behavior/FXBehaviorDirectionalForce.js +74 -0
  9. package/dist/emitter/behavior/FXBehaviorPointForce.d.ts +40 -0
  10. package/dist/emitter/behavior/FXBehaviorPointForce.js +98 -0
  11. package/dist/emitter/behavior/FXBehaviorScaleOverLife.d.ts +9 -8
  12. package/dist/emitter/behavior/FXBehaviorScaleOverLife.js +12 -29
  13. package/dist/emitter/behavior/FXBehaviorTorqueDamping.d.ts +4 -3
  14. package/dist/emitter/behavior/FXBehaviorTorqueDamping.js +3 -2
  15. package/dist/emitter/behavior/FXBehaviorTorqueNoise.d.ts +4 -3
  16. package/dist/emitter/behavior/FXBehaviorTorqueNoise.js +3 -2
  17. package/dist/emitter/behavior/FXBehaviorTorqueOverLife.d.ts +17 -0
  18. package/dist/emitter/behavior/FXBehaviorTorqueOverLife.js +34 -0
  19. package/dist/emitter/behavior/FXBehaviorVelocityDamping.d.ts +3 -2
  20. package/dist/emitter/behavior/FXBehaviorVelocityDamping.js +3 -2
  21. package/dist/emitter/behavior/FXBehaviorVelocityNoise.d.ts +6 -5
  22. package/dist/emitter/behavior/FXBehaviorVelocityNoise.js +6 -5
  23. package/dist/emitter/behavior/FXBehaviorVelocityOverLife.d.ts +20 -0
  24. package/dist/emitter/behavior/FXBehaviorVelocityOverLife.js +48 -0
  25. package/dist/emitter/spawn/FXSpawn.d.ts +4 -2
  26. package/dist/emitter/spawn/FXSpawn.js +3 -2
  27. package/dist/emitter/spawn/FXSpawnBox.d.ts +8 -16
  28. package/dist/emitter/spawn/FXSpawnBox.js +23 -39
  29. package/dist/emitter/spawn/{FXSpawnRandomLifetime.d.ts → FXSpawnLifetime.d.ts} +3 -5
  30. package/dist/emitter/spawn/{FXSpawnRandomLifetime.js → FXSpawnLifetime.js} +8 -10
  31. package/dist/emitter/spawn/FXSpawnOffset.d.ts +9 -0
  32. package/dist/emitter/spawn/FXSpawnOffset.js +9 -0
  33. package/dist/emitter/spawn/FXSpawnPoint.d.ts +8 -0
  34. package/dist/emitter/spawn/FXSpawnPoint.js +8 -0
  35. package/dist/emitter/spawn/{FXSpawnRandomRotation.d.ts → FXSpawnRotation.d.ts} +3 -5
  36. package/dist/emitter/spawn/{FXSpawnRandomRotation.js → FXSpawnRotation.js} +8 -10
  37. package/dist/emitter/spawn/{FXSpawnRandomScale.d.ts → FXSpawnScale.d.ts} +4 -6
  38. package/dist/emitter/spawn/{FXSpawnRandomScale.js → FXSpawnScale.js} +12 -14
  39. package/dist/emitter/spawn/FXSpawnSphere.d.ts +11 -6
  40. package/dist/emitter/spawn/FXSpawnSphere.js +11 -6
  41. package/dist/emitter/spawn/{FXSpawnRandomTorque.d.ts → FXSpawnTorque.d.ts} +3 -5
  42. package/dist/emitter/spawn/{FXSpawnRandomTorque.js → FXSpawnTorque.js} +8 -10
  43. package/dist/emitter/spawn/FXSpawnVelocity.d.ts +32 -0
  44. package/dist/emitter/spawn/{FXSpawnRandomVelocity.js → FXSpawnVelocity.js} +26 -11
  45. package/dist/index.d.ts +23 -16
  46. package/dist/index.js +20 -16
  47. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.d.ts +4 -4
  48. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js +2 -2
  49. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.d.ts +55 -5
  50. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.js +9 -2
  51. package/dist/materials/FXMaterial/FXDepthMaterial.Internal.d.ts +3 -3
  52. package/dist/materials/FXMaterial/FXDistanceMaterial.Internal.d.ts +3 -3
  53. package/dist/materials/FXMaterial/FXMaterial.d.ts +51 -5
  54. package/dist/materials/FXMaterial/FXMaterial.js +5 -0
  55. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.d.ts +3 -3
  56. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.d.ts +3 -3
  57. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.js +3 -3
  58. package/dist/miscellaneous/curve/FXCurve1D.Internal.d.ts +20 -0
  59. package/dist/miscellaneous/curve/FXCurve1D.d.ts +17 -0
  60. package/dist/miscellaneous/curve/FXCurve1D.js +94 -0
  61. package/dist/miscellaneous/miscellaneous.d.ts +3 -1
  62. package/dist/miscellaneous/miscellaneous.js +8 -4
  63. package/dist/miscellaneous/texture/FXTextureView.Internal.js +6 -0
  64. package/dist/miscellaneous/texture/FXTextureView.js +234 -0
  65. package/dist/nodes/color/FXNodeColor.d.ts +7 -0
  66. package/dist/nodes/color/FXNodeColor.js +11 -0
  67. package/dist/nodes/color/FXNodeColorOverLife.d.ts +25 -0
  68. package/dist/nodes/color/FXNodeColorOverLife.js +60 -0
  69. package/dist/nodes/color/FXNodeSphericalClip.d.ts +18 -0
  70. package/dist/nodes/color/FXNodeSphericalClip.js +45 -0
  71. package/dist/nodes/normal/FXNodeFlatNormal.d.ts +7 -0
  72. package/dist/nodes/normal/FXNodeFlatNormal.js +17 -0
  73. package/dist/nodes/normal/FXNodeNormal.d.ts +7 -0
  74. package/dist/nodes/normal/FXNodeNormal.js +7 -0
  75. package/dist/nodes/normal/FXNodeSphericalNormal.d.ts +7 -0
  76. package/dist/nodes/normal/{FXSphericalNormalNode.js → FXNodeSphericalNormal.js} +7 -4
  77. package/dist/nodes/texture/FXNodeAnimatedTexture.d.ts +47 -0
  78. package/dist/nodes/texture/FXNodeAnimatedTexture.js +137 -0
  79. package/dist/nodes/texture/FXNodeStaticTexture.d.ts +18 -0
  80. package/dist/nodes/texture/FXNodeStaticTexture.js +60 -0
  81. package/dist/nodes/texture/FXNodeTexture.d.ts +7 -0
  82. package/dist/nodes/texture/FXNodeTexture.js +11 -0
  83. package/package.json +2 -4
  84. package/dist/emitter/behavior/FXBehaviorDirectionalGravity.d.ts +0 -21
  85. package/dist/emitter/behavior/FXBehaviorDirectionalGravity.js +0 -51
  86. package/dist/emitter/behavior/FXBehaviorPointGravity.d.ts +0 -39
  87. package/dist/emitter/behavior/FXBehaviorPointGravity.js +0 -116
  88. package/dist/emitter/spawn/FXSpawnRandomVelocity.d.ts +0 -17
  89. package/dist/nodes/color/FXColorNode.d.ts +0 -3
  90. package/dist/nodes/color/FXColorNode.js +0 -8
  91. package/dist/nodes/color/FXColorOverLifeNode.d.ts +0 -6
  92. package/dist/nodes/color/FXColorOverLifeNode.js +0 -44
  93. package/dist/nodes/color/FXSphericalClipNode.d.ts +0 -5
  94. package/dist/nodes/color/FXSphericalClipNode.js +0 -30
  95. package/dist/nodes/normal/FXFlatNormalNode.d.ts +0 -4
  96. package/dist/nodes/normal/FXFlatNormalNode.js +0 -14
  97. package/dist/nodes/normal/FXNormalNode.d.ts +0 -3
  98. package/dist/nodes/normal/FXNormalNode.js +0 -4
  99. package/dist/nodes/normal/FXSphericalNormalNode.d.ts +0 -4
  100. package/dist/nodes/texture/FXAnimatedTextureNode.d.ts +0 -12
  101. package/dist/nodes/texture/FXAnimatedTextureNode.js +0 -88
  102. package/dist/nodes/texture/FXStaticTextureNode.d.ts +0 -6
  103. package/dist/nodes/texture/FXStaticTextureNode.js +0 -34
  104. package/dist/nodes/texture/FXTextureNode.d.ts +0 -3
  105. package/dist/nodes/texture/FXTextureNode.js +0 -8
@@ -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,3 +0,0 @@
1
- export declare abstract class FXColorNode {
2
- destroy?(): void;
3
- }
@@ -1,8 +0,0 @@
1
- class FXColorNode {
2
- constructor() {
3
- /** @internal */
4
- this.affectsDepth = false;
5
- }
6
- }
7
-
8
- export { FXColorNode };
@@ -1,6 +0,0 @@
1
- import type { FXColor } from "../../miscellaneous/color/FXColor";
2
- import { FXColorNode } from "./FXColorNode";
3
- export declare class FXColorOverLifeNode extends FXColorNode {
4
- constructor(colors: FXColor[]);
5
- destroy(): void;
6
- }
@@ -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,5 +0,0 @@
1
- import { FXColorNode } from "./FXColorNode";
2
- export declare class FXSphericalClipNode extends FXColorNode {
3
- constructor(innerRadius?: number);
4
- destroy(): void;
5
- }
@@ -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,4 +0,0 @@
1
- import { FXNormalNode } from "./FXNormalNode";
2
- export declare class FXFlatNormalNode extends FXNormalNode {
3
- constructor();
4
- }
@@ -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,3 +0,0 @@
1
- export declare abstract class FXNormalNode {
2
- destroy?(): void;
3
- }
@@ -1,4 +0,0 @@
1
- class FXNormalNode {
2
- }
3
-
4
- export { FXNormalNode };
@@ -1,4 +0,0 @@
1
- import { FXNormalNode } from "./FXNormalNode";
2
- export declare class FXSphericalNormalNode extends FXNormalNode {
3
- constructor();
4
- }
@@ -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 };
@@ -1,6 +0,0 @@
1
- import type { Texture } from "three";
2
- import { FXTextureNode } from "./FXTextureNode";
3
- export declare class FXStaticTextureNode extends FXTextureNode {
4
- constructor(texture: Texture);
5
- destroy(): void;
6
- }
@@ -1,34 +0,0 @@
1
- import { checkSRGBSupport } from '../../miscellaneous/webglCapabilities.js';
2
- import { FXTextureNode } from './FXTextureNode.js';
3
-
4
- const INSTANCES = [];
5
- class FXStaticTextureNode extends FXTextureNode {
6
- constructor(texture) {
7
- super();
8
- INSTANCES.push(this);
9
- const uniformName = `u_StaticTexture_${INSTANCES.length - 1}`;
10
- this.affectsDepth = true;
11
- this.cacheKey = "static";
12
- this.uniformDeclarations = [`uniform sampler2D ${uniformName};`];
13
- this.uniforms = {
14
- [uniformName]: { value: texture },
15
- };
16
- this.helperFunctions = `
17
- vec4 sampleStaticTexture(sampler2D colorTexture, vec2 uv) {
18
- vec4 color = texture2D(colorTexture, uv);
19
- // Apply gamma correction when sRGB textures are not natively supported
20
- ${checkSRGBSupport() ? "" : "color = vec4(pow(color.rgb, vec3(2.2)), color.a);"}
21
- return color;
22
- }
23
- `;
24
- this.colorExpression = `sampleStaticTexture(${uniformName}, p_uv)`;
25
- }
26
- destroy() {
27
- const index = INSTANCES.indexOf(this);
28
- if (index !== -1) {
29
- INSTANCES.splice(index, 1);
30
- }
31
- }
32
- }
33
-
34
- export { FXStaticTextureNode };
@@ -1,3 +0,0 @@
1
- export declare abstract class FXTextureNode {
2
- destroy?(): void;
3
- }
@@ -1,8 +0,0 @@
1
- class FXTextureNode {
2
- constructor() {
3
- /** @internal */
4
- this.affectsDepth = false;
5
- }
6
- }
7
-
8
- export { FXTextureNode };