@babylonjs/core 9.3.0 → 9.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/Engines/abstractEngine.js +2 -2
  2. package/Engines/abstractEngine.js.map +1 -1
  3. package/Engines/engine.d.ts +49 -1118
  4. package/FlowGraph/flowGraph.d.ts +11 -0
  5. package/FlowGraph/flowGraph.js +20 -0
  6. package/FlowGraph/flowGraph.js.map +1 -1
  7. package/FlowGraph/flowGraphContext.d.ts +30 -0
  8. package/FlowGraph/flowGraphContext.js +42 -0
  9. package/FlowGraph/flowGraphContext.js.map +1 -1
  10. package/FlowGraph/flowGraphParser.js +13 -0
  11. package/FlowGraph/flowGraphParser.js.map +1 -1
  12. package/FlowGraph/typeDefinitions.d.ts +16 -0
  13. package/FlowGraph/typeDefinitions.js.map +1 -1
  14. package/Layers/thinSelectionOutlineLayer.js +25 -1
  15. package/Layers/thinSelectionOutlineLayer.js.map +1 -1
  16. package/Materials/GaussianSplatting/gaussianSplattingMaterial.d.ts +18 -0
  17. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +110 -1
  18. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
  19. package/Materials/Textures/baseTexture.d.ts +1 -0
  20. package/Materials/Textures/baseTexture.js +1 -0
  21. package/Materials/Textures/baseTexture.js.map +1 -1
  22. package/Meshes/GaussianSplatting/gaussianSplattingMesh.d.ts +5 -1
  23. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +14 -4
  24. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  25. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.d.ts +24 -0
  26. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js +128 -0
  27. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js.map +1 -1
  28. package/Misc/tools.js +1 -1
  29. package/Misc/tools.js.map +1 -1
  30. package/Particles/IParticleSystem.d.ts +7 -1
  31. package/Particles/IParticleSystem.js.map +1 -1
  32. package/Particles/baseParticleSystem.d.ts +18 -2
  33. package/Particles/baseParticleSystem.js +53 -11
  34. package/Particles/baseParticleSystem.js.map +1 -1
  35. package/Particles/computeShaderParticleSystem.js +16 -0
  36. package/Particles/computeShaderParticleSystem.js.map +1 -1
  37. package/Particles/gpuParticleSystem.d.ts +14 -72
  38. package/Particles/gpuParticleSystem.js +130 -106
  39. package/Particles/gpuParticleSystem.js.map +1 -1
  40. package/Particles/particleSystem.d.ts +0 -80
  41. package/Particles/particleSystem.functions.d.ts +16 -0
  42. package/Particles/particleSystem.functions.js +18 -0
  43. package/Particles/particleSystem.functions.js.map +1 -1
  44. package/Particles/particleSystem.js +0 -114
  45. package/Particles/particleSystem.js.map +1 -1
  46. package/Particles/webgl2ParticleSystem.js +12 -0
  47. package/Particles/webgl2ParticleSystem.js.map +1 -1
  48. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +17 -0
  49. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
  50. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.d.ts +10 -0
  51. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +146 -24
  52. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
  53. package/Rendering/objectRenderer.d.ts +2 -0
  54. package/Rendering/objectRenderer.js +10 -0
  55. package/Rendering/objectRenderer.js.map +1 -1
  56. package/Shaders/ShadersInclude/gaussianSplatting.js +21 -1
  57. package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
  58. package/Shaders/gaussianSplattingVoxel.fragment.d.ts +5 -0
  59. package/Shaders/gaussianSplattingVoxel.fragment.js +27 -0
  60. package/Shaders/gaussianSplattingVoxel.fragment.js.map +1 -0
  61. package/Shaders/gaussianSplattingVoxel.vertex.d.ts +8 -0
  62. package/Shaders/gaussianSplattingVoxel.vertex.js +31 -0
  63. package/Shaders/gaussianSplattingVoxel.vertex.js.map +1 -0
  64. package/Shaders/gpuUpdateParticles.vertex.js +13 -0
  65. package/Shaders/gpuUpdateParticles.vertex.js.map +1 -1
  66. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +21 -1
  67. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
  68. package/ShadersWGSL/gaussianSplattingVoxel.fragment.d.ts +5 -0
  69. package/ShadersWGSL/gaussianSplattingVoxel.fragment.js +22 -0
  70. package/ShadersWGSL/gaussianSplattingVoxel.fragment.js.map +1 -0
  71. package/ShadersWGSL/gaussianSplattingVoxel.vertex.d.ts +8 -0
  72. package/ShadersWGSL/gaussianSplattingVoxel.vertex.js +42 -0
  73. package/ShadersWGSL/gaussianSplattingVoxel.vertex.js.map +1 -0
  74. package/ShadersWGSL/gpuUpdateParticles.compute.js +19 -0
  75. package/ShadersWGSL/gpuUpdateParticles.compute.js.map +1 -1
  76. package/package.json +1 -1
