Skip to content

Base Modules ​

The particle system simulator can have various property modules added to it. Each property module contains one feature implementation and its related parameters. The following are currently built in:

  • ParticleOverLifeScaleModule - Module for size variation over the particle lifecycle
  • ParticleOverLifeSpeedModule - Module for speed variation over the lifecycle
  • ParticleOverLifeRotationModule - Module for spin variation over the lifecycle
  • ParticleOverLifeColorModule - Module for color variation over the lifecycle
  • ParticleGravityModifierModule - Gravity variation module
  • ParticleTextureSheetModule - Texture sheet module

Size Transformation Module ​

If you want the size of a single particle to change over time throughout its own entire lifecycle, you can add the ParticleOverLifeScaleModule module to the simulator:

ts
// Add the over-life size transformation module
let overLifeScaleModule = simulator.addModule(ParticleOverLifeScaleModule);
// Set the size transformation parameters, from 1x size at start to 3x size at end
overLifeScaleModule.scaleSegments = [
    new Vector4(1, 1, 1),
    new Vector4(3, 3, 3),
];

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, AtmosphericComponent, Vector3, Vector4, View3D, HoverCameraController, Object3D, PlaneGeometry, Scene3D, CameraUtil } from '@orillusion/core';

import { ParticleSystem, ParticleMaterial, ParticleStandardSimulator, ParticleEmitterModule, ShapeType, EmitLocation, ParticleOverLifeScaleModule } from '@orillusion/particle';

class Sample_OverLifeScaleModule {
    engine: Engine3D;
    async run() {
        this.engine = await Engine3D.init();

        let scene = new Scene3D();
        scene.addComponent(AtmosphericComponent).sunY = 0.6;

        let camera = CameraUtil.createCamera3DObject(scene);
        camera.perspective(60, this.engine.aspect, 0.1, 5000.0);

        let ctrl = camera.object3D.addComponent(HoverCameraController);
        ctrl.setCamera(45, -15, 30);

        await this.initScene(scene);

        let view = new View3D();
        view.scene = scene;
        view.camera = camera;
        this.engine.startRenderView(view);
    }

    async initScene(scene: Scene3D) {
        // create entity object
        let obj = new Object3D();
        scene.addChild(obj);

        // add particle system component
        let particleSystem = obj.addComponent(ParticleSystem);

        // set particle material
        let material = new ParticleMaterial();
        material.baseMap = await this.engine.res.loadTexture('https://cdn.orillusion.com/particle/fx_a_glow_003.png');

        // set particle geometry
        particleSystem.geometry = new PlaneGeometry(1, 1, 1, 1, Vector3.Z_AXIS);
        particleSystem.material = material;

        // use the specified simulator
        let simulator = particleSystem.useSimulator(ParticleStandardSimulator);

        // add the emitter module
        let emitter = simulator.addModule(ParticleEmitterModule);
        emitter.maxParticle = 1000;
        emitter.duration = 10;
        emitter.emissionRate = 100;
        emitter.startLifecycle.setScalar(1);
        emitter.shapeType = ShapeType.Circle;
        emitter.radius = 10;
        emitter.emitLocation = EmitLocation.Shell;

        // add the over-life scale module
        let overLifeScaleModule = simulator.addModule(ParticleOverLifeScaleModule);
        overLifeScaleModule.scaleSegments = [new Vector4(1, 1, 1), new Vector4(3, 3, 3)];

        // start playing
        particleSystem.play();
    }
}

new Sample_OverLifeScaleModule().run();

Rotation Transformation Module ​

If you want the rotation angle of a single particle to change over time throughout its own entire lifecycle, you can add the ParticleOverLifeRotationModule module to the simulator:

