sparcoon 0.1.0 → 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.
Files changed (100) hide show
  1. package/dist/{elements → emitter}/FXEmitter.Internal.d.ts +0 -4
  2. package/dist/emitter/FXEmitter.Internal.js +7 -0
  3. package/dist/{elements → emitter}/FXEmitter.d.ts +6 -13
  4. package/dist/{elements → emitter}/FXEmitter.js +15 -22
  5. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorDirectionalGravity.d.ts +2 -2
  6. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorDirectionalGravity.js +2 -2
  7. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorModule.d.ts +1 -1
  8. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorPointGravity.d.ts +2 -2
  9. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorPointGravity.js +2 -2
  10. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorScaleOverLife.d.ts +1 -1
  11. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorScaleOverLife.js +2 -2
  12. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueDamping.d.ts +1 -1
  13. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueDamping.js +2 -2
  14. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueNoise.d.ts +1 -1
  15. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorTorqueNoise.js +3 -3
  16. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityDamping.d.ts +1 -1
  17. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityDamping.js +2 -2
  18. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityNoise.d.ts +1 -1
  19. package/dist/{behaviorModules → emitter/behavior}/FXBehaviorVelocityNoise.js +3 -3
  20. package/dist/{spawnModules → emitter/spawn}/FXSpawnBox.d.ts +2 -2
  21. package/dist/{spawnModules → emitter/spawn}/FXSpawnBox.js +2 -2
  22. package/dist/{spawnModules → emitter/spawn}/FXSpawnModule.d.ts +1 -1
  23. package/dist/{spawnModules → emitter/spawn}/FXSpawnOffset.d.ts +2 -2
  24. package/dist/{spawnModules → emitter/spawn}/FXSpawnOffset.js +2 -2
  25. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomLifetime.d.ts +1 -1
  26. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomLifetime.js +2 -2
  27. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomRotation.d.ts +1 -1
  28. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomRotation.js +2 -2
  29. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomScale.d.ts +1 -1
  30. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomScale.js +2 -2
  31. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomTorque.d.ts +1 -1
  32. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomTorque.js +2 -2
  33. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomVelocity.d.ts +1 -1
  34. package/dist/{spawnModules → emitter/spawn}/FXSpawnRandomVelocity.js +2 -2
  35. package/dist/emitter/spawn/FXSpawnSphere.d.ts +38 -0
  36. package/dist/emitter/spawn/FXSpawnSphere.js +89 -0
  37. package/dist/index.d.ts +24 -20
  38. package/dist/index.js +25 -22
  39. package/dist/instancedParticle/FXInstancedParticle.Internal.d.ts +2 -9
  40. package/dist/instancedParticle/FXInstancedParticle.Internal.js +2 -188
  41. package/dist/instancedParticle/FXInstancedParticle.d.ts +3 -5
  42. package/dist/instancedParticle/FXInstancedParticle.js +4 -10
  43. package/dist/instancedParticle/shared.d.ts +1 -1
  44. package/dist/instancedParticle/shared.js +1 -1
  45. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.d.ts +9 -0
  46. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js +108 -0
  47. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.d.ts +15 -0
  48. package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.js +18 -0
  49. package/dist/materials/FXMaterial.Internal.d.ts +4 -0
  50. package/dist/materials/FXMaterial.Internal.js +106 -0
  51. package/dist/materials/FXMaterial.d.ts +14 -0
  52. package/dist/materials/FXMaterial.js +21 -0
  53. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.d.ts +4 -0
  54. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.js +80 -0
  55. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.d.ts +11 -0
  56. package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.js +17 -0
  57. package/dist/materials/color-nodes/FXAnimatedTextureNode.d.ts +10 -0
  58. package/dist/materials/color-nodes/FXAnimatedTextureNode.js +41 -0
  59. package/dist/materials/color-nodes/FXColorNode.d.ts +3 -0
  60. package/dist/materials/color-nodes/FXColorNode.js +8 -0
  61. package/dist/materials/color-nodes/FXColorOverLifeNode.d.ts +7 -0
  62. package/dist/materials/color-nodes/FXColorOverLifeNode.js +38 -0
  63. package/dist/materials/color-nodes/FXStaticTextureNode.d.ts +5 -0
  64. package/dist/materials/color-nodes/FXStaticTextureNode.js +23 -0
  65. package/dist/materials/miscellaneous.d.ts +1 -0
  66. package/dist/materials/miscellaneous.js +25 -0
  67. package/dist/{color → miscellaneous/color}/FXColor.js +2 -2
  68. package/dist/miscellaneous/miscellaneous.d.ts +1 -1
  69. package/package.json +1 -1
  70. package/dist/elements/FXEmitter.Internal.js +0 -12
  71. package/dist/instancedParticle/FXParticleDepthMaterial.d.ts +0 -2
  72. package/dist/instancedParticle/FXParticleDepthMaterial.js +0 -52
  73. package/dist/instancedParticle/FXParticleLambertMaterial.d.ts +0 -4
  74. package/dist/instancedParticle/FXParticleLambertMaterial.js +0 -152
  75. package/dist/instancedParticle/FXParticleNormalsMode.d.ts +0 -5
  76. package/dist/instancedParticle/FXParticleNormalsMode.js +0 -8
  77. package/dist/instancedParticle/FXParticleRenderingMode.d.ts +0 -4
  78. package/dist/instancedParticle/FXParticleRenderingMode.js +0 -7
  79. package/dist/miscellaneous/texture/FXTextureView.Internal.js +0 -6
  80. package/dist/miscellaneous/texture/FXTextureView.js +0 -234
  81. package/dist/renderingModules/FXRenderingAnimatedTexture.d.ts +0 -5
  82. package/dist/renderingModules/FXRenderingAnimatedTexture.js +0 -14
  83. package/dist/renderingModules/FXRenderingColorOverLife.d.ts +0 -14
  84. package/dist/renderingModules/FXRenderingColorOverLife.js +0 -32
  85. package/dist/renderingModules/FXRenderingColorOverVelocity.d.ts +0 -15
  86. package/dist/renderingModules/FXRenderingColorOverVelocity.js +0 -37
  87. package/dist/renderingModules/FXRenderingModule.d.ts +0 -8
  88. package/dist/renderingModules/FXRenderingModule.js +0 -9
  89. package/dist/renderingModules/FXRenderingShadow.d.ts +0 -12
  90. package/dist/renderingModules/FXRenderingTexture.d.ts +0 -14
  91. package/dist/renderingModules/FXRenderingTexture.js +0 -26
  92. package/dist/shaders/FXRenderingAnimatedTexture.glsl.js +0 -3
  93. package/dist/shaders/FXRenderingColorOverLife.glsl.js +0 -3
  94. package/dist/shaders/FXRenderingColorOverVelocity.glsl.js +0 -3
  95. package/dist/shaders/FXRenderingTexture.glsl.js +0 -3
  96. /package/dist/{behaviorModules → emitter/behavior}/FXBehaviorModule.js +0 -0
  97. /package/dist/{spawnModules → emitter/spawn}/FXSpawnModule.js +0 -0
  98. /package/dist/{color → miscellaneous/color}/FXColor.Internal.d.ts +0 -0
  99. /package/dist/{color → miscellaneous/color}/FXColor.Internal.js +0 -0
  100. /package/dist/{color → miscellaneous/color}/FXColor.d.ts +0 -0
