Development

Voxel texture recolorer

Python pipeline to recolor 8192² textures of a voxel soldier while preserving fabric detail.

1 star2026role: sole authorstatus: active

01 Problem and context

A voxel character comes with a single base texture of 8192 pixels per side. Producing uniform variants by painting over it destroys baked-in detail (fabric weave, seams, crease shadows), and a naive pass over the entire image runs out of memory.

A voxel game character ships with a single 8192-pixel base colour texture. Producing uniform variants by painting over it destroys the detail baked into that texture: the weave of the fabric, the seams, the pockets, the shading in the folds. The real problem is separating colour from detail, and doing it on an image large enough that a naive full-texture pass runs out of memory.

02 Solution

Recoloring in Lab color space: luminance variation, where all fabric detail resides, is preserved while replacing only chromaticity with that of the target color. Processing runs in horizontal stripes to keep memory usage bounded, and parts indistinguishable by color (the helmet and uniform share a material) are separated via mesh triangle classification. The face is excluded by geometry, not by color.

  1. Analysing the source texture to work out what could be separated by colour and what could not: helmet and uniform share a single grey material.
  2. Segmenting by chroma and hue to isolate the recolourable area, explicitly protecting the olive of the vest, the skin and the collar.
  3. Recolouring in Lab space: luminance variation is preserved, since that is where all the fabric detail lives, and chromaticity is replaced with the target colour.
  4. Processing in horizontal bands of 1024 rows to keep memory bounded, with the reference brightness estimated from a 512-pixel downsample.
  5. Per-triangle classification of the mesh to separate parts that colour alone cannot tell apart, with the face excluded by geometry rather than by colour.
  6. A desktop application with a three.js viewer: GPU shader recolouring for the live preview, and Python export at full resolution.

03 Results

Verifiable figures in the repository and its documentation:

8192²output texture resolution
4separately recolourable regions, with skin and face locked

04 How it's built

Image processing tool that generates color variations for the uniform and helmet of a 3D voxel model, segmenting the recolorable region in HSV space and recoloring in Lab space to preserve fabric seams, texture, and shadows. Includes a CLI with a JSON-editable palette and a desktop app (pywebview + three.js) with a 3D viewer and real-time color panel, packageable as an executable with PyInstaller. All processing relies strictly on NumPy and Pillow, using band reading to handle 8192×8192 textures without exhausting memory.

05 Ethical decisions

  • Skin and face are locked by geometry rather than by colour: the front-facing triangles of the head are excluded from recolouring, so no variant can change the character's skin tone, neither by accident nor on purpose.

06 Highlights

  • Lab color space recoloring that replaces chromaticity (a*, b*) and preserves luminance L*, keeping fabric details intact.
  • HSV color segmentation that isolates the recolorable region and protects the vest, gloves, skin, and collar using validated thresholds.
  • Band-based processing for 8192×8192 textures using only NumPy and Pillow.
  • Desktop app featuring a 3D viewer in three.js and a Python engine via pywebview, packaged as a .exe using PyInstaller.

07 Limitations

No dataset here: there is one source texture and the thresholds are calibrated against it. The mask assumes the recolourable area is close to achromatic and protects the olive of the vest by hue range; a different character means recalibrating those numbers. Helmet and uniform share a material, so colour alone cannot separate them and a region map derived from mesh geometry was needed. Verification is visual, through side-by-side comparisons of original, result and mask, not a quantitative fidelity metric.