• The Portfolio of Paul Butterworth - Tessel_Orange_Banner14

Tessel

I’m often arranging images while the conversation is still going. It might be concept art for a pitch, storyboards for a shoot, or contact sheets for review. The decisions happen in real time, so the layout has to keep up.

Most tools slow the conversation down. You have to adjust spacing by hand, deal with tricky guides, and use export settings that don’t match what you see on the screen. These programs are made for graphic designers, not for someone who needs to move fifty frames around a page without losing the flow.

Getting the structure right had to come first.

The Idea

Most layout tools start with a blank canvas. You place things first, then figure out the structure. Tessel does the opposite. You set up the grid first, then add your content.

Set columns and rows. Pick an aspect ratio. Adjust the spacing. The grid appears with empty cells ready for images. Drag things in, and they snap into place. You can easily swap images and text. Change the grid and everything reflows. There’s no need for manual positioning or starting over.


Four Productions

I’ve used Tessel on four shows: Metropolis, Mercy for Amazon MGM, Rossum's Universal Robots for Alex Proyas, and my current project, Play Dead for Nocturnal. Each project helped shape the tool.

I built it as an artist, not as a developer, guessing what other artists might want. I needed real-time feedback and the ability to sit with a director or production designer, create a shot live, drop images into a presentation, move them around, adjust the layout, and know it would print exactly as we saw it. That need drove everything else.

Each production added something new, like a faster renderer, better text handling, or mood board layouts that felt less mechanical. The tool grew because I used it, not just because I imagined how it might be used.


Building a Layout

1. Set your grid. Columns, rows, aspect ratio, spacing. The grid appears instantly.

2. Add images. Drag from Finder onto any cell. Or import to the shelf and drag from there. Drop multiple images at once — Tessel automatically fills empty cells.

3. Adjust on the fly. Change spacing. Change columns. Everything reflows in real time.

4. Fine-tune. Select a cell, then ⌘-drag to reposition the image inside it, ⌃-drag to scale, ⇧-drag to rotate. All non-destructive.

5. Export. PDF or print. What you see is what you get.


Storyboard Mode

Film work needs captions under frames. Storyboard mode alternates image rows with text rows — each caption touches its image, spacing only between pairs.


Harmonic Grid

Sometimes you don't want uniformity. Harmonic mode generates layouts using golden ratio subdivision — organic arrangements that feel designed rather than computed.

The algorithm is recursive: take a rectangle, split it at φ⁻¹ (0.618), and recurse on both halves. Repeat until you hit the target cell count. Each split alternates direction based on aspect ratio — wide rectangles split vertically, tall ones horizontally. You don't need to understand this to use it — but it's why the layouts feel intentional rather than arbitrary.

The layouts are random but reproducible. A seeded generator ensures the same input produces the same output — export it Tuesday, export it Friday, identical result.


Under the Hood

Two constraints shaped the architecture: it had to handle 200+ images without stuttering, and PDF export had to match the screen exactly.

60fps Rendering

The canvas is GPU-accelerated. Every frame, Metal shaders composite images, apply transforms, and render text — all on the graphics card.

Two texture caches run in parallel: 512px thumbnails for interaction, 2048px full-resolution for display. Drag an image and you're seeing thumbnails. Stop moving and full-resolution loads within half a second. The switch is invisible but the responsiveness isn't.

Dual Masking

Images can be repositioned, scaled, rotated within their cells. Sometimes you want overflow — an image that bleeds past cell edges. But you never want content bleeding off the page.

The fragment shader checks two masks: cell boundaries (optional, per image) and page boundaries (always enforced). Both must pass for a pixel to render. Users control cell masking; page masking protects them from themselves.

Coordinate Systems

PDF uses Y-up coordinates (origin at bottom-left). The rest of macOS uses Y-down (origin at top-left). Every position calculation has to know which world it's in.

I wrote 2,500 lines of export code to make two coordinate systems produce identical output. The user sees one button.

The Rotation Fix

Early testing revealed warping when rotating images on non-square viewports. The problem: rotation was happening in Normalised Device Coordinates, which stretch to fit the viewport shape.

// Rotate in point space, not NDC
float2 rotated = float2(
    pos.x * cosTheta - pos.y * sinTheta,
    pos.x * sinTheta + pos.y * cosTheta
);

The fix: transform in uniform point space first, then convert to NDC. One-line conceptual change, longer to find than to implement.

Typography

Text needs to match across three contexts: screen, PDF, and print. Most applications compromise somewhere.

Tessel renders text to GPU textures using the same NSLayoutManager pipeline that generates PDF output. Same measurements, same line breaks, same leading calculations. The work happens once; the results render identically everywhere.

Seeded Randomness

Harmonic layouts use a deterministic random generator. The seed is stored with the document — regenerate the layout tomorrow, next week, on a different machine. Same seed, same cells.

// xorshift64 — fast, deterministic, reproducible
state ^= state << 13
state ^= state >> 7
state ^= state << 17

"Random" layouts that export identically every time. Essential for production work where repeatability matters.


Technical Specifications

Rendering Metal 3, 60fps
Texture Cache Dual-resolution (512px + 2048px), LRU eviction
Export PDF, Print — pixel-matched to screen
Minimum macOS 14.0 Sonoma
Architecture Apple Silicon native
Price One-time purchase (A$49.99)

I built it because I needed it. Turns out other people do too.