gl-text
gl-text
is for rendering an insane number (> 100K) of small texts (max 48 chars) with ThreeJS, for
debugging purpose essentially (eg: Mesh inspection).
Font
The font used by default for generating the atlas is the excellent Fira Code.
Demo & Atlas
Demos:
The atlas is made via canvas.toDataURL()
from that page:
Features
-
Colors:
- text & background
- with opacity!
-
Multiple lines
- up to 8 lines (but since only 48 chars ares supported, 3 or 4 is a maximum in real use cases).
-
Billboard mode
- By default the text instances are facing the camera
- But it can be prevented:
new GlText({ billboard: false })
-
Three classic material support. Works well with MeshBasicMaterial & MeshPhysicalMaterial
- eg:
const glText = new GlText({ material: new MeshPhysicalMaterial() })
- eg:
-
Z fighting
- By default a tiny "polygon offset" is enabled, and can be adjusted:
new GlText({ polygonOffsetFactor: -10, polygonOffsetUnits: -10 })
- Even better: a
cameraZOffset
option allows to shift the text directly to the camera!new GlText({ cameraZOffset: .5 })
- By default a tiny "polygon offset" is enabled, and can be adjusted:
-
Supports mipmaps
- Because every chars is drawn through separated triangles (2 triangles actually) mimaps works without any troubles (it was not the case with previous technic using a single plane for multiple chars).
-
ShaderForge
- A small tool for glsl shader code manipulation.
Usage
const glText = new GlText({
count: 100_000, // default is 2000
col = 16, // default is 12
row = 3, // default is 2
billboard = false, // default is true
})
scene.add(glText)
glText.setTextAt(0, 'foo', {
position: new Vector3(4, 2, 1),
color: 'red',
background: 'yellow',
size: 2,
})
For a complete understanding of the tool, see the declaration file (index.d.ts)
How does it works?
GlText uses internally InstancedMesh & MeshBasicMaterial. The text instances are drawn in one draw call thanks to the modified material. The text data is tramsitted to the shader via attributes. There are actually four attributes :
attribute mat4 chars;
attribute vec3 lines;
attribute vec4 textColor;
attribute vec4 backgroundColor;
Chars are encoded into int8 then packed 3 by 3 into float32, then sent through the chars attribute as mat4.
In the vertex shader the data is decoded and custom uv (vUvw) are computed for the fragment shader.
Info
The output (js, .d.ts + map) is generated (but not commited) in the lib folder.
Dev
pnpm dev