Pictures and words

Two kinds of content do not come from a 3D model: images you already have, and words. Both go into the pipeline at the start, as parts of the scene, not as a paint-over at the end — so lines, outlines, occlusion, shadows and the palette all work on them without a single new pass.

A picture in the scene

In the Scene step, the Outliner’s + menu, A picture › From an image file…, puts the image on a plane: billboard foliage, a distant tree, a sign, a lit window, a painted backdrop. It is a part like any other, with a row in the outliner, a Transform block and its own settings in the Inspector, and it is a Picture node of the Scene graph: the row and the node are one thing, its settings are on the node too, and a Row or a Ring after it repeats it.

Setting What it does
Facing Upright, Flat on the ground, Sprite (in sprite space) or Decal (both below).
Mirrored Flipped left to right. It costs nothing and needs no second file.
Tilt Tilted back, in degrees.
Quarter turns Turned about the upright axis. Only quarters: anything between would need filtering, and filtering blurs pixel art.
Metres a pixel How much of the world one image pixel covers.
Take the scene’s light Off by default: a picture is usually already shaded by whoever drew it, and shading it again gives it two light directions.
Lines around it As around any other part.
Cut out under Pixels this transparent are holes, so cut-out foliage works.
Counts for framing Off for a label: a “GAME OVER” banner over a knight should not shrink the knight.
Parallax layer Which layer it belongs to, counted from the back, so drawn art and 3D share one stack of layers.

Two buttons make it crisp, and both use the camera that is shown:

  • Whole pixels sizes it so one image pixel covers a whole number of sprite pixels. Anything else resamples.
  • Face the camera tilts it by that camera’s pitch. A camera that looks down foreshortens an upright card, which drops rows and turns letters to mush.

From the command line:

pxr project set game.pixor --add-picture bush.png:-1.1,0,-0.3:0.05
pxr project set game.pixor --add-picture bush.png:1,0,0.2:0.035 --mirror
pxr project set game.pixor --add-picture sky.png:0,0,-8:0.2 --layer 0 --unframed

In sprite space a picture is not a card at all. After the scene is drawn, its image is put on the sprite’s own pixels where its place lands: so it faces every camera — a billboard, the same bush from every side of the sheet — and each picture pixel is a whole number of sprite pixels (Sprite pixels, 1 by default) whatever the camera, which is what exact letters need. It keeps the depth of its place, so what stands in front of that place still hides it, and it is a part like a card is, so lines, cleanup and the palette treat it as one. It stands on its place, the middle of its bottom edge, as an upright card does; its place counts for framing when Counts for framing is on.

pxr project set game.pixor --add-picture bush.png:-0.8,0,1.1 --facing sprite
pxr project set game.pixor --add-text "+12" --text-at 0.25,0.35,0.9 \
  --facing sprite --picture-pixels 2 --font pixor-5

A decal is painted onto whatever surfaces lie where an upright card would stand, within Reach of its plane (in metres, either side): a sign on a wall, a crack, a scorch mark; tilted back a quarter turn, a puddle or a rug on the ground. It has no geometry and no part of its own: where a surface drawn in the frame falls inside its box, the surface takes the picture’s colour there and keeps its own light, lines and outline, so a sign on a wall is shaded as the wall is.

pxr project set game.pixor --add-text "OPEN" --text-at 0,0.3,0.45 \
  --text-size 0.03 --facing decal --decal-reach 0.25 --font pixor-5

On the palette. A picture is taken to the project’s palette on import when the project has a fixed one, and the render says how many of its pixels moved:

picture  bush: 330 of 330 pixels moved to the palette (100.0%)

--keep-colours leaves them as they are. A project with an automatic palette has none to snap to yet — its palette is built from what is in the scene, cards included — so the pipeline does it further down.

PNG or JPEG: a cut-out wants a PNG’s transparency, a photograph for a background is a JPEG more often than not.

A picture of several frames. An image of frames side by side — a torch flickering in four, a flag waving in six — is one picture with Frames set (--picture-frames 4). The card is one frame wide and shows the first; a clip made in Pixor keys which one it shows (picture:NAME, frame), so a painted flicker plays in the sheet like anything else. Mirrored flips each frame where it is, keeping their order.

The frames can be files of their own instead of one strip — A file a frame, --picture-sequence: the file named is the first, flame_0001.png, and the numbers after it follow, padded the same way; every frame is the first one’s size. And they can play by themselves — Plays by itself, --picture-plays: one a frame, round and round, under whatever the sheet shows, unless a clip keys which one shows. With nothing else moving, they are the animation, a loop called picture.

