Skip to content

@modoki/engine / index / Billboard3D

Variable: Billboard3D

const Billboard3D: Trait<{ alphaTest: number; anchor: "center" | "bottom"; mode: "cylindrical" | "spherical"; pixelsPerUnit: number; }>

Billboard3D — promotes a SkinnedSprite2D entity out of the flat PixiJS 2D canvas and INTO the Three.js 3D scene as a camera-facing (billboarded) mesh. This is the 2.5D bridge: the CPU-skinned deform (skin2DSystemskin2DBuffers) is reused verbatim — the same rig, the same Bone2D skeleton, the same .anim.json clips — but instead of Scene2D drawing a PixiJS Mesh, the 3D renderer (scene3DSync) builds a THREE.BufferGeometry from the deformed positions and orients it toward the camera each frame.

Add this trait ALONGSIDE SkinnedSprite2D. Scene2D then SKIPS the entity (it renders in 3D instead), and the 3D billboard pass picks it up. Remove it and the entity falls back to the flat 2D layer — nothing else about the rig changes.

Rendering model (2.5D): each rig PART draws as an alpha-tested, camera-facing mesh. Parts are layered by the rig's own paint order (like the 2D canvas) with depth-WRITE off so the ~coplanar parts never z-fight, and depth-TEST on so the 3D world still occludes the sprite. The whole sprite composites after opaque geometry, so it reads as a solid character sitting IN the scene — occluded by terrain in front of it and drawn over terrain behind it — rather than a floating overlay.

This is a pure SCALAR trait (see the traitScalarFields guard); it carries only presentation knobs — the rig lives on the sibling SkinnedSprite2D.

Built with Modoki.