Command line

pxr renders the same sprites as the app (the same project gives the same pixels) and suits build scripts and batch work. pxr help prints every command and option, pxr help COMMAND one command with its options, and pxr --version the version. A command line it cannot read says what is wrong, how that command is used, and to see pxr help COMMAND.

Common tasks

# One sprite, 64 px, three-quarter view
pxr render knight.glb -o knight.png

# Every clip, 8 sides, 12 fps, all export formats
pxr render knight.glb --clip all --ring 8 --export all -o out/knight.png

# Two clips, hand-picked frames for the attack
pxr render knight.glb --clip walk --clip attack --keys 0,0.2,0.35,0.6 -o out/knight.png

# A different look
pxr render knight.glb --preset selout --view isometric --light -30,50 --bands 4 --aa 1 -o knight.png

# Your palette
pxr render knight.glb --palette my-palette.hex -o knight.png

# Save the settings as a project, then render it again later (or open it in the app)
pxr render knight.glb --clip all --ring 8 --export aseprite -o out/knight.png --save-project knight.pixor
pxr render knight.pixor

# A whole folder, every clip of every model, with a report
pxr batch models/ --recursive -o out/ --ring 8 --export all

A project is its own recipe: rendering one reads the look and the scene from it, and takes from the command line only where the files go (-o, --export, --names, --scale, --anim-scale, --no-recipe, --debug), the extra layers (--paper-doll, --piece, --parallax, --haze), the backend and which Asset pipeline it writes. Any other flag is named in a warning, since it would change nothing: set it in the project with pxr project set.

Which Asset pipeline. pxr render project.pixor writes the project’s first Asset pipeline, as the app’s Export window writes the one picked in it, which starts at the header’s; --pipeline NAME writes another, and --pipeline all every one. A file is named the same whichever is written, so --pipeline all writes exactly the files the pipelines write one by one. pxr names, pxr watch and pxr run take --pipeline too.

Where files go. -o PATH (or --out PATH; every command takes both) is where a command writes. For a command that writes one file — render, stylize, effect, voxels, tiles, shapes, rebake, project blueprint, project set (the project’s sheet) — it is that file, or a folder the file goes into under its own name when the path ends in / or is a folder that exists: pxr render knight.glb -o out/ writes out/knight.png. A project rendered with -o writes every file into that folder (D51): the project’s sheet folder (out/ by default) becomes it, a path under it keeps its place below, and any other path its last part — archives, animations and icons included. The app’s Export window runs exactly pxr render PROJECT --pipeline NAME -o FOLDER, on a copy of the project as it is open, saved or not, named as the project; --recipe-project FILE.pixor (or none for an untitled project) is what the copy’s recipe names instead of the copy. The commands that write many files — batch, golden, gbuffer, stages, icons, run --jobs — take a folder.

Clip files next to a model named <model>@<clip>.<ext> are added automatically. Other files with the same skeleton can be added with --anim FILE.

Commands

