Skip to content

Renderers ​

The engine ships with four built-in renderer components. Each one extends ActorComponent and handles loading, displaying, and cleaning up a specific type of visual asset.

ModelRenderer ​

Renders a 3D model loaded from an OBJ, FBX, or glTF file. On awake, a clone of the loaded model (skeletons included) is added to the actor's Three.js group, so several actors can share one model asset. The clone shares geometries and materials with the asset and is detached on destroy without disposing them.

ts
import { Actor, ModelRenderer } from "@jolly-pixel/engine";

const actor = new Actor(world, { name: "Knight" });
actor.addComponent(ModelRenderer, {
  asset: KnightModel,
  animations: {
    default: "idle",
    clipNameRewriter: (name) => name.toLowerCase()
  }
});
OptionDefaultDescription
asset—Typed model reference declared by the owning scene
debugfalseLog loaded object and animations to the console
animations.default—Name of the animation clip to play on start
animations.clipNameRewriteridentityTransforms clip names before storing them

Every ModelRenderer exposes an animation property that controls clip playback with crossfade transitions:

ts
const renderer = actor.addComponentAndGet(ModelRenderer, {
  asset: KnightModel
});

renderer.animation.setFadeDuration(0.25);
renderer.animation.play("walk");
renderer.animation.stop();

SpriteRenderer ​

Renders a 2D sprite from a spritesheet texture. Supports frame-based animation, horizontal/vertical flipping, and opacity.

ts
import { Actor, SpriteRenderer } from "@jolly-pixel/engine";

const actor = new Actor(world, { name: "Player" });
actor.addComponent(SpriteRenderer, {
  texture: PlayerSpritesheet,
  tileHorizontal: 8,
  tileVertical: 4,
  animations: {
    walk: { from: 0, to: 7 },
    jump: [8, 9, 10, 11]
  }
});
OptionDefaultDescription
texture—AssetReference<THREE.Texture> declared by the owning scene (for example with TEXTURE_ASSET). Each sprite renders a clone, so frames and flips never leak between sprites
tileHorizontal—Number of columns in the spritesheet
tileVertical—Number of rows in the spritesheet
animations{}Named animation definitions (frame arrays or ranges)
flip.horizontalfalseMirror the sprite horizontally
flip.verticalfalseMirror the sprite vertically

Runtime helpers:

ts
const sprite = actor.addComponentAndGet(SpriteRenderer, {
  texture: HeroSpritesheet,
  tileHorizontal: 6,
  tileVertical: 2,
  animations: { run: { from: 0, to: 5 } }
});

sprite.setFrame(3);
sprite.setHorizontalFlip(true);
sprite.setOpacity(0.8);
sprite.animation.play("run", { duration: 0.6, loop: true });

duration is the length of one full cycle, in seconds. Playback advances with the frame deltaTime. A non-looping animation stops on its last frame and isPlaying becomes false.

TextRenderer ​

Renders 3D extruded text using a Three.js typeface font (.typeface.json).

ts
import * as THREE from "three";
import { Actor, TextRenderer } from "@jolly-pixel/engine";

const actor = new Actor(world, { name: "Title" });
actor.addComponent(TextRenderer, {
  asset: RobotoFont,
  text: "Hello World",
  material: new THREE.MeshStandardMaterial({ color: 0xffffff }),
  textGeometryOptions: { size: 2, depth: 0.5 }
});
OptionDefaultDescription
asset—Typed font reference declared by the owning scene
text""Initial text to display
materialMeshBasicMaterialMaterial applied to the text mesh
textGeometryOptions{ size: 1, depth: 1 }Three.js TextGeometry parameters

To update the text at runtime, use the text property and call updateMesh():

ts
const renderer = actor.addComponentAndGet(TextRenderer, {
  asset: RobotoFont
});

renderer.text.setValue("Score: 100");
renderer.updateMesh();

See also ​