ts
// Add the over-life rotation transformation module
let overLifeRotationModule = simulator.addModule(ParticleOverLifeRotationModule);
// Set the spin transformation parameters, from 0° at start to 270° at end
overLifeRotationModule.rotationSegments = [
    new Vector4(0, 0, 0),
    new Vector4(0, 90 * DEGREES_TO_RADIANS, 0),
];

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, AtmosphericComponent, Vector3, Vector4, View3D, HoverCameraController, Object3D, PlaneGeometry, Scene3D, CameraUtil, BoxGeometry, DEGREES_TO_RADIANS } from '@orillusion/core';

import { ParticleSystem, ParticleMaterial, ParticleStandardSimulator, ParticleEmitterModule, ShapeType, EmitLocation, ParticleOverLifeRotationModule } from '@orillusion/particle';

class Sample_OverLifeRotationModule {
    async run() {
        let engine = await Engine3D.init();

        let scene = new Scene3D();
        scene.addComponent(AtmosphericComponent).sunY = 0.6;

        let camera = CameraUtil.createCamera3DObject(scene);
        camera.perspective(60, engine.aspect, 0.1, 5000.0);

        let ctrl = camera.object3D.addComponent(HoverCameraController);
        ctrl.setCamera(45, -15, 30);

        await this.initScene(scene);

        let view = new View3D();
        view.scene = scene;
        view.camera = camera;
        engine.startRenderView(view);
    }

    async initScene(scene: Scene3D) {
        // create entity object
        let obj = new Object3D();
        scene.addChild(obj);

        // add particle system component
        let particleSystem = obj.addComponent(ParticleSystem);

        // set particle material
        let material = new ParticleMaterial();

        // set particle geometry
        particleSystem.geometry = new PlaneGeometry(1, 1, 1, 1, Vector3.Z_AXIS);
        particleSystem.material = material;

        // use the specified simulator
        let simulator = particleSystem.useSimulator(ParticleStandardSimulator);

        // add the emitter module
        let emitter = simulator.addModule(ParticleEmitterModule);
        emitter.maxParticle = 1000;
        emitter.duration = 10;
        emitter.emissionRate = 100;
        emitter.startLifecycle.setScalar(1);
        emitter.shapeType = ShapeType.Circle;
        emitter.radius = 10;
        emitter.emitLocation = EmitLocation.Shell;

        // add the over-life rotation module
        let overLifeRotationModule = simulator.addModule(ParticleOverLifeRotationModule);
        overLifeRotationModule.rotationSegments = [new Vector4(0, 0, 0), new Vector4(0, 0, 360 * DEGREES_TO_RADIANS)];

        // start playing
        particleSystem.play();
    }
}

new Sample_OverLifeRotationModule().run();

Color Transformation Module ​

If you want the color of a single particle to change over time throughout its own entire lifecycle, you can add the ParticleOverLifeColorModule module to the simulator:

ts
// Add the over-life color transformation module
let overLifeColorModule = simulator.addModule(ParticleOverLifeColorModule);
// Set the start color
overLifeColorModule.startColor = new Color(1, 1, 0);
// Set the start alpha
overLifeColorModule.startAlpha = 0.0;
// Set the end color
overLifeColorModule.endColor = new Color(0.1, 0.6, 1);
// Set the end alpha
overLifeColorModule.endAlpha = 1.0;

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, AtmosphericComponent, Vector3, Vector4, View3D, Color, HoverCameraController, Object3D, PlaneGeometry, Scene3D, CameraUtil, BoxGeometry, DEGREES_TO_RADIANS } from '@orillusion/core';

import { ParticleSystem, ParticleMaterial, ParticleStandardSimulator, ParticleEmitterModule, ShapeType, EmitLocation, ParticleOverLifeColorModule } from '@orillusion/particle';

class Sample_OverLifeRotationModule {
    engine: Engine3D;
    async run() {
        this.engine = await Engine3D.init();

        let scene = new Scene3D();
        scene.addComponent(AtmosphericComponent).sunY = 0.6;

        let camera = CameraUtil.createCamera3DObject(scene);
        camera.perspective(60, this.engine.aspect, 0.1, 5000.0);

        let ctrl = camera.object3D.addComponent(HoverCameraController);
        ctrl.setCamera(45, -15, 30);

        await this.initScene(scene);

        let view = new View3D();
        view.scene = scene;
        view.camera = camera;
        this.engine.startRenderView(view);
    }