package/dist/index.js CHANGED
@@ -1,22 +1,25 @@
1
- export { FXBehaviorDirectionalGravity } from './behaviorModules/FXBehaviorDirectionalGravity.js';
2
- export { FXBehaviorPointGravity } from './behaviorModules/FXBehaviorPointGravity.js';
3
- export { FXBehaviorScaleOverLife } from './behaviorModules/FXBehaviorScaleOverLife.js';
4
- export { FXBehaviorTorqueDamping } from './behaviorModules/FXBehaviorTorqueDamping.js';
5
- export { FXBehaviorTorqueNoise } from './behaviorModules/FXBehaviorTorqueNoise.js';
6
- export { FXBehaviorVelocityDamping } from './behaviorModules/FXBehaviorVelocityDamping.js';
7
- export { FXBehaviorVelocityNoise } from './behaviorModules/FXBehaviorVelocityNoise.js';
8
- export { FXColor } from './color/FXColor.js';
9
- export { FXEmitter } from './elements/FXEmitter.js';
10
- export { FXRenderingAnimatedTexture } from './renderingModules/FXRenderingAnimatedTexture.js';
11
- export { FXRenderingColorOverLife } from './renderingModules/FXRenderingColorOverLife.js';
12
- export { FXRenderingColorOverVelocity } from './renderingModules/FXRenderingColorOverVelocity.js';
13
- export { FXRenderingTexture } from './renderingModules/FXRenderingTexture.js';
14
- export { FXSpawnBox } from './spawnModules/FXSpawnBox.js';
15
- export { FXSpawnOffset } from './spawnModules/FXSpawnOffset.js';
16
- export { FXSpawnRandomLifetime } from './spawnModules/FXSpawnRandomLifetime.js';
17
- export { FXSpawnRandomRotation } from './spawnModules/FXSpawnRandomRotation.js';
18
- export { FXSpawnRandomScale } from './spawnModules/FXSpawnRandomScale.js';
19
- export { FXSpawnRandomTorque } from './spawnModules/FXSpawnRandomTorque.js';
20
- export { FXSpawnRandomVelocity } from './spawnModules/FXSpawnRandomVelocity.js';
21
- export { FXParticleNormalsMode } from './instancedParticle/FXParticleNormalsMode.js';
22
- export { FXParticleRenderingMode } from './instancedParticle/FXParticleRenderingMode.js';
1
+ export { FXBehaviorDirectionalGravity } from './emitter/behavior/FXBehaviorDirectionalGravity.js';
2
+ export { FXBehaviorPointGravity } from './emitter/behavior/FXBehaviorPointGravity.js';
3
+ export { FXBehaviorScaleOverLife } from './emitter/behavior/FXBehaviorScaleOverLife.js';
4
+ export { FXBehaviorTorqueDamping } from './emitter/behavior/FXBehaviorTorqueDamping.js';
5
+ export { FXBehaviorTorqueNoise } from './emitter/behavior/FXBehaviorTorqueNoise.js';
6
+ export { FXBehaviorVelocityDamping } from './emitter/behavior/FXBehaviorVelocityDamping.js';
7
+ export { FXBehaviorVelocityNoise } from './emitter/behavior/FXBehaviorVelocityNoise.js';
8
+ export { FXEmitter } from './emitter/FXEmitter.js';
9
+ export { FXSpawnBox } from './emitter/spawn/FXSpawnBox.js';
10
+ export { FXSpawnOffset } from './emitter/spawn/FXSpawnOffset.js';
11
+ export { FXSpawnRandomLifetime } from './emitter/spawn/FXSpawnRandomLifetime.js';
12
+ export { FXSpawnRandomRotation } from './emitter/spawn/FXSpawnRandomRotation.js';
13
+ export { FXSpawnRandomScale } from './emitter/spawn/FXSpawnRandomScale.js';
14
+ export { FXSpawnRandomTorque } from './emitter/spawn/FXSpawnRandomTorque.js';
15
+ export { FXSpawnRandomVelocity } from './emitter/spawn/FXSpawnRandomVelocity.js';
16
+ export { FXSpawnSphere } from './emitter/spawn/FXSpawnSphere.js';
17
+ export { FXAnimatedTextureNode } from './materials/color-nodes/FXAnimatedTextureNode.js';
18
+ export { FXColorNode } from './materials/color-nodes/FXColorNode.js';
19
+ export { FXColorOverLifeNode } from './materials/color-nodes/FXColorOverLifeNode.js';
20
+ export { FXStaticTextureNode } from './materials/color-nodes/FXStaticTextureNode.js';
21
+ export { FXDiffuseMaterial } from './materials/FXDiffuseMaterial/FXDiffuseMaterial.js';
22
+ export { FXMaterial } from './materials/FXMaterial.js';
23
+ export { FXUnlitMaterial } from './materials/FXUnlitMaterial/FXUnlitMaterial.js';
24
+ export { FXColor } from './miscellaneous/color/FXColor.js';
25
+ export { FXParticleNormalsMode } from './materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js';
@@ -1,13 +1,6 @@
1
- import { InstancedBufferGeometry, ShaderMaterial, type Blending } from "three";
2
- import type { GLProperty, GLTypeInfo } from "./shared";
3
- import { type FXProperty, type FXPropertyName } from "./shared";
1
+ import { InstancedBufferGeometry } from "three";
2
+ import type { FXPropertyName, GLTypeInfo } from "./shared";
4
3
  export declare const INSTANCED_PARTICLE_GEOMETRY: InstancedBufferGeometry;