@@ -23,7 +23,7 @@ import "../Engines/Extensions/engine.transformFeedback.js";
23
23
  import "../Shaders/gpuRenderParticles.fragment.js";
24
24
  import "../Shaders/gpuRenderParticles.vertex.js";
25
25
  import { BindFogParameters, BindLogDepth } from "../Materials/materialHelper.functions.js";
26
- import { CreateConeEmitter, CreateCylinderEmitter, CreateDirectedCylinderEmitter, CreateDirectedSphereEmitter, CreateDirectedConeEmitter, CreateHemisphericEmitter, CreatePointEmitter, CreateSphereEmitter, } from "./particleSystem.functions.js";
26
+ import { MeshParticleEmitter } from "./EmitterTypes/meshParticleEmitter.js";
27
27
  /**
28
28
  * This represents a GPU particle system in Babylon
29
29
  * This is the fastest particle system in Babylon as it uses the GPU to update the individual particle data
@@ -101,111 +101,6 @@ export class GPUParticleSystem extends BaseParticleSystem {
101
101
  }
102
102
  super.addAttractor(attractor);
103
103
  }
104
- /**
105
- * Creates a Point Emitter for the particle system (emits directly from the emitter position)
106
- * @param direction1 Particles are emitted between the direction1 and direction2 from within the box
107
- * @param direction2 Particles are emitted between the direction1 and direction2 from within the box
108
- * @returns the emitter
109
- */
110
- createPointEmitter(direction1, direction2) {
111
- const particleEmitter = CreatePointEmitter(direction1, direction2);
112
- this.particleEmitterType = particleEmitter;
113
- return particleEmitter;
114
- }
115
- /**
116
- * Creates a Hemisphere Emitter for the particle system (emits along the hemisphere radius)
117
- * @param radius The radius of the hemisphere to emit from
118
- * @param radiusRange The range of the hemisphere to emit from [0-1] 0 Surface Only, 1 Entire Radius
119
- * @returns the emitter
120
- */
121
- createHemisphericEmitter(radius = 1, radiusRange = 1) {
122
- const particleEmitter = CreateHemisphericEmitter(radius, radiusRange);
123
- this.particleEmitterType = particleEmitter;
124
- return particleEmitter;
125
- }
126
- /**
127
- * Creates a Sphere Emitter for the particle system (emits along the sphere radius)
128
- * @param radius The radius of the sphere to emit from
129
- * @param radiusRange The range of the sphere to emit from [0-1] 0 Surface Only, 1 Entire Radius
130
- * @returns the emitter
131
- */
132
- createSphereEmitter(radius = 1, radiusRange = 1) {
133
- const particleEmitter = CreateSphereEmitter(radius, radiusRange);
134
- this.particleEmitterType = particleEmitter;
135
- return particleEmitter;
136
- }
137
- /**
138
- * Creates a Directed Sphere Emitter for the particle system (emits between direction1 and direction2)
139
- * @param radius The radius of the sphere to emit from
140
- * @param direction1 Particles are emitted between the direction1 and direction2 from within the sphere
141
- * @param direction2 Particles are emitted between the direction1 and direction2 from within the sphere
142
- * @returns the emitter
143
- */
144
- createDirectedSphereEmitter(radius = 1, direction1 = new Vector3(0, 1.0, 0), direction2 = new Vector3(0, 1.0, 0)) {
145
- const particleEmitter = CreateDirectedSphereEmitter(radius, direction1, direction2);
146
- this.particleEmitterType = particleEmitter;
147
- return particleEmitter;
148
- }
149
- /**
150
- * Creates a Cylinder Emitter for the particle system (emits from the cylinder to the particle position)
151
- * @param radius The radius of the emission cylinder
152
- * @param height The height of the emission cylinder
153
- * @param radiusRange The range of emission [0-1] 0 Surface only, 1 Entire Radius
154
- * @param directionRandomizer How much to randomize the particle direction [0-1]
155
- * @returns the emitter
156
- */
157
- createCylinderEmitter(radius = 1, height = 1, radiusRange = 1, directionRandomizer = 0) {
158
- const particleEmitter = CreateCylinderEmitter(radius, height, radiusRange, directionRandomizer);
159
- this.particleEmitterType = particleEmitter;
160
- return particleEmitter;
161
- }
162
- /**
163
- * Creates a Directed Cylinder Emitter for the particle system (emits between direction1 and direction2)
164
- * @param radius The radius of the cylinder to emit from
165
- * @param height The height of the emission cylinder
166
- * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)
167
- * @param direction1 Particles are emitted between the direction1 and direction2 from within the cylinder
168
- * @param direction2 Particles are emitted between the direction1 and direction2 from within the cylinder
169
- * @returns the emitter
170
- */
171
- createDirectedCylinderEmitter(radius = 1, height = 1, radiusRange = 1, direction1 = new Vector3(0, 1.0, 0), direction2 = new Vector3(0, 1.0, 0)) {
172
- const particleEmitter = CreateDirectedCylinderEmitter(radius, height, radiusRange, direction1, direction2);
173
- this.particleEmitterType = particleEmitter;
174
- return particleEmitter;
175
- }
176
- /**
177
- * Creates a Cone Emitter for the particle system (emits from the cone to the particle position)
178
- * @param radius The radius of the cone to emit from
179
- * @param angle The base angle of the cone
180
- * @returns the emitter
181
- */
182
- createConeEmitter(radius = 1, angle = Math.PI / 4) {
183
- const particleEmitter = CreateConeEmitter(radius, angle);
184
- this.particleEmitterType = particleEmitter;
185
- return particleEmitter;
186
- }
187
- createDirectedConeEmitter(radius = 1, angle = Math.PI / 4, direction1 = new Vector3(0, 1.0, 0), direction2 = new Vector3(0, 1.0, 0)) {
188
- const particleEmitter = CreateDirectedConeEmitter(radius, angle, direction1, direction2);
189
- this.particleEmitterType = particleEmitter;
190
- return particleEmitter;
191
- }
192
- /**
193
- * Creates a Box Emitter for the particle system. (emits between direction1 and direction2 from withing the box defined by minEmitBox and maxEmitBox)
194
- * @param direction1 Particles are emitted between the direction1 and direction2 from within the box
195
- * @param direction2 Particles are emitted between the direction1 and direction2 from within the box
196
- * @param minEmitBox Particles are emitted from the box between minEmitBox and maxEmitBox
197
- * @param maxEmitBox Particles are emitted from the box between minEmitBox and maxEmitBox
198
- * @returns the emitter
199
- */
200
- createBoxEmitter(direction1, direction2, minEmitBox, maxEmitBox) {
201
- const particleEmitter = new BoxParticleEmitter();
202
- this.particleEmitterType = particleEmitter;
203
- this.direction1 = direction1;
204
- this.direction2 = direction2;
205
- this.minEmitBox = minEmitBox;
206
- this.maxEmitBox = maxEmitBox;
207
- return particleEmitter;
208
- }
209
104
  /** Gets or sets the current flow map */
