/single-line-3d-text

JavaScript WebGL single line text from SVG paths to use with three.js

Primary LanguageJavaScriptMIT LicenseMIT

single-line-3d-text

Single-line fonts

JavaScript for single-line 3D text to be used in three.js. Regular fonts characters are usually outline fonts. These font file describes 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

Setup

To install and start do the usual:

$ yarn install
$ yarn start

...and the app will be available at localhost:3009

Or see it here on GitHub Pages:

Minimal 3D text for Three.js

I needed a simple text format for a 3D project, where the text should use minimal resources and the processor could devote all it's power to smooth animation and steady timing. This code renders text in the simplest way possible, in 3D. Each character is just a few straight lines rendered with a LineBasicMaterial.

Asteroids

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 made the original 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.

Asteroids

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 in the C file was easy to translate to a JSON file with SVG paths:

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)