three-slug 1.0.0 → 1.1.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/README.md +4 -0
- package/demo/main.js +30 -4
- package/package.json +1 -1
- package/src/SlugMaterial.js +15 -3
package/README.md
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
|
|
7
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
8
|
|
|
9
|
+
## Demo
|
|
10
|
+
|
|
11
|
+
[Demo](https://manthrax.github.io/JSlug/demo/)
|
|
12
|
+
|
|
9
13
|
## Screenshots
|
|
10
14
|
|
|
11
15
|

|
package/demo/main.js
CHANGED
|
@@ -229,6 +229,25 @@ function createTextMesh() {
|
|
|
229
229
|
const useRawFallback = document.getElementById('useRawShader').checked;
|
|
230
230
|
let material;
|
|
231
231
|
|
|
232
|
+
// Create a procedural grid texture to test local UV-mapping layout support
|
|
233
|
+
const canvas = document.createElement('canvas');
|
|
234
|
+
canvas.width = 128;
|
|
235
|
+
canvas.height = 128;
|
|
236
|
+
const ctx = canvas.getContext('2d');
|
|
237
|
+
|
|
238
|
+
// Draw highly contrasting 2x2 Checkerboard
|
|
239
|
+
ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, 128, 128);
|
|
240
|
+
ctx.fillStyle = '#ee0088'; // Vibrant magenta for clear grid inspection
|
|
241
|
+
ctx.fillRect(0, 0, 64, 64);
|
|
242
|
+
ctx.fillRect(64, 64, 64, 64);
|
|
243
|
+
|
|
244
|
+
const gridTex = new THREE.CanvasTexture(canvas);
|
|
245
|
+
gridTex.wrapS = THREE.RepeatWrapping;
|
|
246
|
+
gridTex.wrapT = THREE.RepeatWrapping;
|
|
247
|
+
gridTex.repeat.set(.5, .5);
|
|
248
|
+
gridTex.magFilter = THREE.NearestFilter;
|
|
249
|
+
gridTex.minFilter = THREE.NearestFilter;
|
|
250
|
+
|
|
232
251
|
|
|
233
252
|
|
|
234
253
|
const textToRender = document.getElementById('textInput').value;
|
|
@@ -255,11 +274,14 @@ function createTextMesh() {
|
|
|
255
274
|
// No custom shadow material for raw shader fallback
|
|
256
275
|
} else {
|
|
257
276
|
material = new THREE.MeshStandardMaterial({
|
|
258
|
-
color:
|
|
259
|
-
roughness: 1
|
|
260
|
-
metalness: 0.
|
|
261
|
-
side: THREE.DoubleSide
|
|
277
|
+
color: 0xffffff,//0x00aaff, // Golden yellow
|
|
278
|
+
roughness: 0.1, // Pure diffuse plastic surface to properly scatter un-angled SpotLight luminance
|
|
279
|
+
metalness: 0.05, // Removing metalness prevents the flat quads from reflecting the void into a dark mirror
|
|
280
|
+
side: THREE.DoubleSide,
|
|
281
|
+
map: gridTex
|
|
262
282
|
});
|
|
283
|
+
material.defines = { SLUG_MODELSPACE_UV: '' };
|
|
284
|
+
material.needsUpdate = true;
|
|
263
285
|
}
|
|
264
286
|
|
|
265
287
|
let newSlugMesh = new THREE.Mesh(geometry, material);
|
|
@@ -300,6 +322,10 @@ function animate() {
|
|
|
300
322
|
slugMesh.position.y -= 1000;
|
|
301
323
|
}
|
|
302
324
|
}
|
|
325
|
+
if (slugMesh.material.map) {
|
|
326
|
+
//let st = 1.1 + (Math.sin(performance.now() / 1000) * .5);
|
|
327
|
+
//slugMesh.material.map.repeat.set(st, st)
|
|
328
|
+
}
|
|
303
329
|
|
|
304
330
|
const glitchCheckbox = document.getElementById('matrixGlitch');
|
|
305
331
|
if (glitchCheckbox && glitchCheckbox.checked && loadedData) {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"opentype.js": "^1.3.4"
|
|
4
4
|
},
|
|
5
5
|
"name": "three-slug",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.1.0",
|
|
7
7
|
"description": "JSlug is a Javascript and WebGL port of Eric Lengyel's **Slug** font rendering algorithm, implemented for **Three.js**.",
|
|
8
8
|
"main": "src/index.js",
|
|
9
9
|
"module": "src/index.js",
|
package/src/SlugMaterial.js
CHANGED
|
@@ -138,6 +138,18 @@ flat out uvec4 vBandMaxTexCoords;
|
|
|
138
138
|
const slug_vertex = `
|
|
139
139
|
vec3 transformed = vec3( position.xy * aScaleBias.xy + aScaleBias.zw, 0.0 );
|
|
140
140
|
vTexCoords = position.xy * 0.5 + 0.5;
|
|
141
|
+
|
|
142
|
+
#ifdef SLUG_MODELSPACE_UV
|
|
143
|
+
#ifdef USE_UV
|
|
144
|
+
vUv = transformed.xy;
|
|
145
|
+
#endif
|
|
146
|
+
#ifdef USE_MAP
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
vMapUv = ( mapTransform * vec3( vec2(length(modelMatrix[0].xyz)*transformed.x,length(modelMatrix[2].xyz)*transformed.y), 1.0 ) ).xy;
|
|
150
|
+
#endif
|
|
151
|
+
#endif
|
|
152
|
+
|
|
141
153
|
vGlyphBandScale = aGlyphBandScale;
|
|
142
154
|
vBandMaxTexCoords = uvec4(aBandMaxTexCoords);
|
|
143
155
|
`;
|
|
@@ -157,7 +169,7 @@ export function injectSlug(target, ...args) {
|
|
|
157
169
|
slugData._depthMaterial = new THREE.MeshDepthMaterial({ side: THREE.DoubleSide });
|
|
158
170
|
injectSlug(slugData._depthMaterial, slugData);
|
|
159
171
|
}
|
|
160
|
-
|
|
172
|
+
|
|
161
173
|
if (!slugData._distanceMaterial) {
|
|
162
174
|
slugData._distanceMaterial = new THREE.MeshDistanceMaterial({ side: THREE.DoubleSide });
|
|
163
175
|
injectSlug(slugData._distanceMaterial, slugData);
|
|
@@ -173,9 +185,9 @@ export function injectSlug(target, ...args) {
|
|
|
173
185
|
const slugData = args[0];
|
|
174
186
|
|
|
175
187
|
if (material.userData && material.userData.slugInjected) return; // Prevent redundant native macro splicing
|
|
176
|
-
|
|
188
|
+
|
|
177
189
|
material.transparent = true;
|
|
178
|
-
material.alphaTest = 0.01;
|
|
190
|
+
material.alphaTest = 0.01;
|
|
179
191
|
|
|
180
192
|
material.onBeforeCompile = (shader) => {
|
|
181
193
|
shader.uniforms.curvesTex = { value: slugData.curvesTex };
|