Skip to content

Repository files navigation

Pixlift

Draw pixel art. Paint depth. Get a real 3D model.

Try it in your browser, nothing to install.

Pixlift is a browser-based editor that turns 2D sprites into 3D models ready for Godot, Unity, Unreal, Blender, MagicaVoxel or a 3D printer. You draw on a pixel grid where every cell can be a shape (square, triangle, half block, rounded corner, circle), paint how far each pixel extrudes, and watch the 3D model build itself live next to your drawing. 100% client-side: no backend, no account, no install.

Pixlift: 2D sprite on the left, live 3D model on the right

Why Pixlift

Cells are shapes, not just squares. Eighteen per-cell cross-sections (triangles, half blocks, convex and concave rounds, circles) extrude into true prisms: sloped blades, rounded gems and smooth wings instead of staircase edges, while staying 100% pixel-art to draw.

Front and back are independent. Most voxel extruders mirror the model front-to-back. In Pixlift every cell stores independent depth and color per side. Keep the symmetry lock on for the classic fast workflow, or open it and sculpt the two faces separately: a detailed front and an armored back on the same sprite.

The 3D result is always on screen. No mode switching, no "preview" button. The model rebuilds on every brushstroke.

Examples

2D drawing 3D model
Sword sprite Sword 3D model
Boat sprite Boat 3D model

Sword combines shaped cells (triangle blade tip, rounded pommel), variable depth (thin blade, thick guard) and front/back asymmetry: the guard gem is brighter and extrudes deeper on the front than on the back. Open docs/sword.pixlift.json in the editor.

Boat shows how one side-view drawing plus depth painting produces the whole volume: hull 8 deep, cabin 6, chimney 2, with rounded-corner cells shaping the hull. The smiley face is painted only on the front face; from behind (docs/boat-back.png) the hull is plain orange. That's the two-sided model in one picture. Open docs/boat.pixlift.json to explore.

Features

Drawing

  • Modeless workspace: canvas and live 3D preview side by side
  • 18 cell shapes; the mirror-X tool mirrors shapes correctly (a left triangle stamps its right-facing twin)
  • Tools: pencil, line, flood fill, eraser, eyedropper (picks color + shape + depth in one click) and a dedicated depth tool that overlays the depth numbers while active
  • Zoom (mouse wheel), pan (middle-drag or space + drag), F to re-fit
  • Custom canvas size (4-128 per axis, resizable at any time, drawing kept centered)
  • Custom depth range (1-64 per project)
  • Undo/redo (50 steps), drag painting, keyboard-first workflow
  • Auto-depth: generate the depth map from color luminosity, palette index or seeded noise, with range and invert controls
  • Custom palettes: add/remove colors, save/load them as files, embedded in every project
  • Light and dark themes
  • Autosave: unsaved work survives tab closes and crashes

Export

Format What you get
GLB (glTF) Vertex colors or a texture-atlas UV variant; imports natively into Godot, Unity, Unreal, Blender
OBJ Universal geometry (no colors)
STL Binary, 3D-printing ready
VOX MagicaVoxel volume (shapes flatten to cubes)
PNG Snapshot of the 3D view
SVG True vector version of the 2D drawing; every cell is a real path

The Optimize toggle greedy-meshes exports: coplanar same-color faces merge into maximal rectangles, typically cutting triangle counts by 5-20x. Projects save as plain-JSON .pixlift.json files (older format versions migrate automatically on open).

Quick start

npm install
npm run dev      # opens the editor at http://localhost:5173/Pixlift/
npm run build    # production build in dist/

Requires Node.js 24+. No Node that new on your machine? Test through Docker instead:

docker compose up dev       # live dev server at http://localhost:5173/Pixlift/
docker compose up preview   # production build at http://localhost:4173/Pixlift/

Every push to main deploys to GitHub Pages via .github/workflows/deploy.yml. Forks need Pages enabled once: Settings > Pages > Source: GitHub Actions.

Keyboard shortcuts

Key Action
P L G E I Pencil, Line, Fill, Eraser, Eyedropper
D Depth tool (digit overlay)
1-8 Select depth
M Mirror X
F Re-fit the view
Space + drag / middle-drag Pan
Alt + paint Paint the opposite side (lock open)
Ctrl+Z / Ctrl+Y Undo / redo
Ctrl+S Save project

Architecture

src/
├── core/        # pure JS, no DOM; testable and reusable from a CLI
│   ├── shapes.js    # shape registry: 2D outlines, culling data, mirror map
│   ├── sprite.js    # data model + serialization/migration
│   ├── extrude.js   # 2D sprite -> voxel Map (color + shape)
│   ├── depthgen.js  # automatic depth generation
│   └── mesh.js      # voxels -> BufferGeometry (prisms, culling, greedy meshing)
├── exporters/   # pure functions: data in, Blob out (GLB/OBJ/STL/VOX/SVG/PNG)
├── ui/          # canvas editor, shelf (shapes/colors/depth), popovers, theme
└── viewer/      # Three.js preview scene

The data model is the central decision. Each grid cell stores { colorF, colorB, front, back, shape }: independent depth and color per side, one shared cross-section shape (the cell is a prism column). Symmetry is just the special case front === back && colorF === colorB; nothing in the pipeline treats it specially.

The drawing plane sits at z = 0: front voxels occupy z = 0..front-1, back voxels z = -back..-1. The mesher emits one wall per outline edge with interval-based culling between neighbors; an all-square sprite produces exactly the same mesh as a classic cube mesher, and the greedy pass merges what geometry allows.

Roadmap

  • Import a PNG and get a sprite (with auto-depth as the second step)
  • Selection tools: move / copy / rotate a region
  • Isometric multi-angle spritesheet export
  • Fully unwrapped UV export

FBX is deliberately out of scope: it is proprietary, and GLB imports natively into every engine FBX would serve.

License

MIT