5
4
  export declare function collectProperties(keeper: Record<string, GLTypeInfo>, modules: readonly {
6
5
  requiredProperties?: Record<string, FXPropertyName>;
7
6
  }[], debugContext: string): void;
8
- export declare function collectUniforms(keeper: Record<string, GLProperty>, modules: readonly {
9
- requiredUniforms: Record<string, FXProperty>;
10
- }[], debugContext: string): void;
11
- export declare function buildParticleVertexShader(uniformDeclarations: string[], attributeDeclarations: string[], varyingDeclarations: string[], vertexAssignments: string[]): string;
12
- export declare function buildParticleFragmentShader(uniformDeclarations: string[], varyingDeclarations: string[], sources: string[]): string;
13
- export declare function buildParticleMaterial(sources: string[], uniformProperties: Record<string, GLProperty>, varyingProperties: Record<string, GLTypeInfo>, blending: Blending, useAlphaHashing: boolean): ShaderMaterial;
@@ -1,6 +1,4 @@
1
- import { InstancedBufferGeometry, BufferAttribute, Float32BufferAttribute, ShaderMaterial } from 'three';
2
- import { FXColor } from '../color/FXColor.js';
3
- import { checkSRGBSupport } from '../miscellaneous/webglCapabilities.js';
1
+ import { InstancedBufferGeometry, BufferAttribute, Float32BufferAttribute } from 'three';
4
2
  import { resolveGLSLTypeInfo } from './shared.js';
5
3
 
6
4
  const INSTANCED_PARTICLE_GEOMETRY = (() => {
@@ -30,189 +28,5 @@ function collectProperties(keeper, modules, debugContext) {
30
28
  }
31
29
  }
32
30
  }
