forked from Experience-Monks/three-bmfont-text
-
Notifications
You must be signed in to change notification settings - Fork 1
/
test-shader.js
92 lines (80 loc) · 2.34 KB
/
test-shader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
This is an example of 3D rendering with
a custom shader, special per-line shader effects,
and glslify.
*/
import * as THREE from 'three';
import {createGeometry} from '../'
import {load} from './load';
import {testScene} from './test-scene';
import quote from 'sun-tzu-quotes'
let duration = 3
let time = 0
load({
font: 'fnt/DejaVu-sdf.fnt',
image: 'fnt/DejaVu-sdf.png'
}, init);
function next (geom, text) {
// set new text string
geom.update(quote());
const lines = geom.visibleGlyphs.map(function (glyph) {
return glyph.line;
})
const lineCount = lines.reduce(function (a, b) {
return Math.max(a, b);
}, 0)
// for each quad, let's give it a vertex attribute
// with the line index
const lineData = lines.map(function (line) {
// map to 0..1 for attribute
const t = lineCount <= 1 ? 1 : (line / (lineCount - 1));
// quad - 4 verts
return [ t, t, t, t ];
}).reduce(function (a, b) {
return a.concat(b);
}, []);
// update the "line" vertex attribute
geom.setAttribute('line', new THREE.BufferAttribute(new Float32Array(lineData), 1));
// center the text
const layout = geom.layout;
text.position.x = -layout.width / 2;
text.position.y = layout.height / 2;
}
function init(font, texture) {
const geom = createGeometry({
font: font,
align: 'center',
width: 500,
flipY: texture.flipY
});
const material = new THREE.RawShaderMaterial({
vertexShader: require('./shaders/fx.vert'),
fragmentShader: require('./shaders/fx.frag'),
uniforms: {
animate: { type: 'f', value: 1 },
iGlobalTime: { type: 'f', value: 0 },
map: { type: 't', value: texture },
color: { type: 'c', value: new THREE.Color('#000') }
},
transparent: true,
side: THREE.DoubleSide,
depthTest: false
});
const text = new THREE.Mesh(geom, material);
// scale it down so it fits in our 3D units
const textAnchor = new THREE.Object3D();
textAnchor.scale.multiplyScalar(-0.005);
textAnchor.add(text);
const { scene, camera, controls } = testScene({ animate: (dt) => {
time += dt;
material.uniforms.iGlobalTime.value = time;
material.uniforms.animate.value = time / duration;
if (time > duration) {
time = 0;
next(geom, text);
}
}});
next(geom, text);
console.error('init', font, scene, camera, controls);
scene.add(textAnchor);
}