Command Does
pxr render MODEL | PROJECT.pixor a sprite, or a sheet when clips, sides or actions are asked for; a project writes one sheet per group of cameras framed together
pxr stages MODEL -o DIR a picture of every pipeline stage (albedo, normals, depth, coverage, light, bands, edges, lines, cleanup, lint…), --only edges,lines for some; --node N instead writes what node N of the Style graph makes as KIND.still.png (a CRT’s screen): a still, never a sprite or a sheet
pxr batch FOLDER -o DIR every model in a folder (.gltf, .glb, .fbx, .obj, .vox; --recursive for subfolders); failing models are reported and skipped; DIR/report.json; --blueprint B.pixorblueprint runs each model through one blueprint; --cache DIR serves the models that have not changed (see libraries). In the app, drop the folder on the window
pxr run BLUEPRINT.pixorblueprint --in model=M a blueprint with its inputs filled in (see the Scene graph); --set NODE.SETTING=VALUE changes one setting, --set PIPELINE/NODE.SETTING=VALUE the same in one pipeline alone (--set hold.times=4 every Asset pipeline’s Hold node); --jobs TABLE.csv -o DIR runs one row of a table per render; --pipeline NAME|all as for render
pxr rebake SHEET.aseprite render the project again into a sheet you painted on, keeping your layers and your edits (see Aseprite)
pxr cache stat|gc DIR what a cache holds; gc --keep 20GiB removes the renders used least recently until it fits
pxr golden CASES.txt render test cases and compare them with stored images (see below); --only TEXT runs the cases whose name holds it, --tolerance F accepts a fraction F of differing pixels, -o DIR (default target/golden) is where results go; --graph renders them through the look’s node graph instead — the preset’s as the shipped Pixelate group — and --flat through the same graph with every group flattened to atoms; both must match the same images. --cache DIR writes each case’s sprite into --out through the cache and compares that file, served or rendered; --no-cache writes the same files without it
pxr bench MODEL measure every budget in tests/budgets.txt and say met or MISSED; --rounds N (default 10) averages the timings over N runs; --from INFO.json adds the ones the app measures
pxr import MODEL --report what happens to the file on import, without rendering it: found, corrected and why, suggested, missing, triangles per sprite pixel; --json for a batch that finds the broken files first
pxr reference SPRITE.png settings read off a sprite you have: palette, size, outline, bands, hue shift, dither, each with why; pxr project set P --match-sprite S.png sets them
pxr voxels MODEL -o OUT.vox the model as voxels, --height tall (1 to 256), in the look’s palette: a MagicaVoxel file; --stack also writes a sprite stack (see Voxels and sprite stacks)
pxr nodes [--graph G] [--json] every node of the four graphs (style, action, scene, asset) as this Pixor has them: what it does, what it takes and gives, each setting with its range and default; --json for tools (the website’s node reference is built from it)
pxr inspect FILE what the importer found in any file Pixor imports (the formats, also in pxr help inspect): for a model, objects, materials, bones, clips, warnings; for a .vdb, its grids and their size; for a picture, its size; for a palette, its colours
pxr gbuffer MODEL -o DIR the raw render targets, for bug reports; the .pxrg dump carries the mesh’s edges when the look draws them
pxr stylize DUMP.pxrg run the pixel passes on a saved render, wireframe included
pxr diff OLD NEW two export folders (or two sheets): which files are new, gone or differ, by how many pixels, and, from each file’s recipe, which setting or input caused it; --all lists the identical files too, --exact exits 1 on any change. Two .pxrg dumps are compared target by target (--depth-tolerance EPS, --samples N)
pxr adapters the GPUs Pixor can use
pxr doctor what this machine can render with, and whether its GPU agrees with the CPU reference
pxr project new|set|show PROJECT.pixor create, change or print a project from scripts and tools: --name NAME names it (the header’s name, not the file’s; show prints it with the rest)
pxr project key PROJECT.pixor TARGET CHANNEL one key of a clip made in Pixor (--clip, --frame, --value, --how, --remove…), so a script can build a clip
pxr project bake PROJECT.pixor CLIP a clip of the model’s own as a clip made in Pixor, every bone keyed at every frame (--as NAME, --fps F)
pxr project scene PROJECT.pixor [NODE] the scene graph a node at a time: ring, row, grid, scatter, look-at, vary… added to the end of the chain, each node’s options named after its settings (--count, --radius, Vary’s --size, a Scatter’s --box, Displace’s --bumps and Height field’s --hills in metres, Subdivide’s --times, Select’s --how); a node that takes nothing in (object, import) starts the chain in place of the bare import, and goes beside a longer chain, merged with it; no node prints it
pxr project blueprint PROJECT.pixor -o B.pixorblueprint the project as a blueprint, its model, palette, prop and volume files lifted out into named slots
pxr style new KIT --from PROJECT save a project’s first Style as a Style kit
pxr kit show FILE.pixorkit what a kit holds: a group of nodes, a Style, a preset or a pipeline
pxr names PROJECT.pixor [--names T] [--pipeline NAME|all] the names the project will write and every frame’s id, without rendering, each render’s files by their own path; two frames on one name, two renders on one file (would be written twice), or two files on one path (a paper doll’s base and the light kit’s, a palette variant and a layer), are an error here rather than a lost file later
pxr graph list|set|add|drop|wire|save|swap|flatten|extra FILE --which scene|action|style|asset any of the four graphs from a script. --pipeline NAME picks which: an action by its name, a Style or an Asset pipeline, the first unless named. Print it, change one setting, add a node into the chain (or beside it with --alone, wiring others in with --in SLOT=NODE), drop one, join two with wire --from N --to M --slot S, save it as a kit (save -o KIT.pixorkit: the Style graph whole, the scene, action or asset graph as one node, --as-pipeline a whole Asset pipeline another project uses with pxr project set --use-pipeline), put a node kit in as a group (add --kit KIT) or in place of a node (swap --kit KIT), or write a graph out with its groups expanded; extra --node N --name LAYER makes a Style node’s picture a layer of the exports too, and --drop stops it. --node (and --set NODE.SETTING in pxr run) names a node by its number, its kind, a group’s name, what its Called says (an Image file, a Sheet) or the name it was given in the app (F2); an object node is the model (of=model), and an item, a shape or a picture is a node of its own. An Asset graph’s sprites, frame-range and hold nodes are set like any other (--node sprites --set action=walk,Static — action=every-one-except-static is a new node’s, action= every action, Static too — --set smart=6, --node frame-range --set from=2 --set to=5, --node hold --set times=2); an action’s — clip, bob, spin, merge… — by kind or number, and one added without --alone plays at once, merged with what is there. In the Style graph a node goes in wired to nothing, --in SLOT=NODE and wire take it on. An edit that would leave a graph unable to run is refused, the file left as it was (see the Scene graph, the asset graph and nodes)
pxr shapes [PROJECT] -o OUT.glb write the shapes built in the app out as geometry, for a modeller or an engine
pxr icons MODELS... -o DIR inventory icons with an atlas per size; rarity from each file’s name, and --save keeps a recipe to run again (see Export)
pxr audit FILE|FOLDER... [--style KIT] check that exported sheets match: preset, light rig, view, pitch, light, bands, lines, palette and pixels per metre, from each file’s recipe, and with a Style kit that every colour is in its palette (exit 1 if not)
pxr watch PROJECT.pixor export again whenever the project, its model or its palette change
pxr effect KIND[:FRAMES] a pixel effect on its own: explosion, hit-spark, slash, magic-burst, heal, portal, smoke-puff, dust, fire-loop, rain, snow, fireflies, falling-leaves
pxr console list|check SHEET.png the console modes, or whether a sheet fits one (exit 1 if not); the console comes from --console or the sheet’s recipe

