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.
Files changed (56) hide show
  1. package/dist/environments.d.ts.map +1 -1
  2. package/dist/environments.js +9 -2
  3. package/dist/environments.js.map +1 -1
  4. package/dist/pageFlip/finish.d.ts +118 -0
  5. package/dist/pageFlip/finish.d.ts.map +1 -0
  6. package/dist/pageFlip/finish.js +225 -0
  7. package/dist/pageFlip/finish.js.map +1 -0
  8. package/dist/pageFlip/leaf.d.ts.map +1 -1
  9. package/dist/pageFlip/leaf.js +3 -0
  10. package/dist/pageFlip/leaf.js.map +1 -1
  11. package/dist/pageFlip/materials.d.ts +4 -2
  12. package/dist/pageFlip/materials.d.ts.map +1 -1
  13. package/dist/pageFlip/materials.js +32 -6
  14. package/dist/pageFlip/materials.js.map +1 -1
  15. package/dist/pageFlip/mirror.d.ts +15 -0
  16. package/dist/pageFlip/mirror.d.ts.map +1 -0
  17. package/dist/pageFlip/mirror.js +54 -0
  18. package/dist/pageFlip/mirror.js.map +1 -0
  19. package/dist/pageFlip/occlusion.d.ts +11 -1
  20. package/dist/pageFlip/occlusion.d.ts.map +1 -1
  21. package/dist/pageFlip/occlusion.js +9 -4
  22. package/dist/pageFlip/occlusion.js.map +1 -1
  23. package/dist/pageFlip/through.d.ts +140 -0
  24. package/dist/pageFlip/through.d.ts.map +1 -0
  25. package/dist/pageFlip/through.js +235 -0
  26. package/dist/pageFlip/through.js.map +1 -0
  27. package/dist/pageFlip.d.ts +9 -0
  28. package/dist/pageFlip.d.ts.map +1 -1
  29. package/dist/pageFlip.js +33 -51
  30. package/dist/pageFlip.js.map +1 -1
  31. package/dist/postext/painting.d.ts +2 -0
  32. package/dist/postext/painting.d.ts.map +1 -1
  33. package/dist/postext/painting.js +28 -10
  34. package/dist/postext/painting.js.map +1 -1
  35. package/dist/postext/state.d.ts +4 -1
  36. package/dist/postext/state.d.ts.map +1 -1
  37. package/dist/postext/through.d.ts +37 -0
  38. package/dist/postext/through.d.ts.map +1 -0
  39. package/dist/postext/through.js +178 -0
  40. package/dist/postext/through.js.map +1 -0
  41. package/dist/postext.d.ts.map +1 -1
  42. package/dist/postext.js +17 -2
  43. package/dist/postext.js.map +1 -1
  44. package/dist/viewer/constants.d.ts +4 -0
  45. package/dist/viewer/constants.d.ts.map +1 -1
  46. package/dist/viewer/constants.js +13 -0
  47. package/dist/viewer/constants.js.map +1 -1
  48. package/dist/viewer/turning.d.ts.map +1 -1
  49. package/dist/viewer/turning.js +2 -1
  50. package/dist/viewer/turning.js.map +1 -1
  51. package/dist/viewer/types.d.ts +2 -0
  52. package/dist/viewer/types.d.ts.map +1 -1
  53. package/dist/viewer.d.ts.map +1 -1
  54. package/dist/viewer.js +4 -2
  55. package/dist/viewer.js.map +1 -1
  56. 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":"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"}
@@ -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;
@@ -1 +1 @@
1
- {"version":3,"file":"pageFlip.d.ts","sourceRoot":"","sources":["../src/pageFlip.ts"],"names":[],"mappings":"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"}
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, Matrix4, Vector4 } from 'three';
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
- const hidden = [];
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();