Add Solid Particle System (SPS) Support to Node Particle Editor
Overview
This PR integrates Babylon.js Solid Particle System (SPS) into the Node Particle Editor, enabling users to create and manage SPS-based particle systems through a visual node graph interface. This brings the power of SPS (instanced rendering, shape-based particles) to the node-based workflow.
Important Note
This is a proposal for discussion and requires future refactoring. The current implementation is created for community discussion as I don't have sufficient knowledge of the node ecosystem architecture. The goal is to gather feedback on the best approach for integrating SPS into the existing node graph system.
Features Added
1. SPS Node Graph Integration
- SPSSystemBlock: Main SPS system node for managing particle systems
- SPSCreateBlock: Node for defining particle shapes and counts
- SPSInitBlock: Node for particle initialization logic
- SPSUpdateBlock: Node for particle update logic
- SPSMeshSourceBlock: Node for mesh shape sources (Box, Sphere, etc.)
Technical Implementation
Core SPS Blocks:
// SPSSystemBlock - Main SPS system
public createSystem(state: NodeParticleBuildState): SolidParticleSystem
// SPSCreateBlock - Particle shape definition
public _build(state: NodeParticleBuildState): ISPSCreateData
// SPSInitBlock - Particle initialization
public _build(state: NodeParticleBuildState): SPSUpdateData
// SPSUpdateBlock - Particle updating
public _build(state: NodeParticleBuildState): SPSUpdateData
// SPSMeshSourceBlock - Mesh shape sources
public _build(state: NodeParticleBuildState): Mesh
Usage Example
// Create SPS system with multiple particle types
const spsSystem = new SPSSystemBlock("SPS System");
const createBox = new SPSCreateBlock("Create Box Particles");
const createSphere = new SPSCreateBlock("Create Sphere Particles");
// Connect multiple particle sources
createBox.solidParticle.connectTo(spsSystem.solidParticle);
createSphere.solidParticle.connectTo(spsSystem.solidParticle);
// Add mesh sources
const boxMesh = new SPSMeshSourceBlock("Box Mesh");
const sphereMesh = new SPSMeshSourceBlock("Sphere Mesh");
boxMesh.mesh.connectTo(createBox.mesh);
sphereMesh.mesh.connectTo(createSphere.mesh);
Current Challenges & Seeking Solutions
1. Multiple Connection Architecture (Incomplete)
Challenge: SPS requires multiple SPSCreateBlock inputs to one SPSSystemBlock.
Current Implementation:
- Added
allowMultipleConnectionsflag - Implemented
connectedPointsarray to store multiple connections - Modified
NodeParticleBlock.build()to traverse all connected blocks Issues: - Visual representation of multiple connections is not fully working
- Graph editor doesn't properly display all connections Question: What's the best architectural approach for handling multiple input connections in the node graph system?
Questions
-
Multiple Connections Architecture: What's the best pattern for handling multiple inputs in the node graph system?
-
SPS Integration: Are there any SPS-specific considerations we should be aware of the implementation?
-
Future Extensibility: How can we make this system more extensible for other particle system?
The main goal is to bring SPS capabilities to the node-based workflow. Looking forward to feedback on the integration approach and suggestions for better solutions to the identified challenges!
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.
-
Multiple Connections Architecture: Look at what I did for the GradientBlock
-
Future Extensibility: Not sure to follow. What are the other particle system? Note that NPE is based on the premise that the update loop is CPU side.
Building or testing the sandbox has failed.
If the tests failed, results can be found here: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/17320/merge/testResults/
Building or testing the playground has failed.
If the tests failed, results can be found here: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/17320/merge/testResults/
Graph tools CI has failed you can find the test results at:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/TOOLS/refs/pull/17320/merge/testResults/
Question for you: How does it integrate with current update nodes that take a particle as parameter?
Ok @Soullnik the more I think about it, the more I struggle to see it working. My main problem is that we cannot share anything with the main blocks. Which blocks will work in both mode? I feel like we are stuffing spa in but it makes not a lot of sense.
Lol sorry I'm thinking too much lol. I think all the nodes working on base types will work still. But all nodes working on particles needs to be hidden. Then it means we need to provide an update node for sps. Same way: update position, etc...
- Multiple Connections Architecture: Look at what I did for the GradientBlock
- Future Extensibility: Not sure to follow. What are the other particle system? Note that NPE is based on the premise that the update loop is CPU side.
i will check gradientBlock
The second question was about architecture - I had to modify NodeParticleSystemSet to support SPS:
private _systemBlocks: (SystemBlock | SPSSystemBlock)[] = [];
This union type works for now, but if we add more particle system types, we'd need:
private _systemBlocks: (SystemBlock | SPSSystemBlock | GPUSystemBlock)[] = [];
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.
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.
- Multiple Connections Architecture: Look at what I did for the GradientBlock
- Future Extensibility: Not sure to follow. What are the other particle system? Note that NPE is based on the premise that the update loop is CPU side.
i will check gradientBlock
The second question was about architecture - I had to modify
NodeParticleSystemSetto support SPS:private _systemBlocks: (SystemBlock | SPSSystemBlock)[] = [];This union type works for now, but if we add more particle system types, we'd need:
private _systemBlocks: (SystemBlock | SPSSystemBlock | GPUSystemBlock)[] = [];
I think that works. Other option will be to have a NodeParticleSystemSet<T>
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.
@deltakosh I’m running into an issue disposing previously created SPS instances. I see that _build inside SPSCreateBlock is called twice for different scenes. What’s the correct way to dispose the previouse SPS associated with the scene?
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.
Well it should be on the user no? That's what I do for particle. The user will generate a new ps on each build and will be the owner
Well it should be on the user no? That's what I do for particle. The user will generate a new ps on each build and will be the owner
I mean sps is created when build is called and for example when we change position in spsnitblock it will automatically call build in related spscreatblock and I see this method is always called 2 times and with different scenes in state, the problem is I need to delete previous sps so there is no duplication.
I struggle to see what is different from the particle system?
@deltakosh in CreateParticleBlock, I see
const system = new ParticleSystem(this.name, state.capacity, state.scene, null, false, undefined, true);
This means that a new particle system will be created with each rebuild.
But in state.scene.particleSystems, I see the correct number of particles. If I have one CreateParticleBlock, I see one particle system in each build.
But in my SPSCreateBlock, each build adds new sps to the scene, and after the third build, I see 3 sps. This means that for regular particles, there's some cleanup happening somewhere before rebuilding, and I can't figure out where.
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.
Hey sorry I'm not available to help right now but you can simply drop a breakpoint in the PS.dispose() and see who is calling? (I think it is done by the preview window)
@deltakosh I have finished implementing a basic example based on https://playground.babylonjs.com/#GLZ1PX#7.
To see this example:
- Run the Node Particle Editor (NPE)
- Select SPS mode
- The example will be displayed, showing a particle system created entirely using node blocks
Note: While this implementation may not be the most optimal approach, it demonstrates the capabilities and opportunities that these SPS blocks provide for creating particle systems through a visual node-based interface.
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.
Building or testing the sandbox has failed.
If the tests failed, results can be found here: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/17320/merge/testResults/
Graph tools CI has failed you can find the test results at:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/TOOLS/refs/pull/17320/merge/testResults/
Building or testing the playground has failed.
If the tests failed, results can be found here: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/17320/merge/testResults/
Audio test results:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/17320/merge/testResults/audioV2/index.html
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.
Nice work mate!! Now we need to make sure you filter the list of the available nodes on the left when in SPS mode (only keep the one working)
We are doing the same in NME. This way there is no need of a special SPS group. When in SPS we only display the SPS + available blocks
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.