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