Render options

Option Default
--view VIEW the preset’s side, three-quarter, isometric or top-down
--pitch DEG the view’s degrees below the horizon
--yaw DEG 0 turn a single sprite, or the one side of a sheet of one
--camera GENRE a game’s camera: platformer, fighting, beat-em-up, adventure, top-down-rpg, action-adventure, isometric, tactics, strategy, racing, top-down-shooter, shmup, icon (view, pitch, turn; size and sides unless given)
--camera-yaw DEG 0 turn the camera about the model, every side
--size N 64 fit into N x N, 4 to 2048; --size 960x540 fits into a canvas that wide and high (a title image, a background)
--pixels-per-metre F fixed pixels per metre instead of --size, 0.5 to 4096 (the app’s Pixels/m)
--up AXIS decided on import the axis that points up in the file (y, z, -z, x, -x, -y): for a model exported lying down
--import-scale F, --import-offset X,Y,Z decided on import the unit and the move, said by hand
--no-import-fix render the file exactly as it is, with nothing corrected
--samples N 4 samples per pixel along each side, 1 to 8 (the app’s Samples)
--light AZ,EL -45,45 key light relative to the camera
--light-space S camera world: the light stays put in the scene instead of following the camera
--fill F the preset’s fill light strength, 0 to 1
--no-shadow no cast shadows
--bands N the preset’s light bands, 1 to 4
--palette P a .hex, .gpl or .png file, or a built-in palette: pixor-16, pixor-8, dusk-12, forest-12, desert-12, ice-10, mono-8
--aa N 0 anti-aliasing: 0 off, 1 silhouette, 2 every line
--match-space S oklab how colours find their nearest in a fixed palette: oklab, srgb or weighted
--dither-pattern P bayer bayer (the crosshatch) or blue-noise (scattered evenly); either stays on the surface as the model moves
--even-stairs off straight silhouette edges with even steps (2, 2, 2 rather than 3, 1, 2)
--smear PX 0 smear frames, 0 to 64: what moved PX pixels or more since the frame before trails behind
--nudge X,Y 0,0 move the model a fraction of a pixel on the grid (each -0.5 to 0.5); only the sampling changes
--foot-plant off a humanoid’s planted feet on the same pixel row in every frame of a clip
--preset NAME clean clean, selout, retro4, flat, wireframe, or a saved preset kit (.pixorkit)
--style KIT a Style kit (.pixorkit): a whole Style (pxr style new, a Style’s Save kit…), its Style graph too, or a Style graph alone (pxr graph save --which style); later flags still change it. In a golden case file, relative to it. pxr icons and pxr audit take the same
--dither F 0 ordered dithering between neighbouring light bands, 0 to 1
--line-colour HEX the preset’s colour of Dark lines, #rrggbb (automatic palettes only)
--no-lines MATERIAL no lines around this material (repeatable; pxr inspect lists them)
--crease-angle DEG 55 how sharp a fold draws a crease line, 1 to 179
--depth-step PX 2.5 the depth step, in pixels, that draws an inner line, 0.1 to 40 (the app’s Depth step)
--shortest-line N 3 the shortest inner or crease line kept, 0 to 16 pixels (the app’s Shortest line)
--no-part-lines no lines between touching parts without a depth step
--outline-inside the silhouette on the sprite’s own edge
--convex LINE none a light line on folds that bulge towards the camera: none, dark or highlightN
--no-material-channels ignore a glTF material’s metal, roughness, emissive, unlit and see-through, and shade from its colour alone
--backend B auto auto, vulkan, metal, dx12, gl, webgpu or cpu (see Choosing a renderer)

