three-text 0.5.2 → 0.6.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/LICENSE_THIRD_PARTY +15 -0
- package/README.md +73 -42
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/three/react.d.ts +2 -0
- package/dist/types/core/types.d.ts +2 -33
- package/dist/types/vector/{core.d.ts → core/index.d.ts} +8 -7
- package/dist/types/vector/index.d.ts +22 -25
- package/dist/types/vector/react.d.ts +4 -3
- package/dist/types/vector/slug/SlugPacker.d.ts +2 -0
- package/dist/types/vector/slug/curveUtils.d.ts +6 -0
- package/dist/types/vector/slug/index.d.ts +8 -0
- package/dist/types/vector/slug/shaderStrings.d.ts +4 -0
- package/dist/types/vector/slug/slugGLSL.d.ts +21 -0
- package/dist/types/vector/slug/slugTSL.d.ts +13 -0
- package/dist/types/vector/slug/types.d.ts +30 -0
- package/dist/types/vector/slug/unpackVertices.d.ts +11 -0
- package/dist/types/vector/webgl/index.d.ts +7 -3
- package/dist/types/vector/webgpu/index.d.ts +4 -4
- package/dist/vector/core/index.cjs +856 -0
- package/dist/vector/core/index.d.ts +63 -0
- package/dist/vector/core/index.js +854 -0
- package/dist/vector/core.cjs +4419 -240
- package/dist/vector/core.d.ts +361 -71
- package/dist/vector/core.js +4406 -226
- package/dist/vector/index.cjs +5 -229
- package/dist/vector/index.d.ts +45 -396
- package/dist/vector/index.js +3 -223
- package/dist/vector/index2.cjs +287 -0
- package/dist/vector/index2.js +264 -0
- package/dist/vector/react.cjs +37 -8
- package/dist/vector/react.d.ts +6 -3
- package/dist/vector/react.js +18 -8
- package/dist/vector/slugTSL.cjs +252 -0
- package/dist/vector/slugTSL.js +231 -0
- package/dist/vector/webgl/index.cjs +131 -201
- package/dist/vector/webgl/index.d.ts +19 -44
- package/dist/vector/webgl/index.js +131 -201
- package/dist/vector/webgpu/index.cjs +100 -283
- package/dist/vector/webgpu/index.d.ts +16 -45
- package/dist/vector/webgpu/index.js +100 -283
- package/package.json +6 -1
- package/dist/types/vector/GlyphVectorGeometryBuilder.d.ts +0 -26
- package/dist/types/vector/LoopBlinnGeometry.d.ts +0 -68
- package/dist/types/vector/loopBlinnTSL.d.ts +0 -22
- package/dist/vector/loopBlinnTSL.cjs +0 -229
- package/dist/vector/loopBlinnTSL.js +0 -207
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var THREE = require('three');
|
|
4
|
-
var webgpu = require('three/webgpu');
|
|
5
|
-
var tsl = require('three/tsl');
|
|
6
|
-
|
|
7
|
-
function _interopNamespaceDefault(e) {
|
|
8
|
-
var n = Object.create(null);
|
|
9
|
-
if (e) {
|
|
10
|
-
Object.keys(e).forEach(function (k) {
|
|
11
|
-
if (k !== 'default') {
|
|
12
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: function () { return e[k]; }
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
n.default = e;
|
|
21
|
-
return Object.freeze(n);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
var THREE__namespace = /*#__PURE__*/_interopNamespaceDefault(THREE);
|
|
25
|
-
|
|
26
|
-
// Loop-Blinn TSL adapter for Three.js WebGPURenderer.
|
|
27
|
-
// Creates meshes with TSL node materials for Loop-Blinn curve evaluation
|
|
28
|
-
// and Kokojima stencil fill. Works on WebGL (r170+) and WebGPU (r182+).
|
|
29
|
-
// Requires peer dependencies: three, three/tsl
|
|
30
|
-
// @ts-ignore - three is a peer dependency
|
|
31
|
-
// TSL fragment node: evaluates u^2 - v = 0 per fragment with
|
|
32
|
-
// screen-space derivative antialiasing. Discards outside fragments.
|
|
33
|
-
// UV convention per triangle: p0=(0,0), p1=(0.5,0), p2=(1,1)
|
|
34
|
-
const loopBlinnFragment = tsl.Fn(() => {
|
|
35
|
-
const curveUV = tsl.uv();
|
|
36
|
-
const px = tsl.dFdx(curveUV);
|
|
37
|
-
const py = tsl.dFdy(curveUV);
|
|
38
|
-
const fx = tsl.float(2.0).mul(curveUV.x).mul(px.x).sub(px.y);
|
|
39
|
-
const fy = tsl.float(2.0).mul(curveUV.x).mul(py.x).sub(py.y);
|
|
40
|
-
const denom = tsl.sqrt(fx.mul(fx).add(fy.mul(fy)));
|
|
41
|
-
const f = curveUV.x.mul(curveUV.x).sub(curveUV.y);
|
|
42
|
-
const sd = f.div(denom.max(1e-6));
|
|
43
|
-
const alpha = tsl.clamp(tsl.float(0.5).sub(sd), 0.0, 1.0);
|
|
44
|
-
tsl.Discard(alpha.lessThanEqual(0.0));
|
|
45
|
-
return tsl.vec4(1.0, 1.0, 1.0, alpha);
|
|
46
|
-
});
|
|
47
|
-
function setGlyphAttrsOnGeometry(geo, attrs, offsetX = 0, offsetY = 0) {
|
|
48
|
-
if (!attrs)
|
|
49
|
-
return;
|
|
50
|
-
const glyphCenter = new Float32Array(attrs.glyphCenter);
|
|
51
|
-
if (offsetX !== 0 || offsetY !== 0) {
|
|
52
|
-
for (let i = 0; i < glyphCenter.length; i += 3) {
|
|
53
|
-
glyphCenter[i] += offsetX;
|
|
54
|
-
glyphCenter[i + 1] += offsetY;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
geo.setAttribute('glyphCenter', new THREE__namespace.Float32BufferAttribute(glyphCenter, 3));
|
|
58
|
-
geo.setAttribute('glyphIndex', new THREE__namespace.Float32BufferAttribute(attrs.glyphIndex, 1));
|
|
59
|
-
geo.setAttribute('glyphProgress', new THREE__namespace.Float32BufferAttribute(attrs.glyphProgress, 1));
|
|
60
|
-
geo.setAttribute('glyphLineIndex', new THREE__namespace.Float32BufferAttribute(attrs.glyphLineIndex, 1));
|
|
61
|
-
geo.setAttribute('glyphBaselineY', new THREE__namespace.Float32BufferAttribute(attrs.glyphBaselineY, 1));
|
|
62
|
-
}
|
|
63
|
-
// Nonzero winding via two-sided stencil: front faces increment,
|
|
64
|
-
// back faces decrement. Three.js materials only expose one set of
|
|
65
|
-
// stencil ops (no front/back split), so we use two single-sided
|
|
66
|
-
// meshes per pass. A Three.js PR to add stencilBack* properties
|
|
67
|
-
// would let us collapse these back to one DoubleSide mesh each.
|
|
68
|
-
function applyStencilNonzero(mat, side) {
|
|
69
|
-
mat.depthTest = false;
|
|
70
|
-
mat.depthWrite = false;
|
|
71
|
-
mat.side = side;
|
|
72
|
-
mat.stencilWrite = true;
|
|
73
|
-
mat.stencilFunc = THREE__namespace.AlwaysStencilFunc;
|
|
74
|
-
mat.stencilRef = 0;
|
|
75
|
-
mat.stencilFuncMask = 0xFF;
|
|
76
|
-
mat.stencilWriteMask = 0xFF;
|
|
77
|
-
mat.stencilFail = THREE__namespace.KeepStencilOp;
|
|
78
|
-
mat.stencilZFail = THREE__namespace.KeepStencilOp;
|
|
79
|
-
mat.stencilZPass = side === THREE__namespace.FrontSide
|
|
80
|
-
? THREE__namespace.IncrementWrapStencilOp
|
|
81
|
-
: THREE__namespace.DecrementWrapStencilOp;
|
|
82
|
-
}
|
|
83
|
-
function createStencilMaterials(opts) {
|
|
84
|
-
function makePair(extra) {
|
|
85
|
-
const mats = [THREE__namespace.FrontSide, THREE__namespace.BackSide].map(side => {
|
|
86
|
-
const mat = new webgpu.MeshBasicNodeMaterial();
|
|
87
|
-
applyStencilNonzero(mat, side);
|
|
88
|
-
mat.colorWrite = false;
|
|
89
|
-
if (opts.positionNode)
|
|
90
|
-
mat.positionNode = opts.positionNode;
|
|
91
|
-
if (extra)
|
|
92
|
-
extra(mat);
|
|
93
|
-
return mat;
|
|
94
|
-
});
|
|
95
|
-
return mats;
|
|
96
|
-
}
|
|
97
|
-
const interiorMats = makePair();
|
|
98
|
-
const curveMats = makePair((mat) => {
|
|
99
|
-
mat.alphaToCoverage = true;
|
|
100
|
-
mat.fragmentNode = loopBlinnFragment();
|
|
101
|
-
});
|
|
102
|
-
const fillMat = new webgpu.MeshBasicNodeMaterial();
|
|
103
|
-
fillMat.depthTest = false;
|
|
104
|
-
fillMat.depthWrite = false;
|
|
105
|
-
fillMat.side = THREE__namespace.DoubleSide;
|
|
106
|
-
fillMat.stencilWrite = true;
|
|
107
|
-
fillMat.stencilFunc = THREE__namespace.NotEqualStencilFunc;
|
|
108
|
-
fillMat.stencilRef = 0;
|
|
109
|
-
fillMat.stencilFuncMask = 0xFF;
|
|
110
|
-
fillMat.stencilWriteMask = 0xFF;
|
|
111
|
-
fillMat.stencilFail = THREE__namespace.KeepStencilOp;
|
|
112
|
-
fillMat.stencilZFail = THREE__namespace.KeepStencilOp;
|
|
113
|
-
fillMat.stencilZPass = THREE__namespace.ZeroStencilOp;
|
|
114
|
-
if (opts.positionNode)
|
|
115
|
-
fillMat.positionNode = opts.positionNode;
|
|
116
|
-
if (opts.colorNode) {
|
|
117
|
-
fillMat.colorNode = opts.colorNode;
|
|
118
|
-
}
|
|
119
|
-
else if (opts.color !== undefined) {
|
|
120
|
-
fillMat.color = new THREE__namespace.Color(opts.color);
|
|
121
|
-
}
|
|
122
|
-
return { interiorMats, curveMats, fillMat };
|
|
123
|
-
}
|
|
124
|
-
// Three meshes rendered in order (via renderOrder or sequential draws):
|
|
125
|
-
// 1. interiorMesh - nonzero stencil winding (fan interiors, no color output)
|
|
126
|
-
// 2. curveMesh - nonzero stencil winding (Loop-Blinn curve eval, alpha-to-coverage)
|
|
127
|
-
// 3. fillMesh - color where stencil != 0, then zeros stencil
|
|
128
|
-
function createVectorMeshes(data, options) {
|
|
129
|
-
const opts = (options !== null && options !== undefined && typeof options === 'object' && !(options instanceof THREE__namespace.Color))
|
|
130
|
-
? options
|
|
131
|
-
: { color: options };
|
|
132
|
-
const interiorGeo = new THREE__namespace.BufferGeometry();
|
|
133
|
-
interiorGeo.setAttribute('position', new THREE__namespace.Float32BufferAttribute(data.interiorPositions, 3));
|
|
134
|
-
interiorGeo.setIndex(new THREE__namespace.BufferAttribute(data.interiorIndices, 1));
|
|
135
|
-
setGlyphAttrsOnGeometry(interiorGeo, data.interiorGlyphAttrs);
|
|
136
|
-
const curveGeo = new THREE__namespace.BufferGeometry();
|
|
137
|
-
curveGeo.setAttribute('position', new THREE__namespace.Float32BufferAttribute(data.curvePositions, 3));
|
|
138
|
-
const curveVertCount = data.curvePositions.length / 3;
|
|
139
|
-
const curveUVs = new Float32Array(curveVertCount * 2);
|
|
140
|
-
for (let i = 0; i < curveVertCount; i += 3) {
|
|
141
|
-
curveUVs[i * 2] = 0;
|
|
142
|
-
curveUVs[i * 2 + 1] = 0;
|
|
143
|
-
curveUVs[i * 2 + 2] = 0.5;
|
|
144
|
-
curveUVs[i * 2 + 3] = 0;
|
|
145
|
-
curveUVs[i * 2 + 4] = 1;
|
|
146
|
-
curveUVs[i * 2 + 5] = 1;
|
|
147
|
-
}
|
|
148
|
-
curveGeo.setAttribute('uv', new THREE__namespace.Float32BufferAttribute(curveUVs, 2));
|
|
149
|
-
setGlyphAttrsOnGeometry(curveGeo, data.curveGlyphAttrs);
|
|
150
|
-
const fillGeo = new THREE__namespace.BufferGeometry();
|
|
151
|
-
fillGeo.setAttribute('position', new THREE__namespace.Float32BufferAttribute(data.fillPositions, 3));
|
|
152
|
-
fillGeo.setIndex(new THREE__namespace.BufferAttribute(data.fillIndices, 1));
|
|
153
|
-
setGlyphAttrsOnGeometry(fillGeo, data.fillGlyphAttrs);
|
|
154
|
-
if (opts.center !== false && data.planeBounds) {
|
|
155
|
-
const cx = (data.planeBounds.min.x + data.planeBounds.max.x) * 0.5;
|
|
156
|
-
const cy = (data.planeBounds.min.y + data.planeBounds.max.y) * 0.5;
|
|
157
|
-
for (const geo of [interiorGeo, curveGeo, fillGeo]) {
|
|
158
|
-
geo.translate(-cx, -cy, 0);
|
|
159
|
-
const gc = geo.attributes.glyphCenter;
|
|
160
|
-
if (gc) {
|
|
161
|
-
for (let i = 0; i < gc.count; i++) {
|
|
162
|
-
gc.setX(i, gc.getX(i) - cx);
|
|
163
|
-
gc.setY(i, gc.getY(i) - cy);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
let { interiorMats, curveMats, fillMat } = createStencilMaterials(opts);
|
|
169
|
-
const interiorMesh = new THREE__namespace.Group();
|
|
170
|
-
interiorMats.forEach(mat => {
|
|
171
|
-
const m = new THREE__namespace.Mesh(interiorGeo, mat);
|
|
172
|
-
m.renderOrder = 0;
|
|
173
|
-
interiorMesh.add(m);
|
|
174
|
-
});
|
|
175
|
-
const curveMesh = new THREE__namespace.Group();
|
|
176
|
-
curveMats.forEach(mat => {
|
|
177
|
-
const m = new THREE__namespace.Mesh(curveGeo, mat);
|
|
178
|
-
m.renderOrder = 1;
|
|
179
|
-
curveMesh.add(m);
|
|
180
|
-
});
|
|
181
|
-
const fillMesh = new THREE__namespace.Mesh(fillGeo, fillMat);
|
|
182
|
-
fillMesh.renderOrder = 2;
|
|
183
|
-
const group = new THREE__namespace.Group();
|
|
184
|
-
group.add(interiorMesh, curveMesh, fillMesh);
|
|
185
|
-
return {
|
|
186
|
-
group,
|
|
187
|
-
interiorMesh,
|
|
188
|
-
curveMesh,
|
|
189
|
-
fillMesh,
|
|
190
|
-
interiorGeometry: interiorGeo,
|
|
191
|
-
curveGeometry: curveGeo,
|
|
192
|
-
fillGeometry: fillGeo,
|
|
193
|
-
setOffset(x, y, z = 0) {
|
|
194
|
-
interiorMesh.position.set(x, y, z);
|
|
195
|
-
curveMesh.position.set(x, y, z);
|
|
196
|
-
fillMesh.position.set(x, y, z);
|
|
197
|
-
},
|
|
198
|
-
updateMaterials(newOpts) {
|
|
199
|
-
const merged = { ...opts, ...newOpts };
|
|
200
|
-
const created = createStencilMaterials(merged);
|
|
201
|
-
interiorMesh.children.forEach((c, i) => {
|
|
202
|
-
const m = c;
|
|
203
|
-
m.material.dispose();
|
|
204
|
-
m.material = created.interiorMats[i];
|
|
205
|
-
});
|
|
206
|
-
curveMesh.children.forEach((c, i) => {
|
|
207
|
-
const m = c;
|
|
208
|
-
m.material.dispose();
|
|
209
|
-
m.material = created.curveMats[i];
|
|
210
|
-
});
|
|
211
|
-
fillMesh.material.dispose();
|
|
212
|
-
fillMesh.material = created.fillMat;
|
|
213
|
-
interiorMats = created.interiorMats;
|
|
214
|
-
curveMats = created.curveMats;
|
|
215
|
-
fillMat = created.fillMat;
|
|
216
|
-
},
|
|
217
|
-
dispose() {
|
|
218
|
-
interiorGeo.dispose();
|
|
219
|
-
curveGeo.dispose();
|
|
220
|
-
fillGeo.dispose();
|
|
221
|
-
interiorMesh.children.forEach(c => c.material.dispose());
|
|
222
|
-
curveMesh.children.forEach(c => c.material.dispose());
|
|
223
|
-
fillMesh.material.dispose();
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
exports.createVectorMeshes = createVectorMeshes;
|
|
229
|
-
exports.loopBlinnFragment = loopBlinnFragment;
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import { MeshBasicNodeMaterial } from 'three/webgpu';
|
|
3
|
-
import { Fn, uv, dFdx, dFdy, float, sqrt, clamp, Discard, vec4 } from 'three/tsl';
|
|
4
|
-
|
|
5
|
-
// Loop-Blinn TSL adapter for Three.js WebGPURenderer.
|
|
6
|
-
// Creates meshes with TSL node materials for Loop-Blinn curve evaluation
|
|
7
|
-
// and Kokojima stencil fill. Works on WebGL (r170+) and WebGPU (r182+).
|
|
8
|
-
// Requires peer dependencies: three, three/tsl
|
|
9
|
-
// @ts-ignore - three is a peer dependency
|
|
10
|
-
// TSL fragment node: evaluates u^2 - v = 0 per fragment with
|
|
11
|
-
// screen-space derivative antialiasing. Discards outside fragments.
|
|
12
|
-
// UV convention per triangle: p0=(0,0), p1=(0.5,0), p2=(1,1)
|
|
13
|
-
const loopBlinnFragment = Fn(() => {
|
|
14
|
-
const curveUV = uv();
|
|
15
|
-
const px = dFdx(curveUV);
|
|
16
|
-
const py = dFdy(curveUV);
|
|
17
|
-
const fx = float(2.0).mul(curveUV.x).mul(px.x).sub(px.y);
|
|
18
|
-
const fy = float(2.0).mul(curveUV.x).mul(py.x).sub(py.y);
|
|
19
|
-
const denom = sqrt(fx.mul(fx).add(fy.mul(fy)));
|
|
20
|
-
const f = curveUV.x.mul(curveUV.x).sub(curveUV.y);
|
|
21
|
-
const sd = f.div(denom.max(1e-6));
|
|
22
|
-
const alpha = clamp(float(0.5).sub(sd), 0.0, 1.0);
|
|
23
|
-
Discard(alpha.lessThanEqual(0.0));
|
|
24
|
-
return vec4(1.0, 1.0, 1.0, alpha);
|
|
25
|
-
});
|
|
26
|
-
function setGlyphAttrsOnGeometry(geo, attrs, offsetX = 0, offsetY = 0) {
|
|
27
|
-
if (!attrs)
|
|
28
|
-
return;
|
|
29
|
-
const glyphCenter = new Float32Array(attrs.glyphCenter);
|
|
30
|
-
if (offsetX !== 0 || offsetY !== 0) {
|
|
31
|
-
for (let i = 0; i < glyphCenter.length; i += 3) {
|
|
32
|
-
glyphCenter[i] += offsetX;
|
|
33
|
-
glyphCenter[i + 1] += offsetY;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
geo.setAttribute('glyphCenter', new THREE.Float32BufferAttribute(glyphCenter, 3));
|
|
37
|
-
geo.setAttribute('glyphIndex', new THREE.Float32BufferAttribute(attrs.glyphIndex, 1));
|
|
38
|
-
geo.setAttribute('glyphProgress', new THREE.Float32BufferAttribute(attrs.glyphProgress, 1));
|
|
39
|
-
geo.setAttribute('glyphLineIndex', new THREE.Float32BufferAttribute(attrs.glyphLineIndex, 1));
|
|
40
|
-
geo.setAttribute('glyphBaselineY', new THREE.Float32BufferAttribute(attrs.glyphBaselineY, 1));
|
|
41
|
-
}
|
|
42
|
-
// Nonzero winding via two-sided stencil: front faces increment,
|
|
43
|
-
// back faces decrement. Three.js materials only expose one set of
|
|
44
|
-
// stencil ops (no front/back split), so we use two single-sided
|
|
45
|
-
// meshes per pass. A Three.js PR to add stencilBack* properties
|
|
46
|
-
// would let us collapse these back to one DoubleSide mesh each.
|
|
47
|
-
function applyStencilNonzero(mat, side) {
|
|
48
|
-
mat.depthTest = false;
|
|
49
|
-
mat.depthWrite = false;
|
|
50
|
-
mat.side = side;
|
|
51
|
-
mat.stencilWrite = true;
|
|
52
|
-
mat.stencilFunc = THREE.AlwaysStencilFunc;
|
|
53
|
-
mat.stencilRef = 0;
|
|
54
|
-
mat.stencilFuncMask = 0xFF;
|
|
55
|
-
mat.stencilWriteMask = 0xFF;
|
|
56
|
-
mat.stencilFail = THREE.KeepStencilOp;
|
|
57
|
-
mat.stencilZFail = THREE.KeepStencilOp;
|
|
58
|
-
mat.stencilZPass = side === THREE.FrontSide
|
|
59
|
-
? THREE.IncrementWrapStencilOp
|
|
60
|
-
: THREE.DecrementWrapStencilOp;
|
|
61
|
-
}
|
|
62
|
-
function createStencilMaterials(opts) {
|
|
63
|
-
function makePair(extra) {
|
|
64
|
-
const mats = [THREE.FrontSide, THREE.BackSide].map(side => {
|
|
65
|
-
const mat = new MeshBasicNodeMaterial();
|
|
66
|
-
applyStencilNonzero(mat, side);
|
|
67
|
-
mat.colorWrite = false;
|
|
68
|
-
if (opts.positionNode)
|
|
69
|
-
mat.positionNode = opts.positionNode;
|
|
70
|
-
if (extra)
|
|
71
|
-
extra(mat);
|
|
72
|
-
return mat;
|
|
73
|
-
});
|
|
74
|
-
return mats;
|
|
75
|
-
}
|
|
76
|
-
const interiorMats = makePair();
|
|
77
|
-
const curveMats = makePair((mat) => {
|
|
78
|
-
mat.alphaToCoverage = true;
|
|
79
|
-
mat.fragmentNode = loopBlinnFragment();
|
|
80
|
-
});
|
|
81
|
-
const fillMat = new MeshBasicNodeMaterial();
|
|
82
|
-
fillMat.depthTest = false;
|
|
83
|
-
fillMat.depthWrite = false;
|
|
84
|
-
fillMat.side = THREE.DoubleSide;
|
|
85
|
-
fillMat.stencilWrite = true;
|
|
86
|
-
fillMat.stencilFunc = THREE.NotEqualStencilFunc;
|
|
87
|
-
fillMat.stencilRef = 0;
|
|
88
|
-
fillMat.stencilFuncMask = 0xFF;
|
|
89
|
-
fillMat.stencilWriteMask = 0xFF;
|
|
90
|
-
fillMat.stencilFail = THREE.KeepStencilOp;
|
|
91
|
-
fillMat.stencilZFail = THREE.KeepStencilOp;
|
|
92
|
-
fillMat.stencilZPass = THREE.ZeroStencilOp;
|
|
93
|
-
if (opts.positionNode)
|
|
94
|
-
fillMat.positionNode = opts.positionNode;
|
|
95
|
-
if (opts.colorNode) {
|
|
96
|
-
fillMat.colorNode = opts.colorNode;
|
|
97
|
-
}
|
|
98
|
-
else if (opts.color !== undefined) {
|
|
99
|
-
fillMat.color = new THREE.Color(opts.color);
|
|
100
|
-
}
|
|
101
|
-
return { interiorMats, curveMats, fillMat };
|
|
102
|
-
}
|
|
103
|
-
// Three meshes rendered in order (via renderOrder or sequential draws):
|
|
104
|
-
// 1. interiorMesh - nonzero stencil winding (fan interiors, no color output)
|
|
105
|
-
// 2. curveMesh - nonzero stencil winding (Loop-Blinn curve eval, alpha-to-coverage)
|
|
106
|
-
// 3. fillMesh - color where stencil != 0, then zeros stencil
|
|
107
|
-
function createVectorMeshes(data, options) {
|
|
108
|
-
const opts = (options !== null && options !== undefined && typeof options === 'object' && !(options instanceof THREE.Color))
|
|
109
|
-
? options
|
|
110
|
-
: { color: options };
|
|
111
|
-
const interiorGeo = new THREE.BufferGeometry();
|
|
112
|
-
interiorGeo.setAttribute('position', new THREE.Float32BufferAttribute(data.interiorPositions, 3));
|
|
113
|
-
interiorGeo.setIndex(new THREE.BufferAttribute(data.interiorIndices, 1));
|
|
114
|
-
setGlyphAttrsOnGeometry(interiorGeo, data.interiorGlyphAttrs);
|
|
115
|
-
const curveGeo = new THREE.BufferGeometry();
|
|
116
|
-
curveGeo.setAttribute('position', new THREE.Float32BufferAttribute(data.curvePositions, 3));
|
|
117
|
-
const curveVertCount = data.curvePositions.length / 3;
|
|
118
|
-
const curveUVs = new Float32Array(curveVertCount * 2);
|
|
119
|
-
for (let i = 0; i < curveVertCount; i += 3) {
|
|
120
|
-
curveUVs[i * 2] = 0;
|
|
121
|
-
curveUVs[i * 2 + 1] = 0;
|
|
122
|
-
curveUVs[i * 2 + 2] = 0.5;
|
|
123
|
-
curveUVs[i * 2 + 3] = 0;
|
|
124
|
-
curveUVs[i * 2 + 4] = 1;
|
|
125
|
-
curveUVs[i * 2 + 5] = 1;
|
|
126
|
-
}
|
|
127
|
-
curveGeo.setAttribute('uv', new THREE.Float32BufferAttribute(curveUVs, 2));
|
|
128
|
-
setGlyphAttrsOnGeometry(curveGeo, data.curveGlyphAttrs);
|
|
129
|
-
const fillGeo = new THREE.BufferGeometry();
|
|
130
|
-
fillGeo.setAttribute('position', new THREE.Float32BufferAttribute(data.fillPositions, 3));
|
|
131
|
-
fillGeo.setIndex(new THREE.BufferAttribute(data.fillIndices, 1));
|
|
132
|
-
setGlyphAttrsOnGeometry(fillGeo, data.fillGlyphAttrs);
|
|
133
|
-
if (opts.center !== false && data.planeBounds) {
|
|
134
|
-
const cx = (data.planeBounds.min.x + data.planeBounds.max.x) * 0.5;
|
|
135
|
-
const cy = (data.planeBounds.min.y + data.planeBounds.max.y) * 0.5;
|
|
136
|
-
for (const geo of [interiorGeo, curveGeo, fillGeo]) {
|
|
137
|
-
geo.translate(-cx, -cy, 0);
|
|
138
|
-
const gc = geo.attributes.glyphCenter;
|
|
139
|
-
if (gc) {
|
|
140
|
-
for (let i = 0; i < gc.count; i++) {
|
|
141
|
-
gc.setX(i, gc.getX(i) - cx);
|
|
142
|
-
gc.setY(i, gc.getY(i) - cy);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
let { interiorMats, curveMats, fillMat } = createStencilMaterials(opts);
|
|
148
|
-
const interiorMesh = new THREE.Group();
|
|
149
|
-
interiorMats.forEach(mat => {
|
|
150
|
-
const m = new THREE.Mesh(interiorGeo, mat);
|
|
151
|
-
m.renderOrder = 0;
|
|
152
|
-
interiorMesh.add(m);
|
|
153
|
-
});
|
|
154
|
-
const curveMesh = new THREE.Group();
|
|
155
|
-
curveMats.forEach(mat => {
|
|
156
|
-
const m = new THREE.Mesh(curveGeo, mat);
|
|
157
|
-
m.renderOrder = 1;
|
|
158
|
-
curveMesh.add(m);
|
|
159
|
-
});
|
|
160
|
-
const fillMesh = new THREE.Mesh(fillGeo, fillMat);
|
|
161
|
-
fillMesh.renderOrder = 2;
|
|
162
|
-
const group = new THREE.Group();
|
|
163
|
-
group.add(interiorMesh, curveMesh, fillMesh);
|
|
164
|
-
return {
|
|
165
|
-
group,
|
|
166
|
-
interiorMesh,
|
|
167
|
-
curveMesh,
|
|
168
|
-
fillMesh,
|
|
169
|
-
interiorGeometry: interiorGeo,
|
|
170
|
-
curveGeometry: curveGeo,
|
|
171
|
-
fillGeometry: fillGeo,
|
|
172
|
-
setOffset(x, y, z = 0) {
|
|
173
|
-
interiorMesh.position.set(x, y, z);
|
|
174
|
-
curveMesh.position.set(x, y, z);
|
|
175
|
-
fillMesh.position.set(x, y, z);
|
|
176
|
-
},
|
|
177
|
-
updateMaterials(newOpts) {
|
|
178
|
-
const merged = { ...opts, ...newOpts };
|
|
179
|
-
const created = createStencilMaterials(merged);
|
|
180
|
-
interiorMesh.children.forEach((c, i) => {
|
|
181
|
-
const m = c;
|
|
182
|
-
m.material.dispose();
|
|
183
|
-
m.material = created.interiorMats[i];
|
|
184
|
-
});
|
|
185
|
-
curveMesh.children.forEach((c, i) => {
|
|
186
|
-
const m = c;
|
|
187
|
-
m.material.dispose();
|
|
188
|
-
m.material = created.curveMats[i];
|
|
189
|
-
});
|
|
190
|
-
fillMesh.material.dispose();
|
|
191
|
-
fillMesh.material = created.fillMat;
|
|
192
|
-
interiorMats = created.interiorMats;
|
|
193
|
-
curveMats = created.curveMats;
|
|
194
|
-
fillMat = created.fillMat;
|
|
195
|
-
},
|
|
196
|
-
dispose() {
|
|
197
|
-
interiorGeo.dispose();
|
|
198
|
-
curveGeo.dispose();
|
|
199
|
-
fillGeo.dispose();
|
|
200
|
-
interiorMesh.children.forEach(c => c.material.dispose());
|
|
201
|
-
curveMesh.children.forEach(c => c.material.dispose());
|
|
202
|
-
fillMesh.material.dispose();
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export { createVectorMeshes, loopBlinnFragment };
|