logo
CarPaint

vehicle · vehicle-combat

CarPaint

Listens toMesh
1
Unlock

Install with the CLI:

bjs download CarPaint

CarPaint

A clear coat on a car model, so it shines like a real car.

What it does

Car paint has two layers. Under it is the colour. On top is a clear coat that shines like glass. A glTF model only has the colour, so under a bright sky it looks like plastic.

CarPaint waits for the model to load (mesh.loaded from Mesh). Then its plugin turns on the clear coat on every part of the model.

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

    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
{
  "Player": {
    "components": {
      "Mesh": { "src": "/vehiclecombat/interceptor.glb", "follow": true },
      "CarPaint": { "clearCoat": 1, "clearCoatRoughness": 0.06 }
    }
  }
}

Call registerCarPaintExtension(adapter) at bootstrap. Only Babylon has the plugin. Without it the car keeps its plain look and CarPaint warns once in the console.

The scene also needs an HDR sky, from EnvironmentTexture or DayNightCycle. With no sky the coat has nothing to shine back.

Shine at a glance

Look straight at a clear coat and only a little light bounces back. Look along it, and nearly all of it does. That is why the far side of a car mirrors the sky while the side facing you shows its colour. clearCoatIOR sets the head-on part:

text
head-on reflection = ((n − 1) / (n + 1))²    (worked numbers, not from the source)

n = 1.5  →  (0.5 / 2.5)²  =  0.04  →  4%
n = 2.0  →  (1.0 / 3.0)²  =  0.11  →  11%

The default of 1.5 matches a polyurethane lacquer.

Safe values

The component clamps each value before the plugin sees it:

TypeScript
  spec(): CarPaintSpec {
    return {
      clearCoat: Math.max(0, Math.min(1, this.clearCoat)),
      clearCoatRoughness: Math.max(0, Math.min(1, this.clearCoatRoughness)),
      clearCoatIOR: Math.max(1, this.clearCoatIOR),
    };
  }

A clearCoat of 0 turns the coat off.

Pools

Put CarPaint on a pool blueprint and every copy gets the coat as it loads. A material shared by several cars is coated once, with the settings of the first car to load it. Cars that share a material should share settings too.

Settings

FieldDefaultWhat it does
clearCoat1How strong the coat is, 0 (none) to 1.
clearCoatRoughness0.080 is a mirror, 0.1 a fresh polish, 0.4 old and dull.
clearCoatIOR1.5Index of refraction. Higher reflects more, most of all head-on.

Events

EventPayloadDirection
mesh.loaded{ entityId, meshId, animationNames, handle }listens

CarPaint sends nothing. It reads entityId and handle.

Needs

  • Mesh: loads the model and sends mesh.loaded with the handle CarPaint coats.

More like this

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search