    async initScene(scene: Scene3D) {
        // create entity object
        let obj = new Object3D();
        scene.addChild(obj);

        // add particle system component
        let particleSystem = obj.addComponent(ParticleSystem);

        // set particle material
        let material = new ParticleMaterial();
        material.baseMap = await this.engine.res.loadTexture('https://cdn.orillusion.com/particle/fx_a_glow_003.png');

        // set particle geometry
        particleSystem.geometry = new PlaneGeometry(1, 1, 1, 1, Vector3.Z_AXIS);
        particleSystem.material = material;

        // use the specified simulator
        let simulator = particleSystem.useSimulator(ParticleStandardSimulator);

        // add the emitter module
        let emitter = simulator.addModule(ParticleEmitterModule);
        emitter.maxParticle = 1000;
        emitter.duration = 10;
        emitter.emissionRate = 100;
        emitter.startLifecycle.setScalar(1);
        emitter.shapeType = ShapeType.Circle;
        emitter.radius = 10;
        emitter.emitLocation = EmitLocation.Shell;

        // add the over-life color module
        let overLifeColorModule = simulator.addModule(ParticleOverLifeColorModule);
        // set the start color
        overLifeColorModule.startColor = new Color(1, 1, 0);
        // set the start alpha
        overLifeColorModule.startAlpha = 0.0;
        // set the end color
        overLifeColorModule.endColor = new Color(0.1, 0.6, 1);
        // set the end alpha
        overLifeColorModule.endAlpha = 1.0;

        // start playing
        particleSystem.play();
    }
}

new Sample_OverLifeRotationModule().run();

Gravity Modifier Module ​

When simulating the motion trajectory of particles, you can add a gravity modifier module ParticleGravityModifierModule to the simulator so that particles can move according to the direction of gravity:

ts
// Add the gravity modifier module
let gravityModifier = simulator.addModule(ParticleGravityModifierModule);
gravityModifier.gravity = new Vector3(0, -0.98, 0);

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, AtmosphericComponent, Vector3, View3D, HoverCameraController, Object3D, PlaneGeometry, Scene3D, CameraUtil, BoxGeometry, DEGREES_TO_RADIANS } from '@orillusion/core';

import { ParticleSystem, ParticleMaterial, ParticleStandardSimulator, ParticleEmitterModule, ShapeType, EmitLocation, ParticleGravityModifierModule } from '@orillusion/particle';

class Sample_OverLifeRotationModule {
    engine: Engine3D;
    async run() {
        this.engine = await Engine3D.init();

        let scene = new Scene3D();
        scene.addComponent(AtmosphericComponent).sunY = 0.6;

        let camera = CameraUtil.createCamera3DObject(scene);
        camera.perspective(60, this.engine.aspect, 0.1, 5000.0);

        let ctrl = camera.object3D.addComponent(HoverCameraController);
        ctrl.setCamera(45, -30, 80);

        await this.initScene(scene);

        let view = new View3D();
        view.scene = scene;
        view.camera = camera;
        this.engine.startRenderView(view);
    }

    async initScene(scene: Scene3D) {
        // create entity object
        let obj = new Object3D();
        obj.y = 10;
        scene.addChild(obj);

        // add particle system component
        let particleSystem = obj.addComponent(ParticleSystem);

        // set particle material
        let material = new ParticleMaterial();
        material.baseMap = await this.engine.res.loadTexture('https://cdn.orillusion.com/particle/fx_a_fragment_003.png');

        // set particle geometry
        particleSystem.geometry = new PlaneGeometry(1, 8, 1, 1, Vector3.Z_AXIS);
        particleSystem.material = material;

        // use the specified simulator
        let simulator = particleSystem.useSimulator(ParticleStandardSimulator);

        // add the emitter module
        let emitter = simulator.addModule(ParticleEmitterModule);
        emitter.maxParticle = 10000;
        emitter.duration = 10;
        emitter.emissionRate = 1000;
        emitter.startLifecycle.setScalar(1);
        emitter.shapeType = ShapeType.Circle;
        emitter.radius = 60;
        emitter.emitLocation = EmitLocation.Shell;

        // add the gravity modifier module
        let gravityModifier = simulator.addModule(ParticleGravityModifierModule);
        gravityModifier.gravity = new Vector3(0, -9.8, 0);

        // start playing
        particleSystem.play();
    }
}

