Context
With Sprite3d (#1513), spritesheet/atlas characters can billboard (face the camera) in a Camera3d scene — enabling 2.5D with an orbiting/pitching camera. Spine skeletal characters can't do this today.
A Spine character renders through the plugin's own SpineBatcher with a 2D vertex layout (a_position(2), z = 0) transformed by the engine MVP_MATRIX. Under cameraClass: Camera3d it is perspective-projected, but the skeleton is a flat object in its XY plane — it does not billboard. If the camera orbits/pitches, the Spine character goes edge-on (like Sprite3d with billboard: false).
So Spine works for camera-fixed / XY-slice 2.5D (side-scroller, static-camera Paper Mario), but not for a scene where the camera turns.
Proposal
Add a billboard mode to the Spine renderable (mirroring Sprite3d's billboard: false | "cylindrical" | "spherical"):
- After
computeWorldVertices produces the skeleton's 2D world vertices (relative to the skeleton origin), map each (x, y) onto a camera-facing 3D basis before projection:
world = origin + right·x + up·y, where right/up come from the active Camera3d (see Camera3d.getBasis / Sprite3d._projectVerticesWorld).
"cylindrical" → up = WORLD_UP, right = forward × up (upright, the 2.5D default).
"spherical" → camera up/right.
- Requires the spine shader/path to accept 3D positions (or fold the billboard transform on the CPU and keep feeding the existing MVP). Capture the active
Camera3d from the per-draw viewport (as Sprite3d does), and no-op under Camera2d.
Considerations
- The plugin already owns its vertex stream (
SpineBatcher / SkeletonRenderer), so the billboard transform is a localized change to where world vertices are computed.
- Keep the default (flat, current behavior) so existing 2D / camera-fixed usage is unchanged.
- Mesh attachments (deformed) and region attachments both flow through the same world-vertex step, so both billboard for free.
- Depth/cull: the skeleton billboards around the renderable's
pos/depth.
Acceptance
- A Spine character with
billboard: "cylindrical" stays facing an orbiting/pitching Camera3d and upright.
- No change to 2D / Camera2d rendering.
- Verified in the spine example under a
Camera3d.
Refs: Sprite3d billboard math (#1513), Working in 3D, 2.5D Games. Counterpart to the Sprite3d billboard feature, for skeletal characters.
Context
With
Sprite3d(#1513), spritesheet/atlas characters can billboard (face the camera) in aCamera3dscene — enabling 2.5D with an orbiting/pitching camera. Spine skeletal characters can't do this today.A Spine character renders through the plugin's own
SpineBatcherwith a 2D vertex layout (a_position(2), z = 0) transformed by the engineMVP_MATRIX. UndercameraClass: Camera3dit is perspective-projected, but the skeleton is a flat object in its XY plane — it does not billboard. If the camera orbits/pitches, the Spine character goes edge-on (likeSprite3dwithbillboard: false).So Spine works for camera-fixed / XY-slice 2.5D (side-scroller, static-camera Paper Mario), but not for a scene where the camera turns.
Proposal
Add a billboard mode to the Spine renderable (mirroring
Sprite3d'sbillboard: false | "cylindrical" | "spherical"):computeWorldVerticesproduces the skeleton's 2D world vertices (relative to the skeleton origin), map each(x, y)onto a camera-facing 3D basis before projection:world = origin + right·x + up·y, whereright/upcome from the activeCamera3d(seeCamera3d.getBasis/Sprite3d._projectVerticesWorld)."cylindrical"→up = WORLD_UP,right = forward × up(upright, the 2.5D default)."spherical"→ cameraup/right.Camera3dfrom the per-drawviewport(asSprite3ddoes), and no-op underCamera2d.Considerations
SpineBatcher/SkeletonRenderer), so the billboard transform is a localized change to where world vertices are computed.pos/depth.Acceptance
billboard: "cylindrical"stays facing an orbiting/pitchingCamera3dand upright.Camera3d.Refs:
Sprite3dbillboard math (#1513), Working in 3D, 2.5D Games. Counterpart to theSprite3dbillboard feature, for skeletal characters.