BabylonJS/Babylon.js · error
GPU particles cannot work without a full Engine. ThinEngine
Error message
GPU particles cannot work without a full Engine. ThinEngine is not supported
What it means
The WebGL2 GPU particle update pipeline relies on engine capabilities that only the full Engine class provides (specifically setState used inside enableEffect/update flow). preUpdateParticleBuffer casts this._engine to Engine and verifies engine.setState exists; if the system was created against a ThinEngine (or another engine lacking setState), it cannot run the GPU update pass and throws.
Source
Thrown at packages/dev/core/src/Particles/webgl2ParticleSystem.pure.ts:224
}
/** @internal */
public bindDrawBuffers(index: number, effect: Effect, indexBuffer: Nullable<DataBuffer>): void {
if (indexBuffer) {
this._engine.bindBuffers(this._renderVertexBuffers, indexBuffer, effect);
} else {
this._engine.bindVertexArrayObject(this._renderVAO[index], null);
}
}
/** @internal */
public preUpdateParticleBuffer(): void {
const engine = this._engine as Engine;
this._engine.enableEffect(this._updateEffect);
if (!engine.setState) {
throw new Error("GPU particles cannot work without a full Engine. ThinEngine is not supported");
}
}
/** @internal */
public updateParticleBuffer(index: number, targetBuffer: Buffer, currentActiveCount: number): void {
this._updateEffect.setTexture("randomSampler", this._parent._randomTexture);
this._updateEffect.setTexture("randomSampler2", this._parent._randomTexture2);
if (this._parent._flowMap) {
this._updateEffect.setTexture("flowMapSampler", this._parent._flowMap);
}
if (this._parent._sizeGradientsTexture) {
this._updateEffect.setTexture("sizeGradientSampler", this._parent._sizeGradientsTexture);
}
if (this._parent._angularSpeedGradientsTexture) {
this._updateEffect.setTexture("angularSpeedGradientSampler", this._parent._angularSpeedGradientsTexture);
View on GitHub (pinned to 0592b347b8)
Solutions
- Create GPUParticleSystem with a full Engine (new Engine(canvas, ...)), not ThinEngine.
- Use the CPU ParticleSystem when only a ThinEngine is available.
- Feature-check engine.setState before wiring GPU particles and fall back to CPU particles.
Example fix
// before
const engine = new ThinEngine(canvas);
const ps = new GPUParticleSystem("p", { capacity: 1000 }, engine);
// after
const engine = new Engine(canvas, true);
const ps = new GPUParticleSystem("p", { capacity: 1000 }, engine); Defensive patterns
Strategy: validation
Validate before calling
if (!("setState" in engine)) {
throw new Error("GPUParticleSystem requires a full Engine, not ThinEngine");
} Type guard
function supportsGpuParticles(engine: AbstractEngine): engine is Engine {
return typeof (engine as Engine).setState === "function";
} Prevention
- Use full Engine for GPU particles; reserve ThinEngine for CPU ParticleSystem.
- Feature-check engine.setState before choosing GPU vs CPU particles.
- Avoid NullEngine/ThinEngine in production particle paths.
When it happens
Trigger: GPUParticleSystem created with a ThinEngine (or engine without a setState method) then running its update loop: preUpdateParticleBuffer() checks !engine.setState and throws.
Common situations: Using GPUParticleSystem with ThinEngine/NullEngine (e.g. headless tests, minimal custom engines) where only ThinEngine is available; constructing the platform class manually against a thin engine.
Related errors
- The WebGL2ParticleSystem class is not available! Make sure y
- Instanced arrays are required for MSDF text rendering.
- createComputeEffect: This engine does not support compute sh
- createComputePipelineContext: This engine does not support c
- computeDispatch: This engine does not support compute shader
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/b93969cd4ebad619.
Report an issue: GitHub.