logo

Babylon.js Market

LensFlare

fx · space-combat-sim

LensFlare

2
Unlock

Install with the CLI:

bjs download LensFlare

LensFlare

A screen-space flare that makes a star read as a light source, and goes dark behind a rock.

What it does

LensFlare: {} on the world entity adds a post-process that finds bright pixels and derives a flare from them: a chromatic ghost chain marching from each bright spot through screen centre (the way a real lens's internal reflections do), a halo, a prismatic fringe, and optionally an anamorphic streak.

Because it works from brightness rather than from a known sun position, it keeps working with two suns, or with an explosion filling the frame.

brightThreshold is the knob that matters. The pass samples the scene, so the threshold is what separates "a light source" from "a lit surface". It defaults to 1.0 — above LDR white — so only HDR emitters like the sun disc (emissive ~14) qualify. Set it much lower and every bright hull in the scene sprouts ghosts.

The occlusion test is ECS work, not shader work. Each frame the System asks whether an asteroid sits on the segment between the camera and the sun, reusing segmentClearOfAsteroids — the same test the target lock uses to refuse a lock through rock, so cover means one consistent thing across the game — and scales the flare to zero when it does. Without it, a flare blazes straight through a solid boulder, which looks worse than having no flare: it reads as the sky being drawn on top of the world.

Setup

The engine work ships with the component. Register it once at bootstrap, before the scene loads:

TypeScript
import { registerLensFlareExtension } from '@babylonjsmarket/…/LensFlare/adapter/register';

const adapter = new BabylonAdapter();
registerLensFlareExtension(adapter);
const game = new ArcadeGame(adapter, { … });

Without it there is no flare and the System warns once.

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 LensFlare
    bjs download LensFlare

    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": {},
      "LensFlare": { "intensity": 1.4, "occlusionTest": true }
    }
  }
}

SpaceDust is what creates the sun the flare feeds on, and the HDR bloom that pairs with it.

Props

  • intensity (number, default 1.4) — master strength of the halo term.
  • ghostIntensity (number, default 1.4) — strength of the ghost chain. 0 disables ghosts.
  • ghostDispersal (number, default 0.3) — spacing of the chain along the line through screen centre.
  • haloWidth (number, default 0.08).
  • streakIntensity (number, default 0) — anamorphic horizontal streak. Off by default; it reads as cinematic or as cheap depending on the scene.
  • streakLength (number, default 0.3).
  • brightThreshold (number, default 1) — brightness a pixel must exceed to flare. See above.
  • chromatic (number, default 0.005) — prismatic fringe offset on the ghosts.
  • localGlow (number, default 0) — local ring glow around bright pixels. Off because HDR bloom already supplies the sun's halo, and both at once produces displaced copies of the disc.
  • occlusionTest (boolean, default true) — dim the flare when an asteroid hides the sun.

Events

None either way.

Dependencies

CameraState6DOF on a camera-tagged entity — the occlusion test needs somewhere to look from. A sun in the scene (SpaceDust creates one) for there to be anything to flare.

Notes

  • Scaling to zero, not detaching. Rebuilding a post-process every time a rock drifts across the sun would cost far more than multiplying by zero.
  • The occlusion result is binary rather than a fade: the disc is either behind a rock or it isn't, and a partial value would imply the test knows how much of it is covered. It doesn't.
  • With no sun, no camera, or occlusionTest off, the flare is left lit — in each case there is nothing to occlude, and silently dimming would be wrong.
  • The pass runs at half resolution. The effect is all low-frequency glow, so the extra pixels buy nothing.
  • Attachment waits for an active camera and retries until there is one, rather than silently doing nothing.

More like this

CameraState6DOF
Asteroid
AsteroidField
ChaseCamera6DOF
ChaseCameraTarget
FlightIntent
FreighterCar
FreighterChain
FreighterHead
GameConfig
NebulaSky
OilBlob
PlayerFlightInput
ShipDamageFX
ShipFlight
SpaceDust
SpaceShooterBullet
SpaceShooterFX
SpaceShooterHUD
SpaceShooterHealth
SpaceShooterScore
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