postext-folio 0.72.1 → 0.73.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/dist/environments.d.ts.map +1 -1
- package/dist/environments.js +9 -2
- package/dist/environments.js.map +1 -1
- package/dist/pageFlip/finish.d.ts +118 -0
- package/dist/pageFlip/finish.d.ts.map +1 -0
- package/dist/pageFlip/finish.js +225 -0
- package/dist/pageFlip/finish.js.map +1 -0
- package/dist/pageFlip/leaf.d.ts.map +1 -1
- package/dist/pageFlip/leaf.js +3 -0
- package/dist/pageFlip/leaf.js.map +1 -1
- package/dist/pageFlip/materials.d.ts +4 -2
- package/dist/pageFlip/materials.d.ts.map +1 -1
- package/dist/pageFlip/materials.js +32 -6
- package/dist/pageFlip/materials.js.map +1 -1
- package/dist/pageFlip/mirror.d.ts +15 -0
- package/dist/pageFlip/mirror.d.ts.map +1 -0
- package/dist/pageFlip/mirror.js +54 -0
- package/dist/pageFlip/mirror.js.map +1 -0
- package/dist/pageFlip/occlusion.d.ts +11 -1
- package/dist/pageFlip/occlusion.d.ts.map +1 -1
- package/dist/pageFlip/occlusion.js +9 -4
- package/dist/pageFlip/occlusion.js.map +1 -1
- package/dist/pageFlip/through.d.ts +140 -0
- package/dist/pageFlip/through.d.ts.map +1 -0
- package/dist/pageFlip/through.js +235 -0
- package/dist/pageFlip/through.js.map +1 -0
- package/dist/pageFlip.d.ts +9 -0
- package/dist/pageFlip.d.ts.map +1 -1
- package/dist/pageFlip.js +33 -51
- package/dist/pageFlip.js.map +1 -1
- package/dist/postext/painting.d.ts +2 -0
- package/dist/postext/painting.d.ts.map +1 -1
- package/dist/postext/painting.js +28 -10
- package/dist/postext/painting.js.map +1 -1
- package/dist/postext/state.d.ts +4 -1
- package/dist/postext/state.d.ts.map +1 -1
- package/dist/postext/through.d.ts +37 -0
- package/dist/postext/through.d.ts.map +1 -0
- package/dist/postext/through.js +178 -0
- package/dist/postext/through.js.map +1 -0
- package/dist/postext.d.ts.map +1 -1
- package/dist/postext.js +17 -2
- package/dist/postext.js.map +1 -1
- package/dist/viewer/constants.d.ts +4 -0
- package/dist/viewer/constants.d.ts.map +1 -1
- package/dist/viewer/constants.js +13 -0
- package/dist/viewer/constants.js.map +1 -1
- package/dist/viewer/turning.d.ts.map +1 -1
- package/dist/viewer/turning.js +2 -1
- package/dist/viewer/turning.js.map +1 -1
- package/dist/viewer/types.d.ts +2 -0
- package/dist/viewer/types.d.ts.map +1 -1
- package/dist/viewer.d.ts.map +1 -1
- package/dist/viewer.js +4 -2
- package/dist/viewer.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// Die-cuts in the WebGL book (#1569). A page with holes (or a shaped leaf)
|
|
2
|
+
// is painted with them transparent: its own texture's alpha is the cut,
|
|
3
|
+
// sharp at full resolution.
|
|
4
|
+
// - An open page has nothing under it but the edges of its block, so it
|
|
5
|
+
// draws its holes itself, from a *through* texture (rgb: the stack seen
|
|
6
|
+
// straight down, a: the depth of the layer each texel shows, in leaves).
|
|
7
|
+
// The fragment walks the view ray down the stack a leaf at a time: a
|
|
8
|
+
// layer shows where the ray reaches it, a cut wall where it meets paper
|
|
9
|
+
// first; the key light's ray is walked back up for the shadow the walls
|
|
10
|
+
// throw, and the deep pages darken with depth.
|
|
11
|
+
// - A leaf in the air (or the block of a long jump) is real geometry: it
|
|
12
|
+
// discards its holes, in its colour, in its key-light depth and in the
|
|
13
|
+
// height map, so the open page under it shows and shadows fall through.
|
|
14
|
+
// - Paper cut away past the leaf's outline (rounded corners, a shaped
|
|
15
|
+
// book) is discarded everywhere.
|
|
16
|
+
import { DataTexture, LinearFilter, MeshDepthMaterial, RGBADepthPacking, RGBAFormat, SRGBColorSpace, UnsignedByteType } from 'three';
|
|
17
|
+
/** A through picture as a texture: its colour sRGB like the pages' (the
|
|
18
|
+
* alpha, the depth codes, stays as it is), filtered; the shader reads
|
|
19
|
+
* the codes texel by texel (`texelFetch`), never blended. */
|
|
20
|
+
export function throughTexture(through) {
|
|
21
|
+
const texture = new DataTexture(new Uint8Array(through.data.buffer, through.data.byteOffset, through.data.byteLength), through.width, through.height, RGBAFormat, UnsignedByteType);
|
|
22
|
+
texture.colorSpace = SRGBColorSpace;
|
|
23
|
+
texture.minFilter = LinearFilter;
|
|
24
|
+
texture.magFilter = LinearFilter;
|
|
25
|
+
texture.generateMipmaps = false;
|
|
26
|
+
texture.needsUpdate = true;
|
|
27
|
+
return texture;
|
|
28
|
+
}
|
|
29
|
+
/** How a page material treats a cut: off (no face is cut), an open page
|
|
30
|
+
* (draws its holes), a leaf in the air (discards them). */
|
|
31
|
+
export const CUT_OFF = 0;
|
|
32
|
+
export const CUT_OPEN = 1;
|
|
33
|
+
export const CUT_AIR = 2;
|
|
34
|
+
export const cutUniforms = (mode) => ({
|
|
35
|
+
uCutMode: { value: mode },
|
|
36
|
+
uHasFrontCut: { value: 0 },
|
|
37
|
+
uHasBackCut: { value: 0 },
|
|
38
|
+
uFrontThrough: { value: null },
|
|
39
|
+
uBackThrough: { value: null },
|
|
40
|
+
uHasFrontThrough: { value: 0 },
|
|
41
|
+
uHasBackThrough: { value: 0 },
|
|
42
|
+
uThroughLayers: { value: 0 },
|
|
43
|
+
uLeafDepth: { value: 1 },
|
|
44
|
+
});
|
|
45
|
+
/** Declarations for the page material's fragment shader. */
|
|
46
|
+
export const CUT_PARS = /* glsl */ `
|
|
47
|
+
uniform float uCutMode;
|
|
48
|
+
uniform float uHasFrontCut;
|
|
49
|
+
uniform float uHasBackCut;
|
|
50
|
+
uniform sampler2D uFrontThrough;
|
|
51
|
+
uniform sampler2D uBackThrough;
|
|
52
|
+
uniform float uHasFrontThrough;
|
|
53
|
+
uniform float uHasBackThrough;
|
|
54
|
+
uniform float uThroughLayers;
|
|
55
|
+
uniform float uLeafDepth;
|
|
56
|
+
// The direct light a hole's wall keeps from a point deep in it, and the
|
|
57
|
+
// sky its depth leaves it.
|
|
58
|
+
float throughLit = 1.0;
|
|
59
|
+
float throughAo = 1.0;
|
|
60
|
+
vec4 throughAt(bool front, ivec2 t) {
|
|
61
|
+
return front ? texelFetch(uFrontThrough, t, 0) : texelFetch(uBackThrough, t, 0);
|
|
62
|
+
}
|
|
63
|
+
// The depth code at a point of the face (y down), 0 off the holes.
|
|
64
|
+
float throughDepth(bool front, vec2 p, vec2 size) {
|
|
65
|
+
ivec2 t = ivec2(clamp(p, vec2(0.0), vec2(0.999999)) * size);
|
|
66
|
+
return floor(throughAt(front, t).a * 255.0 + 0.5);
|
|
67
|
+
}
|
|
68
|
+
vec3 throughColour(bool front, vec2 p) {
|
|
69
|
+
return front ? texture2D(uFrontThrough, p).rgb : texture2D(uBackThrough, p).rgb;
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
/**
|
|
73
|
+
* In `map_fragment`, once the face's page texel `page` (RGBA, alpha the
|
|
74
|
+
* cut) and its print `ink` are known. A leaf in the air drops its holes;
|
|
75
|
+
* an open page draws them: the view ray walked down the stack.
|
|
76
|
+
*/
|
|
77
|
+
export const CUT_FRAGMENT = /* glsl */ `
|
|
78
|
+
if (uCutMode > 0.5 && (front ? uHasFrontCut : uHasBackCut) > 0.5 && cutA < 0.999) {
|
|
79
|
+
if (uCutMode > 1.5) {
|
|
80
|
+
if (cutA < 0.5) discard;
|
|
81
|
+
} else {
|
|
82
|
+
vec2 p0 = vec2(tuv.x, 1.0 - tuv.y);
|
|
83
|
+
bool hasThrough = (front ? uHasFrontThrough : uHasBackThrough) > 0.5;
|
|
84
|
+
vec2 size = hasThrough ? vec2(front ? textureSize(uFrontThrough, 0) : textureSize(uBackThrough, 0)) : vec2(1.0);
|
|
85
|
+
float d0 = hasThrough ? throughDepth(front, p0, size) : 0.0;
|
|
86
|
+
// The picture is coarser than the page: at the hole's rim it may
|
|
87
|
+
// still say paper where the page's alpha says hole.
|
|
88
|
+
if (hasThrough && d0 < 0.5) {
|
|
89
|
+
for (int i = 0; i < 4; i++) {
|
|
90
|
+
vec2 o = vec2(i == 0 ? 1.0 : i == 1 ? -1.0 : 0.0, i == 2 ? 1.0 : i == 3 ? -1.0 : 0.0) / size;
|
|
91
|
+
d0 = max(d0, throughDepth(front, p0 + o, size));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Off the holes (past the leaf's outline): nothing of this page.
|
|
95
|
+
if (d0 < 0.5 && cutA < 0.5) discard;
|
|
96
|
+
vec3 hole = uPaper;
|
|
97
|
+
if (hasThrough && d0 > 0.5) {
|
|
98
|
+
// The face's frame on screen: the gradients of its uv, so a step
|
|
99
|
+
// on the page in view space is a step in the picture.
|
|
100
|
+
vec3 pos = -vViewPosition;
|
|
101
|
+
vec3 dp1 = dFdx(pos);
|
|
102
|
+
vec3 dp2 = dFdy(pos);
|
|
103
|
+
vec3 n = normalize(cross(dp1, dp2));
|
|
104
|
+
vec3 eye = normalize(vViewPosition);
|
|
105
|
+
if (dot(n, eye) < 0.0) n = -n;
|
|
106
|
+
vec2 duv1 = dFdx(p0);
|
|
107
|
+
vec2 duv2 = dFdy(p0);
|
|
108
|
+
vec3 dp2perp = cross(dp2, n);
|
|
109
|
+
vec3 dp1perp = cross(n, dp1);
|
|
110
|
+
float det = dot(dp2perp, dp1);
|
|
111
|
+
vec3 gu = (dp2perp * duv1.x + dp1perp * duv2.x) / det;
|
|
112
|
+
vec3 gv = (dp2perp * duv1.y + dp1perp * duv2.y) / det;
|
|
113
|
+
// A leaf down along the view ray, and a leaf up towards the key.
|
|
114
|
+
float h = uLeafDepth;
|
|
115
|
+
vec3 down = -eye * (h / max(dot(eye, n), 0.05)) + n * h;
|
|
116
|
+
vec2 stepDown = vec2(dot(down, gu), dot(down, gv));
|
|
117
|
+
vec2 stepUp = vec2(0.0);
|
|
118
|
+
#if NUM_DIR_LIGHTS > 0
|
|
119
|
+
vec3 l = directionalLights[0].direction;
|
|
120
|
+
vec3 up = l * (h / max(dot(l, n), 0.05)) - n * h;
|
|
121
|
+
stepUp = vec2(dot(up, gu), dot(up, gv));
|
|
122
|
+
#endif
|
|
123
|
+
float k = 1.0;
|
|
124
|
+
float wall = 0.0;
|
|
125
|
+
vec2 hit = p0;
|
|
126
|
+
for (int i = 1; i <= 33; i++) {
|
|
127
|
+
k = float(i);
|
|
128
|
+
if (k > uThroughLayers) break;
|
|
129
|
+
hit = p0 + stepDown * k;
|
|
130
|
+
float d = throughDepth(front, hit, size);
|
|
131
|
+
if (d < k) { wall = 1.0; break; }
|
|
132
|
+
if (d < k + 0.5) break;
|
|
133
|
+
}
|
|
134
|
+
// The key's ray from there back up: paper on its way is a wall's
|
|
135
|
+
// shadow.
|
|
136
|
+
float lit = 1.0;
|
|
137
|
+
float top = wall > 0.5 ? k - 0.5 : k;
|
|
138
|
+
for (int j = 1; j <= 33; j++) {
|
|
139
|
+
float z = top - float(j);
|
|
140
|
+
if (z < 0.0) break;
|
|
141
|
+
if (throughDepth(front, hit + stepUp * float(j), size) <= z) { lit = 0.0; break; }
|
|
142
|
+
}
|
|
143
|
+
throughLit = wall > 0.5 ? 0.45 * lit : lit;
|
|
144
|
+
// Deeper is darker: less of the sky reaches down a narrow shaft.
|
|
145
|
+
throughAo = mix(0.35, 1.0, exp(-0.12 * (k - 1.0))) * (wall > 0.5 ? 0.7 : 1.0);
|
|
146
|
+
hole = wall > 0.5 ? uPaper * 0.8 : throughColour(front, hit);
|
|
147
|
+
}
|
|
148
|
+
ink = mix(hole, ink, cutA);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
/**
|
|
153
|
+
* The key light's depth material for a cut leaf: three.js's, with the
|
|
154
|
+
* page texture's alpha discarding the holes (the leaf's front, or its back
|
|
155
|
+
* read through the paper), so the key's shadow falls through them.
|
|
156
|
+
*/
|
|
157
|
+
export function cutDepthMaterial() {
|
|
158
|
+
const m = new MeshDepthMaterial({ depthPacking: RGBADepthPacking });
|
|
159
|
+
const cut = { uCut: { value: null }, uCutBack: { value: 0 }, uMirror: { value: 0 } };
|
|
160
|
+
m.userData.cut = cut;
|
|
161
|
+
m.onBeforeCompile = (shader) => {
|
|
162
|
+
Object.assign(shader.uniforms, cut);
|
|
163
|
+
shader.vertexShader = shader.vertexShader
|
|
164
|
+
.replace("#include <common>", "#include <common>\nvarying vec2 vCutUv;")
|
|
165
|
+
.replace("#include <begin_vertex>", "#include <begin_vertex>\nvCutUv = uv;");
|
|
166
|
+
shader.fragmentShader = shader.fragmentShader
|
|
167
|
+
.replace("#include <common>", `#include <common>\n${CUT_UV_PARS}`)
|
|
168
|
+
.replace("#include <clipping_planes_fragment>", `#include <clipping_planes_fragment>\n${CUT_DISCARD}`);
|
|
169
|
+
};
|
|
170
|
+
return m;
|
|
171
|
+
}
|
|
172
|
+
/** The leaf's cut at a point, from either face's texture. */
|
|
173
|
+
const CUT_UV_PARS = /* glsl */ `
|
|
174
|
+
uniform sampler2D uCut;
|
|
175
|
+
uniform float uCutBack;
|
|
176
|
+
uniform float uMirror;
|
|
177
|
+
varying vec2 vCutUv;
|
|
178
|
+
`;
|
|
179
|
+
const CUT_DISCARD = /* glsl */ `
|
|
180
|
+
{
|
|
181
|
+
float u = uMirror > 0.5 ? 1.0 - vCutUv.x : vCutUv.x;
|
|
182
|
+
vec2 st = uCutBack > 0.5 ? vec2(1.0 - u, vCutUv.y) : vec2(u, vCutUv.y);
|
|
183
|
+
if (texture2D(uCut, st).a < 0.5) discard;
|
|
184
|
+
}
|
|
185
|
+
`;
|
|
186
|
+
/** The same discard for the height-map caster of a cut leaf. */
|
|
187
|
+
export const CASTER_CUT = { pars: CUT_UV_PARS, discard: CUT_DISCARD };
|
|
188
|
+
/**
|
|
189
|
+
* Sets a page mesh's cut uniforms from the pages on its faces: which face
|
|
190
|
+
* is cut, what its holes show (open pages), a leaf's thickness, and for a
|
|
191
|
+
* leaf in the air its key-light depth material and its caster, which
|
|
192
|
+
* discard the holes (the shared caster again once it is not cut).
|
|
193
|
+
*/
|
|
194
|
+
export function dressCut(mesh, sources, leafDepth, caster) {
|
|
195
|
+
const u = mesh.material.userData.uniforms;
|
|
196
|
+
const front = mesh.userData.Front;
|
|
197
|
+
const back = mesh.userData.Back;
|
|
198
|
+
const fc = sources.cutOf(front);
|
|
199
|
+
const bc = sources.cutOf(back);
|
|
200
|
+
u.uHasFrontCut.value = fc ? 1 : 0;
|
|
201
|
+
u.uHasBackCut.value = bc ? 1 : 0;
|
|
202
|
+
u.uLeafDepth.value = leafDepth;
|
|
203
|
+
const open = u.uCutMode.value === CUT_OPEN;
|
|
204
|
+
const ft = open && fc ? sources.throughOf(front) : null;
|
|
205
|
+
const bt = open && bc ? sources.throughOf(back) : null;
|
|
206
|
+
u.uFrontThrough.value = ft?.texture ?? null;
|
|
207
|
+
u.uHasFrontThrough.value = ft ? 1 : 0;
|
|
208
|
+
u.uBackThrough.value = bt?.texture ?? null;
|
|
209
|
+
u.uHasBackThrough.value = bt ? 1 : 0;
|
|
210
|
+
u.uThroughLayers.value = Math.max(ft?.layers ?? 0, bt?.layers ?? 0);
|
|
211
|
+
if (u.uCutMode.value !== CUT_AIR)
|
|
212
|
+
return;
|
|
213
|
+
// A leaf: its holes from whichever face is painted and cut.
|
|
214
|
+
const tex = fc && u.uFront.value ? u.uFront.value : bc && u.uBack.value ? u.uBack.value : null;
|
|
215
|
+
const casterMesh = mesh.userData.caster;
|
|
216
|
+
if (!tex) {
|
|
217
|
+
mesh.customDepthMaterial = undefined;
|
|
218
|
+
if (casterMesh)
|
|
219
|
+
casterMesh.material = caster.shared;
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const depth = (mesh.userData.cutDepth ??= cutDepthMaterial());
|
|
223
|
+
const cutCaster = (mesh.userData.cutCaster ??= caster.cut());
|
|
224
|
+
for (const c of [depth.userData.cut, cutCaster.uniforms]) {
|
|
225
|
+
c.uCut.value = tex;
|
|
226
|
+
c.uCutBack.value = tex === u.uFront.value ? 0 : 1;
|
|
227
|
+
c.uMirror.value = u.uMirror.value;
|
|
228
|
+
}
|
|
229
|
+
mesh.customDepthMaterial = depth;
|
|
230
|
+
if (casterMesh)
|
|
231
|
+
casterMesh.material = cutCaster;
|
|
232
|
+
}
|
|
233
|
+
/** The caster discard's uniforms, fresh for each cut leaf. */
|
|
234
|
+
export const casterCut = () => ({ ...CASTER_CUT, uniforms: { uCut: { value: null }, uCutBack: { value: 0 }, uMirror: { value: 0 } } });
|
|
235
|
+
//# sourceMappingURL=through.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"through.js","sourceRoot":"","sources":["../../src/pageFlip/through.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,wEAAwE;AACxE,4BAA4B;AAC5B,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,uEAAuE;AACvE,0EAA0E;AAC1E,0EAA0E;AAC1E,iDAAiD;AACjD,yEAAyE;AACzE,yEAAyE;AACzE,0EAA0E;AAC1E,sEAAsE;AACtE,mCAAmC;AACnC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAgB,MAAM,OAAO,CAAC;AAYnJ;;8DAE8D;AAC9D,MAAM,UAAU,cAAc,CAAC,OAAwB;IACrD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACpL,OAAO,CAAC,UAAU,GAAG,cAAc,CAAC;IACpC,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC;IACjC,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC;IACjC,OAAO,CAAC,eAAe,GAAG,KAAK,CAAC;IAChC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;4DAC4D;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;AAC1B,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AAiBzB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAe,EAAE,CAAC,CAAC;IACzD,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;IACzB,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;IAC1B,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;IACzB,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;IAC9B,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;IAC7B,gBAAgB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;IAC9B,eAAe,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;IAC7B,cAAc,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;IAC5B,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;CACzB,CAAC,CAAC;AAEH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;CAyBlC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0EtC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,CAAC,GAAG,IAAI,iBAAiB,CAAC,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAwC,CAAC;IAC3G,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAsB,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;IACvG,CAAC,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;IACrB,CAAC,CAAC,eAAe,GAAG,CAAC,MAAM,EAAE,EAAE;QAC7B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;aACtC,OAAO,CAAC,mBAAmB,EAAE,yCAAyC,CAAC;aACvE,OAAO,CAAC,yBAAyB,EAAE,uCAAuC,CAAC,CAAC;QAC/E,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc;aAC1C,OAAO,CAAC,mBAAmB,EAAE,sBAAsB,WAAW,EAAE,CAAC;aACjE,OAAO,CAAC,qCAAqC,EAAE,wCAAwC,WAAW,EAAE,CAAC,CAAC;IAC3G,CAAC,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6DAA6D;AAC7D,MAAM,WAAW,GAAG,UAAU,CAAC;;;;;CAK9B,CAAC;AACF,MAAM,WAAW,GAAG,UAAU,CAAC;;;;;;CAM9B,CAAC;AAEF,gEAAgE;AAChE,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AActE;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAa,EAAE,OAAmB,EAAE,SAAiB,EAAE,MAA+C;IAC7H,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAChC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,YAAY,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,WAAW,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,SAAS,CAAC;IAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC;IAC3C,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC,CAAC,aAAa,CAAC,KAAK,GAAG,EAAE,EAAE,OAAO,IAAI,IAAI,CAAC;IAC5C,CAAC,CAAC,gBAAgB,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,YAAY,CAAC,KAAK,GAAG,EAAE,EAAE,OAAO,IAAI,IAAI,CAAC;IAC3C,CAAC,CAAC,eAAe,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,cAAc,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,KAAK,OAAO;QAAE,OAAO;IACzC,4DAA4D;IAC5D,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/F,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,MAA2C,CAAC;IAC7E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;QACrC,IAAI,UAAU;YAAE,UAAU,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;QACpD,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAwC,CAAC;IACrG,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,KAAK,MAAM,CAAC,GAAG,EAAE,CAAqD,CAAC;IACjH,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,CAAC,CAAC,IAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QACpB,CAAC,CAAC,QAAS,CAAC,KAAK,GAAG,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC,CAAC,OAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;IACjC,IAAI,UAAU;QAAE,UAAU,CAAC,QAAQ,GAAG,SAAS,CAAC;AAClD,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC"}
|
package/dist/pageFlip.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type FolioConfig, type FolioPaperConfig } from 'postext';
|
|
2
|
+
import { type FaceFinish } from './pageFlip/finish.js';
|
|
2
3
|
export { BLOCK_PAGES } from './pageFlip/constants.js';
|
|
3
4
|
export { withStockForExtent } from './pageFlip/materials.js';
|
|
4
5
|
export { foldOf, progressFrom, layLeaf, pagePlane } from './pageFlip/leaf.js';
|
|
@@ -200,6 +201,8 @@ export declare class PageFlipper {
|
|
|
200
201
|
private loupe;
|
|
201
202
|
private details;
|
|
202
203
|
private paper;
|
|
204
|
+
/** The pages' special inks (#1568), by page source. */
|
|
205
|
+
private finishes;
|
|
203
206
|
constructor(canvas: HTMLCanvasElement, spread: HTMLElement, book: SpreadSrc[], at: number, onSettle: (index: number) => void,
|
|
204
207
|
/** The reader's hand turned the book to another spread. */
|
|
205
208
|
onTarget: (index: number) => void,
|
|
@@ -234,6 +237,12 @@ export declare class PageFlipper {
|
|
|
234
237
|
/** The paper of leaf k (outside the pages shown: the book's). */
|
|
235
238
|
private specOf;
|
|
236
239
|
private dressPage;
|
|
240
|
+
/** A mesh's faces' finish masks, and the clear coat a varnish needs;
|
|
241
|
+
* their die-cuts (#1569). */
|
|
242
|
+
private dressFinish;
|
|
243
|
+
/** The special inks of the pages (#1568): page source → its finish
|
|
244
|
+
* mask. Pages left out have none; their textures are freed. */
|
|
245
|
+
setFinishes(finishes: ReadonlyMap<PageSource, FaceFinish>): void;
|
|
237
246
|
private pxPerMm;
|
|
238
247
|
/** The leaves lying on each side now (in the air: neither). */
|
|
239
248
|
private stackLeaves;
|
package/dist/pageFlip.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageFlip.d.ts","sourceRoot":"","sources":["../src/pageFlip.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAgD,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"pageFlip.d.ts","sourceRoot":"","sources":["../src/pageFlip.ts"],"names":[],"mappings":"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"}
|
package/dist/pageFlip.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WebGLRenderer, Scene, PerspectiveCamera, Mesh, PlaneGeometry, MeshStandardMaterial, Group, MeshPhysicalMaterial, Texture, BoxGeometry, DirectionalLight, PMREMGenerator, OrthographicCamera, WebGLRenderTarget, Vector2, TextureLoader, Raycaster, SRGBColorSpace, NeutralToneMapping, HalfFloatType, PCFShadowMap, LinearFilter, BufferAttribute, ShadowMaterial, Color, Vector3, LinearMipmapLinearFilter, Plane, DepthTexture
|
|
1
|
+
import { WebGLRenderer, Scene, PerspectiveCamera, Mesh, PlaneGeometry, MeshStandardMaterial, Group, MeshPhysicalMaterial, Texture, BoxGeometry, DirectionalLight, PMREMGenerator, OrthographicCamera, WebGLRenderTarget, Vector2, TextureLoader, Raycaster, SRGBColorSpace, NeutralToneMapping, HalfFloatType, PCFShadowMap, LinearFilter, BufferAttribute, ShadowMaterial, Color, Vector3, LinearMipmapLinearFilter, Plane, DepthTexture } from 'three';
|
|
2
2
|
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
3
3
|
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js';
|
|
4
4
|
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
|
|
@@ -15,6 +15,9 @@ import { FOV, NX_OPEN, NX, NY, BLOCK_PAGES, DURATION, BLOCK_DURATION, GAP, GRIP
|
|
|
15
15
|
import { spreadColumns, column, MAX_PITCH, disposeLeaf, progressFrom, reach, foldOf, layLeaf, pagePlane } from './pageFlip/leaf.js';
|
|
16
16
|
import { edgeMaterial, pageMaterial, withStockForExtent, edgeUniforms, edgeColorOf, ease, easeOut, smooth, behindUniforms } from './pageFlip/materials.js';
|
|
17
17
|
import { occluded, casterMaterial, casterGeometry, occlusionUniforms, syncCaster } from './pageFlip/occlusion.js';
|
|
18
|
+
import { FinishTextures, dressFinish } from './pageFlip/finish.js';
|
|
19
|
+
import { drawMirror } from './pageFlip/mirror.js';
|
|
20
|
+
import { CUT_AIR, CUT_OPEN, casterCut, dressCut } from './pageFlip/through.js';
|
|
18
21
|
export { BLOCK_PAGES } from './pageFlip/constants.js';
|
|
19
22
|
export { withStockForExtent } from './pageFlip/materials.js';
|
|
20
23
|
export { foldOf, progressFrom, layLeaf, pagePlane } from './pageFlip/leaf.js';
|
|
@@ -138,6 +141,8 @@ export class PageFlipper {
|
|
|
138
141
|
loupe = null;
|
|
139
142
|
details = new Map();
|
|
140
143
|
paper = [1, 1, 1];
|
|
144
|
+
/** The pages' special inks (#1568), by page source. */
|
|
145
|
+
finishes = new FinishTextures();
|
|
141
146
|
constructor(canvas, spread, book, at, onSettle,
|
|
142
147
|
/** The reader's hand turned the book to another spread. */
|
|
143
148
|
onTarget,
|
|
@@ -181,8 +186,8 @@ export class PageFlipper {
|
|
|
181
186
|
this.renderer.shadowMap.enabled = true;
|
|
182
187
|
this.renderer.shadowMap.type = PCFShadowMap;
|
|
183
188
|
}
|
|
184
|
-
this.left = new Mesh(this.openGeometry(), pageMaterial(mirror, this.sign));
|
|
185
|
-
this.right = new Mesh(this.openGeometry(), pageMaterial(mirror, this.sign));
|
|
189
|
+
this.left = new Mesh(this.openGeometry(), pageMaterial(mirror, this.sign, CUT_OPEN));
|
|
190
|
+
this.right = new Mesh(this.openGeometry(), pageMaterial(mirror, this.sign, CUT_OPEN));
|
|
186
191
|
for (const m of [this.left, this.right]) {
|
|
187
192
|
m.receiveShadow = m.castShadow = true;
|
|
188
193
|
// A leaf lifting off an open page lies a hair above it: the page
|
|
@@ -481,6 +486,24 @@ export class PageFlipper {
|
|
|
481
486
|
u.uUnderK.value = open ? spec.transmission / 2 : 0;
|
|
482
487
|
u.uTransmit.value = open || mesh === this.blockMesh ? 0 : spec.transmission;
|
|
483
488
|
m.needsUpdate = true;
|
|
489
|
+
this.dressFinish(mesh);
|
|
490
|
+
}
|
|
491
|
+
/** A mesh's faces' finish masks, and the clear coat a varnish needs;
|
|
492
|
+
* their die-cuts (#1569). */
|
|
493
|
+
dressFinish(mesh) {
|
|
494
|
+
const f = this.finishes;
|
|
495
|
+
const spec = mesh.material.userData.spec;
|
|
496
|
+
dressFinish(mesh.material, f.maskOf(mesh.userData.Front), f.maskOf(mesh.userData.Back), spec?.clearcoat ?? 0);
|
|
497
|
+
dressCut(mesh, f, (spec ?? this.bookSpec).caliperMm * this.pxPerMm(), { shared: this.leafCaster, cut: () => casterMaterial(true, casterCut()) });
|
|
498
|
+
}
|
|
499
|
+
/** The special inks of the pages (#1568): page source → its finish
|
|
500
|
+
* mask. Pages left out have none; their textures are freed. */
|
|
501
|
+
setFinishes(finishes) {
|
|
502
|
+
if (!this.finishes.set(finishes))
|
|
503
|
+
return;
|
|
504
|
+
for (const mesh of this.pageMeshes())
|
|
505
|
+
this.dressFinish(mesh);
|
|
506
|
+
this.redraw();
|
|
484
507
|
}
|
|
485
508
|
// ── Layout ──
|
|
486
509
|
pxPerMm() {
|
|
@@ -1158,6 +1181,8 @@ export class PageFlipper {
|
|
|
1158
1181
|
return;
|
|
1159
1182
|
mesh.userData[face] = src;
|
|
1160
1183
|
this.dressVideo(mesh);
|
|
1184
|
+
if (face !== "Under")
|
|
1185
|
+
this.dressFinish(mesh);
|
|
1161
1186
|
u[`uHas${face}`].value = 0;
|
|
1162
1187
|
u[`u${face}`].value = null;
|
|
1163
1188
|
if (src === "")
|
|
@@ -1169,6 +1194,8 @@ export class PageFlipper {
|
|
|
1169
1194
|
return;
|
|
1170
1195
|
u[`u${face}`].value = tex;
|
|
1171
1196
|
u[`uHas${face}`].value = 1;
|
|
1197
|
+
if (face !== "Under")
|
|
1198
|
+
this.dressFinish(mesh);
|
|
1172
1199
|
this.redraw();
|
|
1173
1200
|
};
|
|
1174
1201
|
const tex = this.ready.get(src);
|
|
@@ -1193,7 +1220,7 @@ export class PageFlipper {
|
|
|
1193
1220
|
const geometry = new PlaneGeometry(1, 1, NX, NY);
|
|
1194
1221
|
spreadColumns(geometry, NX);
|
|
1195
1222
|
geometry.setAttribute("ao", new BufferAttribute(new Float32Array(geometry.attributes.position.count).fill(1), 1));
|
|
1196
|
-
const mesh = new Mesh(geometry, pageMaterial(this.sign < 0, this.sign));
|
|
1223
|
+
const mesh = new Mesh(geometry, pageMaterial(this.sign < 0, this.sign, CUT_AIR));
|
|
1197
1224
|
mesh.material.userData.uniforms.uPaper.value.setRGB(...this.paper, SRGBColorSpace);
|
|
1198
1225
|
mesh.castShadow = mesh.receiveShadow = true;
|
|
1199
1226
|
mesh.frustumCulled = false;
|
|
@@ -1990,56 +2017,10 @@ export class PageFlipper {
|
|
|
1990
2017
|
}
|
|
1991
2018
|
/** Draws the leaves in the air as `plane` (an open page's) mirrors them. */
|
|
1992
2019
|
drawMirror(target, plane) {
|
|
1993
|
-
const cam = this.mirrorCamera;
|
|
1994
|
-
// The eye mirrored in the plane, turned round its up axis so it is
|
|
1995
|
-
// still a camera (no mirror in it): its picture is the reflection
|
|
1996
|
-
// turned left for right, and its frustum the main one turned so too.
|
|
1997
|
-
const { x, y, z } = plane.normal;
|
|
1998
|
-
const d = -plane.constant;
|
|
1999
|
-
const reflect = new Matrix4().set(1 - 2 * x * x, -2 * x * y, -2 * x * z, 2 * d * x, -2 * y * x, 1 - 2 * y * y, -2 * y * z, 2 * d * y, -2 * z * x, -2 * z * y, 1 - 2 * z * z, 2 * d * z, 0, 0, 0, 1);
|
|
2000
|
-
cam.matrix.copy(reflect).multiply(this.camera.matrixWorld).multiply(new Matrix4().makeScale(-1, 1, 1));
|
|
2001
|
-
cam.updateMatrixWorld(true);
|
|
2002
|
-
const p = cam.projectionMatrix.copy(this.camera.projectionMatrix);
|
|
2003
|
-
p.elements[8] *= -1;
|
|
2004
|
-
// Its near plane laid along the page (an oblique frustum): nothing
|
|
2005
|
-
// under the page shows in its mirror.
|
|
2006
|
-
const near = new Plane(plane.normal.clone(), plane.constant + 0.2).applyMatrix4(cam.matrixWorldInverse);
|
|
2007
|
-
const clip = new Vector4(near.normal.x, near.normal.y, near.normal.z, near.constant);
|
|
2008
|
-
const e = p.elements;
|
|
2009
|
-
const q = new Vector4((Math.sign(clip.x) + e[8]) / e[0], (Math.sign(clip.y) + e[9]) / e[5], -1, (1 + e[10]) / e[14]);
|
|
2010
|
-
clip.multiplyScalar(2 / clip.dot(q));
|
|
2011
|
-
e[2] = clip.x;
|
|
2012
|
-
e[6] = clip.y;
|
|
2013
|
-
e[10] = clip.z + 1;
|
|
2014
|
-
e[14] = clip.w;
|
|
2015
|
-
cam.projectionMatrixInverse.copy(p).invert();
|
|
2016
|
-
// Only the leaves in the air (and the light on them).
|
|
2017
2020
|
const keep = new Set([this.key, this.key.target, ...this.leaves.values()]);
|
|
2018
2021
|
if (this.blockMesh)
|
|
2019
2022
|
keep.add(this.blockMesh);
|
|
2020
|
-
|
|
2021
|
-
for (const c of this.stage.children) {
|
|
2022
|
-
if (keep.has(c) || !c.visible)
|
|
2023
|
-
continue;
|
|
2024
|
-
c.visible = false;
|
|
2025
|
-
hidden.push(c);
|
|
2026
|
-
}
|
|
2027
|
-
// The key's shadow map as the main view drew it last: the leaves'
|
|
2028
|
-
// own faces under them are not lit by the key anyway.
|
|
2029
|
-
const shadows = this.renderer.shadowMap.autoUpdate;
|
|
2030
|
-
this.renderer.shadowMap.autoUpdate = false;
|
|
2031
|
-
// The picture behind the leaves lies on the main view's screen, not
|
|
2032
|
-
// this one's.
|
|
2033
|
-
const behind = behindUniforms.uBehindOn.value;
|
|
2034
|
-
behindUniforms.uBehindOn.value = 0;
|
|
2035
|
-
this.renderer.setRenderTarget(target);
|
|
2036
|
-
this.renderer.clear();
|
|
2037
|
-
this.renderer.render(this.scene, cam);
|
|
2038
|
-
this.renderer.setRenderTarget(null);
|
|
2039
|
-
this.renderer.shadowMap.autoUpdate = shadows;
|
|
2040
|
-
behindUniforms.uBehindOn.value = behind;
|
|
2041
|
-
for (const c of hidden)
|
|
2042
|
-
c.visible = true;
|
|
2023
|
+
drawMirror({ renderer: this.renderer, scene: this.scene, camera: this.camera, mirror: this.mirrorCamera, stage: this.stage, keep }, target, plane);
|
|
2043
2024
|
}
|
|
2044
2025
|
/** Back to a transparent canvas (the DOM spread shows), unless leaves
|
|
2045
2026
|
* are moving again. A persistent book is drawn at rest instead. */
|
|
@@ -2073,6 +2054,7 @@ export class PageFlipper {
|
|
|
2073
2054
|
cancelAnimationFrame(this.orbitFrame);
|
|
2074
2055
|
for (const tex of this.ready.values())
|
|
2075
2056
|
tex.dispose();
|
|
2057
|
+
this.finishes.dispose();
|
|
2076
2058
|
this.shadowTarget?.dispose();
|
|
2077
2059
|
this.composer.dispose();
|
|
2078
2060
|
this.loupe?.dispose();
|