33
- function collectUniforms(keeper, modules, debugContext) {
34
- for (const module of modules) {
35
- for (const key in module.requiredUniforms) {
36
- const value = module.requiredUniforms[key];
37
- const existingGLProperty = keeper[key];
38
- const newPropertyTypeInfo = resolveGLSLTypeInfo(value);
39
- if (existingGLProperty === undefined) {
40
- keeper[key] = { value, glslTypeInfo: newPropertyTypeInfo };
41
- }
42
- else if (existingGLProperty.glslTypeInfo.glslTypeName !== newPropertyTypeInfo.glslTypeName) {
43
- throw new Error(`${debugContext}: property conflict for "${key}"`);
44
- }
45
- }
46
- }
47
- }
48
- function buildParticleVertexShader(uniformDeclarations, attributeDeclarations, varyingDeclarations, vertexAssignments) {
49
- return `
50
- #define PARTICLE_POSITION_X p_builtin[0][0]
51
- #define PARTICLE_POSITION_Y p_builtin[0][1]
52
- #define PARTICLE_POSITION_Z p_builtin[0][2]
53
-
54
- #define PARTICLE_VELOCITY_X p_builtin[0][3]
55
- #define PARTICLE_VELOCITY_Y p_builtin[1][0]
56
- #define PARTICLE_VELOCITY_Z p_builtin[1][1]
57
-
58
- #define PARTICLE_SCALE_X p_builtin[1][2]
59
- #define PARTICLE_SCALE_Y p_builtin[1][3]
60
- #define PARTICLE_SCALE_Z p_builtin[2][0]
61
-
62
- #define PARTICLE_ROTATION p_builtin[2][1]
63
- #define PARTICLE_TORQUE p_builtin[2][2]
64
-
65
- #define PARTICLE_LIFETIME p_builtin[2][3]
66
- #define PARTICLE_AGE p_builtin[3][0]
67
-
68
- #define PARTICLE_RANDOM_A p_builtin[3][1]
69
- #define PARTICLE_RANDOM_B p_builtin[3][2]
70
- #define PARTICLE_RANDOM_C p_builtin[3][3]
71
-
72
- // User attributes
73
- ${attributeDeclarations.join("\n")}
74
-
75
- // Uniforms
76
- ${uniformDeclarations.join("\n")}
77
-
78
- // Builtin varyings
79
- varying vec2 p_uv;
80
-
81
- // User varyings
82
- ${varyingDeclarations.join("\n")}
83
-
84
- void main() {
85
- ${vertexAssignments.join("\n")}
86
-
87
- p_uv = uv;
88
-
89
- vec2 transformedPosition = position.xy;
90
-
91
- transformedPosition.x *= PARTICLE_SCALE_X;
92
- transformedPosition.y *= PARTICLE_SCALE_Y;
93
-
94
- float cosR = cos(PARTICLE_ROTATION);
95
- float sinR = sin(PARTICLE_ROTATION);
96
-
97
- transformedPosition = vec2(
98
- transformedPosition.x * cosR - transformedPosition.y * sinR,
99
- transformedPosition.x * sinR + transformedPosition.y * cosR
100
- );
101
-
102
- vec3 center = vec3(
103
- PARTICLE_POSITION_X,
104
- PARTICLE_POSITION_Y,
105
- PARTICLE_POSITION_Z
106
- );
107
-
108
- vec4 modelViewCenter = modelViewMatrix * vec4(center, 1.0);
109
- modelViewCenter.xy += transformedPosition;
110
- gl_Position = projectionMatrix * modelViewCenter;
111
- }
112
- `;
113
- }
114
- function buildParticleFragmentShader(uniformDeclarations, varyingDeclarations, sources) {
115
- const renamedSources = sources.map((source, index) => {
116
- return source.replace(/vec4\s+draw\s*\(\s*\)/g, `vec4 draw${index}()`);
117
- });
118
- let drawCalls = "";
119
- for (let i = 0; i < sources.length; i++) {
120
- drawCalls += i !== 0 ? " * " : "";
121
- drawCalls += `draw${i}()`;
122
- }
123
- return `
124
- #include <common>
125
-
126
- // Defines
127
- #define SRGB_SUPPORTED ${checkSRGBSupport() ? "1" : "0"}
128
-
129
- #define PARTICLE_POSITION_X p_builtin[0][0]
130
- #define PARTICLE_POSITION_Y p_builtin[0][1]
131
- #define PARTICLE_POSITION_Z p_builtin[0][2]
132
-
133
- #define PARTICLE_VELOCITY_X p_builtin[0][3]
134
- #define PARTICLE_VELOCITY_Y p_builtin[1][0]
135
- #define PARTICLE_VELOCITY_Z p_builtin[1][1]
136
-
137
- #define PARTICLE_SCALE_X p_builtin[1][2]
138
- #define PARTICLE_SCALE_Y p_builtin[1][3]
139
- #define PARTICLE_SCALE_Z p_builtin[2][0]
140
-
141
- #define PARTICLE_ROTATION p_builtin[2][1]
142
- #define PARTICLE_TORQUE p_builtin[2][2]
143
-
144
- #define PARTICLE_LIFETIME p_builtin[2][3]
145
- #define PARTICLE_AGE p_builtin[3][0]
146
-
147
- #define PARTICLE_RANDOM_A p_builtin[3][1]
148
- #define PARTICLE_RANDOM_B p_builtin[3][2]
149
- #define PARTICLE_RANDOM_C p_builtin[3][3]
150
-
151
- // Uniforms
152
- ${uniformDeclarations.join("\n")}
153
-
154
- // Builtin varyings
155
- varying vec2 p_uv;
156
-
157
- // User varyings
158
- ${varyingDeclarations.join("\n")}
159
-
160
- #include <alphahash_pars_fragment>
161
-
162
- // sRGB decode helper
163
- vec4 srgbTexture2D(sampler2D textureSampler, vec2 uv) {
164
- #if SRGB_SUPPORTED
165
- return texture2D(textureSampler, uv);
166
- #else
167
- vec4 textureValue = texture2D(textureSampler, uv);
168
- return vec4(pow(textureValue.rgb, vec3(2.2)), textureValue.a);
169
- #endif
170
- }
171
-
172
- // Source must define vec4 draw() function
173
- ${renamedSources.join("\n")}
174
-
175
- void main() {
176
- vec4 diffuseColor = ${drawCalls};
177
- if (diffuseColor.a < 0.0035) {
178
- discard;
179
- }
180
- #ifdef USE_ALPHAHASH
181
- if (diffuseColor.a < getAlphaHashThreshold(vec3(p_builtin[0][0], p_builtin[0][1], p_builtin[0][2]))) {
182
- discard;
183
- }
184
- #endif
185
- gl_FragColor = linearToOutputTexel(diffuseColor);
186
- }
187
- `;
188
- }
189
- function buildParticleMaterial(sources, uniformProperties, varyingProperties, blending, useAlphaHashing) {
190
- const uniforms = {};
191
- const uniformDeclarations = [];
192
- const attributeDeclarations = [];
193
- const varyingDeclarations = [];
194
- const vertexAssignments = [];
195
- for (const name in uniformProperties) {
196
- const { value, glslTypeInfo } = uniformProperties[name];
197
- uniforms[`p_${name}`] = { value: value instanceof FXColor ? value.toGLSLColor() : value };
198
- uniformDeclarations.push(`uniform ${glslTypeInfo.glslTypeName} p_${name};`);
199
- }
200
- for (const name in varyingProperties) {
201
- const { glslTypeName } = varyingProperties[name];
202
- attributeDeclarations.push(`attribute ${glslTypeName} a_${name};`);
203
- varyingDeclarations.push(`varying ${glslTypeName} p_${name};`);
204
- vertexAssignments.push(`p_${name} = a_${name};`);
205
- }
206
- return new ShaderMaterial({
207
- uniforms,
208
- vertexShader: buildParticleVertexShader(uniformDeclarations, attributeDeclarations, varyingDeclarations, vertexAssignments),
209
- fragmentShader: buildParticleFragmentShader(uniformDeclarations, varyingDeclarations, sources),
210
- transparent: true,
211
- depthWrite: false,
212
- depthTest: true,
213
- alphaHash: useAlphaHashing,
214
- blending,
215
- });
216
- }
217
31
 
218
- export { INSTANCED_PARTICLE_GEOMETRY, buildParticleFragmentShader, buildParticleMaterial, buildParticleVertexShader, collectProperties, collectUniforms };
32
+ export { INSTANCED_PARTICLE_GEOMETRY, collectProperties };
@@ -1,15 +1,13 @@
1
- import type { Blending } from "three";
1
+ import type { Material } from "three";
2
2
  import { InstancedBufferAttribute, Mesh } from "three";
