@drawcall/lod 0.0.0-stage → 0.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.
Files changed (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -2
  3. package/dist/baked/codec.d.ts +10 -0
  4. package/dist/baked/codec.js +291 -0
  5. package/dist/baked/codec.js.map +1 -0
  6. package/dist/baked/index.d.ts +51 -0
  7. package/dist/baked/index.js +183 -0
  8. package/dist/baked/index.js.map +1 -0
  9. package/dist/baked/interior/faces.d.ts +26 -0
  10. package/dist/baked/interior/faces.js +105 -0
  11. package/dist/baked/interior/faces.js.map +1 -0
  12. package/dist/baked/interior/material.d.ts +31 -0
  13. package/dist/baked/interior/material.js +157 -0
  14. package/dist/baked/interior/material.js.map +1 -0
  15. package/dist/baked/interior/rooms.d.ts +22 -0
  16. package/dist/baked/interior/rooms.js +78 -0
  17. package/dist/baked/interior/rooms.js.map +1 -0
  18. package/dist/baked/low.d.ts +20 -0
  19. package/dist/baked/low.js +75 -0
  20. package/dist/baked/low.js.map +1 -0
  21. package/dist/baked/raster.d.ts +20 -0
  22. package/dist/baked/raster.js +71 -0
  23. package/dist/baked/raster.js.map +1 -0
  24. package/dist/baked/transfer.d.ts +36 -0
  25. package/dist/baked/transfer.js +243 -0
  26. package/dist/baked/transfer.js.map +1 -0
  27. package/dist/baked/unwrap.d.ts +9 -0
  28. package/dist/baked/unwrap.js +167 -0
  29. package/dist/baked/unwrap.js.map +1 -0
  30. package/dist/baked/xatlas.d.ts +2 -0
  31. package/dist/baked/xatlas.js +31 -0
  32. package/dist/baked/xatlas.js.map +1 -0
  33. package/dist/bounds.d.ts +33 -0
  34. package/dist/bounds.js +127 -0
  35. package/dist/bounds.js.map +1 -0
  36. package/dist/dispose.d.ts +5 -0
  37. package/dist/dispose.js +28 -0
  38. package/dist/dispose.js.map +1 -0
  39. package/dist/fade.d.ts +44 -0
  40. package/dist/fade.js +78 -0
  41. package/dist/fade.js.map +1 -0
  42. package/dist/impostor/bake/atlas.d.ts +51 -0
  43. package/dist/impostor/bake/atlas.js +190 -0
  44. package/dist/impostor/bake/atlas.js.map +1 -0
  45. package/dist/impostor/bake/index.d.ts +50 -0
  46. package/dist/impostor/bake/index.js +221 -0
  47. package/dist/impostor/bake/index.js.map +1 -0
  48. package/dist/impostor/bake/materials.d.ts +29 -0
  49. package/dist/impostor/bake/materials.js +156 -0
  50. package/dist/impostor/bake/materials.js.map +1 -0
  51. package/dist/impostor/bake/source.d.ts +3 -0
  52. package/dist/impostor/bake/source.js +23 -0
  53. package/dist/impostor/bake/source.js.map +1 -0
  54. package/dist/impostor/cache.d.ts +15 -0
  55. package/dist/impostor/cache.js +44 -0
  56. package/dist/impostor/cache.js.map +1 -0
  57. package/dist/impostor/codec.d.ts +14 -0
  58. package/dist/impostor/codec.js +137 -0
  59. package/dist/impostor/codec.js.map +1 -0
  60. package/dist/impostor/impostor.d.ts +67 -0
  61. package/dist/impostor/impostor.js +79 -0
  62. package/dist/impostor/impostor.js.map +1 -0
  63. package/dist/impostor/mesh/card.d.ts +38 -0
  64. package/dist/impostor/mesh/card.js +79 -0
  65. package/dist/impostor/mesh/card.js.map +1 -0
  66. package/dist/impostor/mesh/index.d.ts +66 -0
  67. package/dist/impostor/mesh/index.js +174 -0
  68. package/dist/impostor/mesh/index.js.map +1 -0
  69. package/dist/impostor/mesh/material.d.ts +63 -0
  70. package/dist/impostor/mesh/material.js +199 -0
  71. package/dist/impostor/mesh/material.js.map +1 -0
  72. package/dist/impostor/mesh/surface.d.ts +63 -0
  73. package/dist/impostor/mesh/surface.js +162 -0
  74. package/dist/impostor/mesh/surface.js.map +1 -0
  75. package/dist/impostor/mesh/textures.d.ts +4 -0
  76. package/dist/impostor/mesh/textures.js +37 -0
  77. package/dist/impostor/mesh/textures.js.map +1 -0
  78. package/dist/impostor/octahedral.d.ts +29 -0
  79. package/dist/impostor/octahedral.js +83 -0
  80. package/dist/impostor/octahedral.js.map +1 -0
  81. package/dist/index.d.ts +15 -0
  82. package/dist/index.js +16 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/instanced/args.d.ts +20 -0
  85. package/dist/instanced/args.js +77 -0
  86. package/dist/instanced/args.js.map +1 -0
  87. package/dist/instanced/bounds.d.ts +50 -0
  88. package/dist/instanced/bounds.js +271 -0
  89. package/dist/instanced/bounds.js.map +1 -0
  90. package/dist/instanced/dirty.d.ts +12 -0
  91. package/dist/instanced/dirty.js +61 -0
  92. package/dist/instanced/dirty.js.map +1 -0
  93. package/dist/instanced/index.d.ts +116 -0
  94. package/dist/instanced/index.js +573 -0
  95. package/dist/instanced/index.js.map +1 -0
  96. package/dist/instanced/meshes.d.ts +14 -0
  97. package/dist/instanced/meshes.js +54 -0
  98. package/dist/instanced/meshes.js.map +1 -0
  99. package/dist/instanced/select.d.ts +84 -0
  100. package/dist/instanced/select.js +264 -0
  101. package/dist/instanced/select.js.map +1 -0
  102. package/dist/lazy.d.ts +64 -0
  103. package/dist/lazy.js +187 -0
  104. package/dist/lazy.js.map +1 -0
  105. package/dist/levels.d.ts +72 -0
  106. package/dist/levels.js +146 -0
  107. package/dist/levels.js.map +1 -0
  108. package/dist/loader/cache.d.ts +15 -0
  109. package/dist/loader/cache.js +37 -0
  110. package/dist/loader/cache.js.map +1 -0
  111. package/dist/loader/dispose.d.ts +3 -0
  112. package/dist/loader/dispose.js +25 -0
  113. package/dist/loader/dispose.js.map +1 -0
  114. package/dist/loader.d.ts +99 -0
  115. package/dist/loader.js +234 -0
  116. package/dist/loader.js.map +1 -0
  117. package/dist/lod.d.ts +78 -0
  118. package/dist/lod.js +211 -0
  119. package/dist/lod.js.map +1 -0
  120. package/dist/material.d.ts +12 -0
  121. package/dist/material.js +52 -0
  122. package/dist/material.js.map +1 -0
  123. package/dist/pause.d.ts +6 -0
  124. package/dist/pause.js +20 -0
  125. package/dist/pause.js.map +1 -0
  126. package/dist/renderer.d.ts +21 -0
  127. package/dist/renderer.js +83 -0
  128. package/dist/renderer.js.map +1 -0
  129. package/dist/simplify.d.ts +24 -0
  130. package/dist/simplify.js +148 -0
  131. package/dist/simplify.js.map +1 -0
  132. package/dist/source/error.d.ts +14 -0
  133. package/dist/source/error.js +94 -0
  134. package/dist/source/error.js.map +1 -0
  135. package/dist/source/frame.d.ts +11 -0
  136. package/dist/source/frame.js +25 -0
  137. package/dist/source/frame.js.map +1 -0
  138. package/dist/source/shading.d.ts +96 -0
  139. package/dist/source/shading.js +224 -0
  140. package/dist/source/shading.js.map +1 -0
  141. package/dist/source/source.d.ts +23 -0
  142. package/dist/source/source.js +50 -0
  143. package/dist/source/source.js.map +1 -0
  144. package/dist/source/surface.d.ts +31 -0
  145. package/dist/source/surface.js +110 -0
  146. package/dist/source/surface.js.map +1 -0
  147. package/dist/source/texels.d.ts +45 -0
  148. package/dist/source/texels.js +191 -0
  149. package/dist/source/texels.js.map +1 -0
  150. package/dist/source/trace.d.ts +42 -0
  151. package/dist/source/trace.js +153 -0
  152. package/dist/source/trace.js.map +1 -0
  153. package/dist/three.d.ts +55 -0
  154. package/dist/three.js +103 -0
  155. package/dist/three.js.map +1 -0
  156. package/dist/tsl.d.ts +45 -0
  157. package/dist/tsl.js +99 -0
  158. package/dist/tsl.js.map +1 -0
  159. package/dist/view.d.ts +30 -0
  160. package/dist/view.js +75 -0
  161. package/dist/view.js.map +1 -0
  162. package/dist/wind/bounds.d.ts +3 -0
  163. package/dist/wind/bounds.js +47 -0
  164. package/dist/wind/bounds.js.map +1 -0
  165. package/dist/wind/hooks.d.ts +5 -0
  166. package/dist/wind/hooks.js +3 -0
  167. package/dist/wind/hooks.js.map +1 -0
  168. package/dist/wind/index.d.ts +57 -0
  169. package/dist/wind/index.js +196 -0
  170. package/dist/wind/index.js.map +1 -0
  171. package/dist/wind/sway.d.ts +29 -0
  172. package/dist/wind/sway.js +71 -0
  173. package/dist/wind/sway.js.map +1 -0
  174. package/package.json +69 -3
  175. package/skills/lod/SKILL.md +137 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fade.js","sourceRoot":"","sources":["../src/fade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { ImpostorMap } from "../impostor.js";
2
+ /**
3
+ * One mip of the atlas being baked: one RGBA8 layer per map, plus each texel's coverage.
4
+ * The bake stores the normals two ways (see its materials): the maps hold the surface's
5
+ * own normals, `turned` the shading normals turned toward the camera, each with the share
6
+ * of the surface that shades with the normal rather than its opposite (in orm.a). One way
7
+ * is kept for the whole impostor, as texels filtered together must mean the same thing.
8
+ * With `specular`, the bake also writes each surface's dielectric specular, of which only
9
+ * the coverage-weighted sum is kept, for its mean.
10
+ */
11
+ export declare class Atlas {
12
+ readonly maps: ImpostorMap[];
13
+ readonly frames: number;
14
+ readonly cell: number;
15
+ readonly specular: boolean;
16
+ readonly size: number;
17
+ readonly layers: Uint8Array[];
18
+ readonly coverage: Float32Array;
19
+ /** Turned normal in RGB, the share of the surface that shades with it in A. */
20
+ readonly turned: Uint8Array;
21
+ /** How far each way's normals agree, summed over the texels by coverage: the averages' lengths. */
22
+ readonly agreement: {
23
+ own: number;
24
+ turned: number;
25
+ };
26
+ /** F0 RGB and F90 summed over the texels by coverage, and the coverage summed. */
27
+ private readonly specularSum;
28
+ constructor(maps: ImpostorMap[], frames: number, cell: number, specular: boolean);
29
+ /** Keep the turned normals: write them over the own normals and their shares. */
30
+ useTurned(): void;
31
+ private layer;
32
+ /**
33
+ * Box-filter one supersampled frame into cell (col, row): the `cell * ss` square at
34
+ * (x0, y0) of `pixels[m]`, map m as RGBA floats `width` wide, then the turned normals,
35
+ * then the specular if baked.
36
+ * Every value is weighted by coverage, so the silhouette's colour is the object's colour
37
+ * rather than a mix with the cleared background; coverage itself is the plain average.
38
+ */
39
+ write(pixels: Float32Array[], width: number, ss: number, col: number, row: number, x0: number, y0: number): void;
40
+ /** The coverage-weighted mean of the baked specular: F0 RGB, then F90. */
41
+ meanSpecular(): [number, number, number, number];
42
+ /** Whether any texel of any frame was covered. */
43
+ covered(): boolean;
44
+ /**
45
+ * Give every uncovered texel of every cell the values of its nearest covered texel
46
+ * (breadth-first, within the cell). Filtering and mips then only ever read the object's
47
+ * own colours, normals and depths near the silhouette. Coverage stays zero.
48
+ */
49
+ fillGutters(): void;
50
+ private fillGutter;
51
+ }
@@ -0,0 +1,190 @@
1
+ // Typed-array reads below are in bounds; their `?? 0` only answers noUncheckedIndexedAccess.
2
+ const toSrgb = (c) => Math.round(255 * (c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055));
3
+ const NEIGHBOURS = [
4
+ [1, 0],
5
+ [-1, 0],
6
+ [0, 1],
7
+ [0, -1],
8
+ ];
9
+ /**
10
+ * One mip of the atlas being baked: one RGBA8 layer per map, plus each texel's coverage.
11
+ * The bake stores the normals two ways (see its materials): the maps hold the surface's
12
+ * own normals, `turned` the shading normals turned toward the camera, each with the share
13
+ * of the surface that shades with the normal rather than its opposite (in orm.a). One way
14
+ * is kept for the whole impostor, as texels filtered together must mean the same thing.
15
+ * With `specular`, the bake also writes each surface's dielectric specular, of which only
16
+ * the coverage-weighted sum is kept, for its mean.
17
+ */
18
+ export class Atlas {
19
+ maps;
20
+ frames;
21
+ cell;
22
+ specular;
23
+ size;
24
+ layers;
25
+ coverage;
26
+ /** Turned normal in RGB, the share of the surface that shades with it in A. */
27
+ turned;
28
+ /** How far each way's normals agree, summed over the texels by coverage: the averages' lengths. */
29
+ agreement = { own: 0, turned: 0 };
30
+ /** F0 RGB and F90 summed over the texels by coverage, and the coverage summed. */
31
+ specularSum = { value: [0, 0, 0, 0], coverage: 0 };
32
+ constructor(maps, frames, cell, specular) {
33
+ this.maps = maps;
34
+ this.frames = frames;
35
+ this.cell = cell;
36
+ this.specular = specular;
37
+ this.size = frames * cell;
38
+ this.layers = maps.map(() => new Uint8Array(this.size * this.size * 4));
39
+ this.coverage = new Float32Array(this.size * this.size);
40
+ this.turned = new Uint8Array(this.size * this.size * 4);
41
+ }
42
+ /** Keep the turned normals: write them over the own normals and their shares. */
43
+ useTurned() {
44
+ const normalDepth = this.layer("normalDepth");
45
+ const orm = this.layer("orm");
46
+ for (let i = 0; i < this.turned.length; i += 4) {
47
+ for (let k = 0; k < 3; k++)
48
+ normalDepth[i + k] = this.turned[i + k] ?? 0;
49
+ orm[i + 3] = this.turned[i + 3] ?? 0;
50
+ }
51
+ }
52
+ layer(map) {
53
+ const layer = this.layers[this.maps.indexOf(map)];
54
+ if (!layer)
55
+ throw new Error(`Atlas: no ${map} layer`);
56
+ return layer;
57
+ }
58
+ /**
59
+ * Box-filter one supersampled frame into cell (col, row): the `cell * ss` square at
60
+ * (x0, y0) of `pixels[m]`, map m as RGBA floats `width` wide, then the turned normals,
61
+ * then the specular if baked.
62
+ * Every value is weighted by coverage, so the silhouette's colour is the object's colour
63
+ * rather than a mix with the cleared background; coverage itself is the plain average.
64
+ */
65
+ write(pixels, width, ss, col, row, x0, y0) {
66
+ const { cell, size, maps, layers } = this;
67
+ const [alpha] = pixels;
68
+ if (!alpha || pixels.length !== maps.length + (this.specular ? 2 : 1))
69
+ throw new Error("Atlas.write: one pixel array per map, then the turned normals, then the specular if baked");
70
+ const sources = [...maps, "turned"];
71
+ const specular = this.specular ? pixels[maps.length + 1] : undefined;
72
+ for (let y = 0; y < cell; y++)
73
+ for (let x = 0; x < cell; x++) {
74
+ const out = ((row * cell + y) * size + col * cell + x) * 4;
75
+ const first = ((y0 + y * ss) * width + x0 + x * ss) * 4;
76
+ let weight = 0;
77
+ for (let sy = 0; sy < ss; sy++)
78
+ for (let sx = 0; sx < ss; sx++)
79
+ weight += alpha[first + (sy * width + sx) * 4 + 3] ?? 0;
80
+ const cover = weight / (ss * ss);
81
+ this.coverage[out / 4] = cover;
82
+ if (weight === 0)
83
+ continue;
84
+ // The coverage-weighted mean of `source` over this texel's samples.
85
+ const average = (source) => {
86
+ let [r, g, b, a] = [0, 0, 0, 0];
87
+ for (let sy = 0; sy < ss; sy++)
88
+ for (let sx = 0; sx < ss; sx++) {
89
+ const i = first + (sy * width + sx) * 4;
90
+ const w = alpha[i + 3] ?? 0;
91
+ r += (source[i] ?? 0) * w;
92
+ g += (source[i + 1] ?? 0) * w;
93
+ b += (source[i + 2] ?? 0) * w;
94
+ a += (source[i + 3] ?? 0) * w;
95
+ }
96
+ return [r / weight, g / weight, b / weight, a / weight];
97
+ };
98
+ if (specular) {
99
+ const sum = this.specularSum;
100
+ sum.value = average(specular).map((v, k) => (sum.value[k] ?? 0) + cover * v);
101
+ sum.coverage += cover;
102
+ }
103
+ sources.forEach((map, m) => {
104
+ const source = pixels[m];
105
+ const layer = map === "turned" ? this.turned : layers[m];
106
+ if (!source || !layer)
107
+ throw new Error(`Atlas.write: no pixels for ${map}`);
108
+ const [r, g, b, a] = average(source);
109
+ if (map === "normalDepth")
110
+ this.agreement.own += cover * Math.hypot(r * 2 - 1, g * 2 - 1, b * 2 - 1);
111
+ if (map === "turned")
112
+ this.agreement.turned += cover * Math.hypot(r * 2 - 1, g * 2 - 1, b * 2 - 1);
113
+ store(layer, out, [r, g, b, map === "base" ? cover : a], map === "base" || map === "emissive");
114
+ });
115
+ }
116
+ }
117
+ /** The coverage-weighted mean of the baked specular: F0 RGB, then F90. */
118
+ meanSpecular() {
119
+ const { value, coverage } = this.specularSum;
120
+ if (!this.specular || coverage === 0)
121
+ throw new Error("Atlas.meanSpecular: no specular was baked");
122
+ const [r = 0, g = 0, b = 0, f90 = 0] = value.map((v) => v / coverage);
123
+ return [r, g, b, f90];
124
+ }
125
+ /** Whether any texel of any frame was covered. */
126
+ covered() {
127
+ return this.coverage.some((c) => c > 0);
128
+ }
129
+ /**
130
+ * Give every uncovered texel of every cell the values of its nearest covered texel
131
+ * (breadth-first, within the cell). Filtering and mips then only ever read the object's
132
+ * own colours, normals and depths near the silhouette. Coverage stays zero.
133
+ */
134
+ fillGutters() {
135
+ for (let row = 0; row < this.frames; row++)
136
+ for (let col = 0; col < this.frames; col++)
137
+ this.fillGutter(col, row);
138
+ }
139
+ fillGutter(col, row) {
140
+ const { cell, size } = this;
141
+ const x0 = col * cell;
142
+ const y0 = row * cell;
143
+ const filled = new Uint8Array(cell * cell);
144
+ const queue = new Int32Array(cell * cell);
145
+ let tail = 0;
146
+ for (let y = 0; y < cell; y++)
147
+ for (let x = 0; x < cell; x++)
148
+ if ((this.coverage[(y0 + y) * size + x0 + x] ?? 0) > 0) {
149
+ filled[y * cell + x] = 1;
150
+ queue[tail++] = y * cell + x;
151
+ }
152
+ for (let head = 0; head < tail; head++) {
153
+ const p = queue[head] ?? 0;
154
+ const px = p % cell;
155
+ const py = (p - px) / cell;
156
+ const from = ((y0 + py) * size + x0 + px) * 4;
157
+ for (const [dx, dy] of NEIGHBOURS) {
158
+ const nx = px + dx;
159
+ const ny = py + dy;
160
+ if (nx < 0 || ny < 0 || nx >= cell || ny >= cell || filled[ny * cell + nx])
161
+ continue;
162
+ filled[ny * cell + nx] = 1;
163
+ queue[tail++] = ny * cell + nx;
164
+ const to = ((y0 + ny) * size + x0 + nx) * 4;
165
+ // Base keeps zero coverage; the other layers' alpha is data (depth) and spreads too.
166
+ this.layers.forEach((layer, m) => {
167
+ const n = this.maps[m] === "base" ? 3 : 4;
168
+ for (let k = 0; k < n; k++)
169
+ layer[to + k] = layer[from + k] ?? 0;
170
+ });
171
+ for (let k = 0; k < 4; k++)
172
+ this.turned[to + k] = this.turned[from + k] ?? 0;
173
+ }
174
+ }
175
+ }
176
+ }
177
+ /**
178
+ * Pack one texel into `layer` at byte `out`: colour as sRGB if `srgb`, the rest linearly.
179
+ * An averaged normal keeps its length, which says how far the normals it averages agree
180
+ * and is lit by: renormalised, a texel of leaves facing every which way would light as one
181
+ * smooth surface turned to the camera.
182
+ */
183
+ function store(layer, out, [r, g, b, a], srgb) {
184
+ const encode = srgb ? toSrgb : (v) => Math.round(v * 255);
185
+ layer[out] = encode(r);
186
+ layer[out + 1] = encode(g);
187
+ layer[out + 2] = encode(b);
188
+ layer[out + 3] = Math.round(a * 255);
189
+ }
190
+ //# sourceMappingURL=atlas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlas.js","sourceRoot":"","sources":["../../../src/impostor/bake/atlas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { type Object3D } from "three/webgpu";
2
+ import { type Impostor, type ImpostorLayout } from "../impostor.js";
3
+ export interface BakeImpostorOptions {
4
+ /**
5
+ * "full" (default): views from every side, so any orientation works. "hemi": views
6
+ * from the horizon up only, for objects that always stand upright; the same quality
7
+ * there with about 45% less memory.
8
+ */
9
+ layout?: ImpostorLayout;
10
+ /** views per atlas side; default 16 for full, 12 for hemi */
11
+ frames?: number;
12
+ /**
13
+ * pixels per view: the impostor stays sharp up to about this size on screen. Rounded
14
+ * down to a power of two so mip levels never mix two views; default 128.
15
+ */
16
+ resolution?: number;
17
+ /**
18
+ * Largest on-screen height (CSS pixels, as `LodLevel.maxPixels`) the impostor will be
19
+ * drawn at, when that is above the height where it is sharp (its default maxPixels).
20
+ * Larger, it shows its top mip magnified, which then reads the source's textures as
21
+ * sharp as they are at this height: alpha-tested leaves keep the coverage and colour
22
+ * they show up close, not the denser, darker look of their texture's small mips.
23
+ * Default: the height where it is sharp.
24
+ */
25
+ maxPixels?: number;
26
+ /**
27
+ * bake an emissive layer; default: when any material emits. It is stored as 0..1
28
+ * sRGB, so emissive * emissiveIntensity above 1 is clipped.
29
+ */
30
+ emissive?: boolean;
31
+ /**
32
+ * renders per output pixel per axis, for smooth edges; default 2. Textures are read at
33
+ * the output pixel's size, as multisampling does.
34
+ */
35
+ supersample?: number;
36
+ }
37
+ /**
38
+ * Bake `object` (in its own space, ignoring its own transform) into an impostor. Nested
39
+ * LODs are baked at their level 0, an InstancedLod with every instance at its level 0.
40
+ * ImpostorMeshes are refused: bake from their source instead.
41
+ *
42
+ * Each frame is an orthographic look at the bounding-box centre, rendered once per mip
43
+ * level at that level's size. The object's materials are rendered unlit into one target
44
+ * per map: base colour + coverage, object-space normal + depth,
45
+ * occlusion/roughness/metalness and, if needed, emissive. A material that changes three's
46
+ * default specular adds the object's mean specular (see `Impostor.specular`).
47
+ */
48
+ export declare function bakeImpostor(object: Object3D, options?: BakeImpostorOptions): Promise<Impostor>;
49
+ /** Loader entry: rooms attached for the close source are absent from distant bakes. */
50
+ export declare function bake(object: Object3D, options: BakeImpostorOptions, excluded?: readonly Object3D[]): Promise<Impostor>;
@@ -0,0 +1,221 @@
1
+ import { HalfFloatType, Matrix4, NearestFilter, OrthographicCamera, RenderTarget, Scene, Vector3 } from "three/webgpu";
2
+ import { uniform } from "three/tsl";
3
+ import { MAPS, boundingRadius, texelPixels, validateImpostor } from "../impostor.js";
4
+ import { frameBasis, frameDirection } from "../octahedral.js";
5
+ import { boundingBox, forEachVertex, showDetail } from "../../bounds.js";
6
+ import { pause } from "../../pause.js";
7
+ import { borrow, readFloats, sharedRenderer } from "../../renderer.js";
8
+ import { Atlas } from "./atlas.js";
9
+ import { OUTPUTS, swapMaterials } from "./materials.js";
10
+ import { sourceForBake } from "./source.js";
11
+ /**
12
+ * Empty border around the object in every frame, as a fraction of the frame's half
13
+ * size. It keeps mip levels from blending a frame's silhouette into its neighbour.
14
+ */
15
+ const PAD = 0.06;
16
+ /**
17
+ * Bake `object` (in its own space, ignoring its own transform) into an impostor. Nested
18
+ * LODs are baked at their level 0, an InstancedLod with every instance at its level 0.
19
+ * ImpostorMeshes are refused: bake from their source instead.
20
+ *
21
+ * Each frame is an orthographic look at the bounding-box centre, rendered once per mip
22
+ * level at that level's size. The object's materials are rendered unlit into one target
23
+ * per map: base colour + coverage, object-space normal + depth,
24
+ * occlusion/roughness/metalness and, if needed, emissive. A material that changes three's
25
+ * default specular adds the object's mean specular (see `Impostor.specular`).
26
+ */
27
+ export function bakeImpostor(object, options = {}) {
28
+ return bake(object, options);
29
+ }
30
+ /** Loader entry: rooms attached for the close source are absent from distant bakes. */
31
+ export async function bake(object, options, excluded = []) {
32
+ const layout = options.layout ?? "full";
33
+ const frames = options.frames ?? (layout === "hemi" ? 12 : 16);
34
+ const resolution = options.resolution ?? 128;
35
+ const supersample = options.supersample ?? 2;
36
+ if (!Number.isInteger(frames) || frames < 2)
37
+ throw new Error("bakeImpostor: frames must be an integer >= 2");
38
+ if (!Number.isFinite(resolution) || resolution < 4)
39
+ throw new Error("bakeImpostor: resolution must be a number >= 4");
40
+ if (!Number.isInteger(supersample) || supersample < 1)
41
+ throw new Error("bakeImpostor: supersample must be an integer >= 1");
42
+ if (options.maxPixels !== undefined && !(options.maxPixels > 0))
43
+ throw new Error("bakeImpostor: maxPixels must be > 0");
44
+ const cell = 2 ** Math.floor(Math.log2(resolution));
45
+ const source = sourceForBake(object, excluded);
46
+ source.matrix.identity();
47
+ source.matrix.decompose(source.position, source.quaternion, source.scale);
48
+ // Bones are descendants, so this also moves them; getVertexPosition reads bone.matrixWorld.
49
+ source.updateMatrixWorld(true);
50
+ // The object is baked whatever a parent LOD shows of it, and nested LODs at full detail.
51
+ source.visible = true;
52
+ showDetail(source);
53
+ const bounds = boundingBox(source);
54
+ if (bounds.isEmpty())
55
+ throw new Error("bakeImpostor: object has no visible geometry");
56
+ const box = [bounds.min.x, bounds.min.y, bounds.min.z, bounds.max.x, bounds.max.y, bounds.max.z];
57
+ const centre = bounds.getCenter(new Vector3());
58
+ const radius = boundingRadius(box);
59
+ const directions = [];
60
+ for (let row = 0; row < frames; row++)
61
+ for (let col = 0; col < frames; col++)
62
+ directions.push(frameDirection(layout, frames, col, row));
63
+ const halfSize = fittedHalfSize(source, centre, directions) * (1 + PAD);
64
+ const distance = 2 * radius + 1e-3;
65
+ // Textures are read at the size of an atlas texel; the top mip's at the size of a pixel at maxPixels.
66
+ const sharp = texelPixels({ size: cell * frames, frames, box, halfSize });
67
+ const textureBias = (m) => Math.log2(supersample) - (m === 0 ? Math.log2(Math.max(1, (options.maxPixels ?? sharp) / sharp)) : 0);
68
+ const settings = { distance, radius, textureBias: uniform(0) };
69
+ const swapped = swapMaterials(source, settings);
70
+ const emissive = options.emissive ?? swapped.emits;
71
+ const maps = emissive ? [...MAPS] : ["base", "normalDepth", "orm"];
72
+ // Every mip level is rendered, not filtered from the one above: the source does not look
73
+ // the same at every size (alpha-tested leaves whose texture mips mix in the dark texels
74
+ // around them darken with distance), and filtering would freeze the look of the largest.
75
+ const atlases = Array.from({ length: Math.log2(cell) + 1 }, (_, m) => new Atlas(maps, frames, cell >> m, swapped.specular));
76
+ const renderer = await sharedRenderer();
77
+ const scene = new Scene();
78
+ scene.add(source);
79
+ const camera = new OrthographicCamera(-halfSize, halfSize, halfSize, -halfSize, 0, 4 * radius + 1e-3);
80
+ camera.matrixAutoUpdate = false;
81
+ // Bounds count meshes on every layer, so the bake draws them all.
82
+ camera.layers.enableAll();
83
+ const views = directions.map((n) => {
84
+ const { tangent: t, bitangent: b } = frameBasis(n);
85
+ return new Matrix4().set(t[0], b[0], n[0], centre.x + n[0] * distance, t[1], b[1], n[1], centre.y + n[1] * distance, t[2], b[2], n[2], centre.z + n[2] * distance, 0, 0, 0, 1);
86
+ });
87
+ try {
88
+ for (const [m, atlas] of atlases.entries()) {
89
+ settings.textureBias.value = textureBias(m);
90
+ await bakeMip(atlas, supersample, renderer, scene, camera, views);
91
+ }
92
+ }
93
+ finally {
94
+ for (const material of swapped.materials)
95
+ material.dispose();
96
+ }
97
+ if (!atlases.some((atlas) => atlas.covered()))
98
+ throw new Error("bakeImpostor: nothing visible was baked");
99
+ for (const atlas of atlases)
100
+ atlas.fillGutters();
101
+ const sum = (way) => atlases.reduce((total, atlas) => total + atlas.agreement[way], 0);
102
+ if (sum("turned") > sum("own"))
103
+ for (const atlas of atlases)
104
+ atlas.useTurned();
105
+ const layers = maps.map((map, i) => atlases.map((atlas) => {
106
+ const layer = atlas.layers[i];
107
+ if (!layer)
108
+ throw new Error(`bakeImpostor: no ${map} layer`);
109
+ return layer;
110
+ }));
111
+ const impostor = { version: 3, layout, frames, size: cell * frames, box, halfSize, maps, layers };
112
+ const [top] = atlases;
113
+ if (!top)
114
+ throw new Error("bakeImpostor: no mip levels");
115
+ if (swapped.specular)
116
+ impostor.specular = top.meanSpecular();
117
+ validateImpostor(impostor);
118
+ return impostor;
119
+ }
120
+ /** Edge of the largest target frames render into side by side, which is read back at once. */
121
+ const TILE = 1024;
122
+ /**
123
+ * Colour attachments one pass renders: four half-float targets fill the 32 bytes per
124
+ * sample WebGPU guarantees.
125
+ */
126
+ const PER_PASS = 4;
127
+ /**
128
+ * Render every frame (`views`: camera matrices, in atlas order) into `atlas`, at its cell
129
+ * size × `supersample`. Frames render side by side into tiles of up to TILE square, so
130
+ * that each map is read back once per tile, in passes of up to PER_PASS outputs.
131
+ */
132
+ async function bakeMip(atlas, supersample, renderer, scene, camera, views) {
133
+ const { frames, maps } = atlas;
134
+ const side = atlas.cell * supersample;
135
+ const per = Math.max(1, Math.min(frames, Math.floor(TILE / side)));
136
+ const width = per * side;
137
+ // one output per map, then the second way to store the normals (see Atlas), then the specular
138
+ const names = OUTPUTS.filter((name) => (name === "emissive" ? maps.includes("emissive") : name !== "specular" || atlas.specular));
139
+ const passes = Array.from({ length: Math.ceil(names.length / PER_PASS) }, (_, p) => {
140
+ const outputs = names.slice(p * PER_PASS, (p + 1) * PER_PASS);
141
+ const target = new RenderTarget(width, width, {
142
+ count: outputs.length,
143
+ type: HalfFloatType,
144
+ minFilter: NearestFilter,
145
+ magFilter: NearestFilter,
146
+ depthBuffer: true,
147
+ });
148
+ outputs.forEach((name, i) => {
149
+ const texture = target.textures[i];
150
+ if (!texture)
151
+ throw new Error("bakeImpostor: a render target lacks a texture");
152
+ texture.name = name;
153
+ });
154
+ return target;
155
+ });
156
+ try {
157
+ for (let row0 = 0; row0 < frames; row0 += per)
158
+ for (let col0 = 0; col0 < frames; col0 += per) {
159
+ const tile = [];
160
+ for (let row = row0; row < Math.min(row0 + per, frames); row++)
161
+ for (let col = col0; col < Math.min(col0 + per, frames); col++)
162
+ tile.push({ col, row, x: (col - col0) * side, y: (row - row0) * side });
163
+ const placed = tile.map(({ col, row, x, y }) => ({ view: views[row * frames + col], x, y }));
164
+ for (const target of passes)
165
+ renderTile(renderer, target, scene, camera, placed, side);
166
+ const pixels = await Promise.all(passes.flatMap((target) => target.textures.map((_, i) => readFloats(renderer, target, i))));
167
+ for (const { col, row, x, y } of tile)
168
+ atlas.write(pixels, width, supersample, col, row, x, y);
169
+ await pause();
170
+ }
171
+ }
172
+ finally {
173
+ for (const target of passes)
174
+ target.dispose();
175
+ }
176
+ }
177
+ /** Clear `target` and render each frame's view into its `side` square at (x, y), counted from the bottom left as the atlas is. */
178
+ function renderTile(renderer, target, scene, camera, frames, side) {
179
+ const restore = borrow(renderer, target);
180
+ try {
181
+ renderer.clear(true, true, true);
182
+ target.scissorTest = true;
183
+ for (const { view, x, y } of frames) {
184
+ if (!view)
185
+ throw new Error("bakeImpostor: a frame has no view");
186
+ // WebGPU counts viewport rows from the top; `readFloats` turns the image over.
187
+ const top = target.height - y - side;
188
+ target.viewport.set(x, top, side, side);
189
+ target.scissor.set(x, top, side, side);
190
+ camera.matrix.copy(view);
191
+ camera.updateMatrixWorld(true);
192
+ renderer.render(scene, camera);
193
+ }
194
+ }
195
+ finally {
196
+ // The next tile clears it whole.
197
+ target.scissorTest = false;
198
+ restore();
199
+ }
200
+ }
201
+ /**
202
+ * The smallest square half-size that holds the object in every frame: the largest
203
+ * extent of any vertex along any frame's image axes. Tighter than the bounding
204
+ * sphere, which wastes about a third of every frame on a tree.
205
+ */
206
+ function fittedHalfSize(source, centre, directions) {
207
+ const axes = directions.flatMap((n) => {
208
+ const { tangent, bitangent } = frameBasis(n);
209
+ return [tangent, bitangent];
210
+ });
211
+ let half = 0;
212
+ forEachVertex(source, (p) => {
213
+ p.sub(centre);
214
+ for (const a of axes)
215
+ half = Math.max(half, Math.abs(p.x * a[0] + p.y * a[1] + p.z * a[2]));
216
+ });
217
+ if (half === 0)
218
+ throw new Error("bakeImpostor: object has no extent (every vertex is at one point)");
219
+ return half;
220
+ }
221
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/impostor/bake/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type Material, type Node, type Object3D } from "three/webgpu";
2
+ /** What every bake material reads, shared by all of them and set per bake. */
3
+ export interface BakeSettings {
4
+ /** the cameras' distance from the bounding box centre, and the bounding radius: the depth encoding */
5
+ distance: number;
6
+ radius: number;
7
+ /** mip bias of every texture read, per mip level: textures are read at the size of a texel (see `bakeImpostor`) */
8
+ textureBias: Node<"float"> & {
9
+ value: number;
10
+ };
11
+ }
12
+ /**
13
+ * The outputs a bake material writes, by name: one per atlas map, then the second way to
14
+ * store the normals (see Atlas) and the specular. A render target takes the ones it has
15
+ * textures of that name for, so every material writes them all and the bake decides,
16
+ * once it knows every material, which it keeps.
17
+ */
18
+ export declare const OUTPUTS: readonly ["base", "normalDepth", "orm", "emissive", "turned", "specular"];
19
+ export type Output = (typeof OUTPUTS)[number];
20
+ /**
21
+ * Replace the materials of every visible mesh under `root` with bake materials, which
22
+ * write the surface values unlit into the atlas maps. Returns the bake materials (to
23
+ * dispose), whether any of them emits light and whether any changes three's default specular.
24
+ */
25
+ export declare function swapMaterials(root: Object3D, settings: BakeSettings): {
26
+ materials: Material[];
27
+ emits: boolean;
28
+ specular: boolean;
29
+ };