spriteforge/docs/blender-backend.md

78 lines
3.5 KiB
Markdown
Raw Normal View History

# Blender backend
The Blender backend launches an external Blender process without a UI:
```text
blender -b rig.blend -P blender_driver.py -- --request request.json ...
```
No rendered image enters an agent context. The driver writes JSON metadata and
NumPy RGBA, view-normal and Z arrays into a temporary directory; the parent
process consumes them and deletes the directory.
Blender 5+ pass extraction uses a temporary compositor multi-layer EXR because
that release removed the legacy `Image.layers` API. Official Blender builds
bundle OpenImageIO, so this compatibility path adds no Python dependency to the
host project. Blender 4 and older retain the direct Render Result path.
```yaml
demo_actor:
backend: blender
rig: rigs/demo_actor.blend
parts: {body: BodyMesh, head: HeadMesh, weapon: WeaponMesh}
anims: [idle, walk, attack]
dirs: 8
fps: 12
params:
render_size: 192x192
ortho_scale: 4.0
elevation: 35.264
samples: 16
# Manifest clip names can map to arbitrary actions in a reusable source rig.
actions: {idle: Idle_Loop, walk: Walk_Loop, attack: Pistol_Shoot}
# Sample the full source actions into compact pre-rendered sprite cycles.
frames: {idle: 4, walk: 8, attack: 6}
animation_fps: {idle: 8, walk: 12, attack: 12}
loop_sampling: {idle: true, walk: true, attack: false}
direction_offset_deg: 90
camera_target: [0, 0, 0.9]
model_rotation_deg: 0
# One logical Z-sorted layer may contain several Blender objects.
part_members: {body: [BodyMesh, HelmetMesh]}
# Or select every renderable object whose name starts with this prefix.
part_prefixes: {body: actor_body_}
```
`parts` values are directly renderable Blender object names. Each object is
rendered alone while armatures remain active. The camera is orthographic;
direction zero looks from +X toward the origin and subsequent directions rotate
counter-clockwise around world Z.
For every animation/direction/frame, pairwise Z comparisons create a
back-to-front layer permutation. If both relative orders occur over a material
fraction of overlapping pixels, `sf validate` reports the exact asset,
animation, direction, frame and layer pair and advises splitting the component
into passes. Cycles fall back to median depth and also produce a warning.
Blender Z is quantized per frame into 8 bits while `depth_min/depth_max` preserve
the camera-space range in world units. Normal-pass X/Y values are stored
directly; positive Z is reconstructed by the runtime.
The executable is resolved from `params.executable`, then `BLENDER_BIN`, then
`PATH`. On Windows SpriteForge also discovers official versioned installs under
`Program Files/Blender Foundation`, because the Blender installer commonly does
not add itself to `PATH`. Other parameters
are `render_size`, `samples`, `ortho_scale`, `elevation`, `camera_distance`,
`engine`, `timeout_seconds`, `depth_epsilon`, `crossing_ratio`, `dither`,
`actions`, `frames`, `loop_sampling`, `direction_offset_deg`, `camera_target`,
`model_rotation_deg`, `part_members`, and `part_prefixes`.
Unknown parameters are rejected.
For separately built paper-doll equipment, add the reserved
`paperdoll_layer` tag. Its pivot is intentionally inherited from the body and
may lie far outside the small layer bbox; `sf validate` suppresses only that
specific heuristic while still checking hashes, streams, frames and durations.
Tags and palette metadata are excluded from the expensive backend-input hash,
so reorganizing or retagging a library updates the catalog without rerendering
unchanged Blender frames.