210
105
  get flowMap() {
211
106
  return this._flowMap;
@@ -825,6 +720,18 @@ export class GPUParticleSystem extends BaseParticleSystem {
825
720
  * The strength of the flow map
826
721
  */
827
722
  this.flowMapStrength = 1.0;
723
+ /** Mesh emitter textures */
724
+ /** @internal */
725
+ this._meshPositionTexture = null;
726
+ /** @internal */
727
+ this._meshNormalTexture = null;
728
+ /** @internal */
729
+ this._meshTriangleCount = 0;
730
+ /** @internal */
731
+ this._meshTextureWidth = 0;
732
+ // Track mesh emitter inputs for invalidation
733
+ this._meshEmitterMeshId = -1;
734
+ this._meshEmitterUsedNormals = false;
828
735
  /** @internal */
829
736
  this._onBeforeDrawParticlesObservable = null;
830
737
  if (!sceneOrEngine || sceneOrEngine.getClassName() === "Scene") {
@@ -1152,6 +1059,7 @@ export class GPUParticleSystem extends BaseParticleSystem {
1152
1059
  this._createVelocityGradientTexture();
1153
1060
  this._createLimitVelocityGradientTexture();
1154
1061
  this._createDragGradientTexture();
1062
+ this._createMeshEmitterTextures();
1155
1063
  let defines = this.particleEmitterType ? this.particleEmitterType.getEffectDefines() : "";
1156
1064
  if (this._isBillboardBased) {
1157
1065
  // Stretched local needs initialDirection in the buffer, which requires !BILLBOARD in the update shader.
@@ -1206,6 +1114,12 @@ export class GPUParticleSystem extends BaseParticleSystem {
1206
1114
  if (this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {
1207
1115
  defines += "\n#define LIFETIMEGRADIENTS";
1208
1116
  }
1117
+ if (this.particleEmitterType instanceof MeshParticleEmitter && this._meshPositionTexture) {
1118
+ defines += "\n#define MESHEMITTER";
1119
+ if (this._meshNormalTexture) {
1120
+ defines += "\n#define MESHNORMALS";
1121
+ }
1122
+ }
1209
1123
  if (this._platform.isUpdateBufferCreated() && this._cachedUpdateDefines === defines) {
1210
1124
  return this._platform.isUpdateBufferReady();
1211
1125
  }
@@ -1400,6 +1314,109 @@ export class GPUParticleSystem extends BaseParticleSystem {
1400
1314
  _createDragGradientTexture() {
1401
1315
  this._createFactorGradientTexture(this._dragGradients, "_dragGradientsTexture");
1402
1316
  }
1317
+ _disposeMeshEmitterTextures() {
1318
+ if (this._meshPositionTexture) {
1319
+ this._meshPositionTexture.dispose();
1320
+ this._meshPositionTexture = null;
1321
+ }
1322
+ if (this._meshNormalTexture) {
1323
+ this._meshNormalTexture.dispose();
1324
+ this._meshNormalTexture = null;
1325
+ }
1326
+ this._meshTriangleCount = 0;
1327
+ this._meshTextureWidth = 0;
1328
+ this._meshEmitterMeshId = -1;
1329
+ this._meshEmitterUsedNormals = false;
1330
+ }
1331
+ _createMeshEmitterTextures() {
1332
+ if (!(this.particleEmitterType instanceof MeshParticleEmitter)) {
1333
+ // Emitter type changed away from mesh — dispose stale textures
1334
+ if (this._meshPositionTexture) {
1335
+ this._disposeMeshEmitterTextures();
1336
+ }
1337
+ return;
1338
+ }
1339
+ const meshEmitter = this.particleEmitterType;
1340
+ const mesh = meshEmitter.mesh;
1341
+ if (!mesh) {
1342
+ // Mesh removed — dispose stale textures
1343
+ if (this._meshPositionTexture) {
1344
+ this._disposeMeshEmitterTextures();
1345
+ }
1346
+ return;
1347
+ }
1348
+ const useNormals = meshEmitter.useMeshNormalsForDirection;
1349
+ // Invalidate if the source mesh or normals usage changed
1350
+ if (this._meshPositionTexture && (mesh.uniqueId !== this._meshEmitterMeshId || useNormals !== this._meshEmitterUsedNormals)) {
1351
+ this._disposeMeshEmitterTextures();
1352
+ }
1353
+ // Already created and still valid
1354
+ if (this._meshPositionTexture) {
1355
+ return;
1356
+ }
1357
+ const positions = mesh.getVerticesData(VertexBuffer.PositionKind);
1358
+ const normals = mesh.getVerticesData(VertexBuffer.NormalKind);
1359
+ const indices = mesh.getIndices();
1360
+ if (!positions || !indices) {
1361
+ return;
1362
+ }
1363
+ const triangleCount = indices.length / 3;
1364
+ this._meshTriangleCount = triangleCount;
1365
+ // Use a 2D texture layout so large meshes don't exceed maxTextureSize
1366
+ const totalTexels = triangleCount * 3;
1367
+ const maxTexSize = this._engine.getCaps().maxTextureSize;
1368
+ const texWidth = Math.min(totalTexels, maxTexSize);
1369
+ const texHeight = Math.ceil(totalTexels / texWidth);
1370
+ this._meshTextureWidth = texWidth;
1371
+ // Pack vertex positions: one texel per vertex, 3 vertices per triangle, RGBA float (xyz + padding)
1372
+ const posData = new Float32Array(texWidth * texHeight * 4);
1373
+ for (let t = 0; t < triangleCount; t++) {
1374
+ const i0 = indices[t * 3];
1375
+ const i1 = indices[t * 3 + 1];
1376
+ const i2 = indices[t * 3 + 2];
1377
+ const baseOffset = t * 3 * 4;
1378
+ posData[baseOffset] = positions[i0 * 3];
1379
+ posData[baseOffset + 1] = positions[i0 * 3 + 1];
1380
+ posData[baseOffset + 2] = positions[i0 * 3 + 2];
1381
+ posData[baseOffset + 3] = 0;
1382
+ posData[baseOffset + 4] = positions[i1 * 3];
1383
+ posData[baseOffset + 5] = positions[i1 * 3 + 1];
1384
+ posData[baseOffset + 6] = positions[i1 * 3 + 2];
1385
+ posData[baseOffset + 7] = 0;
1386
+ posData[baseOffset + 8] = positions[i2 * 3];
1387
+ posData[baseOffset + 9] = positions[i2 * 3 + 1];
1388
+ posData[baseOffset + 10] = positions[i2 * 3 + 2];
1389
+ posData[baseOffset + 11] = 0;
1390
+ }
1391
+ this._meshPositionTexture = new RawTexture(posData, texWidth, texHeight, 5, this._scene || this._engine, false, false, 1, 1);
1392
+ this._meshPositionTexture.name = "meshPositionTexture";
1393
+ // Pack normals the same way if available
1394
+ if (normals && useNormals) {
1395
+ const normData = new Float32Array(texWidth * texHeight * 4);
1396
+ for (let t = 0; t < triangleCount; t++) {
1397
+ const i0 = indices[t * 3];
1398
+ const i1 = indices[t * 3 + 1];
1399
+ const i2 = indices[t * 3 + 2];
1400
+ const baseOffset = t * 3 * 4;
1401
+ normData[baseOffset] = normals[i0 * 3];
1402
+ normData[baseOffset + 1] = normals[i0 * 3 + 1];
1403
+ normData[baseOffset + 2] = normals[i0 * 3 + 2];
1404
+ normData[baseOffset + 3] = 0;
1405
+ normData[baseOffset + 4] = normals[i1 * 3];
1406
+ normData[baseOffset + 5] = normals[i1 * 3 + 1];
1407
+ normData[baseOffset + 6] = normals[i1 * 3 + 2];
1408
+ normData[baseOffset + 7] = 0;
1409
+ normData[baseOffset + 8] = normals[i2 * 3];
1410
+ normData[baseOffset + 9] = normals[i2 * 3 + 1];
1411
+ normData[baseOffset + 10] = normals[i2 * 3 + 2];
1412
+ normData[baseOffset + 11] = 0;
1413
+ }
1414
+ this._meshNormalTexture = new RawTexture(normData, texWidth, texHeight, 5, this._scene || this._engine, false, false, 1, 1);
1415
+ this._meshNormalTexture.name = "meshNormalTexture";
1416
+ }
1417
+ this._meshEmitterMeshId = mesh.uniqueId;
1418
+ this._meshEmitterUsedNormals = useNormals;
1419
+ }
1403
1420
  _createColorGradientTexture() {
1404
1421
  if (!this._colorGradients || !this._colorGradients.length || this._colorGradientsTexture) {
1405
1422
  return;
@@ -1574,6 +1591,10 @@ export class GPUParticleSystem extends BaseParticleSystem {
1574
1591
  if (this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {
1575
1592
  this._updateBuffer.setFloat2("lifeTimeGradientRange", this._lifeTimeGradientMin, this._lifeTimeGradientMax);
1576
1593
  }
1594
+ if (this._meshPositionTexture) {
1595
+ this._updateBuffer.setInt("meshTriangleCount", this._meshTriangleCount);
1596
+ this._updateBuffer.setInt("meshTextureWidth", this._meshTextureWidth);
1597
+ }
1577
1598
  this._platform.updateParticleBuffer(this._targetIndex, this._targetBuffer, this._currentActiveCount);
1578
1599
  // Switch VAOs
1579
1600
  this._targetIndex++;
@@ -1773,6 +1794,8 @@ export class GPUParticleSystem extends BaseParticleSystem {
1773
1794
  };
1774
1795
  this._createIndexBuffer();
1775
1796
  this._cachedUpdateDefines = "";
1797
+ // Re-upload mesh emitter data if the mesh geometry changed
1798
+ this._disposeMeshEmitterTextures();
1776
1799
  this._platform.contextLost();
1777
1800
  this._rebuildingAfterContextLost = true;
1778
1801
  checkUpdateEffect();
@@ -1841,6 +1864,7 @@ export class GPUParticleSystem extends BaseParticleSystem {
1841
1864
  this._dragGradientsTexture.dispose();
1842
1865
  this._dragGradientsTexture = null;
1843
1866
  }
1867
+ this._disposeMeshEmitterTextures();
1844
1868
  if (this._randomTexture) {
1845
1869
  this._randomTexture.dispose();
1846
1870
  this._randomTexture = null;