pxr project set game.pixor --add-picture flame_0001.png:0.7,0,0.8 \
  --picture-frames 4 --picture-sequence --picture-plays --facing sprite

A sky

A sky goes behind everything, in the pixels nothing was drawn on — so the model keeps the outline it has without one. It is bands, a top colour and a bottom one and a whole number of steps between, never a blend; or a painted picture, anchored at the top of the frame and centred, a whole number of sprite pixels to a picture pixel, its edges carried on past its sides. Its colours are in the palette exactly, so the bands are the colours you asked for. It is part of the world: the Outliner’s + menu, The world › Sky, or pxr project set game.pixor --sky '#2c3e6b,#9dbcd9,4' (or --sky dusk.png:2), and --no-sky.

Words in the scene

A text card is a card whose image is drawn rather than read, so words get a card’s facing, turns, scale, cut-out and lines for nothing. In the app, the Outliner’s + menu, A picture › Text, puts one above the model — a Text node of the Scene graph — a pixel of the font to a pixel of the sprite; its Inspector holds the Words, the Font, the Text scale, the Ink and an Outline, and the card’s own settings below them. Words are a label, in the app as from a script: they do not decide how the shot is framed, so the app puts them just inside the top of the frame; turn Counts for framing on to frame round them instead. From a script:

pxr project set game.pixor --size 128
pxr project set game.pixor --add-text "GAME OVER" \
  --text-at 0,2.3,0 --text-size 0.033 --tilt -45 \
  --text-colour '#f4ecf2' --text-outline '#1a1620'

--text-size is metres to a font pixel, so the words read when it comes to a sprite pixel or more: the render prints the sheet’s pixels a metre (about 40 for a knight project at --size 128, 0.033 × 40 ≈ 1.3; 37 with this page’s bushes and pictures, still over 1). At 64 px it is about 24, under a pixel to a font pixel, and the letters break up.

Option What it does
--font NAME|FILE pixor-11, pixor-5, or a font file of your own: Pixor’s own format or a .bdf.
--align left|middle|right Where each line sits.
--wrap PIXELS Wrap at this width. A word too long is left whole: a broken word is harder to read than a line that sticks out.
--letter-spacing N, --line-spacing N Extra whole pixels.
--text-colour, --text-outline, --text-shadow Ink, a one-pixel outline, a pixel shadow.
--text-scale N Each pixel becomes N by N. Whole steps only.
--facing sprite, --picture-pixels N In sprite space, N sprite pixels to a font pixel, on every camera.

Layout is integer-only everywhere: advance widths and line heights are whole pixels, there is no shaping and no sub-pixel positioning, so a string gives the same pixels on every machine. A character the font has not got is a gap rather than a box, because a box in a sprite is worse than a gap.

Words are a label by default: they do not decide how the shot is framed. In sprite space they are exact from every side, with no tilting and no sizing to a camera: --facing sprite.

Words as geometry

A letters shape spells its words and extrudes each pixel of the font into a block, so the letters take lighting, bands, outlines and the palette like any other geometry — a sign, a banner, a gravestone:

pxr shapes -o sign.glb --shape letters:2,0.5,0.25
pxr project set game.pixor --add-shape letters:1.2,0.3,0.1:0,3,0 --words HELLO

Standing 3 m up, the word is clear of the knight’s helmet; like any shape it needs a sprite pixel or more to each font pixel to read, which the knight at --size 128 gives.

Only the faces no neighbour hides are built, so a word is a few hundred triangles, and the letters stand on their ink rather than on the empty room a descender needs.

Fonts

Pixor ships two fonts, both drawn for it: pixor-11, the font the interface is drawn in, and pixor-5, five pixels to a capital and three to most letters, for numbers over a sprite, labels and a HUD, where the bigger one would outweigh what it names. A letters shape chooses between them with Font in its Inspector. A font of your own is a text file of the same shape, which is as simple as it looks:

== A
.###.
#...#
#####
#...#
#...#

A line == C names the character (or == U+00E9 for one you cannot type), then its rows: # is ink, . is empty. It is readable, it diffs, and it needs no font library.

A BDF file works as it is: that is the format most pixel fonts are shared in. Its glyphs sit on one cell of the font’s ascent and descent, and each is as wide as the font says it advances, so the spacing its designer chose is kept and Pixor adds none.

A palette from a picture

A palette file may be a picture: a reference image, a screenshot of a game whose look you want, or a strip of swatches.

pxr render hero.glb --palette reference.png

A picture with sixteen colours or fewer gives exactly those, in a stable order; one with more gives up to sixteen of its most representative ones (colours too close to tell apart become one). The same picture gives the same palette on every machine.

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