# 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.