Single-line 3D text

webgl screenshot

I wrote some JavaScript to create single-line 3D text using the three.js library to render 3D on a canvas using WebGL. Three.js can already render text with its TextGeometry class, but I wanted something simpler: single-line fonts.

Regular fonts characters are usually outline fonts. These font files describe the outline of characters, and the outline is filled with a color. The fill is the only actual visible part.

In a single-line font the line itself is the visible part of the font. It makes for much simpler font files. Compare it to writing with a pen: It’s much quicker and simpler to directly write characters as lines than to draw them as outlined shapes and fill in the shapes.

Single-line fonts are also knowns as engraving fonts, stroke fonts, technical lettering fonts, pen plotter fonts or stick fonts.

font comparison

Font comparison

Setup

Clone the repository from GitHub at:

https://github.com/hisschemoller/single-line-3d-text.git

To install and start do the usual:

$ yarn install
$ yarn start

…and the app will be available at localhost:3009

Or see it here live on GitHub Pages:

https://hisschemoller.github.io/single-line-3d-text/

Asteroids

Searching for information on single-line fonts I found an interesting summary of single-line fonts by Lindsay Robert Wilson, which mentions the font used in Atari’s 1979 Asteroids game.

Atari programmer Ed Logg designed the original Asteroids font. More recently Trammell Hudson made a slightly adjusted version of the font for his own projects, of which he put the source file on GitHub.

font comparison

Image: Ed Logg’s original hand-drawn sketch on the left and Trammell Hudson’s variation on the right. (image from Trammell Hudson’s website)

Three.js implementation

The font description by Trammell Hudson is a C language file, but it was easy to translate to a JSON file with SVG paths for the characters:

const asteroids_char_t asteroids_font[] = {
  ['0' - 0x20] = { P(0,0), P(8,0), P(8,12), P(0,12), P(0,0), P(8,12), FONT_LAST },
  ['1' - 0x20] = { P(4,0), P(4,12), P(3,10), FONT_LAST },
  ['2' - 0x20] = { P(0,12), P(8,12), P(8,7), P(0,5), P(0,0), P(8,0), FONT_LAST },
{
  "chars": {
    "0": "M0 12 L8 12 L8 0 L0 0 L0 12 L8 0",
    "1": "M4 12 L4 0 L3 2",
    "2": "M0 0 L8 0 L8 5 L0 7 L0 12 L8 12",

From there I could take some functions from ThreeJS’s SVGLoader to parse the SVG strings into Path objects, en then create Line objects for each character and align them horizontally as a line of text in a Group.

Very cheap and simple text. The only thing I don’t like about the LineBasicMaterial text is that lines can only be 1 pixel wide. I would have liked to be able to adjust the line thickness. I will try and see if I can change that at some point, but for now this code does what I need.

Ed Logg

Ed Logg, designer of Asteroids (image: Aaron Hightower/Wikipedia)

Leave a Reply

Your email address will not be published. Required fields are marked *