Skip to content

Add GPUParticleSystem.fromParticleSystem helper#18330

Open
VicenteCartas wants to merge 4 commits intoBabylonJS:masterfrom
VicenteCartas:gpu-migrate
Open

Add GPUParticleSystem.fromParticleSystem helper#18330
VicenteCartas wants to merge 4 commits intoBabylonJS:masterfrom
VicenteCartas:gpu-migrate

Conversation

@VicenteCartas
Copy link
Copy Markdown
Contributor

@VicenteCartas VicenteCartas commented Apr 16, 2026

Migrate CPU particle systems to GPU (GPUParticleSystem.fromParticleSystem)

Summary

Adds GPUParticleSystem.fromParticleSystem(source, scene, options?), a static helper that produces a GPUParticleSystem configured to match an existing CPU ParticleSystem as closely as the GPU pipeline allows. Any GPU-unsupported feature on the source is logged as a warning and skipped; everything that the GPU pipeline can represent is copied 1:1.

As part of this work, the GPU render pipeline now also supports the color2 component of color gradients (previously only color1 was honored), bringing GPU color gradients to parity with the CPU path.

What's included

New API

  • GPUParticleSystem.fromParticleSystem(source, scene, options?) — migrates a CPU ParticleSystem to a new GPUParticleSystem. Copies all transferable state (emitter, min/max ranges, gradients, attractors, animations, flow map, pre-warm, etc.) and returns the new system.

GPU color gradient color2 support

  • GPUParticleSystem.addColorGradient(gradient, color1, color2?) now accepts a second color. When any stop has a color2, the color gradient texture is built as a 2-row RGBA8 texture (row 0 = color1 ramp, row 1 = color2 ramp, with color2 ?? color1 fallback).
  • The render vertex shader (gpuRenderParticles.vertex.fx) gains a COLORGRADIENTS_COLOR2 define. Under that define it samples both rows and mixes them using the particle's persistent seed.x, producing a stable per-particle random color — matching the CPU system's behavior.
  • The seed attribute is wired into the render vertex buffers only when COLORGRADIENTS_COLOR2 is active (zero cost when unused).
  • removeColorGradient recomputes the flag, so removing the last color2 stop drops back to the single-row path cleanly.

Reviewer-feedback fixes (after initial code review)

  • color2 was being silently dropped by fromParticleSystem. Now fully supported in the GPU path (see above); fromParticleSystem clones color2 through to the destination.
  • _flowMap was never disposed by GPUParticleSystem.dispose() — added disposal.
  • animations array and beginAnimationOn* flags were not copied by fromParticleSystem — now copied.
  • JSDoc of fromParticleSystem claimed to warn on "custom update functions", but the code doesn't (and cannot feasibly) detect a custom override — corrected the doc to list only what is actually detected.
  • Redundant gradient getter calls in the copy path — cached.
  • preWarmCycles was not applying flow-map advection (bug in thinParticleSystem) — added scene.updateTransformMatrix() inside the pre-warm loop so flow-map sampling uses a valid transform during warm-up.

Tests

  • Unit tests (packages/dev/core/test/unit/Particles/gpuParticleFromCPU.test.ts): 15 tests covering emitter state, ranges, attractors, gradient copying (including a new test asserting color2 is preserved with and without a second color per stop), flow map, animation flags, and warning paths for unsupported features (sub-emitters, startDirectionFunction, startPositionFunction, customShader, ramp/remap gradients).
  • Visual tests (packages/tools/tests/test/visualization/config.json): 3 new entries, all passing on WebGL2 and WebGPU:
    • GPU Particles - From Particle System - Basic
    • GPU Particles - From Particle System - Gradients + Attractors
    • GPU Particles - Change - Color Gradient With Color2

Quality

  • npm run format:check
  • npm run lint:check
  • npm run test:unit — 168/168 Particle tests passing
  • Visual tests — 3 new entries passing on both engines

Backward compatibility

  • addColorGradient(gradient, color1) signature unchanged — color2 is an optional third parameter. Existing callers are unaffected.
  • No public API removed or renamed.
  • Render shader define COLORGRADIENTS_COLOR2 only activates when the user explicitly adds a color2; existing content produces byte-identical output.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 16, 2026

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 16, 2026

Snapshot stored with reference name:
refs/pull/18330/merge

Test environment:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18330/merge/index.html

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18330/merge/index.html#WGZLGJ#4600

Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves):

https://playground.babylonjs.com/?snapshot=refs/pull/18330/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18330/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18330/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18330/merge

To test the snapshot in the playground with a playground ID add it after the snapshot query string:

https://playground.babylonjs.com/?snapshot=refs/pull/18330/merge#BCU1XR#0

If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 16, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 16, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new conversion helper for particles, enabling creation of a GPUParticleSystem from an existing CPU ParticleSystem by copying/cloning supported state, warning on unsupported features, and converting CPU flow maps into GPU textures. Also includes lifecycle fixes (disposing flow-map textures) and a pre-warm transform-matrix update to ensure matrix-dependent steps behave correctly.

Changes:

  • Added GPUParticleSystem.fromParticleSystem(...) conversion helper with flow-map conversion and warning logs for unsupported CPU features.
  • Ensured GPUParticleSystem.dispose() disposes the internal flow-map texture when disposeTexture is true.
  • Added unit + visual tests for conversion behavior (including flow-map cases) and updated ThinParticleSystem pre-warm to update the scene transform matrix.

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/dev/core/src/Particles/gpuParticleSystem.ts Adds fromParticleSystem and disposes _flowMap in dispose() to prevent GPU texture leaks.
packages/dev/core/src/Particles/thinParticleSystem.ts Updates scene transform matrix before pre-warm cycles to ensure matrix-dependent updates are correct.
packages/dev/core/test/unit/Particles/gpuParticleFromCPU.test.ts Adds unit tests covering conversion behavior, warnings, gradients, attractors, textures, and flow-map conversion.
packages/tools/tests/test/visualization/config.json Registers two new visual tests for CPU→GPU conversion and flow-map conversion.
packages/tools/tests/test/visualization/ReferenceImages/*.png Adds reference images for the new visual tests.

Comment thread packages/dev/core/src/Particles/gpuParticleSystem.ts Outdated
Comment thread packages/dev/core/src/Particles/gpuParticleSystem.ts Outdated
Vicente Cartas Espinel added 2 commits April 16, 2026 17:09
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 17, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 17, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 17, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 17, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 17, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 17, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants