three-slug 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GOAL.md +32 -0
- package/README.md +78 -0
- package/demo/fonts/DejaVu Fonts License.txt +97 -0
- package/demo/fonts/DejaVuSansMono-Bold.sluggish +0 -0
- package/demo/fonts/DejaVuSansMono-Bold.ttf +0 -0
- package/demo/fonts/DejaVuSansMono-BoldOblique.ttf +0 -0
- package/demo/fonts/DejaVuSansMono-Oblique.ttf +0 -0
- package/demo/fonts/DejaVuSansMono.ttf +0 -0
- package/demo/fonts/Roboto-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/demo/fonts/Roboto-VariableFont_wdth,wght.ttf +0 -0
- package/demo/fonts/SpaceMono-Bold.ttf +0 -0
- package/demo/fonts/SpaceMono-BoldItalic.ttf +0 -0
- package/demo/fonts/SpaceMono-Italic.ttf +0 -0
- package/demo/fonts/SpaceMono-Regular.sluggish +0 -0
- package/demo/fonts/SpaceMono-Regular.ttf +0 -0
- package/demo/fonts/fonts.json +12 -0
- package/demo/index.html +103 -0
- package/demo/main.js +357 -0
- package/package.json +29 -0
- package/screenshot.png +0 -0
- package/src/SlugGenerator.js +399 -0
- package/src/SlugGeometry.js +211 -0
- package/src/SlugLoader.js +123 -0
- package/src/SlugMaterial.js +254 -0
- package/src/index.js +4 -0
package/GOAL.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Background:
|
|
2
|
+
The Slug font rendering algorithm/tooling has recently been open sourced.
|
|
3
|
+
There are C/C++ implementations available, but I want to create a first class Three.js library for it.
|
|
4
|
+
I have 2 repos.. One is the open sourced repo, containing the HSLS code for rendering: Slug-main
|
|
5
|
+
|
|
6
|
+
And a supporting repo by another person, which is a C++ implementation of the algorithm: Sluggish-master
|
|
7
|
+
|
|
8
|
+
Role: You are an expert Computer Graphics Engineer specializing in Three.js, GLSL, and Font Geometry. Your goal is to help me port the "Sluggish" project (a toy implementation of the Slug Font Rendering algorithm) into a first-class Three.js library.
|
|
9
|
+
|
|
10
|
+
Project Context:
|
|
11
|
+
|
|
12
|
+
Core Algorithm: We are implementing the Slug algorithm (vector-based GPU text rendering).
|
|
13
|
+
|
|
14
|
+
Legal Status: As of March 2026, the Slug patent is in the public domain. We are authorized to implement this without workarounds.
|
|
15
|
+
|
|
16
|
+
Target Framework: Three.js (using BufferGeometry and ShaderMaterial).
|
|
17
|
+
|
|
18
|
+
Technical Constraints:
|
|
19
|
+
|
|
20
|
+
Data Layout: Translate C-style structs from the Sluggish generator into JavaScript InterleavedBuffer or Float32Array.
|
|
21
|
+
|
|
22
|
+
Shaders: Port raw GLSL into Three.js-friendly code. We prioritize the Banded-Bézier approach to minimize per-pixel curve tests.
|
|
23
|
+
|
|
24
|
+
Precision: We must handle "Floating Point Jitter" for large-scale coordinates (e.g., world-space text in a racing sim). (This may be less of an issue in JS, but we should be mindful of it.)
|
|
25
|
+
|
|
26
|
+
Your Workflow:
|
|
27
|
+
|
|
28
|
+
When I provide C code, explain the memory layout before writing the JS port.
|
|
29
|
+
|
|
30
|
+
When writing shaders, ensure they are compatible with Three.js onBeforeCompile (and optionally the new Node Material (WebGPU) system, unless this is too much work.)
|
|
31
|
+
|
|
32
|
+
Prioritize performance and usability.
|
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# three-slug: Native Three.js GPU Text Rendering
|
|
4
|
+
|
|
5
|
+
`three-slug` is a Javascript and WebGL port of Eric Lengyel's **Slug** font rendering algorithm, implemented natively for **Three.js**.
|
|
6
|
+
|
|
7
|
+
Unlike traditional MSDF (Multi-Channel Signed Distance Field) font rendering which can suffer from corner rounding and texture resolution limits, the Slug algorithm evaluates the quadratic bezier curves of the TrueType font directly within the fragment shader. This enables resolution-independent font rendering, sharp corners, and precise anti-aliasing.
|
|
8
|
+
|
|
9
|
+
## Screenshots
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Client-side Generation**: Parses `.ttf` and `.otf` data dynamically using `opentype.js` to compute curve layouts and spatial binning locally.
|
|
17
|
+
- **Binary Format**: Serializes curves and bin maps to `.sluggish` file payloads for cache delivery.
|
|
18
|
+
- **Instanced Rendering**: Passes coordinate frames and glyph indexing variables to WebGL vertex attributes backends.
|
|
19
|
+
- **Typography Alignment**: Iterates layout structures utilizing metric scalars mapping direct width increments.
|
|
20
|
+
|
|
21
|
+
### Phase 2: Native PBR & Shadow Integration
|
|
22
|
+
- **Modular Shader Chunks**: The core Slug mathematical raytracer has been decoupled into distinct Three.js `#include` chunks (`slug_fragment_core`, `slug_fragment_standard`, `slug_pars_vertex`).
|
|
23
|
+
- **Standard Material Hooks**: Utilizes `onBeforeCompile` to non-destructively splice the font rendering algorithm directly into native Three.js materials (e.g. `MeshStandardMaterial`, `MeshDepthMaterial`).
|
|
24
|
+
- **Physical Lighting**: Evaluates vector glyphs securely under physically based rendering paradigms, seamlessly scattering Light arrays and mapping PBR Specular boundaries.
|
|
25
|
+
- **Dynamic Occlusions**: Typography casts and receives accurate, anti-aliased shadows inside the active scene viewport using standard Depth buffer constraints and custom `MeshDistanceMaterial` definitions.
|
|
26
|
+
|
|
27
|
+
## Quick Start Example
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
import * as THREE from 'three';
|
|
31
|
+
import { SlugLoader, SlugGeometry, injectSlug } from 'three-slug';
|
|
32
|
+
|
|
33
|
+
// 1. Load the pre-compiled .sluggish binary font data
|
|
34
|
+
new SlugLoader().load('path/to/font.sluggish', (slugData) => {
|
|
35
|
+
|
|
36
|
+
// 2. Initialize the scalable vector geometry
|
|
37
|
+
const geometry = new SlugGeometry(1000); // Specify max glyph capacity
|
|
38
|
+
|
|
39
|
+
// 3. Create a native Three.js Standard Material
|
|
40
|
+
const material = new THREE.MeshStandardMaterial({
|
|
41
|
+
color: 0xffcc00,
|
|
42
|
+
roughness: 1.0,
|
|
43
|
+
metalness: 0.0,
|
|
44
|
+
side: THREE.DoubleSide
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// 4. Spawn the finalized PBR Mesh
|
|
48
|
+
const slugMesh = new THREE.Mesh(geometry, material);
|
|
49
|
+
|
|
50
|
+
// 5. Inject the mathematical Slug raytracer and auto-bind Shadow caches seamlessly
|
|
51
|
+
injectSlug(slugMesh, material, slugData);
|
|
52
|
+
|
|
53
|
+
// 6. Append your text
|
|
54
|
+
geometry.addText('MyString! WOOHOO!', slugData, {
|
|
55
|
+
fontScale: 0.5,
|
|
56
|
+
justify: 'center'
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
slugMesh.castShadow = true;
|
|
60
|
+
slugMesh.receiveShadow = true;
|
|
61
|
+
scene.add(slugMesh);
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
1. Serve the repository locally (e.g., `npx http-server`).
|
|
68
|
+
2. Open `demo/index.html`.
|
|
69
|
+
3. Use the UI to load a standard `.ttf` file. The Javascript generator will parse the curves, initialize the GPU textures, and dynamically render standard PBR typography inside the demo viewer.
|
|
70
|
+
4. Toggle the **RawShader Fallback** to swap between Native Standard Lighting graphs or unlit baseline GLSL debugging buffers.
|
|
71
|
+
5. (Optional) Click **Download .sluggish** to cache the generated font data to a serialized binary array.
|
|
72
|
+
|
|
73
|
+
## Credits & Acknowledgements
|
|
74
|
+
|
|
75
|
+
* **Eric Lengyel** for the [Slug Algorithm](http://sluglibrary.com/).
|
|
76
|
+
* **The Sluggish C++ Port** for providing the architectural reference for mapping Slug textures directly to generic WebGL buffer pipelines.
|
|
77
|
+
* **[opentype.js](https://github.com/opentypejs/opentype.js)** for providing the native Javascript TrueType parsing core.
|
|
78
|
+
* Ported to Javascript and Three.js by **[manthrax](https://github.com/manthrax)**.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
|
2
|
+
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
|
3
|
+
|
|
4
|
+
Bitstream Vera Fonts Copyright
|
|
5
|
+
------------------------------
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
|
8
|
+
a trademark of Bitstream, Inc.
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of the fonts accompanying this license ("Fonts") and associated
|
|
12
|
+
documentation files (the "Font Software"), to reproduce and distribute the
|
|
13
|
+
Font Software, including without limitation the rights to use, copy, merge,
|
|
14
|
+
publish, distribute, and/or sell copies of the Font Software, and to permit
|
|
15
|
+
persons to whom the Font Software is furnished to do so, subject to the
|
|
16
|
+
following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright and trademark notices and this permission notice shall
|
|
19
|
+
be included in all copies of one or more of the Font Software typefaces.
|
|
20
|
+
|
|
21
|
+
The Font Software may be modified, altered, or added to, and in particular
|
|
22
|
+
the designs of glyphs or characters in the Fonts may be modified and
|
|
23
|
+
additional glyphs or characters may be added to the Fonts, only if the fonts
|
|
24
|
+
are renamed to names not containing either the words "Bitstream" or the word
|
|
25
|
+
"Vera".
|
|
26
|
+
|
|
27
|
+
This License becomes null and void to the extent applicable to Fonts or Font
|
|
28
|
+
Software that has been modified and is distributed under the "Bitstream
|
|
29
|
+
Vera" names.
|
|
30
|
+
|
|
31
|
+
The Font Software may be sold as part of a larger software package but no
|
|
32
|
+
copy of one or more of the Font Software typefaces may be sold by itself.
|
|
33
|
+
|
|
34
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
35
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
|
36
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
|
37
|
+
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
|
38
|
+
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
|
39
|
+
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
|
40
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
41
|
+
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
|
42
|
+
FONT SOFTWARE.
|
|
43
|
+
|
|
44
|
+
Except as contained in this notice, the names of Gnome, the Gnome
|
|
45
|
+
Foundation, and Bitstream Inc., shall not be used in advertising or
|
|
46
|
+
otherwise to promote the sale, use or other dealings in this Font Software
|
|
47
|
+
without prior written authorization from the Gnome Foundation or Bitstream
|
|
48
|
+
Inc., respectively. For further information, contact: fonts at gnome dot
|
|
49
|
+
org.
|
|
50
|
+
|
|
51
|
+
Arev Fonts Copyright
|
|
52
|
+
------------------------------
|
|
53
|
+
|
|
54
|
+
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
|
55
|
+
|
|
56
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
57
|
+
a copy of the fonts accompanying this license ("Fonts") and
|
|
58
|
+
associated documentation files (the "Font Software"), to reproduce
|
|
59
|
+
and distribute the modifications to the Bitstream Vera Font Software,
|
|
60
|
+
including without limitation the rights to use, copy, merge, publish,
|
|
61
|
+
distribute, and/or sell copies of the Font Software, and to permit
|
|
62
|
+
persons to whom the Font Software is furnished to do so, subject to
|
|
63
|
+
the following conditions:
|
|
64
|
+
|
|
65
|
+
The above copyright and trademark notices and this permission notice
|
|
66
|
+
shall be included in all copies of one or more of the Font Software
|
|
67
|
+
typefaces.
|
|
68
|
+
|
|
69
|
+
The Font Software may be modified, altered, or added to, and in
|
|
70
|
+
particular the designs of glyphs or characters in the Fonts may be
|
|
71
|
+
modified and additional glyphs or characters may be added to the
|
|
72
|
+
Fonts, only if the fonts are renamed to names not containing either
|
|
73
|
+
the words "Tavmjong Bah" or the word "Arev".
|
|
74
|
+
|
|
75
|
+
This License becomes null and void to the extent applicable to Fonts
|
|
76
|
+
or Font Software that has been modified and is distributed under the
|
|
77
|
+
"Tavmjong Bah Arev" names.
|
|
78
|
+
|
|
79
|
+
The Font Software may be sold as part of a larger software package but
|
|
80
|
+
no copy of one or more of the Font Software typefaces may be sold by
|
|
81
|
+
itself.
|
|
82
|
+
|
|
83
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
84
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
85
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
86
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
|
87
|
+
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
88
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
89
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
90
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
91
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
92
|
+
|
|
93
|
+
Except as contained in this notice, the name of Tavmjong Bah shall not
|
|
94
|
+
be used in advertising or otherwise to promote the sale, use or other
|
|
95
|
+
dealings in this Font Software without prior written authorization
|
|
96
|
+
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
|
97
|
+
. fr.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
"DejaVuSansMono.ttf",
|
|
3
|
+
"DejaVuSansMono-Bold.ttf",
|
|
4
|
+
"DejaVuSansMono-Oblique.ttf",
|
|
5
|
+
"DejaVuSansMono-BoldOblique.ttf",
|
|
6
|
+
"Roboto-VariableFont_wdth,wght.ttf",
|
|
7
|
+
"Roboto-Italic-VariableFont_wdth,wght.ttf",
|
|
8
|
+
"SpaceMono-Regular.ttf",
|
|
9
|
+
"SpaceMono-Bold.ttf",
|
|
10
|
+
"SpaceMono-Italic.ttf",
|
|
11
|
+
"SpaceMono-BoldItalic.ttf"
|
|
12
|
+
]
|
package/demo/index.html
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Slug Font Rendering Three.js</title>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
margin: 0;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
background-color: #004040;
|
|
13
|
+
color: white;
|
|
14
|
+
font-family: sans-serif;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#ui {
|
|
18
|
+
position: absolute;
|
|
19
|
+
top: 20px;
|
|
20
|
+
left: 20px;
|
|
21
|
+
z-index: 10;
|
|
22
|
+
background: rgba(10, 15, 20, 0.6);
|
|
23
|
+
backdrop-filter: blur(8px);
|
|
24
|
+
-webkit-backdrop-filter: blur(8px);
|
|
25
|
+
padding: 15px;
|
|
26
|
+
border-radius: 8px;
|
|
27
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
28
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
|
|
29
|
+
max-width: 320px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
h3 {
|
|
33
|
+
margin-top: 0;
|
|
34
|
+
font-size: 1.2rem;
|
|
35
|
+
letter-spacing: 1px;
|
|
36
|
+
color: #ffcc00;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
button,
|
|
40
|
+
input {
|
|
41
|
+
margin-bottom: 5px;
|
|
42
|
+
cursor: pointer;
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
45
|
+
</head>
|
|
46
|
+
|
|
47
|
+
<body>
|
|
48
|
+
<div id="ui">
|
|
49
|
+
<h3>Three-Slug</h3>
|
|
50
|
+
<div>
|
|
51
|
+
<label>Select Font:</label><br>
|
|
52
|
+
<select id="fontSelect"
|
|
53
|
+
style="width: 100%; margin-bottom: 10px; padding: 5px; background: #333; color: #fff; border: 1px solid #555;">
|
|
54
|
+
<!-- Dynamically populated from fonts.json -->
|
|
55
|
+
</select>
|
|
56
|
+
</div>
|
|
57
|
+
<hr style="border-color: #444; margin: 15px 0;">
|
|
58
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
|
59
|
+
<label><input type="checkbox" id="autoScroll" checked /> Auto Scroll</label>
|
|
60
|
+
<label><input type="checkbox" id="matrixGlitch" /> Matrix Glitch</label>
|
|
61
|
+
<label><input type="checkbox" id="useRawShader" /> RawShader Fallback</label>
|
|
62
|
+
</div>
|
|
63
|
+
<div style="margin-bottom: 15px;">
|
|
64
|
+
<label style="font-size: 0.9em; color:#ccc; display: block; margin-bottom: 5px;">Text Alignment:</label>
|
|
65
|
+
<select id="textJustify"
|
|
66
|
+
style="width: 100%; padding: 5px; background: #333; color: #fff; border: 1px solid #555;">
|
|
67
|
+
<option value="left" selected>Left</option>
|
|
68
|
+
<option value="center">Center</option>
|
|
69
|
+
<option value="right">Right</option>
|
|
70
|
+
</select>
|
|
71
|
+
</div>
|
|
72
|
+
<div>
|
|
73
|
+
<label>Load .ttf font:</label><br>
|
|
74
|
+
<input type="file" id="fileTtf" accept=".ttf"><br>
|
|
75
|
+
<button id="btnDownload">Download .sluggish</button>
|
|
76
|
+
</div>
|
|
77
|
+
<hr style="border-color: #444; margin: 15px 0;">
|
|
78
|
+
<div style="margin-bottom: 15px;">
|
|
79
|
+
<label style="font-size: 0.9em; color:#ccc;">Load .sluggish file:</label><br>
|
|
80
|
+
<input type="file" id="fileSluggish" accept=".sluggish" style="font-size: 0.8em;">
|
|
81
|
+
</div>
|
|
82
|
+
<hr>
|
|
83
|
+
<div>
|
|
84
|
+
<label>Text to Render:</label><br>
|
|
85
|
+
<textarea id="textInput" rows="4"
|
|
86
|
+
style="width: 100%; box-sizing: border-box; background: #222; color: #fff; border: 1px solid #444; padding: 5px;">The quick brown fox jumps over the lazy dog.
|
|
87
|
+
SLUG!</textarea>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<script type="importmap">
|
|
92
|
+
{
|
|
93
|
+
"imports": {
|
|
94
|
+
"three": "https://unpkg.com/three@0.183.2/build/three.module.js",
|
|
95
|
+
"three/addons/": "https://unpkg.com/three@0.183.2/examples/jsm/",
|
|
96
|
+
"opentype.js": "https://unpkg.com/opentype.js@1.3.4/dist/opentype.module.js"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
</script>
|
|
100
|
+
<script type="module" src="./main.js"></script>
|
|
101
|
+
</body>
|
|
102
|
+
|
|
103
|
+
</html>
|