Skin tone presets are a real design decision, not a config detail. The problem statement here is precise: emojis offer five shades, a makeup brand might offer fifty, and a character creator will often hand you all 16,777,216 RGB values and call it inclusivity. Toney Alexander wanted the middle ground — a bounded, simple region of RGB that plausibly covers real people, with code you can drop into a character creator or a procedural population generator.

The method is refreshingly unglamorous and written up in full:

  • Label a large set of RGB colors by eye, plausible or not, using a click-through UI that shows each color on a drawn face.
  • Run PCA with N=3 to rotate the crescent-shaped point cloud so its main directions of variation sit on the axes.
  • Fit a sphere to the rotated cloud by hand in Desmos 3D — literal guess-and-check, no regression — then invert the relations to get TUV → RGB.
  • Ship it as about fifteen lines of code, plus a picker and a sampler.

Three things make it worth reading beyond the specific result:

  • The PCA axes turned out to be meaningful, and nobody chose them. Once the picker existed, the three controls read as deep/fair, flushed/ochre, and cool/warm. That is PCA doing the one thing it is supposed to do, visible on screen.
  • One knob controls the whole tradeoff. The sphere’s radius R² sets variety: 1.0 is the minimum for decent random variety, 2.0 is what the generator uses, higher values suit a picker UI (users can ignore implausible colors) or a fantasy setting. Because it is a sphere, shrinking it reduces variation uniformly — it does not selectively cut deep or fair tones.
  • The origin of the space is a bias detector. Shrink R² to zero and you should land on a neutral, ambiguous tone. If the origin leans in some direction, the mapping is biased.

The limitations are listed explicitly rather than buried: skin is never one color, conditions like jaundice and argyria sit outside “plausible” ranges, RGB values shift across displays and lighting, and the labeling was one person’s subjective eye. “Good enough is fine if you’re an engineer,” the author writes — and because the whole space is defined by concrete equations, critics can point at exactly which coefficient to change instead of arguing about taste.

It is also a small, reusable pattern for games: when a parameter space has an awkward shape, relabel the data, rotate it with PCA until the axes mean something, fit a simple primitive, and expose the primitive’s radius as your content knob.