3
- import { FXParticleNormalsMode } from "./FXParticleNormalsMode";
4
- import { FXParticleRenderingMode } from "./FXParticleRenderingMode";
5
- import type { GLProperty, GLTypeInfo } from "./shared";
3
+ import type { GLTypeInfo } from "./shared";
6
4
  export declare class FXInstancedParticle extends Mesh {
7
5
  private readonly capacityStep;
8
6
  readonly propertyBuffers: Record<string, InstancedBufferAttribute>;
9
7
  private readonly instancedGeometry;
10
8
  private readonly particleMaterial;
11
9
  private capacity;
12
- constructor(sources: string[], uniforms: Record<string, GLProperty>, varyings: Record<string, GLTypeInfo>, expectedCapacity: number, capacityStep: number, blending: Blending, useAlphaHashing: boolean, renderingMode: FXParticleRenderingMode, normalsMode: FXParticleNormalsMode);
10
+ constructor(varyings: Record<string, GLTypeInfo>, expectedCapacity: number, capacityStep: number, material: Material);
13
11
  get instanceCount(): number;
14
12
  createInstances(count: number): void;
15
13
  removeDeadParticles(): void;
@@ -1,23 +1,17 @@
1
1
  import { Mesh, InstancedBufferAttribute, StreamDrawUsage } from 'three';
2
2
  import { BUILTIN_OFFSET_AGE, BUILTIN_OFFSET_LIFETIME } from '../miscellaneous/miscellaneous.js';
3
- import { INSTANCED_PARTICLE_GEOMETRY, buildParticleMaterial } from './FXInstancedParticle.Internal.js';
4
- import { buildParticleLambertMaterial } from './FXParticleLambertMaterial.js';
5
- import './FXParticleNormalsMode.js';
6
- import { FXParticleRenderingMode } from './FXParticleRenderingMode.js';
3
+ import { INSTANCED_PARTICLE_GEOMETRY } from './FXInstancedParticle.Internal.js';
7
4
 
8
5
  class FXInstancedParticle extends Mesh {
9
- constructor(sources, uniforms, varyings, expectedCapacity, _private_capacityStep, blending, useAlphaHashing, renderingMode, normalsMode) {
6
+ constructor(varyings, expectedCapacity, _private_capacityStep, material) {
10
7
  const instancedGeometry = INSTANCED_PARTICLE_GEOMETRY.clone();
11
- const particleMaterial = renderingMode === FXParticleRenderingMode.Lambert
12
- ? buildParticleLambertMaterial(sources, uniforms, varyings, blending, useAlphaHashing, normalsMode)
13
- : buildParticleMaterial(sources, uniforms, varyings, blending, useAlphaHashing);
14
- super(instancedGeometry, particleMaterial);
8
+ super(instancedGeometry, material);
15
9
  this._private_capacityStep = _private_capacityStep;
16
10
  this.propertyBuffers = {};
17
11
  this.frustumCulled = false;
18
12
  this._private_instancedGeometry = instancedGeometry;
19
13
  this._private_instancedGeometry.instanceCount = 0;
20
- this._private_particleMaterial = particleMaterial;
14
+ this._private_particleMaterial = material;
21
15
  this._private_capacity = Math.max(Math.ceil(expectedCapacity / this._private_capacityStep) * this._private_capacityStep, this._private_capacityStep);
22
16
  for (const name in varyings) {
23
17
  const { bufferSize } = varyings[name];
@@ -1,6 +1,6 @@
1
1
  import type { IUniform, ShaderMaterial } from "three";
2
2
  import { Matrix3, Matrix4, Texture, Vector2, Vector3, Vector4 } from "three";
3
- import { FXColor } from "../color/FXColor";
3
+ import { FXColor } from "../miscellaneous/color/FXColor";
4
4
  export type FXProperty = Texture | FXColor | Vector2 | Vector3 | Vector4 | Matrix3 | Matrix4 | number;
5
5
  export type FXPropertyName = "Texture" | "FXColor" | "Vector2" | "Vector3" | "Vector4" | "Matrix3" | "Matrix4" | "number";
6
6
  export type FXPropertyConstructor = typeof Texture | typeof FXColor | typeof Vector2 | typeof Vector3 | typeof Vector4 | typeof Matrix3 | typeof Matrix4 | NumberConstructor;
@@ -1,5 +1,5 @@
1
1
  import { Texture, Vector2, Vector3, Vector4, Matrix3, Matrix4 } from 'three';
2
- import { FXColor } from '../color/FXColor.js';
2
+ import { FXColor } from '../miscellaneous/color/FXColor.js';
3
3
 
4
4
  const GLSL_TYPE_INFO_FLOAT = Object.freeze({
5
5
  glslTypeName: "float",
@@ -0,0 +1,9 @@
1
+ import { MeshLambertMaterial, type Blending } from "three";
2
+ import type { GLTypeInfo } from "../../instancedParticle/shared";
3
+ import type { FXColorNode } from "../color-nodes/FXColorNode";
4
+ export declare enum FXParticleNormalsMode {
5
+ FLAT = 0,
6
+ SPHERICAL = 1,
7
+ TOWARDS_LIGHT = 2
8
+ }
9
+ export declare function buildFXDiffuseMaterial(varyings: Record<string, GLTypeInfo>, blending: Blending, useAlphaHashing: boolean, normalsMode: FXParticleNormalsMode, colorNodes: readonly FXColorNode[]): MeshLambertMaterial;
@@ -0,0 +1,108 @@
1
+ import { MeshLambertMaterial, DoubleSide } from 'three';
2
+ import { PARTICLE_DEFINES } from '../miscellaneous.js';
3
+
4
+ var FXParticleNormalsMode;
5
+ (function (FXParticleNormalsMode) {
6
+ FXParticleNormalsMode[FXParticleNormalsMode["FLAT"] = 0] = "FLAT";
7
+ FXParticleNormalsMode[FXParticleNormalsMode["SPHERICAL"] = 1] = "SPHERICAL";
8
+ FXParticleNormalsMode[FXParticleNormalsMode["TOWARDS_LIGHT"] = 2] = "TOWARDS_LIGHT";
9
+ })(FXParticleNormalsMode || (FXParticleNormalsMode = {}));
10
+ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, normalsMode, colorNodes) {
11
+ const attributeDeclarations = [];
12
+ const varyingDeclarations = [];
13
+ const vertexAssignments = [];
14
+ for (const name in varyings) {
15
+ const { glslTypeName } = varyings[name];
16
+ attributeDeclarations.push(`attribute ${glslTypeName} a_${name};`);
17
+ varyingDeclarations.push(`varying ${glslTypeName} p_${name};`);
18
+ vertexAssignments.push(`p_${name} = a_${name};`);
19
+ }
20
+ const material = new MeshLambertMaterial({
21
+ transparent: !useAlphaHashing,
22
+ depthWrite: useAlphaHashing,
23
+ depthTest: true,
24
+ alphaHash: useAlphaHashing,
25
+ blending,
26
+ side: DoubleSide,
27
+ forceSinglePass: true,
28
+ alphaTest: 1 / 255,
29
+ });
30
+ material.onBeforeCompile = (shader) => {
31
+ const vertexPreamble = [
32
+ PARTICLE_DEFINES,
33
+ attributeDeclarations.join("\n"),
34
+ "varying vec2 p_uv;",
35
+ varyingDeclarations.join("\n"),
36
+ ].join("\n");
37
+ shader.vertexShader =
38
+ vertexPreamble +
39
+ "\n" +
40
+ shader.vertexShader
41
+ .replace("#include <beginnormal_vertex>", "vec3 objectNormal = vec3(0.0, 0.0, 1.0);")
42
+ .replace("#include <defaultnormal_vertex>", "vec3 transformedNormal = vec3(0.0, 0.0, 1.0);")
43
+ .replace("#include <begin_vertex>", [
44
+ "p_uv = uv;",
45
+ vertexAssignments.join("\n"),
46
+ "vec3 transformed = position;",
47
+ "#ifdef USE_ALPHAHASH",
48
+ " vPosition = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z) + vec3(position.xy, 0.0);",
49
+ "#endif",
50
+ ].join("\n"))
51
+ .replace("#include <project_vertex>", `
52
+ vec2 p_bp = position.xy;
53
+ p_bp.x *= PARTICLE_SCALE_X;
54
+ p_bp.y *= PARTICLE_SCALE_Y;
55
+ float p_cosR = cos(PARTICLE_ROTATION);
56
+ float p_sinR = sin(PARTICLE_ROTATION);
57
+ p_bp = vec2(
58
+ p_bp.x * p_cosR - p_bp.y * p_sinR,
59
+ p_bp.x * p_sinR + p_bp.y * p_cosR
60
+ );
61
+ vec3 p_c = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);
62
+ vec4 mvPosition = modelViewMatrix * vec4(p_c, 1.0);
63
+ mvPosition.xy += p_bp;
64
+ gl_Position = projectionMatrix * mvPosition;
65
+ `)
66
+ .replace("#include <worldpos_vertex>", `
67
+ #if defined(USE_SHADOWMAP) || defined(USE_ENVMAP) || defined(DISTANCE) || (NUM_SPOT_LIGHT_COORDS > 0)
68
+ vec3 p_cr = vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);
69
+ vec3 p_cu = vec3(viewMatrix[0][1], viewMatrix[1][1], viewMatrix[2][1]);
70
+ vec4 worldPosition = vec4(
71
+ (modelMatrix * vec4(p_c, 1.0)).xyz + p_cr * p_bp.x + p_cu * p_bp.y,
72
+ 1.0
73
+ );
74
+ #endif
75
+ `);
76
+ const fragmentPreamble = [
77
+ PARTICLE_DEFINES,
78
+ "varying vec2 p_uv;",
79
+ varyingDeclarations.join("\n"),
80
+ colorNodes.flatMap((n) => n.uniformDeclarations).join("\n"),
81
+ colorNodes.map((n) => n.helperFunctions).join("\n"),
82
+ ].join("\n");
83
+ for (const node of colorNodes) {
84
+ Object.assign(shader.uniforms, node.uniforms);
85
+ }
86
+ let fragmentShader = shader.fragmentShader;
87
+ if (normalsMode === FXParticleNormalsMode.SPHERICAL) {
88
+ fragmentShader = fragmentShader.replace("#include <normal_fragment_begin>", `
89
+ float faceDirection = gl_FrontFacing ? 1.0 : -1.0;
90
+ vec2 p_sn = p_uv * 2.0 - 1.0;
91
+ vec3 normal = normalize(vec3(p_sn, sqrt(max(0.0, 1.0 - dot(p_sn, p_sn)))));
92
+ `);
93
+ }
94
+ else if (normalsMode === FXParticleNormalsMode.TOWARDS_LIGHT) {
95
+ fragmentShader = fragmentShader.replace("float dotNL = saturate( dot( geometryNormal, directLight.direction ) );", "float dotNL = 1.0;");
96
+ }
97
+ if (colorNodes.length > 0) {
98
+ const combinedExpression = colorNodes.map((n) => n.colorExpression).join(" * ");
99
+ const discardLine = useAlphaHashing ? "" : "if (diffuseColor.a < 0.0035) discard;";
100
+ fragmentShader = fragmentShader.replace("#include <map_fragment>", `diffuseColor = ${combinedExpression}; ${discardLine}`);
101
+ }
102
+ shader.fragmentShader = fragmentPreamble + "\n" + fragmentShader;
103
+ };
104
+ material.customProgramCacheKey = () => `fx-diffuse-${normalsMode}-${colorNodes.map((n) => n.cacheKey).join("-") || "none"}`;
105
+ return material;
106
+ }
107
+
108
+ export { FXParticleNormalsMode, buildFXDiffuseMaterial };
@@ -0,0 +1,15 @@
1
+ import { type Blending } from "three";
2
+ import { FXMaterial, type FXMaterialOptions } from "../FXMaterial";
3
+ import { FXParticleNormalsMode } from "./FXDiffuseMaterial.Internal";
4
+ export { FXParticleNormalsMode };
5
+ export interface FXDiffuseMaterialOptions extends FXMaterialOptions {
6
+ blending: Blending;
7
+ useAlphaHashing: boolean;
8
+ normalsMode: FXParticleNormalsMode;
9
+ }
10
+ export declare class FXDiffuseMaterial extends FXMaterial {
11
+ private readonly blending;
12
+ private readonly useAlphaHashing;
13
+ private readonly normalsMode;
14
+ constructor(options?: Partial<FXDiffuseMaterialOptions>);
15
+ }
@@ -0,0 +1,18 @@
1
+ import { NormalBlending } from 'three';
2
+ import { FXMaterial } from '../FXMaterial.js';
3
+ import { FXParticleNormalsMode, buildFXDiffuseMaterial } from './FXDiffuseMaterial.Internal.js';
4
+
5
+ class FXDiffuseMaterial extends FXMaterial {
6
+ constructor(options = {}) {
7
+ super(options);
8
+ this._private_blending = options.blending ?? NormalBlending;
9
+ this._private_useAlphaHashing = options.useAlphaHashing ?? false;
10
+ this._private_normalsMode = options.normalsMode ?? FXParticleNormalsMode.SPHERICAL;
11
+ }
12
+ /** @internal */
13
+ buildThreeMaterial(varyings) {
14
+ return buildFXDiffuseMaterial(varyings, this._private_blending, this._private_useAlphaHashing, this._private_normalsMode, this.colorNodes);
15
+ }
16
+ }
17
+
18
+ export { FXDiffuseMaterial, FXParticleNormalsMode };
@@ -0,0 +1,4 @@
1
+ import { MeshDepthMaterial } from "three";
2
+ import type { FXColorNode } from "./color-nodes/FXColorNode";
3
+ export declare const DEPTH_VERTEX_SHADER = "\n #define PARTICLE_POSITION_X a_builtin[0][0]\n #define PARTICLE_POSITION_Y a_builtin[0][1]\n #define PARTICLE_POSITION_Z a_builtin[0][2]\n\n #define PARTICLE_SCALE_X a_builtin[1][2]\n #define PARTICLE_SCALE_Y a_builtin[1][3]\n\n #define PARTICLE_ROTATION a_builtin[2][1]\n\n attribute mat4 a_builtin;\n varying mat4 p_builtin;\n varying vec2 p_uv;\n varying vec2 vHighPrecisionZW;\n varying float v_viewZ;\n #ifdef USE_ALPHAHASH\n varying vec3 vPosition;\n #endif\n\n void main() {\n p_builtin = a_builtin;\n p_uv = uv;\n #ifdef USE_ALPHAHASH\n vPosition = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z) + vec3(position.xy, 0.0);\n #endif\n\n vec2 transformedPosition = position.xy;\n transformedPosition.x *= PARTICLE_SCALE_X;\n transformedPosition.y *= PARTICLE_SCALE_Y;\n\n float cosR = cos(PARTICLE_ROTATION);\n float sinR = sin(PARTICLE_ROTATION);\n transformedPosition = vec2(\n transformedPosition.x * cosR - transformedPosition.y * sinR,\n transformedPosition.x * sinR + transformedPosition.y * cosR\n );\n\n vec3 center = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);\n vec4 modelViewCenter = modelViewMatrix * vec4(center, 1.0);\n v_viewZ = modelViewCenter.z;\n modelViewCenter.xy += transformedPosition;\n gl_Position = projectionMatrix * modelViewCenter;\n vHighPrecisionZW = gl_Position.zw;\n }\n";
4
+ export declare function buildDepthMaterial(colorNodes: readonly FXColorNode[], depthAlphaTest: number, useDepthAlphaHash: boolean, useSphericalDepth: boolean): MeshDepthMaterial;
@@ -0,0 +1,106 @@
1
+ import { MeshDepthMaterial, DoubleSide, RGBADepthPacking } from 'three';
2
+ import { PARTICLE_DEFINES } from './miscellaneous.js';
3
+
4
+ const DEPTH_VERTEX_SHADER = `
5
+ #define PARTICLE_POSITION_X a_builtin[0][0]
6
+ #define PARTICLE_POSITION_Y a_builtin[0][1]
7
+ #define PARTICLE_POSITION_Z a_builtin[0][2]
8
+
9
+ #define PARTICLE_SCALE_X a_builtin[1][2]
10
+ #define PARTICLE_SCALE_Y a_builtin[1][3]
11
+
12
+ #define PARTICLE_ROTATION a_builtin[2][1]
13
+
14
+ attribute mat4 a_builtin;
15
+ varying mat4 p_builtin;
16
+ varying vec2 p_uv;
17
+ varying vec2 vHighPrecisionZW;
18
+ varying float v_viewZ;
19
+ #ifdef USE_ALPHAHASH
20
+ varying vec3 vPosition;
21
+ #endif
22
+
23
+ void main() {
24
+ p_builtin = a_builtin;
25
+ p_uv = uv;
26
+ #ifdef USE_ALPHAHASH
27
+ vPosition = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z) + vec3(position.xy, 0.0);
28
+ #endif
29
+
30
+ vec2 transformedPosition = position.xy;
31
+ transformedPosition.x *= PARTICLE_SCALE_X;
32
+ transformedPosition.y *= PARTICLE_SCALE_Y;
33
+
34
+ float cosR = cos(PARTICLE_ROTATION);
35
+ float sinR = sin(PARTICLE_ROTATION);
36
+ transformedPosition = vec2(
37
+ transformedPosition.x * cosR - transformedPosition.y * sinR,
38
+ transformedPosition.x * sinR + transformedPosition.y * cosR
39
+ );
40
+
41
+ vec3 center = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);
42
+ vec4 modelViewCenter = modelViewMatrix * vec4(center, 1.0);
43
+ v_viewZ = modelViewCenter.z;
44
+ modelViewCenter.xy += transformedPosition;
45
+ gl_Position = projectionMatrix * modelViewCenter;
46
+ vHighPrecisionZW = gl_Position.zw;
47
+ }
48
+ `;
49
+ const DEPTH_SPHERICAL_FRAG_COORD_Z = `
50
+ float _dx = (p_uv.x - 0.5) * PARTICLE_SCALE_X;
51
+ float _dy = (p_uv.y - 0.5) * PARTICLE_SCALE_Y;
52
+ float _r = min(PARTICLE_SCALE_X, PARTICLE_SCALE_Y) * 0.5;
53
+ float _d2 = _dx * _dx + _dy * _dy;
54
+ if (_d2 > _r * _r) discard;
55
+ float _sphereZ = v_viewZ + sqrt(_r * _r - _d2);
56
+ float _pz = projectionMatrix[2][2] * _sphereZ + projectionMatrix[3][2];
57
+ float _pw = projectionMatrix[2][3] * _sphereZ + projectionMatrix[3][3];
58
+ float _ndc_z = _pz / _pw;
59
+ #ifdef USE_REVERSEDEPTHBUF
60
+ float fragCoordZ = _ndc_z;
61
+ #else
62
+ float fragCoordZ = 0.5 * _ndc_z + 0.5;
63
+ #endif
64
+ `;
65
+ function buildDepthMaterial(colorNodes, depthAlphaTest, useDepthAlphaHash, useSphericalDepth) {
66
+ const depthNodes = colorNodes.filter((n) => n.affectsDepth);
67
+ const needsFragmentMod = depthNodes.length > 0 || useSphericalDepth;
68
+ const material = new MeshDepthMaterial({
69
+ depthPacking: RGBADepthPacking,
70
+ side: DoubleSide,
71
+ forceSinglePass: true,
72
+ alphaHash: useDepthAlphaHash,
73
+ });
74
+ material.onBeforeCompile = (shader) => {
75
+ shader.vertexShader = DEPTH_VERTEX_SHADER;
76
+ if (!needsFragmentMod) {
77
+ return;
78
+ }
79
+ const fragmentPreamble = [
80
+ PARTICLE_DEFINES,
81
+ "varying mat4 p_builtin;",
82
+ "varying vec2 p_uv;",
83
+ "varying float v_viewZ;",
84
+ useSphericalDepth ? "uniform mat4 projectionMatrix;" : "",
85
+ depthNodes.flatMap((n) => n.uniformDeclarations).join("\n"),
86
+ depthNodes.map((n) => n.helperFunctions).join("\n"),
87
+ ].join("\n");
88
+ for (const node of depthNodes) {
89
+ Object.assign(shader.uniforms, node.uniforms);
90
+ }
91
+ let fs = shader.fragmentShader;
92
+ if (depthNodes.length > 0) {
93
+ const combinedAlpha = depthNodes.map((n) => n.colorExpression).join(" * ");
94
+ fs = fs.replace("#include <map_fragment>", `diffuseColor.a = (${combinedAlpha}).a;
95
+ if (diffuseColor.a < ${depthAlphaTest.toFixed(4)}) discard;`);
96
+ }
97
+ if (useSphericalDepth) {
98
+ fs = fs.replace(/float fragCoordZ\b[^;]*;/, DEPTH_SPHERICAL_FRAG_COORD_Z);
99
+ }
100
+ shader.fragmentShader = fragmentPreamble + "\n" + fs;
101
+ };
102
+ material.customProgramCacheKey = () => `fx-depth-${useDepthAlphaHash ? "ah" : "at"}-${useSphericalDepth ? "sd" : "flat"}-${depthNodes.map((n) => n.cacheKey).join("-") || "none"}`;
103
+ return material;
104
+ }
105
+
106
+ export { DEPTH_VERTEX_SHADER, buildDepthMaterial };
@@ -0,0 +1,14 @@
1
+ import type { FXColorNode } from "./color-nodes/FXColorNode";
2
+ export interface FXMaterialOptions {
3
+ colorNodes?: FXColorNode[];
4
+ depthAlphaTest?: number;
5
+ useDepthAlphaHash?: boolean;
6
+ useSphericalDepth?: boolean;
7
+ }
8
+ export declare abstract class FXMaterial {
9
+ private readonly depthAlphaTest;
10
+ private readonly useDepthAlphaHash;
11
+ private readonly useSphericalDepth;
12
+ constructor(options?: FXMaterialOptions);
13
+ destroy(): void;
14
+ }
@@ -0,0 +1,21 @@
1
+ import { buildDepthMaterial } from './FXMaterial.Internal.js';
2
+
3
+ class FXMaterial {
4
+ constructor(options = {}) {
5
+ this.colorNodes = options.colorNodes ?? [];
6
+ this._private_depthAlphaTest = options.depthAlphaTest ?? 0.5;
7
+ this._private_useDepthAlphaHash = options.useDepthAlphaHash ?? false;
8
+ this._private_useSphericalDepth = options.useSphericalDepth ?? false;
9
+ }
10
+ destroy() {
11
+ for (const node of this.colorNodes) {
12
+ node.destroy?.();
13
+ }
14
+ }
15
+ /** @internal */
16
+ buildDepthMaterial() {
17
+ return buildDepthMaterial(this.colorNodes, this._private_depthAlphaTest, this._private_useDepthAlphaHash, this._private_useSphericalDepth);
18
+ }
19
+ }
20
+
21
+ export { FXMaterial };
@@ -0,0 +1,4 @@
1
+ import { MeshBasicMaterial, type Blending } from "three";
2
+ import type { GLTypeInfo } from "../../instancedParticle/shared";
3
+ import type { FXColorNode } from "../color-nodes/FXColorNode";
4
+ export declare function buildFXUnlitMaterial(varyings: Record<string, GLTypeInfo>, blending: Blending, useAlphaHashing: boolean, colorNodes: readonly FXColorNode[]): MeshBasicMaterial;