logo

Babylon.js Market

SpaceDust

rendering · space-combat-sim

SpaceDust

1
Unlock

Install with the CLI:

bjs download SpaceDust

SpaceDust

The whole space backdrop for a 6-DOF flight scene — a camera-anchored dust field plus glow, bloom, and a positioned sun — from one marker component.

What it does

SpaceDustComponent is pure data: dust-emitter tuning (capacity, emit rate/radius, size + lifetime ranges), a glow intensity, a bloom weight, and a positioned-sun spec. It carries no runtime handle. On first sight of the entity, SpaceDustSystem wires the scene's visual chrome through this.world.renderer exactly once (a setUp latch): it CPU-rasterises a soft dust-dot sprite and uploads it (createDynamicTexture), starts a continuous, camera-anchored dust emitter that re-seats at the active camera every frame (createParticleEmitter with followCamera), enables the selective glow post-pass (setGlowLayer) and HDR bloom (setBloom), and creates a parallax-free camera-following sun — a directional light plus an emissive disc (createSun). The specks have zero emit power, so they hang in space and the camera flies through them; floating-origin world streaming makes a starfield-of-entities pointless, so the field is pure particle chrome. The live emitter handle lives in a System-side WeakMap, never on the component, and is disposed when the entity leaves the world.

Use it in a scene

A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.

Build it from scratch with the bjs CLI:

  1. 1Scaffold a project
    npm create @babylonjsmarket/arcade@latest my-game

    World, renderer, and dev server — ready to run.

  2. 2Install dependencies
    cd my-game && npm install
  3. 3Add SpaceDust
    bjs download SpaceDust

    Copies its source into src/ so the scene resolves.

    First time? Run bjs login once.

  4. 4Paste the scene into src/scenes/arcade-room.ts and run
    npm run dev

    SceneLoader builds the world from the JSON; reload to rebuild.

JSON
{
  "World": {
    "tags": ["world"],
    "components": {
      "SpaceDust": {
        "emitRate": 1800,
        "emitRadius": 60,
        "glowIntensity": 0.9,
        "bloomWeight": 0.15,
        "sun": true,
        "sunDirection": [0, -0.22, 1],
        "sunIntensity": 2.4
      }
    }
  }
}

Props

  • capacity (number, default 4000) — max live dust particles; the GPU buffer size.
  • emitRate (number, default 1800) — dust particles spawned per second.
  • emitRadius (number, default 60) — radius (world units) of the sphere the dust spawns within around the camera.
  • minSize / maxSize (number, default 0.04 / 0.12) — per-particle size range.
  • minLifeTime / maxLifeTime (number, default 1.4 / 3.2) — per-particle lifetime range, in seconds.
  • glowIntensity (number, default 0.9) — selective-glow strength; 0 disables the glow layer.
  • bloomWeight (number, default 0.15) — HDR bloom contribution weight; 0 disables bloom.
  • sun (boolean, default true) — create the positioned camera-following sun (directional light + emissive disc).
  • sunDirection ([x,y,z], default [0, -0.22, 1]) — unit world-space direction the sun's rays travel.
  • sunIntensity (number, default 2.4) — directional-light intensity for the sun.
  • sunDistance (number, default 2400) — distance from the camera to the sun disc (parallax-free framing).

Events

None. SpaceDust neither emits nor listens for any EventBus events — it is fire-and-forget scene chrome. All of its work happens through the renderer adapter (this.world.renderer), so there is no bus coupling to wire up and nothing downstream to subscribe to. (meta.json emits/listens are both empty by design.)

Dependencies

None required — the System's query is just [SpaceDustComponent]. In practice, though, the backdrop only makes sense with an active camera for the dust and sun to anchor to (the emitter and sun re-seat at the active camera every frame), so it lives alongside the flight-camera stack (CameraState6DOF + a chase camera). It needs no mesh or MeshPrimitive of its own.

Notes

  • Put it on the world singleton entity (tag world), next to the other global markers — one SpaceDust per scene. It is not attached to the ship.
  • The chrome is applied once, on first sight, behind the setUp latch. Editing the numbers after setup will not re-configure the emitter, glow, bloom, or sun — which is why the debug panel is a read-only readout, not a live-tuning slider panel. Set the values in scene JSON before the scene loads.
  • Turn features off by zeroing them: glowIntensity: 0 drops the glow layer, bloomWeight: 0 drops bloom, and sun: false skips the directional light + disc.
  • The glow layer ships an empty whitelist — meshes opt in elsewhere (a render-sync pass adds glowing meshes via the adapter), so raising glowIntensity alone won't make everything bloom; only meshes that were opted in will.
  • Renderer-agnostic: zero @babylonjs / three imports, and the sprite is rasterised on the CPU (makeDustDotPixels) before upload — the same marker runs under any adapter.
  • A companion SpaceDustDebugger component (toggle key Digit8 by default) shows the applied backdrop config in a viz panel if you want to inspect it at runtime.

More like this

Asteroid
CameraState6DOF
ChaseCamera6DOF
ChaseCameraTarget
DirectionalLight
EnvironmentTexture
FlightIntent
FreighterCar
FreighterChain
FreighterHead
GameConfig
HemisphericLight
Mesh
MeshPrimitive
OilBlob
PlayerFlightInput
Renderable
Shadow
ShipFlight
Skybox
SpaceShooterBullet
SpaceShooterHealth
SpaceShooterScore
ToneMapping
Transform6DOF
Velocity6DOF
WaveDirector
Waypoint
WaypointTrack
WorldOriginAnchor

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search