new Sample_OverLifeRotationModule().run();

Texture Sheet Module ​

When you need to provide a different texture for each particle or to give a single particle a texture animation, you can add a texture sheet module ParticleTextureSheetModule to the simulator:

ts
// Add the texture sheet module
let sheetModule = simulator.addModule(ParticleTextureSheetModule);
// Set how many sub-tiles each column contains
sheetModule.clipCol = 4;
// Set how many sub-tiles the entire texture contains in total
sheetModule.totalClip = 4 * 4;
// Set the width of the entire texture
sheetModule.textureWidth = material.baseMap.width;
// Set the height of the entire texture
sheetModule.textureHeight = material.baseMap.height;
// Set the playback rate of the texture animation
sheetModule.playRate = 1.0;

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, AtmosphericComponent, Vector3, View3D, HoverCameraController, Object3D, PlaneGeometry, Scene3D, CameraUtil } from '@orillusion/core';

import { ParticleSystem, ParticleMaterial, ParticleStandardSimulator, ParticleEmitterModule, ShapeType, EmitLocation, ParticleTextureSheetModule } from '@orillusion/particle';

class Sample_OverLifeRotationModule {
    engine: Engine3D;
    async run() {
        this.engine = await Engine3D.init();

        let scene = new Scene3D();
        scene.addComponent(AtmosphericComponent).sunY = 0.6;

        let camera = CameraUtil.createCamera3DObject(scene);
        camera.perspective(60, this.engine.aspect, 0.1, 5000.0);

        let ctrl = camera.object3D.addComponent(HoverCameraController);
        ctrl.setCamera(45, -15, 5);

        await this.initScene(scene);

        let view = new View3D();
        view.scene = scene;
        view.camera = camera;
        this.engine.startRenderView(view);
    }

    async initScene(scene: Scene3D) {
        // create entity object
        let obj = new Object3D();
        scene.addChild(obj);

        // add particle system component
        let particleSystem = obj.addComponent(ParticleSystem);

        // set particle material
        let material = new ParticleMaterial();
        material.baseMap = await this.engine.res.loadTexture('https://cdn.orillusion.com/particle/crystal_debug.png');

        // set particle geometry
        particleSystem.geometry = new PlaneGeometry(1, 1, 1, 1, Vector3.Z_AXIS);
        particleSystem.material = material;

        // use the specified simulator
        let simulator = particleSystem.useSimulator(ParticleStandardSimulator);

        // add the emitter module
        let emitter = simulator.addModule(ParticleEmitterModule);
        emitter.maxParticle = 1000;
        emitter.duration = 10;
        emitter.emissionRate = 10;
        emitter.startLifecycle.setScalar(1);
        emitter.shapeType = ShapeType.Circle;
        emitter.radius = 2.0;
        emitter.emitLocation = EmitLocation.Shell;

        // add the texture sheet module
        let sheetModule = simulator.addModule(ParticleTextureSheetModule);
        // set how many sub-tiles each column contains
        sheetModule.clipCol = 4;
        // set the total number of sub-tiles in the whole texture
        sheetModule.totalClip = 4 * 4;
        // set the width of the whole texture
        sheetModule.textureWidth = material.baseMap.width;
        // set the height of the whole texture
        sheetModule.textureHeight = material.baseMap.height;
        // set the texture animation play rate
        sheetModule.playRate = 10.0;

        // start playing
        particleSystem.play();
    }
}

new Sample_OverLifeRotationModule().run();

Released under the MIT License