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 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"):
world = origin + right·x + up·y, where right/up come from the active Camera3d (see Camera3d.getBasis / Sprite3d._projectVerticesWorld).
Considerations
Acceptance
Refs: Sprite3d billboard math (#1513), Working in 3D, 2.5D Games. Counterpart to the Sprite3d billboard feature, for skeletal characters.