Light and colour options

Option
--rig NAME a light rig: noon, dusk, torchlight, moonlight or studio
--cycle MATERIAL cycle this material’s colours on a --colour-cycle action (repeatable)
--team MATERIAL|#RRGGBB the team colour: a material, or every ramp of that colour’s hue (repeatable); --variant team:blue recolours only it
--console C a console mode: gameboy, nes, pico8, tic80, c64 (see Console modes)

Animation options

Option
--clip NAME a clip to render (repeat for more), or all
--anim FILE also use the clips of FILE
--ring N sides, counter-clockwise from the front (1 to 64, default 1), named South, Southeast, East…: a camera each, sharing one size, in one sheet
--sides A1,A2,... a side at each angle instead, in degrees (0 = front, 90 = facing right)
--fps F frames per second of clip time (default 12), the cut of every Sprites node
--keys T1,T2,... hand-picked clip times, in seconds, the cut of every Sprites node
--clip lib:NAME a motion library clip fitted to the model’s skeleton: idle, walk, run, jump, attack, hit, death
--parallax N split the picture by depth into N layers (2–8) for scrolling backgrounds (see Scenes of several models)
--haze #RRGGBB the colour far parallax layers fade towards; none keeps every layer on the palette as it is
--spring NODE[:S,D,G] NODE and what’s below it swing with the motion: stiffness, damping, gravity (repeatable); in a project, a Spring node of the scene graph
--smart-frames N keep N frames of each clip, chosen from its poses (each held until the next), the cut of every Sprites node
--root-motion M keep (default), in-place (pin the root bone horizontally) or in-place-sway (remove only the clip’s net travel)
--turntable N add an action of N frames turning the model once
--turntable-seconds S how long that turn takes (default: N frames at --fps)
--motion M[:N[:A]] add a loop: spin, bob, swing, pulse, squash or flicker, N frames, strength A (for spin, the part of a turn the loop makes: spin:8:0.125 turns a gem of eight facets by one facet, a seamless loop)
--colour-cycle N add an action of N frames turning the cycling materials’ shades
--prop FILE:BONE[@at=X,Y,Z][@turn=X,Y,Z][@scale=S][@grip=NODE] attach another model to a bone, held by its grip, moved and turned on the bone’s axes (see Props on bones)
--shape SPEC add a shape: [NAME=]KIND[:SIZE[:AT[:#RRGGBB[:TURN]]]], e.g. box:1,0.5,1:0,0.25,0:#c86432, or wheel=cylinder:0.5,0.2,0.5:0.7,0.25,0.5:#14101c:90,0,0 for a named wheel on its side (repeatable). KIND is box, sphere, cylinder, cone, torus, plane, capsule, wedge, pyramid, prism, stairs, arch or letters (pxr help render lists them from the same list the flag reads): letters is the font’s pixels extruded into blocks, spelling PIXOR, or a project’s words, pxr project set --add-shape letters --words WORDS --font NAME (render takes no --words)
--volume SPEC add a volume: puff, flame, cloud, mist or a .vdb path, then [:SIZE[:AT]], then [:FRAMES[,EVERY[,LOOP]]] for a numbered .vdb sequence, then @BONE to be carried by a bone or @effect:N by the Nth effect’s emitter (Volumes)
--wire LINE the wireframe look: none, dark or seloutN, with --wire-fill, --wire-hidden, --wire-angle (0 to 180), --wire-all-edges and --wire-glow MATERIAL (settings)
--light-sweep N add an action of N frames moving the light
--effect KIND[:N] add a pixel-effect action of N frames (see pxr effect), with --effect-size, --effect-energy, --effect-seed, --effect-at X,Y,Z, --effect-bone BONE, --effect-clip CLIP, --effect-hit FRAME and --effect-alone
--hitbox PART, --hurtbox PART, --socket BONE boxes and bone positions per frame in the JSON (repeatable; see Export)
--paper-doll, --piece NAME:PARTS paper-doll layers (see Export)
--item MODEL@X,Z[,YAW,SCALE[,LAYER]][:CLIP[,PHASE]], --ground W,D[,#RRGGBB] more models beside the first, each an Item node of the scene graph in a project, and a ground plane under them (see Export)
--chunks COLSxROWS write a big map as chunks with exact seams; --chunk-margin N (default 8)
--max-flicker F warn above this flicker share (e.g. 0.01); in a golden case, fail
--require-visible OBJECT warn if OBJECT disappears in any frame

Export options

Option
--export LIST comma-separated or repeated: png, json, aseprite, normal, depth, emission, layers, palette, godot, gif, apng, light-kit, p8, report, video, or all (every one but p8 and video, which are written only when named); the PNG is always written (see Exporting). render, batch, run, watch, project set and tiles (with its own formats) read it the same way
--layout L grid (a row per action and side, the default) or strip
--padding N transparent pixels between cells, 0 to 256 (default 0)
--extrude N repeat cell edges N pixels outward, 0 to 64 (default 0)
--pot power-of-two sheet size
--godot-path RES where Godot finds the sheet (default res://<png name>)
--anim-scale K integer scale of the GIF and APNG files, 1 to 16 (default 1)
--video-scale K, --video-fps N, --video-background #RRGGBB how the videos are written: scale 1 to 16 (default 4), 1 to 100 frames a second (default 30), what the sprite is drawn over (default black)
--trim cut each cell down to its pixels (the JSON and Godot file keep the placement)
--dedupe store identical frames once
--max-width N start a new row before the sheet gets wider than N pixels (0 to 65536; 0: no limit)
--columns N N frames per row, every clip running on after the last: a contact sheet
--max-height N split a sheet taller than N pixels into pages, whole clips to a page (NAME_1.png, NAME_2.png; 0 to 65536)
--variant NAME also export a palette variant (repeatable): an effect such as hit-flash or night, hue:DEG, team:COLOUR (a name or #rrggbb; needs --team), or palette:NAME|FILE; adds an index sheet and a lookup texture
--shadow KIND also write name_shadow.png: contact or drop
--names TEMPLATE how the files and the JSON keys are named: a pattern over {project}, {object}, {action}, {side}, {layer}, {set}, {size}, {index} and {ext}, with {index:3} padded to three digits (see Exporting)
--no-recipe don’t store the recipe (how the sheet was made) in the PNG and .aseprite
--scale K upscale the PNG K times (previews only; not with other formats)
--save-project FILE.pixor also write this command line as a project
--debug DIR render targets, palette, lint and flicker images

Golden tests for your own pipeline

A cases file lists one render per line: a name, a model or project path (relative to the file) and options.

hero-walk   models/hero.glb --clip walk --ring 8 --max-flicker 0.02
hero-proj   hero.pixor

pxr golden cases.txt --bless stores the results as NAME.png next to the file; later, pxr golden cases.txt fails when any pixel changes, when a sprite has lint findings (stray pixels, L-shaped line corners, 2 px lines), or when a --max-flicker or --require-visible check fails; the error says which cases’ pixels differ (their NAME.actual.png and NAME.diff.png are in target/golden) and which failed their checks. --bless stores the images even when a check fails, and exits 1 naming those cases. Use it to notice when a model change alters your sprites.

A library, not a run

A studio renders the same five thousand sprites again because one ramp moved. Three things make that a decision rather than an overnight job.

A cache that outlives the process. --cache DIR on pxr batch and pxr run keeps every render it makes, with the files it read and a hash of what was in them: the model, the clip files beside it, the textures a .gltf points at, palettes, kits, pictures and volumes. The next run serves every render whose files still hash the same, and renders the rest.

pxr batch models/ --cache .pxrcache --out out/     # renders what changed
pxr cache stat .pxrcache
pxr cache gc .pxrcache --keep 20GiB                # least recently used go first

The cache is never the source of truth: --no-cache gives the same bytes, a stored file that does not hash to its name is rendered again rather than served, and a new build of Pixor starts a new cache rather than trusting the old one.

A job file. A table with one row per render, one column per slot of the blueprint, and optionally name (the row’s folder), out (its sheet under --out) and NODE.SETTING columns (a --set for that row):

model,name,palette,sprites.fps
heroes/knight.glb,knight,palettes/steel.hex,8
heroes/mage.glb,mage,palettes/robes.hex,

Here sheet.pixorblueprint comes from pxr project blueprint sheet.pixor, a project of heroes/knight.glb with a palette, so its slots are model and palette; the knight is cut at 8 frames a second and the mage, its cell empty, at the blueprint’s own rate. Every row writes out/NAME/NAME.png.

pxr run sheet.pixorblueprint --jobs assets.csv --cache .pxrcache --out out/ --jobs-report report.json
pxr run sheet.pixorblueprint --jobs assets.csv --cache /shared/cache --out out/ --rows 400..   # the second machine, of 800 rows

Paths are relative to the table. A row is exactly pxr run with the row’s --in and --set added, so a row that goes wrong can be run on its own. A failing row never stops the others: the report lists every row with whether it was rendered, served from the cache, or failed and why, and the job exits 1 at the end if any did.

Budgets as flags. --max-pixels N, --max-memory SIZE and --max-time DURATION hold per render (per row, per model). What the plan already knows — how many pixels a sheet will have, about how much memory it will hold — is checked before anything is drawn; time and memory are checked between frames. Going over one exits 6 with what it was and where it stopped; in a job the row fails with that reason and the others go on.

pxr run sheet.pixorblueprint --jobs assets.csv --out out/ --max-memory 1.5GiB --max-time 5m --max-pixels 16M

Long clips. A clip’s frames are drawn, then finished together, since the passes that keep a clip from flickering look along it. What they read is kept within 512 MiB (half of --max-memory when it is given), a few sides at a time; a clip too long for even one side is kept on disk while it is drawn — under ~/.cache/pixor/spill, or PXR_SPILL_DIR — and read back as needed: the same pixels, slower, and the folder goes when the render does.

Exit codes

Code
0 success
1 a failed render, export, batch model, job row or golden case
2 a usage error: the message, the command’s usage and see pxr help COMMAND on stderr
3 an input that couldn’t be read: a model, project, palette, kit, case file or dump
4 a backend asked for by name that is not there
5 an output that couldn’t be written: a file or a folder
6 over a --max-pixels, --max-memory or --max-time budget
7 a re-bake that kept paint it will not decide about alone (--resolve keep|pixor)

No GPU at all is not an error: Pixor draws on its own rasterizer instead. An error says what was wrong the same way everywhere: --flag takes A to B, got X.

Choosing a renderer

--backend auto|vulkan|metal|dx12|gl|webgpu|cpu says who draws the geometry. The look — every pixel pass — is worked out on the CPU whatever this says.

  • auto (the default) takes whatever the machine has, and falls back to the CPU when no adapter works.
  • cpu is Pixor’s own rasterizer. It needs no adapter and no driver, it is in the binary, and it draws the same pixels on every machine — the portable choice for an asset pack or a CI build.
  • A backend named and not there is an error (exit 4), because silently rendering somewhere else is worse than saying so.

Every export’s recipe records which backend drew it. pxr doctor prints the adapters found, the one Pixor would pick, the driver versions, and whether that backend draws the same picture as the CPU reference:

adapter  NVIDIA GeForce RTX 3070 Ti (Vulkan, DiscreteGpu) driver NVIDIA 610.57.04
backend  vulkan (NVIDIA GeForce RTX 3070 Ti (Vulkan, DiscreteGpu))
agrees   vulkan vs the CPU reference: coverage 0.00%, ids 0.00%, albedo 0.00% (allowed 1.00%); normals within 0.028 deg, depth within 9.5e-7

In the app the same choice is Preferences › Renderer › Draw sprites on the CPU, or for one session pixor --backend B with the same names as pxr (cpu, auto, or a GPU backend by name), which leaves the preference as it is. Each keeps what it drew: switching to the other renders the frames again, and switching back brings the first one’s frames back without a render, as long as nothing about the scene changed.

For tools and scripts

Add --json to any command: standard output then carries one JSON event per line (progress, wrote, warning, error, done) and the readable log moves to standard error. The commands that read rather than write give what they print as one event too: inspect, adapters, tiles --list (terrains), graph list and graph flatten, and diff of two dumps.

What this page describes is in the full version; the free browser demo keeps to the default look and the PNG sheet.

Try in browser Get Pixor