@oeave/bakery3 0.2.0 → 0.3.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/bake/index.js +3 -3
- package/dist/catalog/index.js +1 -1
- package/dist/{chunk-KNUAOILG.js → chunk-3T3FJOSD.js} +4 -4
- package/dist/{chunk-KNUAOILG.js.map → chunk-3T3FJOSD.js.map} +1 -1
- package/dist/{chunk-6FYI6AJM.js → chunk-6FAMQZXB.js} +7 -7
- package/dist/{chunk-6FYI6AJM.js.map → chunk-6FAMQZXB.js.map} +1 -1
- package/dist/{chunk-QRCT5UGZ.js → chunk-CSSJRP5W.js} +9 -6
- package/dist/chunk-CSSJRP5W.js.map +1 -0
- package/dist/{chunk-APWUCEEB.js → chunk-EN4ROBYQ.js} +3 -3
- package/dist/{chunk-APWUCEEB.js.map → chunk-EN4ROBYQ.js.map} +1 -1
- package/dist/{chunk-JFYUDERE.js → chunk-NEK5TBEH.js} +2 -2
- package/dist/chunk-NEK5TBEH.js.map +1 -0
- package/dist/chunk-OPM2L63B.js +253 -0
- package/dist/chunk-OPM2L63B.js.map +1 -0
- package/dist/{chunk-UWBP7B54.js → chunk-R5IUPOWI.js} +3 -3
- package/dist/{chunk-UWBP7B54.js.map → chunk-R5IUPOWI.js.map} +1 -1
- package/dist/{chunk-HNMSWQU7.js → chunk-STRK4SZN.js} +3 -3
- package/dist/{chunk-HNMSWQU7.js.map → chunk-STRK4SZN.js.map} +1 -1
- package/dist/{chunk-Z7IYVH22.js → chunk-WLEFNUOH.js} +30 -279
- package/dist/chunk-WLEFNUOH.js.map +1 -0
- package/dist/{chunk-NXBAZGNB.js → chunk-X6GW43EX.js} +3 -3
- package/dist/{chunk-NXBAZGNB.js.map → chunk-X6GW43EX.js.map} +1 -1
- package/dist/devtools/index.js +7 -6
- package/dist/hotspots/index.d.ts +237 -31
- package/dist/hotspots/index.js +1013 -118
- package/dist/hotspots/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -6
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +2 -2
- package/dist/presets/index.js +2 -2
- package/dist/r3f/index.js +9 -8
- package/dist/r3f/index.js.map +1 -1
- package/dist/{room-FS26KAPQ.js → room-BM7Z7NKG.js} +4 -4
- package/dist/{room-FS26KAPQ.js.map → room-BM7Z7NKG.js.map} +1 -1
- package/dist/session-NPVBESWA.js +9 -0
- package/dist/{session-VCIQEO26.js.map → session-NPVBESWA.js.map} +1 -1
- package/dist/tsl/index.d.ts +14 -1
- package/dist/tsl/index.js +8 -2
- package/dist/tsl/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-JFYUDERE.js.map +0 -1
- package/dist/chunk-QRCT5UGZ.js.map +0 -1
- package/dist/chunk-Z7IYVH22.js.map +0 -1
- package/dist/session-VCIQEO26.js +0 -9
package/dist/tsl/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tsl/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @oeave/bakery3/tsl: the renderer's shading vocabulary, usable from TSL.\n *\n * Two things happen here, and importing this module is what turns both on:\n *\n * 1. Registration. TSL's anonymous singletons (`positionWorld`, `time`,\n * `cameraPosition`) carry no recognizable structure, so the extractor can\n * only know them by being introduced. This module imports them from\n * `three/tsl` and registers them by uuid. It is its own entry point\n * because it needs three r170 (one of the nodes it imports is not\n * exported before that); the core SDK keeps working for anyone older.\n *\n * 2. Renderer-only nodes. The renderer has procedural textures and shading\n * inputs a browser cannot compute: traced ambient occlusion, shade-time\n * bevel, pointiness, the classic noise textures. Each function below\n * returns a real TSL node that draws an approximation in the WebGPU\n * viewport and carries a marker the extractor serializes exactly for the\n * render. The viewport is the sketch; the render is the real one.\n * `check()` reports their use as info, never as an error.\n *\n * Everything accepts plain numbers for its dials, and a TSL expression for\n * its coordinate input. Dials are baked into the manifest, so a dial driven\n * by another node is not accepted, rather than accepted and ignored.\n */\n\nimport {\n clamp,\n dot,\n float,\n fract,\n mix,\n mx_cell_noise_float,\n mx_fractal_noise_float,\n mx_worley_noise_float,\n normalView,\n normalWorld,\n positionLocal,\n positionView,\n positionViewDirection,\n positionWorld,\n cameraPosition,\n pow,\n sin,\n smoothstep,\n sqrt,\n time,\n deltaTime,\n vec3,\n vec4,\n} from 'three/tsl';\nimport {\n BAKERY_NODE_MARKER,\n registerBuiltin,\n registerNodeObject,\n type BakeryNodeMarker,\n} from '../shader/registry.js';\n\n// ---------------------------------------------------------------------------\n// Registration, on import\n// ---------------------------------------------------------------------------\n\nconst asNode = (value: unknown) => ({\n uuid: (value as { uuid?: string })?.uuid,\n});\n\nregisterBuiltin(asNode(positionWorld), {\n op: 'position',\n params: () => ({ space: 'world' }),\n});\nregisterBuiltin(asNode(positionLocal), {\n op: 'position',\n params: () => ({ space: 'local' }),\n});\nregisterBuiltin(asNode(positionView), {\n op: 'position',\n params: () => ({ space: 'view' }),\n});\nregisterBuiltin(asNode(normalWorld), {\n op: 'normal',\n params: () => ({ space: 'world' }),\n});\nregisterBuiltin(asNode(normalView), {\n op: 'normal',\n params: () => ({ space: 'view' }),\n});\nregisterBuiltin(asNode(positionViewDirection), { op: 'view_direction' });\nregisterBuiltin(asNode(cameraPosition), { op: 'camera_position' });\n// Time is a uniform like any other: baked to the moment of capture. Reading\n// `.value` lazily matters: import time is not capture time.\nregisterBuiltin(asNode(time), {\n op: 'uniform',\n params: () => ({\n value: (time as { value?: number }).value ?? 0,\n type: 'float',\n name: 'time',\n }),\n});\nregisterBuiltin(asNode(deltaTime), {\n op: 'uniform',\n params: () => ({\n value: (deltaTime as { value?: number }).value ?? 0,\n type: 'float',\n name: 'deltaTime',\n }),\n});\n\nregisterNodeObject((value) => {\n // `float()` runs plain numbers through TSL's own const-node machinery,\n // which is exactly what Fn expansion needs; nodes pass through untouched.\n return typeof value === 'number' ? float(value) : value;\n});\n\n// ---------------------------------------------------------------------------\n// The marker\n// ---------------------------------------------------------------------------\n\n// Every type here is derived from a `three/tsl` export, so the published\n// declarations name no file inside three's own source tree. Those paths are\n// one @types/three release's layout: a declaration that imported them would\n// fail to compile under `skipLibCheck: false` against any other. Derived\n// this way, a node type is whatever the developer's own @types/three says\n// `float()` and `vec3()` return.\ntype TSLExpr = ReturnType<typeof float>;\ntype Coord = TSLExpr | null | undefined;\n/** A float node: a mask, a factor, a texture's fac output. */\ntype FloatNode = ReturnType<typeof float>;\n/** A three-component node: a color or a normal. */\ntype Vec3Node = ReturnType<typeof vec3>;\n/** A color with alpha. */\ntype Vec4Node = ReturnType<typeof vec4>;\n\nfunction mark<T>(node: unknown, marker: BakeryNodeMarker): T {\n (node as Record<string, unknown>)[BAKERY_NODE_MARKER] = marker;\n return node as T;\n}\n\n/** The renderer's procedural textures default to object-space coordinates;\n * object-space position is the closest thing a live three scene has. */\nconst defaultCoord = () => positionLocal;\n\nconst params = (\n entries: Record<string, number | string | boolean | number[] | undefined>,\n): Record<string, number | string | boolean | number[]> => {\n const out: Record<string, number | string | boolean | number[]> = {};\n for (const [key, value] of Object.entries(entries)) {\n if (value !== undefined) out[key] = value;\n }\n return out;\n};\n\n// ---------------------------------------------------------------------------\n// Procedural textures\n// ---------------------------------------------------------------------------\n\nexport type NoiseTextureOptions = {\n scale?: number;\n detail?: number;\n roughness?: number;\n lacunarity?: number;\n distortion?: number;\n dimensions?: 2 | 3 | 4;\n};\n\n/**\n * The renderer's fractal noise texture. Preview: MaterialX fractal noise,\n * the same character on a different lattice.\n */\nexport function bakeryNoiseTexture(\n coord?: Coord,\n options: NoiseTextureOptions = {},\n): FloatNode {\n const {\n scale = 5,\n detail = 2,\n roughness = 0.5,\n lacunarity = 2,\n distortion = 0,\n } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const preview = mx_fractal_noise_float(\n p,\n Math.max(1, Math.round(detail)),\n lacunarity,\n roughness,\n )\n .mul(0.5)\n .add(0.5);\n return mark<FloatNode>(preview, {\n op: 'bk_noise_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n scale,\n detail,\n roughness,\n lacunarity,\n distortion,\n dimensions: options.dimensions ?? 3,\n }),\n });\n}\n\nexport type VoronoiTextureOptions = {\n scale?: number;\n randomness?: number;\n feature?: 'F1' | 'F2' | 'SMOOTH_F1' | 'DISTANCE_TO_EDGE';\n metric?: 'EUCLIDEAN' | 'MANHATTAN' | 'CHEBYCHEV';\n dimensions?: 2 | 3 | 4;\n};\n\n/** The renderer's Voronoi texture (distance output). Preview: MaterialX Worley. */\nexport function bakeryVoronoiTexture(\n coord?: Coord,\n options: VoronoiTextureOptions = {},\n): FloatNode {\n const { scale = 5, randomness = 1 } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n // three's Worley is the SQUARED distance; the renderer's Voronoi is the\n // distance itself.\n const preview = sqrt(mx_worley_noise_float(p, float(randomness)));\n return mark<FloatNode>(preview, {\n op: 'bk_voronoi_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n scale,\n randomness,\n feature: options.feature ?? 'F1',\n metric: options.metric ?? 'EUCLIDEAN',\n dimensions: options.dimensions ?? 3,\n }),\n });\n}\n\nexport type WaveTextureOptions = {\n scale?: number;\n distortion?: number;\n detail?: number;\n detailScale?: number;\n detailRoughness?: number;\n phase?: number;\n type?: 'BANDS' | 'RINGS';\n direction?: 'X' | 'Y' | 'Z' | 'DIAGONAL';\n profile?: 'SIN' | 'SAW' | 'TRI';\n};\n\n/** The renderer's wave texture. Preview: a sine along the chosen axis. */\nexport function bakeryWaveTexture(\n coord?: Coord,\n options: WaveTextureOptions = {},\n): FloatNode {\n const { scale = 5, phase = 0, direction = 'X' } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const axis =\n direction === 'Y'\n ? p.y\n : direction === 'Z'\n ? p.z\n : direction === 'DIAGONAL'\n ? p.x.add(p.y).add(p.z)\n : p.x;\n const preview = sin(axis.add(phase)).mul(0.5).add(0.5);\n return mark<FloatNode>(preview, {\n op: 'bk_wave_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n scale,\n distortion: options.distortion ?? 0,\n detail: options.detail ?? 2,\n detail_scale: options.detailScale ?? 1,\n detail_roughness: options.detailRoughness ?? 0.5,\n phase,\n type: options.type ?? 'BANDS',\n direction,\n profile: options.profile ?? 'SIN',\n }),\n });\n}\n\nexport type MagicTextureOptions = {\n scale?: number;\n distortion?: number;\n depth?: number;\n};\n\n/** The renderer's interference \"magic\" texture. Preview: interfering sines,\n * the flavor and not the math. */\nexport function bakeryMagicTexture(\n coord?: Coord,\n options: MagicTextureOptions = {},\n): FloatNode {\n const { scale = 5, distortion = 1 } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const preview = sin(p.x.add(sin(p.y.mul(distortion))))\n .mul(0.5)\n .add(0.5);\n return mark<FloatNode>(preview, {\n op: 'bk_magic_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({ scale, distortion, depth: options.depth ?? 2 }),\n });\n}\n\nexport type GradientType =\n | 'LINEAR'\n | 'QUADRATIC'\n | 'EASING'\n | 'DIAGONAL'\n | 'SPHERICAL'\n | 'QUADRATIC_SPHERE'\n | 'RADIAL';\n\nexport type GradientTextureOptions = { type?: GradientType };\n\n/** The renderer's gradient texture. Preview: the linear ramp. */\nexport function bakeryGradientTexture(\n coord?: Coord,\n options: GradientTextureOptions = {},\n): FloatNode {\n const p = coord ?? defaultCoord();\n const preview = clamp(p.x, 0, 1);\n return mark<FloatNode>(preview, {\n op: 'bk_gradient_texture',\n inputs: [p],\n params: params({ gradient_type: options.type ?? 'LINEAR' }),\n });\n}\n\nexport type BrickTextureOptions = {\n offset?: number;\n offsetFrequency?: number;\n squash?: number;\n squashFrequency?: number;\n scale?: number;\n mortarSize?: number;\n mortarSmooth?: number;\n bias?: number;\n brickWidth?: number;\n rowHeight?: number;\n};\n\n/** The renderer's brick texture (fac output, the mortar mask). Preview: a grid. */\nexport function bakeryBrickTexture(\n coord?: Coord,\n options: BrickTextureOptions = {},\n): FloatNode {\n const {\n scale = 5,\n mortarSize = 0.02,\n rowHeight = 0.25,\n brickWidth = 0.5,\n } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const gx = fract(p.x.div(brickWidth));\n const gy = fract(p.y.div(rowHeight));\n const edge = float(1).sub(\n smoothstep(\n 0,\n mortarSize * 4,\n gx.min(float(1).sub(gx)).min(gy.min(float(1).sub(gy))),\n ),\n );\n return mark<FloatNode>(edge, {\n op: 'bk_brick_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n offset: options.offset ?? 0.5,\n offset_frequency: options.offsetFrequency ?? 2,\n squash: options.squash ?? 1,\n squash_frequency: options.squashFrequency ?? 2,\n scale,\n mortar_size: mortarSize,\n mortar_smooth: options.mortarSmooth ?? 0.1,\n bias: options.bias ?? 0,\n brick_width: brickWidth,\n row_height: rowHeight,\n }),\n });\n}\n\n/** White noise, a hash of the coordinate. Preview: cell noise. */\nexport function bakeryWhiteNoise(\n coord?: Coord,\n options: { dimensions?: 2 | 3 | 4 } = {},\n): FloatNode {\n const p = coord ?? defaultCoord();\n const preview = mx_cell_noise_float(p.mul(1024));\n return mark<FloatNode>(preview, {\n op: 'bk_white_noise',\n inputs: [p],\n params: params({ dimensions: options.dimensions ?? 3 }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Shading inputs the browser cannot compute\n// ---------------------------------------------------------------------------\n\n/**\n * Traced ambient occlusion. The browser has no rays, so the preview is plain\n * white, which is exactly what an unoccluded surface reads as. The render\n * traces the real thing.\n */\nexport function bakeryAmbientOcclusion(\n options: { distance?: number; samples?: number; onlyLocal?: boolean } = {},\n): FloatNode {\n const preview = float(1);\n return mark<FloatNode>(preview, {\n op: 'bk_ambient_occlusion',\n params: params({\n distance: options.distance ?? 1,\n samples: options.samples ?? 16,\n only_local: options.onlyLocal ?? false,\n }),\n });\n}\n\n/**\n * Shade-time edge rounding. Preview: the unrounded normal, so geometry looks\n * crisp in the viewport and gets the worn edge in the render.\n */\nexport function bakeryBevel(\n options: { radius?: number; samples?: number } = {},\n): Vec3Node {\n const preview = normalWorld;\n return mark<Vec3Node>(vec3(preview), {\n op: 'bk_bevel',\n params: params({\n radius: options.radius ?? 0.05,\n samples: options.samples ?? 4,\n }),\n });\n}\n\n/** Surface curvature: concave 0, flat 0.5, convex 1. Preview: flat 0.5. */\nexport function bakeryPointiness(): FloatNode {\n return mark<FloatNode>(float(0.5), { op: 'bk_pointiness' });\n}\n\n/** 1 on triangle edges. Preview: 0, no wires in the viewport. */\nexport function bakeryWireframe(\n options: { size?: number; pixelSize?: boolean } = {},\n): FloatNode {\n return mark<FloatNode>(float(0), {\n op: 'bk_wireframe',\n params: params({\n size: options.size ?? 0.01,\n pixel_size: options.pixelSize ?? false,\n }),\n });\n}\n\n/** Physically correct fresnel. Preview: Schlick's approximation, close enough\n * that the viewport and the render agree on where the rim light lives. */\nexport function bakeryFresnel(ior: number = 1.45): FloatNode {\n const f0 = ((1 - ior) / (1 + ior)) ** 2;\n const facing = clamp(dot(normalView, positionViewDirection), 0, 1);\n const preview = float(f0).add(\n float(1 - f0).mul(pow(float(1).sub(facing), 5)),\n );\n return mark<FloatNode>(preview, { op: 'bk_fresnel', inputs: [float(ior)] });\n}\n\n/** A facing/fresnel layer weight. Preview: the facing term it is built from. */\nexport function bakeryLayerWeight(\n blend: number = 0.5,\n options: { output?: 'FRESNEL' | 'FACING' } = {},\n): FloatNode {\n const facing = float(1).sub(\n clamp(dot(normalView, positionViewDirection), 0, 1),\n );\n return mark<FloatNode>(facing, {\n op: 'bk_layer_weight',\n inputs: [float(blend)],\n params: params({ output: options.output ?? 'FACING' }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Color tools\n// ---------------------------------------------------------------------------\n\nexport type ColorRampStop = {\n position: number;\n color: [number, number, number] | [number, number, number, number];\n};\n\n/**\n * A color ramp. Preview: the same ramp, rebuilt from mix chains; for LINEAR\n * and CONSTANT interpolation the viewport matches the render.\n */\nexport function bakeryColorRamp(\n fac: TSLExpr,\n stops: ColorRampStop[],\n options: { interpolation?: 'LINEAR' | 'CONSTANT' } = {},\n): Vec4Node {\n if (stops.length < 1)\n throw new Error('bakeryColorRamp needs at least one stop.');\n const sorted = [...stops].sort((a, b) => a.position - b.position);\n const rgba = (stop: ColorRampStop) =>\n vec4(stop.color[0], stop.color[1], stop.color[2], stop.color[3] ?? 1);\n\n let preview = rgba(sorted[0]!) as unknown as ReturnType<typeof mix>;\n for (let i = 1; i < sorted.length; i++) {\n const previous = sorted[i - 1]!;\n const current = sorted[i]!;\n const span = Math.max(current.position - previous.position, 1e-5);\n const t =\n (options.interpolation ?? 'LINEAR') === 'CONSTANT'\n ? smoothstep(current.position - 1e-5, current.position, fac)\n : clamp(fac.sub(previous.position).div(span), 0, 1);\n preview = mix(preview, rgba(current), t);\n }\n\n const flat: number[] = [];\n for (const stop of sorted) {\n flat.push(\n stop.position,\n stop.color[0],\n stop.color[1],\n stop.color[2],\n stop.color[3] ?? 1,\n );\n }\n return mark<Vec4Node>(preview, {\n op: 'bk_color_ramp',\n inputs: [fac],\n params: params({\n interpolation: options.interpolation ?? 'LINEAR',\n stops: flat,\n }),\n });\n}\n\n/** Blackbody temperature to color. Preview: a two-anchor tint, warm below\n * and cool above. */\nexport function bakeryBlackbody(kelvin: number = 5000): Vec3Node {\n const t = smoothstep(2000, 10000, float(kelvin));\n const preview = mix(vec3(1.0, 0.58, 0.27), vec3(0.78, 0.85, 1.0), t);\n return mark<Vec3Node>(preview, {\n op: 'bk_blackbody',\n inputs: [float(kelvin)],\n });\n}\n\n/** A gamma curve. The preview is the same math. */\nexport function bakeryGamma(color: TSLExpr, gamma: number = 1): Vec3Node {\n const preview = pow(color, vec3(gamma, gamma, gamma));\n return mark<Vec3Node>(preview, {\n op: 'bk_gamma',\n inputs: [color, float(gamma)],\n });\n}\n\n/** Brightness/contrast. Preview: the same formula the render uses. */\nexport function bakeryBrightnessContrast(\n color: TSLExpr,\n options: { brightness?: number; contrast?: number } = {},\n): Vec3Node {\n const { brightness = 0, contrast = 0 } = options;\n const a = 1 + contrast;\n const b = brightness - contrast * 0.5;\n const preview = clamp(color.mul(a).add(b), 0, 1e6);\n return mark<Vec3Node>(preview, {\n op: 'bk_brightness_contrast',\n inputs: [color, float(brightness), float(contrast)],\n });\n}\n\n/** Hue/saturation/value. Preview: value and saturation only; a hue rotation\n * in the viewport is not worth a hand-rolled HSV conversion. */\nexport function bakeryHueSaturation(\n color: TSLExpr,\n options: {\n hue?: number;\n saturation?: number;\n value?: number;\n fac?: number;\n } = {},\n): Vec3Node {\n const { hue = 0.5, saturation = 1, value = 1, fac = 1 } = options;\n const scaled = color.mul(value);\n const gray = dot(scaled, vec3(0.2126, 0.7152, 0.0722));\n const adjusted = mix(vec3(gray, gray, gray), scaled, saturation);\n const preview = mix(color, adjusted, fac);\n return mark<Vec3Node>(preview, {\n op: 'bk_hsv',\n inputs: [color],\n params: params({ hue, saturation, value, fac }),\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/tsl/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @oeave/bakery3/tsl: the renderer's shading vocabulary, usable from TSL.\n *\n * Two things happen here, and importing this module is what turns both on:\n *\n * 1. Registration. TSL's anonymous singletons (`positionWorld`, `time`,\n * `cameraPosition`) carry no recognizable structure, so the extractor can\n * only know them by being introduced. This module imports them from\n * `three/tsl` and registers them by uuid. It is its own entry point\n * because it needs three r170 (one of the nodes it imports is not\n * exported before that); the core SDK keeps working for anyone older.\n *\n * 2. Renderer-only nodes. The renderer has procedural textures and shading\n * inputs a browser cannot compute: traced ambient occlusion, shade-time\n * bevel, pointiness, the classic noise textures. Each function below\n * returns a real TSL node that draws an approximation in the WebGPU\n * viewport and carries a marker the extractor serializes exactly for the\n * render. The viewport is the sketch; the render is the real one.\n * `check()` reports their use as info, never as an error.\n *\n * Everything accepts plain numbers for its dials, and a TSL expression for\n * its coordinate input. Dials are baked into the manifest, so a dial driven\n * by another node is not accepted, rather than accepted and ignored.\n */\n\nimport {\n clamp,\n dot,\n float,\n fract,\n materialReference,\n mix,\n mx_cell_noise_float,\n mx_fractal_noise_float,\n mx_worley_noise_float,\n normalView,\n normalWorld,\n positionLocal,\n positionView,\n positionViewDirection,\n positionWorld,\n cameraPosition,\n pow,\n sin,\n smoothstep,\n sqrt,\n time,\n deltaTime,\n vec3,\n vec4,\n} from 'three/tsl';\nimport {\n BAKERY_NODE_MARKER,\n registerBuiltin,\n registerNodeObject,\n type BakeryNodeMarker,\n} from '../shader/registry.js';\n\n// ---------------------------------------------------------------------------\n// Registration, on import\n// ---------------------------------------------------------------------------\n\nconst asNode = (value: unknown) => ({\n uuid: (value as { uuid?: string })?.uuid,\n});\n\nregisterBuiltin(asNode(positionWorld), {\n op: 'position',\n params: () => ({ space: 'world' }),\n});\nregisterBuiltin(asNode(positionLocal), {\n op: 'position',\n params: () => ({ space: 'local' }),\n});\nregisterBuiltin(asNode(positionView), {\n op: 'position',\n params: () => ({ space: 'view' }),\n});\nregisterBuiltin(asNode(normalWorld), {\n op: 'normal',\n params: () => ({ space: 'world' }),\n});\nregisterBuiltin(asNode(normalView), {\n op: 'normal',\n params: () => ({ space: 'view' }),\n});\nregisterBuiltin(asNode(positionViewDirection), { op: 'view_direction' });\nregisterBuiltin(asNode(cameraPosition), { op: 'camera_position' });\n// Time is a uniform like any other: baked to the moment of capture. Reading\n// `.value` lazily matters: import time is not capture time.\nregisterBuiltin(asNode(time), {\n op: 'uniform',\n params: () => ({\n value: (time as { value?: number }).value ?? 0,\n type: 'float',\n name: 'time',\n }),\n});\nregisterBuiltin(asNode(deltaTime), {\n op: 'uniform',\n params: () => ({\n value: (deltaTime as { value?: number }).value ?? 0,\n type: 'float',\n name: 'deltaTime',\n }),\n});\n\nregisterNodeObject((value) => {\n // `float()` runs plain numbers through TSL's own const-node machinery,\n // which is exactly what Fn expansion needs; nodes pass through untouched.\n return typeof value === 'number' ? float(value) : value;\n});\n\n// ---------------------------------------------------------------------------\n// The marker\n// ---------------------------------------------------------------------------\n\n// Every type here is derived from a `three/tsl` export, so the published\n// declarations name no file inside three's own source tree. Those paths are\n// one @types/three release's layout: a declaration that imported them would\n// fail to compile under `skipLibCheck: false` against any other. Derived\n// this way, a node type is whatever the developer's own @types/three says\n// `float()` and `vec3()` return.\ntype TSLExpr = ReturnType<typeof float>;\ntype Coord = TSLExpr | null | undefined;\n/** A float node: a mask, a factor, a texture's fac output. */\ntype FloatNode = ReturnType<typeof float>;\n/** A three-component node: a color or a normal. */\ntype Vec3Node = ReturnType<typeof vec3>;\n/** A color with alpha. */\ntype Vec4Node = ReturnType<typeof vec4>;\n\nfunction mark<T>(node: unknown, marker: BakeryNodeMarker): T {\n (node as Record<string, unknown>)[BAKERY_NODE_MARKER] = marker;\n return node as T;\n}\n\n/** The renderer's procedural textures default to object-space coordinates;\n * object-space position is the closest thing a live three scene has. */\nconst defaultCoord = () => positionLocal;\n\nconst params = (\n entries: Record<string, number | string | boolean | number[] | undefined>,\n): Record<string, number | string | boolean | number[]> => {\n const out: Record<string, number | string | boolean | number[]> = {};\n for (const [key, value] of Object.entries(entries)) {\n if (value !== undefined) out[key] = value;\n }\n return out;\n};\n\n// ---------------------------------------------------------------------------\n// Procedural textures\n// ---------------------------------------------------------------------------\n\nexport type NoiseTextureOptions = {\n scale?: number;\n detail?: number;\n roughness?: number;\n lacunarity?: number;\n distortion?: number;\n dimensions?: 2 | 3 | 4;\n};\n\n/**\n * The renderer's fractal noise texture. Preview: MaterialX fractal noise,\n * the same character on a different lattice.\n */\nexport function bakeryNoiseTexture(\n coord?: Coord,\n options: NoiseTextureOptions = {},\n): FloatNode {\n const {\n scale = 5,\n detail = 2,\n roughness = 0.5,\n lacunarity = 2,\n distortion = 0,\n } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const preview = mx_fractal_noise_float(\n p,\n Math.max(1, Math.round(detail)),\n lacunarity,\n roughness,\n )\n .mul(0.5)\n .add(0.5);\n return mark<FloatNode>(preview, {\n op: 'bk_noise_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n scale,\n detail,\n roughness,\n lacunarity,\n distortion,\n dimensions: options.dimensions ?? 3,\n }),\n });\n}\n\nexport type VoronoiTextureOptions = {\n scale?: number;\n randomness?: number;\n feature?: 'F1' | 'F2' | 'SMOOTH_F1' | 'DISTANCE_TO_EDGE';\n metric?: 'EUCLIDEAN' | 'MANHATTAN' | 'CHEBYCHEV';\n dimensions?: 2 | 3 | 4;\n};\n\n/** The renderer's Voronoi texture (distance output). Preview: MaterialX Worley. */\nexport function bakeryVoronoiTexture(\n coord?: Coord,\n options: VoronoiTextureOptions = {},\n): FloatNode {\n const { scale = 5, randomness = 1 } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n // three's Worley is the SQUARED distance; the renderer's Voronoi is the\n // distance itself.\n const preview = sqrt(mx_worley_noise_float(p, float(randomness)));\n return mark<FloatNode>(preview, {\n op: 'bk_voronoi_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n scale,\n randomness,\n feature: options.feature ?? 'F1',\n metric: options.metric ?? 'EUCLIDEAN',\n dimensions: options.dimensions ?? 3,\n }),\n });\n}\n\nexport type WaveTextureOptions = {\n scale?: number;\n distortion?: number;\n detail?: number;\n detailScale?: number;\n detailRoughness?: number;\n phase?: number;\n type?: 'BANDS' | 'RINGS';\n direction?: 'X' | 'Y' | 'Z' | 'DIAGONAL';\n profile?: 'SIN' | 'SAW' | 'TRI';\n};\n\n/** The renderer's wave texture. Preview: a sine along the chosen axis. */\nexport function bakeryWaveTexture(\n coord?: Coord,\n options: WaveTextureOptions = {},\n): FloatNode {\n const { scale = 5, phase = 0, direction = 'X' } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const axis =\n direction === 'Y'\n ? p.y\n : direction === 'Z'\n ? p.z\n : direction === 'DIAGONAL'\n ? p.x.add(p.y).add(p.z)\n : p.x;\n const preview = sin(axis.add(phase)).mul(0.5).add(0.5);\n return mark<FloatNode>(preview, {\n op: 'bk_wave_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n scale,\n distortion: options.distortion ?? 0,\n detail: options.detail ?? 2,\n detail_scale: options.detailScale ?? 1,\n detail_roughness: options.detailRoughness ?? 0.5,\n phase,\n type: options.type ?? 'BANDS',\n direction,\n profile: options.profile ?? 'SIN',\n }),\n });\n}\n\nexport type MagicTextureOptions = {\n scale?: number;\n distortion?: number;\n depth?: number;\n};\n\n/** The renderer's interference \"magic\" texture. Preview: interfering sines,\n * the flavor and not the math. */\nexport function bakeryMagicTexture(\n coord?: Coord,\n options: MagicTextureOptions = {},\n): FloatNode {\n const { scale = 5, distortion = 1 } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const preview = sin(p.x.add(sin(p.y.mul(distortion))))\n .mul(0.5)\n .add(0.5);\n return mark<FloatNode>(preview, {\n op: 'bk_magic_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({ scale, distortion, depth: options.depth ?? 2 }),\n });\n}\n\nexport type GradientType =\n | 'LINEAR'\n | 'QUADRATIC'\n | 'EASING'\n | 'DIAGONAL'\n | 'SPHERICAL'\n | 'QUADRATIC_SPHERE'\n | 'RADIAL';\n\nexport type GradientTextureOptions = { type?: GradientType };\n\n/** The renderer's gradient texture. Preview: the linear ramp. */\nexport function bakeryGradientTexture(\n coord?: Coord,\n options: GradientTextureOptions = {},\n): FloatNode {\n const p = coord ?? defaultCoord();\n const preview = clamp(p.x, 0, 1);\n return mark<FloatNode>(preview, {\n op: 'bk_gradient_texture',\n inputs: [p],\n params: params({ gradient_type: options.type ?? 'LINEAR' }),\n });\n}\n\nexport type BrickTextureOptions = {\n offset?: number;\n offsetFrequency?: number;\n squash?: number;\n squashFrequency?: number;\n scale?: number;\n mortarSize?: number;\n mortarSmooth?: number;\n bias?: number;\n brickWidth?: number;\n rowHeight?: number;\n};\n\n/** The renderer's brick texture (fac output, the mortar mask). Preview: a grid. */\nexport function bakeryBrickTexture(\n coord?: Coord,\n options: BrickTextureOptions = {},\n): FloatNode {\n const {\n scale = 5,\n mortarSize = 0.02,\n rowHeight = 0.25,\n brickWidth = 0.5,\n } = options;\n const p = (coord ?? defaultCoord()).mul(scale);\n const gx = fract(p.x.div(brickWidth));\n const gy = fract(p.y.div(rowHeight));\n const edge = float(1).sub(\n smoothstep(\n 0,\n mortarSize * 4,\n gx.min(float(1).sub(gx)).min(gy.min(float(1).sub(gy))),\n ),\n );\n return mark<FloatNode>(edge, {\n op: 'bk_brick_texture',\n inputs: [coord ?? defaultCoord()],\n params: params({\n offset: options.offset ?? 0.5,\n offset_frequency: options.offsetFrequency ?? 2,\n squash: options.squash ?? 1,\n squash_frequency: options.squashFrequency ?? 2,\n scale,\n mortar_size: mortarSize,\n mortar_smooth: options.mortarSmooth ?? 0.1,\n bias: options.bias ?? 0,\n brick_width: brickWidth,\n row_height: rowHeight,\n }),\n });\n}\n\n/** White noise, a hash of the coordinate. Preview: cell noise. */\nexport function bakeryWhiteNoise(\n coord?: Coord,\n options: { dimensions?: 2 | 3 | 4 } = {},\n): FloatNode {\n const p = coord ?? defaultCoord();\n const preview = mx_cell_noise_float(p.mul(1024));\n return mark<FloatNode>(preview, {\n op: 'bk_white_noise',\n inputs: [p],\n params: params({ dimensions: options.dimensions ?? 3 }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Shading inputs the browser cannot compute\n// ---------------------------------------------------------------------------\n\n/**\n * Traced ambient occlusion. The browser has no rays, so the preview is plain\n * white, which is exactly what an unoccluded surface reads as. The render\n * traces the real thing.\n */\nexport function bakeryAmbientOcclusion(\n options: { distance?: number; samples?: number; onlyLocal?: boolean } = {},\n): FloatNode {\n const preview = float(1);\n return mark<FloatNode>(preview, {\n op: 'bk_ambient_occlusion',\n params: params({\n distance: options.distance ?? 1,\n samples: options.samples ?? 16,\n only_local: options.onlyLocal ?? false,\n }),\n });\n}\n\n/**\n * Shade-time edge rounding. Preview: the unrounded normal, so geometry looks\n * crisp in the viewport and gets the worn edge in the render.\n */\nexport function bakeryBevel(\n options: { radius?: number; samples?: number } = {},\n): Vec3Node {\n const preview = normalWorld;\n return mark<Vec3Node>(vec3(preview), {\n op: 'bk_bevel',\n params: params({\n radius: options.radius ?? 0.05,\n samples: options.samples ?? 4,\n }),\n });\n}\n\n/** Surface curvature: concave 0, flat 0.5, convex 1. Preview: flat 0.5. */\nexport function bakeryPointiness(): FloatNode {\n return mark<FloatNode>(float(0.5), { op: 'bk_pointiness' });\n}\n\n/** 1 on triangle edges. Preview: 0, no wires in the viewport. */\nexport function bakeryWireframe(\n options: { size?: number; pixelSize?: boolean } = {},\n): FloatNode {\n return mark<FloatNode>(float(0), {\n op: 'bk_wireframe',\n params: params({\n size: options.size ?? 0.01,\n pixel_size: options.pixelSize ?? false,\n }),\n });\n}\n\n/**\n * The material's own `emissiveIntensity`, for an `emissiveNode` to multiply.\n *\n * three ignores `emissiveIntensity` once a node material has an\n * `emissiveNode`; the renderer does not, because it puts the intensity on\n * the emission's strength. So an animated intensity (a timeline track, a\n * hotspot opening) dims the render and leaves the viewport alone. Multiply by\n * this and the two agree: in the viewport it reads the material's value every\n * frame, in the render it is 1, since the strength already carries it.\n *\n * material.emissiveNode = myGlow.mul(bakeryEmissiveIntensity());\n */\nexport function bakeryEmissiveIntensity(): FloatNode {\n return mark<FloatNode>(materialReference('emissiveIntensity', 'float'), {\n op: 'const',\n params: { value: 1, type: 'float' },\n });\n}\n\n/** Physically correct fresnel. Preview: Schlick's approximation, close enough\n * that the viewport and the render agree on where the rim light lives. */\nexport function bakeryFresnel(ior: number = 1.45): FloatNode {\n const f0 = ((1 - ior) / (1 + ior)) ** 2;\n const facing = clamp(dot(normalView, positionViewDirection), 0, 1);\n const preview = float(f0).add(\n float(1 - f0).mul(pow(float(1).sub(facing), 5)),\n );\n return mark<FloatNode>(preview, { op: 'bk_fresnel', inputs: [float(ior)] });\n}\n\n/** A facing/fresnel layer weight. Preview: the facing term it is built from. */\nexport function bakeryLayerWeight(\n blend: number = 0.5,\n options: { output?: 'FRESNEL' | 'FACING' } = {},\n): FloatNode {\n const facing = float(1).sub(\n clamp(dot(normalView, positionViewDirection), 0, 1),\n );\n return mark<FloatNode>(facing, {\n op: 'bk_layer_weight',\n inputs: [float(blend)],\n params: params({ output: options.output ?? 'FACING' }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Color tools\n// ---------------------------------------------------------------------------\n\nexport type ColorRampStop = {\n position: number;\n color: [number, number, number] | [number, number, number, number];\n};\n\n/**\n * A color ramp. Preview: the same ramp, rebuilt from mix chains; for LINEAR\n * and CONSTANT interpolation the viewport matches the render.\n */\nexport function bakeryColorRamp(\n fac: TSLExpr,\n stops: ColorRampStop[],\n options: { interpolation?: 'LINEAR' | 'CONSTANT' } = {},\n): Vec4Node {\n if (stops.length < 1)\n throw new Error('bakeryColorRamp needs at least one stop.');\n const sorted = [...stops].sort((a, b) => a.position - b.position);\n const rgba = (stop: ColorRampStop) =>\n vec4(stop.color[0], stop.color[1], stop.color[2], stop.color[3] ?? 1);\n\n let preview = rgba(sorted[0]!) as unknown as ReturnType<typeof mix>;\n for (let i = 1; i < sorted.length; i++) {\n const previous = sorted[i - 1]!;\n const current = sorted[i]!;\n const span = Math.max(current.position - previous.position, 1e-5);\n const t =\n (options.interpolation ?? 'LINEAR') === 'CONSTANT'\n ? smoothstep(current.position - 1e-5, current.position, fac)\n : clamp(fac.sub(previous.position).div(span), 0, 1);\n preview = mix(preview, rgba(current), t);\n }\n\n const flat: number[] = [];\n for (const stop of sorted) {\n flat.push(\n stop.position,\n stop.color[0],\n stop.color[1],\n stop.color[2],\n stop.color[3] ?? 1,\n );\n }\n return mark<Vec4Node>(preview, {\n op: 'bk_color_ramp',\n inputs: [fac],\n params: params({\n interpolation: options.interpolation ?? 'LINEAR',\n stops: flat,\n }),\n });\n}\n\n/** Blackbody temperature to color. Preview: a two-anchor tint, warm below\n * and cool above. */\nexport function bakeryBlackbody(kelvin: number = 5000): Vec3Node {\n const t = smoothstep(2000, 10000, float(kelvin));\n const preview = mix(vec3(1.0, 0.58, 0.27), vec3(0.78, 0.85, 1.0), t);\n return mark<Vec3Node>(preview, {\n op: 'bk_blackbody',\n inputs: [float(kelvin)],\n });\n}\n\n/** A gamma curve. The preview is the same math. */\nexport function bakeryGamma(color: TSLExpr, gamma: number = 1): Vec3Node {\n const preview = pow(color, vec3(gamma, gamma, gamma));\n return mark<Vec3Node>(preview, {\n op: 'bk_gamma',\n inputs: [color, float(gamma)],\n });\n}\n\n/** Brightness/contrast. Preview: the same formula the render uses. */\nexport function bakeryBrightnessContrast(\n color: TSLExpr,\n options: { brightness?: number; contrast?: number } = {},\n): Vec3Node {\n const { brightness = 0, contrast = 0 } = options;\n const a = 1 + contrast;\n const b = brightness - contrast * 0.5;\n const preview = clamp(color.mul(a).add(b), 0, 1e6);\n return mark<Vec3Node>(preview, {\n op: 'bk_brightness_contrast',\n inputs: [color, float(brightness), float(contrast)],\n });\n}\n\n/** Hue/saturation/value. Preview: value and saturation only; a hue rotation\n * in the viewport is not worth a hand-rolled HSV conversion. */\nexport function bakeryHueSaturation(\n color: TSLExpr,\n options: {\n hue?: number;\n saturation?: number;\n value?: number;\n fac?: number;\n } = {},\n): Vec3Node {\n const { hue = 0.5, saturation = 1, value = 1, fac = 1 } = options;\n const scaled = color.mul(value);\n const gray = dot(scaled, vec3(0.2126, 0.7152, 0.0722));\n const adjusted = mix(vec3(gray, gray, gray), scaled, saturation);\n const preview = mix(color, adjusted, fac);\n return mark<Vec3Node>(preview, {\n op: 'bk_hsv',\n inputs: [color],\n params: params({ hue, saturation, value, fac }),\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/capture/ids.ts","../src/capture/scene.ts","../src/bake/candidates.ts","../src/bake/shadow.ts","../src/bake/shading.ts","../src/bake/proxies.ts","../src/bake/apply.ts","../src/bake/view.ts","../src/bake/probe.ts"],"names":["Mesh","material","PlaneGeometry","MeshBasicMaterial","DoubleSide","attribute","values","BufferAttribute","BufferGeometry","Vector3","scratchBox","Box3","scratchSize","scratchCenter","round"],"mappings":"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","file":"chunk-JFYUDERE.js","sourcesContent":["/**\n * Object identity, and the opt-in that makes it survive a reload.\n *\n * Every id in the manifest (hidden objects, transforms, instances, morphs,\n * poses, lights, materials, animation targets) comes from one function, and\n * the renderer matches on the same key. `stampIds` writes `object.uuid` into\n * `userData.bakery3Id` for anything that has not been given one, so the\n * default costs the developer nothing.\n *\n * `THREE.Object3D.uuid` is minted at construction. Reload the page, rebuild\n * the scene, and every uuid is different. That is fine for a render (the ids\n * only have to agree with the GLB in the same request) and fatal for a bake,\n * whose whole value is that yesterday's lightmaps land on today's meshes. A\n * developer who wants a bake to outlive a refresh writes:\n *\n * mesh.userData.bakery3Id = 'pedestal';\n *\n * and that id is what travels, in every field. It is opt-in per object: an\n * app can name the six things it bakes and leave the rest to uuids.\n *\n * Two objects sharing a declared id is refused rather than resolved by\n * order. The renderer indexes by this key, so a duplicate would mean one of\n * the two silently loses its transform, its visibility or its lightmap.\n */\n\nimport type { Material, Object3D } from 'three';\nimport { Bakery3Error } from '../errors.js';\n\n/**\n * The key the SDK stamps into `userData` so a glTF node can be matched back\n * to the object it came from.\n *\n * glTF has no stable identity of its own: node order is an implementation\n * detail of the exporter and names are neither unique nor required. But\n * `GLTFExporter` copies `object.userData` into the node's `extras`, so\n * stamping a key here is what lets the renderer resolve \"hide this object\"\n * to an actual node.\n */\nexport const ID_KEY = 'bakery3Id';\n\n/** Anything with a uuid and a userData bag: an `Object3D` or a `Material`. */\nexport type Identifiable = {\n uuid: string;\n userData?: Record<string, unknown>;\n};\n\n/**\n * The id this thing travels under. Developer-declared if there is one, the\n * three uuid otherwise.\n *\n * Deliberately tolerant of a stamped id equal to the uuid (that is what\n * `stampIds` writes) so the answer does not depend on whether stamping has\n * happened yet.\n */\nexport function idOf(target: Identifiable): string {\n const declared = target.userData?.[ID_KEY];\n return typeof declared === 'string' && declared.length > 0\n ? declared\n : target.uuid;\n}\n\n/**\n * Materials the SDK cloned from one of the developer's, keyed to the one they\n * came from. A bake that lights one of several meshes sharing a material\n * gives that mesh a clone with its lightmap, and `clone()` copies `userData`,\n * declared id included. The clone IS that material to the renderer (the\n * lightmap is not exported), so it keeps the id and is not a duplicate of it.\n */\nconst clonedFrom = new WeakMap<Material, Material>();\n\n/** Say that `clone` is the SDK's copy of `source`, for {@link assertUniqueIds}. */\nexport function markClone(clone: Material, source: Material): void {\n clonedFrom.set(clone, clonedFrom.get(source) ?? source);\n}\n\nconst sourceOf = (material: Material): Material =>\n clonedFrom.get(material) ?? material;\n\n/** True only for an id the developer wrote, not one `stampIds` left behind. */\nfunction isDeclared(target: Identifiable): boolean {\n const declared = target.userData?.[ID_KEY];\n return (\n typeof declared === 'string' &&\n declared.length > 0 &&\n declared !== target.uuid\n );\n}\n\n/**\n * Refuse a scene in which two objects, or two materials, claim the same\n * declared id.\n *\n * Objects and materials are separate namespaces, because the renderer\n * resolves them from different places (glTF node extras versus material\n * extras). Naming a mesh `'chair'` and its material `'chair'` is unambiguous\n * and stays legal.\n *\n * The error carries both paths: \"duplicate id\" without saying which two\n * objects is a scavenger hunt through a scene graph.\n */\nexport function assertUniqueIds(root: Object3D): void {\n const objects = new Map<string, Object3D>();\n const materials = new Map<string, { material: Material; owner: Object3D }>();\n\n root.traverse((object) => {\n if (isDeclared(object)) {\n const id = idOf(object);\n const first = objects.get(id);\n if (first && first !== object)\n throw duplicate('object', id, [scenePath(first), scenePath(object)]);\n objects.set(id, object);\n }\n\n const mesh = object as Object3D & {\n isMesh?: boolean;\n material?: Material | Material[];\n };\n if (!mesh.isMesh || !mesh.material) return;\n const list = Array.isArray(mesh.material) ? mesh.material : [mesh.material];\n for (const material of list) {\n if (!material || !isDeclared(material)) continue;\n const id = idOf(material);\n const first = materials.get(id);\n if (first && sourceOf(first.material) !== sourceOf(material)) {\n throw duplicate('material', id, [\n `${scenePath(first.owner)} → ${first.material.name || first.material.type}`,\n `${scenePath(object)} → ${material.name || material.type}`,\n ]);\n }\n materials.set(id, { material, owner: object });\n }\n });\n}\n\n/** `<Scene>/<Group>/<Mesh>`: where in the graph something lives. */\nexport function scenePath(object: Object3D): string {\n const parts: string[] = [];\n let current: Object3D | null = object;\n while (current && current.parent) {\n parts.unshift(`<${current.name || current.type}>`);\n current = current.parent;\n }\n return parts.join('/');\n}\n\nfunction duplicate(\n kind: 'object' | 'material',\n id: string,\n where: string[],\n): Bakery3Error {\n return new Bakery3Error({\n code: 'InvalidRequest',\n message: `Two ${kind}s declare userData.bakery3Id \"${id}\".`,\n why:\n `Ids are how the renderer matches your live ${kind}s to the ones in the exported ` +\n `scene. With two claiming \"${id}\", one of them would silently take the other's ` +\n 'transform, visibility or lightmap.',\n fix:\n 'Give one of them a different userData.bakery3Id, or remove it and let the SDK ' +\n 'use the uuid.',\n path: where.join(' and '),\n });\n}\n","/**\n * Walking the scene: ids, runtime state, lights, and what to skip.\n *\n * Everything here reads the live graph and writes plain JSON. Nothing mutates\n * the developer's scene except `stampIds`, which is reversed before the\n * capture returns: a render must never leave a visible mark on the\n * application it was called from.\n */\n\nimport type { InstancedMesh, Mesh, Object3D, Scene, SkinnedMesh } from 'three';\nimport type {\n CompatibilityIssue,\n FogSpec,\n LightSpec,\n RuntimeState,\n Vec3,\n} from '../protocol/index.js';\nimport { ID_KEY, assertUniqueIds, idOf } from './ids.js';\n\n/** Re-exported from `./ids.js`, where identity lives. */\nexport { ID_KEY, assertUniqueIds, idOf } from './ids.js';\n\n/** What `userData.bakery3` can say about an object. */\ntype Bakery3UserData = {\n /** Leave this object out of the render entirely. */\n exclude?: boolean;\n /**\n * Render this object even though the viewport hides it. Set dressing a\n * configurator keeps out of its live view (the room the product is\n * photographed in, a sky outside the window) stays `visible = false` in\n * three and still ships and renders. The alternative, flipping `visible`\n * around every capture, races the animation loop and flashes the set in\n * the preview.\n */\n renderOnly?: boolean;\n /** A material to substitute for one that cannot be translated. */\n fallback?: Record<string, unknown>;\n /**\n * A DirectionalLight's angular diameter in degrees, which is how soft its\n * shadows are. three has no property for it (a shadow map's blur is a\n * raster setting, not a physical one), so it rides here. The real sun is\n * 0.53°; without it the renderer uses a studio-soft 12°.\n */\n angleDeg?: number;\n};\n\nexport function readUserData(object: Object3D): Bakery3UserData {\n const data = object.userData?.bakery3;\n return (data && typeof data === 'object' ? data : {}) as Bakery3UserData;\n}\n\n/**\n * Stamp every object and every material with its id, and hand back the undo.\n *\n * Materials too: `GLTFExporter` writes material `userData` into the\n * material's extras, which is what lets the renderer match a declared\n * fallback or a shader graph to the material it rebuilds, rather than guessing\n * from a name that is neither unique nor required.\n *\n * An id the developer set themselves is left alone, both here and by the\n * undo, which only removes stamps this call added. That is what makes\n * `userData.bakery3Id = 'pedestal'` an identity that outlives a page reload\n * (see ./ids.ts), and why the whole scene is checked for duplicates first:\n * two objects claiming one id is a refusal, not a race.\n *\n * The undo is a closure so the caller cannot forget which objects were\n * touched; a partial unstamp would leave junk in the developer's `userData`.\n */\nexport function stampIds(root: Object3D): () => void {\n assertUniqueIds(root);\n const touched: Array<{ userData: Record<string, unknown> }> = [];\n const stamp = (target: {\n uuid: string;\n userData?: Record<string, unknown>;\n }) => {\n if (target.userData?.[ID_KEY] !== undefined) return;\n target.userData = target.userData ?? {};\n target.userData[ID_KEY] = target.uuid;\n touched.push(target as { userData: Record<string, unknown> });\n };\n root.traverse((object) => {\n stamp(object);\n const mesh = object as Mesh;\n if (!mesh.isMesh || !mesh.material) return;\n const materials = Array.isArray(mesh.material)\n ? mesh.material\n : [mesh.material];\n for (const material of materials) if (material) stamp(material);\n });\n return () => {\n for (const target of touched) delete target.userData[ID_KEY];\n };\n}\n\n/**\n * Which objects the exporter should skip.\n *\n * Not the same set as \"hidden\". A hidden object still ships in the GLB and is\n * hidden per render, so a configurator toggling parts keeps hitting the asset\n * cache. This is only for things that must never reach the renderer at all:\n * helpers, gizmos, the developer's own opt-outs, and anything transient the\n * app draws over the top.\n */\nexport function shouldExclude(object: Object3D): boolean {\n // An exclusion covers the whole subtree, the way detaching for the export\n // does: a light inside an excluded group, or a mesh inside a preset room's\n // stand-in, must not be captured either.\n for (let node: Object3D | null = object; node; node = node.parent) {\n if (excludedItself(node)) return true;\n }\n return false;\n}\n\n/** Whether this object itself is the reason for an exclusion, not an ancestor. */\nexport function excludedItself(object: Object3D): boolean {\n if (readUserData(object).exclude) return true;\n // A preset room's stand-in is preview furniture: the renderer rebuilds the\n // room from its own definition, so none of it ships (presets/room.ts).\n // Unless the room was made bakeable, in which case the stand-in's surfaces\n // are the ones a lightmap lands on and they travel like any mesh. Its\n // preview lights are marked excluded one by one either way.\n const roomPreset = (\n object.userData?.bakery3Preset as\n { roomPreset?: { standIn?: boolean } } | undefined\n )?.roomPreset;\n if (roomPreset) return !roomPreset.standIn;\n // Helpers are debug furniture; nobody wants a grid in their hero image.\n if (/Helper$/.test(object.type)) return true;\n // Transform gizmos and drei's <Gizmo*> widgets follow the same reasoning.\n if (object.type === 'TransformControls') return true;\n return false;\n}\n\n/**\n * The state the application is in: what is hidden, instanced, morphed, posed.\n *\n * Visibility is recorded as a hidden list rather than by pruning the export.\n * three hides a subtree by hiding its root, so recording only the root is\n * both smaller and exactly what the renderer needs to reproduce.\n */\nexport function captureRuntime(\n root: Object3D,\n productState?: Record<string, unknown>,\n): RuntimeState {\n const hiddenObjectIds: string[] = [];\n const instances: NonNullable<RuntimeState['instances']> = [];\n const morphs: NonNullable<RuntimeState['morphs']> = [];\n const poses: NonNullable<RuntimeState['poses']> = [];\n\n root.traverse((object) => {\n if (shouldExclude(object)) return;\n\n if (!object.visible && !readUserData(object).renderOnly) {\n hiddenObjectIds.push(idOf(object));\n // Its children inherit the hide; recording them too would be noise.\n return;\n }\n\n const mesh = object as Mesh & InstancedMesh & SkinnedMesh;\n\n if (mesh.isInstancedMesh) {\n // The exporter writes InstancedMesh as a single mesh at its base\n // transform, so without this every instance after the first vanishes.\n instances.push({\n objectId: idOf(object),\n count: mesh.count,\n matrices: Array.from(mesh.instanceMatrix.array),\n });\n }\n\n if (mesh.isMesh && mesh.morphTargetInfluences?.length) {\n // Only when something is driven: a mesh sitting at every influence 0\n // is the rest pose and needs no override.\n if (mesh.morphTargetInfluences.some((v) => v > 1e-6)) {\n morphs.push({\n objectId: idOf(object),\n influences: Array.from(mesh.morphTargetInfluences),\n });\n }\n }\n\n if (mesh.isSkinnedMesh && mesh.skeleton) {\n poses.push({\n objectId: idOf(object),\n boneMatrices: mesh.skeleton.bones.map((bone) => {\n bone.updateMatrixWorld();\n return Array.from(bone.matrixWorld.elements);\n }),\n });\n }\n });\n\n return {\n ...(hiddenObjectIds.length ? { hiddenObjectIds } : {}),\n ...(instances.length ? { instances } : {}),\n ...(morphs.length ? { morphs } : {}),\n ...(poses.length ? { poses } : {}),\n ...(productState ? { productState } : {}),\n };\n}\n\n/**\n * The union of every light property this file reads.\n *\n * Written out rather than imported because three's light classes cannot be\n * intersected; see the cast in `captureLights`.\n */\ntype AnyLight = Object3D & {\n isLight?: boolean;\n isAmbientLight?: boolean;\n isDirectionalLight?: boolean;\n isSpotLight?: boolean;\n isPointLight?: boolean;\n isRectAreaLight?: boolean;\n isHemisphereLight?: boolean;\n color: { getHexString(): string };\n groundColor?: { getHexString(): string };\n intensity: number;\n castShadow?: boolean;\n target?: Object3D;\n angle?: number;\n penumbra?: number;\n distance?: number;\n decay?: number;\n width?: number;\n height?: number;\n};\n\n/**\n * Lights, lifted out of the graph into the manifest.\n *\n * glTF can carry punctual lights, but not area lights and not three's own\n * intensity semantics, which are the most common source of \"why is my render\n * darker\". The good version lives here and the GLB copy is a fallback.\n *\n * The intensity is passed through unconverted, in three's own units. The\n * physical conversion is one table in the renderer, so there is exactly one\n * place it can be got wrong.\n */\nexport function captureLights(root: Object3D): LightSpec[] {\n const lights: LightSpec[] = [];\n\n root.traverse((object) => {\n // A structural view rather than an intersection of three's light classes:\n // `DirectionalLight & SpotLight & …` reduces to `never`, because their\n // `shadow` properties are incompatible types. Duck typing on the `isX`\n // flags is what three does itself, and it keeps working across a version\n // that adds a light type.\n const light = object as AnyLight;\n if (\n !light.isLight ||\n shouldExclude(object) ||\n (!object.visible && !readUserData(object).renderOnly)\n )\n return;\n\n light.updateMatrixWorld();\n const position = worldPosition(light);\n const color = `#${light.color.getHexString()}`;\n const base = {\n objectId: idOf(object),\n color,\n intensity: light.intensity,\n castShadow: light.castShadow ?? false,\n };\n\n if (light.isAmbientLight) {\n // Handled as the environment's flat term rather than as a lamp: a\n // uniform dome is an environment, not a light.\n return;\n }\n\n if (light.isDirectionalLight) {\n light.target?.updateMatrixWorld();\n const angleDeg = readUserData(object).angleDeg;\n lights.push({\n ...base,\n type: 'directional',\n position,\n target: light.target ? worldPosition(light.target) : [0, 0, 0],\n ...(typeof angleDeg === 'number' && angleDeg > 0 ? { angleDeg } : {}),\n });\n return;\n }\n\n if (light.isSpotLight) {\n light.target?.updateMatrixWorld();\n lights.push({\n ...base,\n type: 'spot',\n position,\n target: light.target ? worldPosition(light.target) : [0, 0, 0],\n angle: light.angle,\n penumbra: light.penumbra,\n distance: light.distance,\n decay: light.decay,\n });\n return;\n }\n\n if (light.isPointLight) {\n lights.push({\n ...base,\n type: 'point',\n position,\n distance: light.distance,\n decay: light.decay,\n });\n return;\n }\n\n if (light.isRectAreaLight) {\n // A RectAreaLight shines along its own -Z, wherever its rotation (or a\n // `lookAt`) turned that; one meter along it is the point the renderer\n // aims the lamp at, which is how three's `lookAt` itself aims a light.\n const facing = worldZ(light);\n lights.push({\n ...base,\n type: 'area',\n position,\n target: [\n position[0] - facing[0],\n position[1] - facing[1],\n position[2] - facing[2],\n ],\n // three's RectAreaLight defaults are 10x10. Falling back to 1x1 would\n // silently make it a hundred times dimmer than the browser drew it.\n size: { width: light.width ?? 10, height: light.height ?? 10 },\n });\n return;\n }\n\n if (light.isHemisphereLight) {\n // `position` is its up axis (three normalizes it), `color` the sky.\n lights.push({\n ...base,\n type: 'hemisphere',\n position,\n groundColor: `#${light.groundColor?.getHexString() ?? '000000'}`,\n });\n }\n });\n\n return lights;\n}\n\n/**\n * The scene's environment intensity and rotation.\n *\n * The HDRI texture itself is handled by the asset pass: it may be a\n * `DataTexture` with no source URL at all, in which case its pixels are what\n * gets hashed and uploaded.\n */\nexport function captureEnvironmentSettings(scene: Scene): {\n intensity?: number;\n rotation?: Vec3;\n} {\n const anyScene = scene as Scene & {\n environmentIntensity?: number;\n environmentRotation?: { x: number; y: number; z: number };\n };\n return {\n ...(anyScene.environmentIntensity !== undefined\n ? { intensity: anyScene.environmentIntensity }\n : {}),\n ...(anyScene.environmentRotation\n ? {\n rotation: [\n anyScene.environmentRotation.x,\n anyScene.environmentRotation.y,\n anyScene.environmentRotation.z,\n ] as Vec3,\n }\n : {}),\n };\n}\n\n/**\n * The scene's fog. A `FogExp2` travels (the renderer traces it as a volume);\n * a linear `Fog` has a near and a far plane and no density, which no volume\n * reproduces, so it is reported and left out.\n */\nexport function captureFog(scene: Scene): {\n fog?: FogSpec;\n issue?: CompatibilityIssue;\n} {\n const fog = (scene as Scene & { fog?: unknown }).fog as\n | {\n isFogExp2?: boolean;\n isFog?: boolean;\n density?: number;\n color?: { getHexString(): string };\n }\n | null\n | undefined;\n if (!fog) return {};\n if (fog.isFogExp2) {\n const density = fog.density ?? 0;\n if (!(density > 0) || !Number.isFinite(density)) return {};\n return {\n fog: { color: `#${fog.color?.getHexString() ?? 'ffffff'}`, density },\n issue: {\n code: 'fog_traced_as_volume',\n severity: 'info',\n message:\n 'The scene has fog. The render traces it as a volume that scatters light, so lights glow and throw beams in it; the viewport only fades surfaces with distance.',\n docs: 'https://bakery3.com/docs/environment#fog',\n },\n };\n }\n if (fog.isFog) {\n return {\n issue: {\n code: 'fog_linear_unsupported',\n severity: 'warning',\n message:\n 'The scene has a linear `Fog`, which is not rendered: a near and a far plane describe no volume. Use `FogExp2` to have the fog in the render.',\n docs: 'https://bakery3.com/docs/environment#fog',\n },\n };\n }\n return {};\n}\n\nfunction worldPosition(object: Object3D): Vec3 {\n const e = object.matrixWorld.elements;\n return [e[12]!, e[13]!, e[14]!];\n}\n\n/** The object's local +Z in world space, unit length. */\nfunction worldZ(object: Object3D): Vec3 {\n const e = object.matrixWorld.elements;\n const length = Math.hypot(e[8]!, e[9]!, e[10]!) || 1;\n return [e[8]! / length, e[9]! / length, e[10]! / length];\n}\n","/**\n * Which of your meshes can take a lightmap, and, for the ones that cannot,\n * why and what to do about it.\n *\n * The SDK decides this, not the render worker: the worker sees a GLB, which\n * has already flattened a `MeshPhysicalNodeMaterial` into something plausible\n * and lost the fact that it was transmissive. The SDK is looking at the live\n * material. So `bake.include` leaves the browser explicit and authoritative,\n * and every mesh that did not make the list carries a `reason` the panel can\n * show in place: never a silent skip.\n *\n * Two different verdicts live here:\n *\n * `bakeable: false`: a lightmap cannot be applied to this at all. The\n * checkbox is disabled and the reason says why.\n * `defaultInclude: false`: it would work, but baking it is probably not\n * what you meant (glass, a hidden variant, something you opted out of).\n * The checkbox is off and you can turn it on.\n */\n\nimport type { Material, Mesh, Object3D } from 'three';\nimport { idOf, scenePath } from '../capture/ids.js';\nimport { shouldExclude } from '../capture/scene.js';\n\n/** A refusal, per object, with the same fields as `BakeSkip` and\n * `PreflightIssue`, so a reason from here and one from the render worker\n * read identically in the panel. */\nexport type BakeCandidateReason = {\n code: string;\n message: string;\n why?: string;\n fix?: string;\n};\n\nexport type BakeCandidate = {\n /** The id this object travels under: `userData.bakery3Id` or its uuid. */\n objectId: string;\n object: Mesh;\n /** For humans: the three name, falling back to the graph path. */\n name: string;\n /** Where in the scene graph it lives, for a tooltip. */\n path: string;\n /** Can a lightmap be applied to this mesh at all? */\n bakeable: boolean;\n /** Present whenever there is something to say: on a refusal and on a\n * bakeable object that is off by default. */\n reason?: BakeCandidateReason;\n /** Whether the checkbox starts ticked. Always false when `!bakeable`. */\n defaultInclude: boolean;\n};\n\n/** `userData.bakery3.bake === false`, the per-object opt-out. */\ntype BakeUserData = { bake?: boolean };\n\n/**\n * Every mesh in the scene, classified.\n *\n * Excluded objects (helpers, gizmos, `userData.bakery3.exclude`) are not\n * listed at all: they never reach the renderer, so there is nothing to\n * explain. Everything else appears, including the things that cannot be\n * baked, because a list that quietly omits the instanced chairs is exactly\n * the list that makes a developer think the bake covered them.\n */\nexport function bakeCandidates(options: { scene: Object3D }): BakeCandidate[] {\n const candidates: BakeCandidate[] = [];\n\n options.scene.traverse((object) => {\n if (shouldExclude(object)) return;\n const mesh = object as Mesh & {\n isInstancedMesh?: boolean;\n isSkinnedMesh?: boolean;\n isBatchedMesh?: boolean;\n };\n if (!mesh.isMesh) return;\n\n const base = {\n objectId: idOf(object),\n object: mesh as Mesh,\n name: object.name || object.type,\n path: scenePath(object),\n };\n\n const refusal = refuse(mesh);\n if (refusal) {\n candidates.push({\n ...base,\n bakeable: false,\n reason: refusal,\n defaultInclude: false,\n });\n return;\n }\n\n const advisory = advise(mesh);\n candidates.push({\n ...base,\n bakeable: true,\n ...(advisory ? { reason: advisory } : {}),\n defaultInclude: !advisory,\n });\n });\n\n return candidates;\n}\n\n/** Convenience for the common \"what would a bake include\" question. */\nexport function defaultIncludeIds(candidates: BakeCandidate[]): string[] {\n return candidates\n .filter((candidate) => candidate.bakeable && candidate.defaultInclude)\n .map((candidate) => candidate.objectId);\n}\n\n/**\n * Does this material even have somewhere to put a lightmap?\n *\n * `'lightMap' in material` rather than a type whitelist: three's node\n * materials copy the classic material's defaults onto themselves\n * (`NodeMaterial.setDefaultValues`), so `MeshStandardNodeMaterial` answers\n * true without this module having to know the class exists, and a raw\n * `ShaderMaterial`, which genuinely has nowhere to put one, answers false.\n */\nexport function hasLightMapSlot(material: Material): boolean {\n return 'lightMap' in material;\n}\n\nexport function materialsOf(mesh: Mesh): Material[] {\n const material = mesh.material as Material | Material[] | undefined;\n if (!material) return [];\n return (Array.isArray(material) ? material : [material]).filter(Boolean);\n}\n\nfunction refuse(\n mesh: Mesh & {\n isInstancedMesh?: boolean;\n isSkinnedMesh?: boolean;\n isBatchedMesh?: boolean;\n },\n): BakeCandidateReason | undefined {\n if (mesh.isInstancedMesh) {\n return {\n code: 'BakeInstancedMesh',\n message: `\"${mesh.name || mesh.type}\" is an InstancedMesh, so it cannot take a lightmap.`,\n why: 'Every instance shares one geometry and one material, so it would also share one lightmap: the chair in the corner would be lit like the chair by the window.',\n fix: 'Convert the instances you want baked into individual meshes, or leave them lit in realtime on top of the baked room.',\n };\n }\n if (mesh.isBatchedMesh) {\n return {\n code: 'BakeBatchedMesh',\n message: `\"${mesh.name || mesh.type}\" is a BatchedMesh, so it cannot take a lightmap.`,\n why: 'A BatchedMesh packs many objects into one draw with one material; a per-object lightmap has nowhere to attach.',\n fix: 'Bake the geometries as individual meshes, or leave this one lit in realtime.',\n };\n }\n if (mesh.isSkinnedMesh) {\n return {\n code: 'BakeSkinnedMesh',\n message: `\"${mesh.name || mesh.type}\" is skinned, so its lighting cannot be baked.`,\n why: 'A lightmap is fixed to the surface in its bind pose. The moment the skeleton moves, the baked shadows stay where the mesh used to be.',\n fix: 'Leave animated characters lit in realtime. They will still receive the baked room through your own lights.',\n };\n }\n\n const materials = materialsOf(mesh);\n if (!materials.length) {\n return {\n code: 'BakeNoMaterial',\n message: `\"${mesh.name || mesh.type}\" has no material.`,\n why: 'A lightmap is a material slot; without a material there is nothing to set.',\n fix: 'Give the mesh a MeshStandardMaterial (or any material with a lightMap slot).',\n };\n }\n\n const unsupported = materials.filter(\n (material) => !hasLightMapSlot(material),\n );\n if (unsupported.length) {\n const names = unsupported\n .map((material) => `${material.name || material.type}`)\n .join(', ');\n return {\n code: 'BakeNoLightMapSlot',\n message: `\"${mesh.name || mesh.type}\" uses ${names}, which has no lightMap slot.`,\n why: 'three multiplies a lightmap into irradiance inside its own shading model. A raw ShaderMaterial writes its own color, so there is nothing to multiply into.',\n fix: 'Use MeshStandardMaterial / MeshPhysicalMaterial (or their Node variants), or sample the lightmap yourself in your shader.',\n };\n }\n\n return undefined;\n}\n\nfunction advise(mesh: Mesh): BakeCandidateReason | undefined {\n const userData = (mesh.userData?.bakery3 ?? {}) as BakeUserData;\n if (userData.bake === false) {\n return {\n code: 'BakeOptedOut',\n message: `\"${mesh.name || mesh.type}\" is marked userData.bakery3.bake = false.`,\n why: 'You asked for this one to stay out of bakes.',\n fix: 'Remove the flag, or tick the box to include it this once.',\n };\n }\n\n if (!mesh.visible || hasHiddenAncestor(mesh)) {\n return {\n code: 'BakeObjectHidden',\n message: `\"${mesh.name || mesh.type}\" is hidden right now.`,\n why: 'Hidden objects are hidden in the bake too, so its lightmap would come back black, and the render it is hidden from does not need one.',\n fix: 'Make it visible before baking if this variant is one you ship.',\n };\n }\n\n const glassy = materialsOf(mesh).filter(isTransmissive);\n if (glassy.length) {\n return {\n code: 'BakeTransmissiveMaterial',\n message: `\"${mesh.name || mesh.type}\" is transparent or transmissive.`,\n why: 'A lightmap only modulates diffuse irradiance. Glass is almost entirely refraction and specular, so the baked map costs texels and changes nothing you can see.',\n fix: 'Leave it out: it will still refract the baked room around it. Tick the box if it is a frosted surface with real diffuse.',\n };\n }\n\n return undefined;\n}\n\nfunction hasHiddenAncestor(object: Object3D): boolean {\n for (let node = object.parent; node; node = node.parent) {\n if (!node.visible) return true;\n }\n return false;\n}\n\nfunction isTransmissive(material: Material): boolean {\n const surface = material as Material & {\n transmission?: number;\n opacity?: number;\n };\n if ((surface.transmission ?? 0) > 0) return true;\n if (material.transparent && (surface.opacity ?? 1) < 1) return true;\n return false;\n}\n","/**\n * The shadow a product casts on a floor that was lit before it existed.\n *\n * See `BakeShadow` in the protocol for what the render worker traces.\n * This is the other half: a plane the width of the shadow, lying a few\n * millimetres above the floor, carrying the ratio and multiplying it in.\n *\n * The plane composites in the framebuffer, which holds what every material\n * has already written: tone mapped and encoded, not linear light. Multiplying\n * there is exact when the encoding is a pure power function, because\n * `enc(L) · enc(r) = (L · r)^g = enc(L · r)`, so the plane must emit the\n * encoded ratio, which is what `toneMapped: false` on a linear map gets:\n * three skips the tone curve and still applies the output colour space.\n *\n * Under a tone curve (`ACESFilmicToneMapping`) it is an approximation: the\n * floor's pixel is `aces(L)` and this gives `aces(L) · r` where the truth is\n * `aces(L · r)`. The curve is near enough to linear through the midtones that\n * a contact shadow lands within a percent or two, and it diverges only where\n * the floor is blown out, which is not where a product's shadow is.\n */\n\nimport {\n DoubleSide,\n LinearSRGBColorSpace,\n Mesh,\n MeshBasicMaterial,\n MultiplyBlending,\n PlaneGeometry,\n type Object3D,\n type Texture,\n} from 'three';\nimport type { BakedShadow } from '../protocol/index.js';\n\n/** What `buildPatch` needs to put one in and take it out again. */\nexport type ShadowTouch = {\n on(): void;\n off(): void;\n dispose(): void;\n mesh: Mesh;\n};\n\nexport function shadowMesh(shadow: BakedShadow, texture: Texture): Mesh {\n const geometry = new PlaneGeometry(shadow.width, shadow.height);\n // Flat, facing up. PlaneGeometry stands in XY.\n geometry.rotateX(-Math.PI / 2);\n const material = new MeshBasicMaterial({\n map: texture,\n blending: MultiplyBlending,\n // Required: both renderers refuse MultiplyBlending without it and draw\n // the plane opaque instead, so the ratio, near 1 almost everywhere, lands\n // as a white square. With it the blend is `src·dst + dst·(1 − a)`, and\n // the ratio has no alpha channel (a = 1), so it is exactly\n // `floor · ratio`.\n premultipliedAlpha: true,\n transparent: true,\n // It contributes nothing to depth: it is a mark on a surface that is\n // already there, and writing depth would make it occlude the product\n // standing on it.\n depthWrite: false,\n // Lit by nothing, tone mapped by nothing: see the header.\n toneMapped: false,\n side: DoubleSide,\n });\n const mesh = new Mesh(geometry, material);\n mesh.position.set(\n shadow.center[0],\n shadow.center[1] + shadow.lift,\n shadow.center[2],\n );\n mesh.renderOrder = 1;\n mesh.castShadow = false;\n mesh.receiveShadow = false;\n mesh.name = 'bakery3 shadow';\n mesh.userData.bakery3 = { exclude: true, shadow: true };\n return mesh;\n}\n\n/** Configure the ratio texture: linear data, never decoded, never mipped\n * across its own edge. */\nexport function configureShadow(texture: Texture): Texture {\n texture.colorSpace = LinearSRGBColorSpace;\n texture.flipY = false;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n\nexport function shadowTouch(\n scene: Object3D,\n shadow: BakedShadow,\n texture: Texture,\n): ShadowTouch {\n const mesh = shadowMesh(shadow, texture);\n return {\n mesh,\n on() {\n scene.add(mesh);\n },\n off() {\n scene.remove(mesh);\n },\n dispose() {\n mesh.geometry.dispose();\n (mesh.material as MeshBasicMaterial).dispose();\n },\n };\n}\n","/**\n * How a lightmap is combined with the lights that are still running.\n *\n * three adds a lightmap to everything else that lights a surface, which is\n * right when only the bounce was baked and wrong here: a Bakery3 lightmap is\n * the whole diffuse answer (direct light, bounce, ambient and the\n * environment's diffuse) in one texture, so adding it to a scene whose lamps\n * are still on counts everything twice. Muting the lights\n * (`session.muteLights`) fixes the diffuse and breaks the specular: the\n * highlight a lamp puts on a glossy floor is not in a lightmap, and an\n * environment map cannot be muted without losing its reflections.\n *\n * So this module leaves every light on and changes what the diffuse lobe\n * listens to: the lightmap alone. Specular keeps hearing the lamps and the\n * environment map, which is the closest a rasterizer gets to the traced\n * frame, with the lights exactly as you left them.\n *\n * Two renderers, one material. WebGLRenderer compiles GLSL from chunks, and\n * `onBeforeCompile` inserts a few lines after the chunk that samples the\n * lightmap: direct diffuse is discarded and the indirect irradiance is\n * replaced by the lightmap's, routed through a physical material's\n * energy-conserving path so a metal stays dark. WebGPURenderer (and its WebGL\n * backend) builds node materials, and converts a classic material by copying\n * its own properties across, which is what lets `setupLightMap` and\n * `setupLightingModel`, assigned here as own properties, arrive on the node\n * side and wrap the lighting model the same way. Nothing is imported from the\n * node system, so an app that never touches WebGPU never downloads it.\n *\n * Reversible, like everything else in the bake: each hook records the\n * property descriptor it replaced (your own `onBeforeCompile`, or nothing)\n * and `off()` puts it back. Your own `onBeforeCompile` keeps running first,\n * and your cache key is folded into ours, so two materials that differed\n * before still compile to two programs after.\n */\n\nimport type { Material } from 'three';\n\n/**\n * `'replace'`: the lightmap is the diffuse lighting, and lamps, ambient and\n * the environment contribute specular only. The default, because it is what\n * makes a baked scene match its traced still.\n *\n * `'add'`: three's stock behavior, the lightmap added on top of whatever else\n * lights the surface. For a bake that deliberately contains only part of the\n * lighting.\n */\nexport type BakeShading = 'replace' | 'add';\n\nexport type ShadingTouch = {\n on(): void;\n off(): void;\n};\n\n/** The own properties this module installs, and restores. The last one is\n * the scratch slot the node-side hooks hand a node between each other. */\nconst HOOKS = [\n 'onBeforeCompile',\n 'customProgramCacheKey',\n 'setupLightMap',\n 'setupLightingModel',\n '_bakery3LightMapNode',\n] as const;\n\n/**\n * A reversible install of the replace-mode shading hooks on one material.\n *\n * `on()` must run before the caller sets `needsUpdate`, so the program that is\n * rebuilt is the patched one; `off()` before the `needsUpdate` that follows a\n * revert, for the same reason in the other direction.\n */\nexport function bakedShadingTouch(material: Material): ShadingTouch {\n const previous = new Map<string, PropertyDescriptor | undefined>();\n let installed = false;\n const target = material as unknown as Record<string, unknown>;\n\n return {\n on() {\n if (installed) return;\n for (const key of HOOKS)\n previous.set(key, Object.getOwnPropertyDescriptor(target, key));\n installBakedShading(material);\n installed = true;\n },\n off() {\n if (!installed) return;\n for (const key of HOOKS) {\n const descriptor = previous.get(key);\n if (descriptor) Object.defineProperty(target, key, descriptor);\n else delete target[key];\n }\n installed = false;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// WebGL: the GLSL patch\n// ---------------------------------------------------------------------------\n\n/** The chunk that samples the lightmap. The patch goes right after it. */\nconst ANCHOR = '#include <lights_fragment_maps>';\n/** Where the accumulated terms are consumed: the fallback anchor for a\n * material whose own `onBeforeCompile` replaced the chunk above. */\nconst FALLBACK_ANCHOR = '#include <lights_fragment_end>';\n\n/**\n * Inserted into the fragment shader of every lit material that carries a\n * lightmap. Sampled again rather than reusing the chunk's local so it stands\n * on its own after the fallback anchor too; the compiler folds the duplicate.\n *\n * `STANDARD` is defined for MeshStandardMaterial and MeshPhysicalMaterial,\n * whose indirect specular pass takes an irradiance argument and splits it\n * between diffuse and multiple-scattering specular with energy conservation.\n * Handing the lightmap in there is what the environment's diffuse would have\n * received, so the material's response is the one three already validates.\n * Lambert, Phong and Toon have no such pass and read `irradiance` directly.\n */\nexport const REPLACE_DIFFUSE_GLSL = `\n#if defined( USE_LIGHTMAP ) && defined( RE_IndirectDiffuse )\n\t// Bakery3: the lightmap is the whole diffuse irradiance (direct, ambient\n\t// and environment included), so nothing else may add diffuse. Specular from\n\t// the lamps and the environment stays live.\n\t{\n\t\tvec3 bakery3Irradiance = texture2D( lightMap, vLightMapUv ).rgb * lightMapIntensity;\n\t\treflectedLight.directDiffuse = vec3( 0.0 );\n\t\t#if defined( STANDARD )\n\t\t\tirradiance = vec3( 0.0 );\n\t\t\tiblIrradiance = bakery3Irradiance;\n\t\t#else\n\t\t\tirradiance = bakery3Irradiance;\n\t\t#endif\n\t}\n#endif\n`;\n\nexport function patchFragmentShader(source: string): string {\n if (source.includes(ANCHOR))\n return source.replace(ANCHOR, `${ANCHOR}\\n${REPLACE_DIFFUSE_GLSL}`);\n if (source.includes(FALLBACK_ANCHOR)) {\n return source.replace(\n FALLBACK_ANCHOR,\n `${REPLACE_DIFFUSE_GLSL}\\n${FALLBACK_ANCHOR}`,\n );\n }\n return source;\n}\n\nconst CACHE_KEY_TAG = '|bakery3:lightmap-replace';\n\n// ---------------------------------------------------------------------------\n// Install\n// ---------------------------------------------------------------------------\n\n/** The shape three's shader object has when it reaches `onBeforeCompile`. */\ntype ShaderLike = { fragmentShader: string };\n\ntype CompileHook = (\n this: Material,\n shader: ShaderLike,\n renderer: unknown,\n) => void;\ntype CacheKeyHook = (this: Material) => string;\n\n/** The subset of the node-material surface this module touches. Typed here\n * rather than imported from three/webgpu so the bake entry stays free of it. */\ntype NodeLike = {\n mul(value: number): NodeLike;\n toVar(): NodeLike;\n assign(value: NodeLike): unknown;\n};\ntype ReflectedLight = {\n directDiffuse: NodeLike;\n directSpecular: NodeLike;\n indirectDiffuse: NodeLike;\n indirectSpecular: NodeLike;\n};\ntype LightingContext = {\n irradiance?: NodeLike;\n iblIrradiance?: NodeLike;\n};\ntype Builder = { context: LightingContext };\ntype LightingModel = {\n direct?(input: { reflectedLight: ReflectedLight }, builder: Builder): unknown;\n directRectArea?(\n input: { reflectedLight: ReflectedLight },\n builder: Builder,\n ): unknown;\n indirect?(builder: Builder): unknown;\n computeMultiscattering?: unknown;\n};\ntype IrradianceNodeLike = { node?: NodeLike } | null | undefined;\ntype NodeMaterialLike = Material & {\n setupLightMap?(builder: Builder): IrradianceNodeLike;\n setupLightingModel?(builder: Builder): LightingModel | null | undefined;\n _bakery3LightMapNode?: NodeLike | null;\n};\n\nfunction installBakedShading(material: Material): void {\n const target = material as Material & {\n onBeforeCompile: CompileHook;\n customProgramCacheKey: CacheKeyHook;\n };\n\n // ---- WebGL ------------------------------------------------------------\n const previousCompile = target.onBeforeCompile;\n const ownCacheKey = Object.prototype.hasOwnProperty.call(\n material,\n 'customProgramCacheKey',\n )\n ? target.customProgramCacheKey\n : null;\n\n target.onBeforeCompile = function (this: Material, shader, renderer) {\n previousCompile.call(this, shader, renderer);\n shader.fragmentShader = patchFragmentShader(shader.fragmentShader);\n };\n // three's default cache key is `onBeforeCompile.toString()`, which after the\n // line above would be the same wrapper for every material. So the key is\n // built from what you had: your own key function if you wrote one,\n // otherwise the source of the hook you had (the default's own rule, applied\n // to the right function).\n target.customProgramCacheKey = function (this: Material) {\n const base = ownCacheKey\n ? ownCacheKey.call(this)\n : previousCompile.toString();\n return `${base}${CACHE_KEY_TAG}`;\n };\n\n // ---- Node materials -----------------------------------------------------\n // Own properties, so a classic material's conversion to a node material\n // carries them across, and a real node material's prototype method is\n // shadowed rather than edited.\n const node = material as NodeMaterialLike;\n\n node.setupLightMap = function (this: NodeMaterialLike, builder) {\n const proto = Object.getPrototypeOf(this) as NodeMaterialLike;\n const irradianceNode = proto.setupLightMap\n ? proto.setupLightMap.call(this, builder)\n : null;\n // The texture-times-intensity node the material would have added to the\n // irradiance. Kept so the lighting model below can put it where it\n // belongs instead.\n this._bakery3LightMapNode = irradianceNode?.node ?? null;\n return irradianceNode;\n };\n\n node.setupLightingModel = function (this: NodeMaterialLike, builder) {\n const proto = Object.getPrototypeOf(this) as NodeMaterialLike;\n const model = proto.setupLightingModel\n ? proto.setupLightingModel.call(this, builder)\n : null;\n if (!model) return model;\n return bakedLightingModel(model, this._bakery3LightMapNode ?? null);\n };\n}\n\n/**\n * A lighting model that lets the lamps contribute specular only and reads the\n * lightmap as the sole diffuse irradiance.\n *\n * Built over the original with `Object.create`, so every method and every\n * field it sets up on itself (`clearcoatSpecularDirect`, the sheen and\n * iridescence terms) keeps working, and only the three methods that decide\n * where diffuse comes from are overridden.\n */\nfunction bakedLightingModel(\n model: LightingModel,\n lightMap: NodeLike | null,\n): LightingModel {\n const wrapped = Object.create(model) as LightingModel;\n\n if (model.direct) {\n const direct = model.direct;\n wrapped.direct = function (this: LightingModel, input, builder) {\n return direct.call(\n this,\n { ...input, reflectedLight: withoutDiffuse(input.reflectedLight) },\n builder,\n );\n };\n }\n if (model.directRectArea) {\n const directRectArea = model.directRectArea;\n wrapped.directRectArea = function (this: LightingModel, input, builder) {\n return directRectArea.call(\n this,\n { ...input, reflectedLight: withoutDiffuse(input.reflectedLight) },\n builder,\n );\n };\n }\n if (model.indirect) {\n const indirect = model.indirect;\n wrapped.indirect = function (this: LightingModel, builder) {\n const context = builder.context;\n if (lightMap && context.irradiance && context.iblIrradiance) {\n // Everything the light nodes accumulated into `irradiance` (ambient,\n // hemisphere, and the lightmap itself, which the material's own\n // setupLightMap added) is replaced by the lightmap alone, entering\n // through the path the lighting model treats with energy\n // conservation when it has one.\n const zero = context.irradiance.mul(0);\n if (typeof model.computeMultiscattering === 'function') {\n context.iblIrradiance.assign(lightMap);\n context.irradiance.assign(zero);\n } else {\n context.irradiance.assign(lightMap);\n }\n }\n return indirect.call(this, builder);\n };\n }\n\n return wrapped;\n}\n\n/** The same accumulators, with the diffuse one pointed at a throwaway. */\nfunction withoutDiffuse(reflectedLight: ReflectedLight): ReflectedLight {\n return {\n ...reflectedLight,\n directDiffuse: reflectedLight.directDiffuse.mul(0).toVar(),\n };\n}\n","/**\n * Stand-ins in the live scene: the objects a bake replaced go out of sight,\n * and what it made in their place goes in.\n *\n * A stand-in is new geometry, which is the one thing the rest of a bake never\n * adds: everywhere else your own meshes are kept and only their light\n * changes. So it is held to the same rule as everything else here and a\n * little more strictly: `on()` adds a mesh and hides the objects it stands\n * for, `off()` takes it out and puts their visibility back exactly as it was\n * found, and nothing about your own objects is touched beyond that one flag.\n *\n * The stand-in is marked `userData.bakery3.exclude`, so the next capture does\n * not mistake it for part of the scene and bake a stand-in of a stand-in.\n */\n\nimport {\n BufferAttribute,\n BufferGeometry,\n DoubleSide,\n Mesh,\n MeshBasicMaterial,\n MeshStandardMaterial,\n PlaneGeometry,\n Vector2,\n Vector3,\n type Camera,\n type Material,\n type Object3D,\n type Texture,\n} from 'three';\nimport type { BakedProxy } from '../protocol/index.js';\nimport type { BakeApplySkip } from './apply.js';\nimport { bakedShadingTouch, type BakeShading } from './shading.js';\n\n/** The textures one stand-in needs, already loaded and configured. */\nexport type ProxyTextures =\n | { kind: 'mesh'; color: Texture; normal: Texture; light: Texture }\n | { kind: 'decimated'; light: Texture }\n | { kind: 'billboard'; map: Texture };\n\ntype Touch = { on(): void; off(): void; dispose(): void };\n\nexport type ProxyPatchResult = {\n touches: Touch[];\n /** `BakedProxy.index` of every stand-in that went in. */\n applied: number[];\n /** objectIds hidden because a stand-in took their place. */\n replaced: string[];\n skipped: BakeApplySkip[];\n};\n\nexport function buildProxyTouches(options: {\n scene: Object3D;\n proxies: Array<{ proxy: BakedProxy; textures: ProxyTextures }>;\n byId: Map<string, Object3D[]>;\n intensity: number;\n shading: BakeShading;\n /** The reflection probe, and the meshes it goes on. A decimated stand-in\n * takes it when the object it replaces would have. */\n probe?: { texture: Texture; meshes: ReadonlySet<Object3D> };\n}): ProxyPatchResult {\n const touches: Touch[] = [];\n const applied: number[] = [];\n const replaced: string[] = [];\n const skipped: BakeApplySkip[] = [];\n\n for (const { proxy, textures } of options.proxies) {\n const stoodFor = proxy.replaces.flatMap((id) => options.byId.get(id) ?? []);\n if (!stoodFor.length) {\n // Nothing it replaces is in the scene any more. Adding it anyway would\n // put a bookcase back in a room you took it out of.\n skipped.push({\n objectId: `simplify[${proxy.index}]`,\n ...(proxy.name ? { name: proxy.name } : {}),\n code: 'BakeStandInUnmatched',\n message: `None of the objects \"${proxy.name ?? `stand-in ${proxy.index}`}\" replaces are in the scene.`,\n why: 'A stand-in goes in where the objects it was made from come out, and they are gone.',\n fix: 'Bake again against the scene as it stands.',\n });\n continue;\n }\n const mesh =\n proxy.kind === 'billboard' && textures.kind === 'billboard'\n ? billboardMesh(proxy, textures.map)\n : proxy.kind === 'mesh' && textures.kind === 'mesh'\n ? standInMesh(proxy, textures, options.intensity, options.shading)\n : proxy.kind === 'decimated' && textures.kind === 'decimated'\n ? decimatedMesh(proxy, textures.light, stoodFor[0] as Mesh, options)\n : null;\n if (!mesh) continue;\n mesh.name = `bakery3 stand-in ${proxy.index}${proxy.name ? ` (${proxy.name})` : ''}`;\n mesh.userData.bakery3 = { exclude: true, standIn: proxy.index };\n\n touches.push(swapTouch(options.scene, mesh, stoodFor));\n applied.push(proxy.index);\n replaced.push(...proxy.replaces.filter((id) => options.byId.has(id)));\n }\n return { touches, applied, replaced, skipped };\n}\n\nfunction standInMesh(\n proxy: Extract<BakedProxy, { kind: 'mesh' }>,\n textures: Extract<ProxyTextures, { kind: 'mesh' }>,\n intensity: number,\n shading: BakeShading,\n): Mesh {\n const geometry = new BufferGeometry();\n const source = proxy.geometry;\n geometry.setAttribute(\n 'position',\n new BufferAttribute(new Float32Array(source.position), 3),\n );\n geometry.setAttribute(\n 'normal',\n new BufferAttribute(new Float32Array(source.normal), 3),\n );\n const uv = new Float32Array(source.uv);\n geometry.setAttribute('uv', new BufferAttribute(uv, 2));\n // The lightmap contract is the second uv set (textures.ts). A stand-in has\n // one unwrap for everything, so the second set is the first.\n geometry.setAttribute('uv1', new BufferAttribute(uv, 2));\n if (source.tangent)\n geometry.setAttribute(\n 'tangent',\n new BufferAttribute(new Float32Array(source.tangent), 4),\n );\n const count = source.position.length / 3;\n geometry.setIndex(\n new BufferAttribute(\n count > 65535\n ? new Uint32Array(source.index)\n : new Uint16Array(source.index),\n 1,\n ),\n );\n geometry.computeBoundingSphere();\n geometry.computeBoundingBox();\n\n const material = new MeshStandardMaterial({\n map: textures.color,\n normalMap: textures.normal,\n normalScale: new Vector2(1, 1),\n roughness: proxy.roughness,\n metalness: proxy.metalness,\n lightMap: textures.light,\n lightMapIntensity: intensity,\n });\n if (shading === 'replace') bakedShadingTouch(material).on();\n return new Mesh(geometry, material);\n}\n\n/**\n * The replaced object with fewer triangles, in its own materials: every map,\n * color and finish it had, at the resolution it had them. The materials are\n * cloned, never edited, because the object they belong to is only hidden\n * and comes back on revert exactly as it was; a clone shares the textures,\n * so it costs a material and not a download.\n */\nfunction decimatedMesh(\n proxy: Extract<BakedProxy, { kind: 'decimated' }>,\n light: Texture,\n replaced: Mesh,\n options: {\n intensity: number;\n shading: BakeShading;\n probe?: { texture: Texture; meshes: ReadonlySet<Object3D> };\n },\n): Mesh {\n const geometry = new BufferGeometry();\n const source = proxy.geometry;\n geometry.setAttribute(\n 'position',\n new BufferAttribute(new Float32Array(source.position), 3),\n );\n geometry.setAttribute(\n 'normal',\n new BufferAttribute(new Float32Array(source.normal), 3),\n );\n geometry.setAttribute(\n 'uv',\n new BufferAttribute(new Float32Array(source.uv), 2),\n );\n if (source.uv1)\n geometry.setAttribute(\n 'uv1',\n new BufferAttribute(new Float32Array(source.uv1), 2),\n );\n if (source.color)\n geometry.setAttribute(\n 'color',\n new BufferAttribute(new Float32Array(source.color), 3),\n );\n const count = source.position.length / 3;\n geometry.setIndex(\n new BufferAttribute(\n count > 65535\n ? new Uint32Array(source.index)\n : new Uint16Array(source.index),\n 1,\n ),\n );\n for (const group of source.groups ?? [])\n geometry.addGroup(group.start, group.count, group.materialIndex);\n geometry.computeBoundingSphere();\n geometry.computeBoundingBox();\n\n // The lightmap reads the channel the render worker laid it on. Loaded lightmaps\n // read `uv1` (textures.ts); on the texture uv it is a view of the same\n // image that reads `uv` instead.\n let lightmap = light;\n if (proxy.lightmapChannel !== light.channel) {\n lightmap = light.clone();\n lightmap.channel = proxy.lightmapChannel;\n lightmap.needsUpdate = true;\n }\n const probed =\n options.probe && options.probe.meshes.has(replaced)\n ? options.probe.texture\n : undefined;\n const dress = (material: Material): Material => {\n const clone = material.clone() as Material & {\n lightMap?: Texture | null;\n lightMapIntensity?: number;\n envMap?: Texture | null;\n };\n // Vertex colors on and none to read would draw it black: only when the\n // model had them do they come through the decimation.\n if ((clone as { vertexColors?: boolean }).vertexColors && !source.color) {\n (clone as { vertexColors?: boolean }).vertexColors = false;\n }\n if ('lightMap' in clone) {\n clone.lightMap = lightmap;\n clone.lightMapIntensity = options.intensity;\n if (probed && 'envMap' in clone) clone.envMap = probed;\n if (options.shading === 'replace')\n bakedShadingTouch(clone as MeshStandardMaterial).on();\n }\n return clone;\n };\n const material = Array.isArray(replaced.material)\n ? replaced.material.map(dress)\n : dress(replaced.material);\n const mesh = new Mesh(geometry, material);\n mesh.userData.bakery3LightmapView = lightmap === light ? undefined : lightmap;\n return mesh;\n}\n\n/**\n * An upright picture that turns about the vertical to face whoever is\n * looking. Turned in `onBeforeRender`, which runs before the renderer works\n * out the model-view matrix, so it is right for every camera that draws it\n * in a frame (a second viewport, a reflection pass) and costs nothing when\n * it is off screen.\n */\nfunction billboardMesh(\n proxy: Extract<BakedProxy, { kind: 'billboard' }>,\n map: Texture,\n): Mesh {\n const geometry = new PlaneGeometry(proxy.width, proxy.height);\n const material = new MeshBasicMaterial({\n map,\n // A cutout, not a blend: a blended plant sorts against the glass behind\n // it and loses, and the edge of a leaf is a hard edge anyway.\n alphaTest: 0.5,\n side: DoubleSide,\n });\n const mesh = new Mesh(geometry, material);\n mesh.position.set(proxy.center[0], proxy.center[1], proxy.center[2]);\n mesh.castShadow = false;\n mesh.receiveShadow = false;\n // Its bounds are tested against where it faced last frame.\n mesh.frustumCulled = false;\n\n const eye = new Vector3();\n const here = new Vector3();\n mesh.onBeforeRender = (_renderer, _scene, camera: Camera) => {\n eye.setFromMatrixPosition(camera.matrixWorld);\n here.setFromMatrixPosition(mesh.matrixWorld);\n const turn = Math.atan2(eye.x - here.x, eye.z - here.z);\n if (Math.abs(turn - mesh.rotation.y) < 1e-4) return;\n mesh.rotation.set(0, turn, 0);\n mesh.updateMatrix();\n mesh.updateMatrixWorld(true);\n };\n return mesh;\n}\n\n/** The stand-in in, the objects it replaces out of sight; and back. */\nfunction swapTouch(scene: Object3D, mesh: Mesh, stoodFor: Object3D[]): Touch {\n const was = new Map<Object3D, boolean>();\n return {\n on() {\n for (const object of stoodFor) {\n was.set(object, object.visible);\n object.visible = false;\n }\n scene.add(mesh);\n },\n off() {\n scene.remove(mesh);\n for (const [object, visible] of was) object.visible = visible;\n was.clear();\n },\n dispose() {\n mesh.geometry.dispose();\n for (const material of Array.isArray(mesh.material)\n ? mesh.material\n : [mesh.material])\n material.dispose();\n (mesh.userData.bakery3LightmapView as Texture | undefined)?.dispose();\n },\n };\n}\n","/**\n * Putting the lightmaps on, and taking them off again.\n *\n * A bake is applied to your live meshes, in a running application, next to\n * your r3f component graph and event handlers. That is only acceptable if it\n * is exactly reversible, so nothing here mutates anything without first\n * recording the reference or the value it replaced, and every mutation is a\n * pair (`on`/`off`) over that record. `off()` restores references, not\n * equivalents: the same `BufferAttribute` object, the same `Material` object,\n * the same `lightMapIntensity` number. That pairing is also what makes\n * hold-to-compare instant: it is `off()` then `on()` on a patch that is\n * already built, so it flips within a frame.\n *\n * Three cases decide whether your geometry is touched:\n *\n * 1. `uv: { values }` and nobody else uses this geometry: the second UV set\n * is written straight onto the existing geometry as `uv1`. Your\n * `BufferGeometry` object survives, which matters in r3f, where a swapped\n * geometry is a prop React does not know changed.\n * 2. `uv: { topology }`: the unwrap split vertices, so a new geometry is\n * built by gathering every original attribute (custom ones included)\n * through `vertexSource`, and the mesh points at it. The original is kept,\n * untouched, for revert.\n * 3. The geometry is shared by another mesh that needs a different unwrap:\n * the same rebuild, per mesh, because one geometry cannot hold two\n * `uv1`s. Shared geometry whose sharers all got the same unwrap (25\n * spheres from one `SphereGeometry`) is written once, in place.\n *\n * Materials follow the same logic: a material used by one mesh is mutated in\n * place (its `lightMap` and `lightMapIntensity` saved first); one shared with\n * another mesh is cloned, because two objects have two lightmaps and one\n * material holds one.\n */\n\nimport {\n BufferAttribute,\n BufferGeometry,\n type InterleavedBufferAttribute,\n type Material,\n type Mesh,\n type Object3D,\n type Texture,\n} from 'three';\nimport type { BakedObject, BakeUv } from '../protocol/index.js';\nimport { idOf, markClone } from '../capture/ids.js';\nimport type { BakedProxy, BakedShadow } from '../protocol/index.js';\nimport { buildProxyTouches, type ProxyTextures } from './proxies.js';\nimport { shadowTouch } from './shadow.js';\nimport { materialsOf } from './candidates.js';\nimport { bakedShadingTouch, type BakeShading } from './shading.js';\n\n/** A per-object refusal, with the same fields as the render worker's\n * `BakeSkip`, so a skip that happened here and one that happened on the\n * worker render the same way in the panel. */\nexport type BakeApplySkip = {\n objectId: string;\n name?: string;\n code: string;\n message: string;\n why?: string;\n fix?: string;\n};\n\n/** One built, reversible edit to the scene. Built once per generation and\n * kept for as long as that generation is the applied one. */\nexport type BakePatch = {\n /** Put the baked state in place. Idempotent. */\n on(): void;\n /** Put the original state back, exactly. Idempotent. */\n off(): void;\n /** True while `on()` is in effect. */\n readonly active: boolean;\n /** Release the GPU resources this patch created (rebuilt geometries,\n * cloned materials). Reverts first if it is still applied. */\n dispose(): void;\n /** How many meshes this patch touches, for the panel's report line. */\n readonly meshes: number;\n};\n\n/** A material that can carry an environment map: every PBR material, and\n * the node materials that copy their defaults. */\ntype EnvMappable = Material & { envMap: Texture | null };\n\nexport type BuildPatchResult = {\n patch: BakePatch;\n /** objectIds that landed on a live mesh. */\n applied: string[];\n /** objectIds in the bundle with no object in the scene: the \"you edited\n * the scene since this bake\" case, reported rather than swallowed. */\n unmatched: string[];\n skipped: BakeApplySkip[];\n /** objectIds whose materials received the reflection probe as `envMap`. */\n probed: string[];\n /** `BakedProxy.index` of every stand-in that went into the scene. */\n standIns: number[];\n /** objectIds out of sight because a stand-in took their place. */\n replaced: string[];\n /** True when the bake's shadow plane went into the scene. */\n shadow: boolean;\n};\n\ntype LightMappable = Material & {\n lightMap: Texture | null;\n lightMapIntensity: number;\n};\n\ntype Touch = {\n on(): void;\n off(): void;\n dispose(): void;\n};\n\n/**\n * Every `uv1` this module has written, so a later capture can tell your own\n * second uv set from one a previous bake left on the mesh. The render worker\n * may lay a lightmap on your `uv1` (`BakeUv` `channel`); laying the next one\n * on ours would point it at an attribute the next revert takes away. See\n * `existingUv` in `prepareBake`.\n */\nconst bakeWritten = new WeakSet<object>();\n\nexport function isBakeWrittenUv(attribute: object | undefined | null): boolean {\n return Boolean(attribute && bakeWritten.has(attribute));\n}\n\n/**\n * Work out every edit this generation implies, without performing any of them.\n *\n * Building the whole patch before touching anything is what makes a partly\n * applicable generation safe: an object that fails validation becomes a skip\n * with a reason, and the objects around it still land.\n */\nexport function buildPatch(options: {\n scene: Object3D;\n objects: Array<{ baked: BakedObject; texture: Texture }>;\n /** What to write into `lightMapIntensity`. */\n intensity: number;\n /** How the lightmap meets the lights that are still running. Default\n * `'replace'`, see shading.ts. */\n shading?: BakeShading;\n /** The reflection probe, and the meshes it goes on: the ones the bake did\n * not light (`probeTargets` in probe.ts). Their materials get it as `envMap`,\n * restored on `off()` like everything else. */\n probe?: { texture: Texture; meshes: Mesh[] };\n /** The bundle's stand-ins, each with its textures. See proxies.ts. */\n proxies?: Array<{ proxy: BakedProxy; textures: ProxyTextures }>;\n /** The bundle's shadow plane and its ratio map. See shadow.ts. */\n shadow?: { shadow: BakedShadow; texture: Texture };\n}): BuildPatchResult {\n const { scene, intensity } = options;\n const shading = options.shading ?? 'replace';\n\n const byId = indexObjects(scene);\n const geometryUsers = new Map<BufferGeometry, Mesh[]>();\n const materialUsers = new Map<Material, Set<Mesh>>();\n scene.traverse((object) => {\n const mesh = object as Mesh;\n if (!mesh.isMesh) return;\n if (mesh.geometry) {\n const users = geometryUsers.get(mesh.geometry) ?? [];\n users.push(mesh);\n geometryUsers.set(mesh.geometry, users);\n }\n for (const material of materialsOf(mesh)) {\n const users = materialUsers.get(material) ?? new Set<Mesh>();\n users.add(mesh);\n materialUsers.set(material, users);\n }\n });\n\n /** objectId → the uv the bundle carries for it, for the shared-geometry\n * question \"did my co-tenants get the same unwrap?\". */\n const uvById = new Map<string, BakeUv>();\n for (const entry of options.objects)\n uvById.set(entry.baked.objectId, entry.baked.uv);\n\n const touches: Touch[] = [];\n /** One in-place uv1 write per geometry, not per mesh: two meshes sharing a\n * geometry and an unwrap would otherwise record each other's edit as the\n * value to restore, and revert would leave the attribute behind. */\n const uvWrites = new Map<BufferGeometry, true>();\n\n const applied: string[] = [];\n const unmatched: string[] = [];\n const skipped: BakeApplySkip[] = [];\n const meshes = new Set<Mesh>();\n\n for (const { baked, texture } of options.objects) {\n const found = byId.get(baked.objectId);\n if (!found || found.length === 0) {\n unmatched.push(baked.objectId);\n continue;\n }\n if (found.length > 1) {\n skipped.push({\n objectId: baked.objectId,\n ...(baked.name ? { name: baked.name } : {}),\n code: 'BakeAmbiguousObjectId',\n message: `${found.length} objects in the scene answer to the id \"${baked.objectId}\".`,\n why: 'Applying the lightmap to one of them would be a coin toss, and applying it to all of them would light the wrong surfaces.',\n fix: 'Give each object a distinct userData.bakery3Id.',\n });\n continue;\n }\n\n const object = found[0]!;\n const mesh = object as Mesh & {\n isInstancedMesh?: boolean;\n isSkinnedMesh?: boolean;\n };\n if (!mesh.isMesh || mesh.isInstancedMesh || mesh.isSkinnedMesh) {\n skipped.push({\n objectId: baked.objectId,\n ...(baked.name ? { name: baked.name } : {}),\n code: 'BakeObjectChanged',\n message: `\"${baked.name ?? baked.objectId}\" is a ${object.type} now, not a plain mesh.`,\n why: 'The bake was made against a mesh that could take a lightmap. Whatever is under that id today cannot.',\n fix: 'Bake again against the scene as it stands.',\n });\n continue;\n }\n\n const plan = planGeometry({\n mesh,\n uv: baked.uv,\n geometryUsers,\n uvById,\n objectId: baked.objectId,\n ...(baked.name !== undefined ? { name: baked.name } : {}),\n });\n if ('skip' in plan) {\n skipped.push(plan.skip);\n continue;\n }\n\n let lightmap = texture;\n if (plan.kind === 'in-place') {\n // Deduped by geometry, see `uvWrites`.\n if (!uvWrites.has(mesh.geometry)) {\n uvWrites.set(mesh.geometry, true);\n touches.push(uvAttributeTouch(mesh.geometry, plan.attribute));\n }\n } else if (plan.kind === 'channel') {\n lightmap = onChannel(texture, plan.channel, touches);\n } else {\n touches.push(geometrySwapTouch(mesh, plan.geometry));\n }\n\n touches.push(\n ...materialTouches(mesh, lightmap, intensity, materialUsers, shading),\n );\n meshes.add(mesh);\n applied.push(baked.objectId);\n }\n\n const probed: string[] = [];\n if (options.probe) {\n const targets = new Set(options.probe.meshes);\n /** One in-place `envMap` write per material, not per mesh, for the same\n * reason `uvWrites` exists: a second touch would record the probe as\n * the value to restore. */\n const written = new Set<Material>();\n for (const mesh of options.probe.meshes) {\n const probeTouchesFor = probeTouches(\n mesh,\n options.probe.texture,\n materialUsers,\n targets,\n written,\n );\n if (!probeTouchesFor.length) continue;\n touches.push(...probeTouchesFor);\n meshes.add(mesh);\n probed.push(idOf(mesh));\n }\n }\n\n // Last, so that `off()` (which runs in reverse) takes the stand-ins out\n // before anything else is put back.\n const standIns = buildProxyTouches({\n scene,\n proxies: options.proxies ?? [],\n byId,\n intensity,\n shading,\n ...(options.probe\n ? {\n probe: {\n texture: options.probe.texture,\n meshes: new Set(options.probe.meshes),\n },\n }\n : {}),\n });\n touches.push(...standIns.touches);\n skipped.push(...standIns.skipped);\n\n // Last of all, so it is drawn over a floor that already has its lightmap.\n if (options.shadow) {\n touches.push(\n shadowTouch(scene, options.shadow.shadow, options.shadow.texture),\n );\n }\n\n return {\n patch: makePatch(touches, meshes.size + standIns.applied.length),\n applied,\n unmatched,\n skipped,\n probed,\n standIns: standIns.applied,\n replaced: standIns.replaced,\n shadow: Boolean(options.shadow),\n };\n}\n\n/**\n * The reflection probe onto a mesh's materials, as `envMap`.\n *\n * The same sharing rule as a lightmap, one level down: a material every\n * user of which is getting the probe is written in place (its `envMap`\n * saved first); one shared with a mesh that is not (a baked wall using the\n * product's material) is cloned, so the wall keeps its own environment.\n * A material with no `envMap` slot is left alone: there is nowhere to put a\n * reflection, and nothing to reflect.\n */\nfunction probeTouches(\n mesh: Mesh,\n texture: Texture,\n materialUsers: Map<Material, Set<Mesh>>,\n targets: ReadonlySet<Mesh>,\n written: Set<Material>,\n): Touch[] {\n const original = mesh.material as Material | Material[];\n const slots = materialsOf(mesh).filter((material) => 'envMap' in material);\n if (!slots.length) return [];\n const touches: Touch[] = [];\n const clones: Material[] = [];\n const mapped = new Map<Material, Material>();\n let swapped = false;\n\n for (const material of slots) {\n if (mapped.has(material)) continue;\n const users = materialUsers.get(material) ?? new Set<Mesh>([mesh]);\n const allTargets = [...users].every((user) => targets.has(user));\n if (allTargets) {\n mapped.set(material, material);\n if (!written.has(material)) {\n written.add(material);\n touches.push(inPlaceProbeTouch(material as EnvMappable, texture));\n }\n continue;\n }\n const clone = material.clone() as EnvMappable;\n markClone(clone, material);\n clone.envMap = texture;\n clone.needsUpdate = true;\n mapped.set(material, clone);\n clones.push(clone);\n swapped = true;\n }\n\n if (swapped) {\n const applied = Array.isArray(original)\n ? original.map((material) => mapped.get(material) ?? material)\n : (mapped.get(original) ?? original);\n touches.push(materialSwapTouch(mesh, applied, clones));\n }\n return touches;\n}\n\nfunction inPlaceProbeTouch(material: EnvMappable, texture: Texture): Touch {\n const previous = material.envMap;\n return {\n on() {\n material.envMap = texture;\n // The program has to be rebuilt: whether a material has its own\n // envMap is a compile-time define in three.\n material.needsUpdate = true;\n },\n off() {\n material.envMap = previous;\n material.needsUpdate = true;\n },\n dispose() {},\n };\n}\n\n// ---------------------------------------------------------------------------\n// The patch\n// ---------------------------------------------------------------------------\n\nfunction makePatch(touches: Touch[], meshes: number): BakePatch {\n let active = false;\n let disposed = false;\n return {\n get active() {\n return active;\n },\n get meshes() {\n return meshes;\n },\n on() {\n if (active || disposed) return;\n for (const touch of touches) touch.on();\n active = true;\n },\n off() {\n if (!active) return;\n // Reverse order: a mesh whose geometry was swapped and whose material\n // was swapped comes back through the same door it went in.\n for (let i = touches.length - 1; i >= 0; i--) touches[i]!.off();\n active = false;\n },\n dispose() {\n if (disposed) return;\n if (active) {\n for (let i = touches.length - 1; i >= 0; i--) touches[i]!.off();\n active = false;\n }\n for (const touch of touches) touch.dispose();\n disposed = true;\n },\n };\n}\n\nfunction uvAttributeTouch(\n geometry: BufferGeometry,\n attribute: BufferAttribute,\n): Touch {\n const previous = geometry.getAttribute('uv1') as\n BufferAttribute | InterleavedBufferAttribute | undefined;\n return {\n on() {\n geometry.setAttribute('uv1', attribute);\n },\n off() {\n // Restoring the exact previous attribute matters: if you already had a\n // second UV set (a decal atlas, an AO map) you get your attribute back,\n // not a copy of it.\n if (previous) geometry.setAttribute('uv1', previous);\n else geometry.deleteAttribute('uv1');\n },\n dispose() {\n // Nothing of ours to free: the attribute we added is dropped by `off()`\n // and its GPU buffer goes with the geometry it briefly lived on.\n },\n };\n}\n\nfunction geometrySwapTouch(mesh: Mesh, rebuilt: BufferGeometry): Touch {\n const previous = mesh.geometry;\n return {\n on() {\n mesh.geometry = rebuilt;\n },\n off() {\n mesh.geometry = previous;\n },\n dispose() {\n rebuilt.dispose();\n },\n };\n}\n\n/**\n * The lightmap, reading uv set `channel`. Loaded textures read `uv1`\n * (textures.ts); one laid on the mesh's own `uv` gets a view of the same\n * image that reads channel 0 instead: a clone shares the image, and it is\n * disposed with the patch, never the loaded texture itself, which the\n * session may still hand to another generation.\n */\nfunction onChannel(\n texture: Texture,\n channel: 0 | 1,\n touches: Touch[],\n): Texture {\n if (texture.channel === channel) return texture;\n const view = texture.clone();\n view.channel = channel;\n view.needsUpdate = true;\n touches.push({ on() {}, off() {}, dispose: () => view.dispose() });\n return view;\n}\n\n/**\n * The material side. Every slot of the mesh gets the same lightmap, because\n * the bundle carries one lightmap per object: the unwrap is per object, and a\n * mesh with four material slots has one atlas covering all four.\n */\nfunction materialTouches(\n mesh: Mesh,\n texture: Texture,\n intensity: number,\n materialUsers: Map<Material, Set<Mesh>>,\n shading: BakeShading,\n): Touch[] {\n const original = mesh.material as Material | Material[];\n const slots = materialsOf(mesh);\n const touches: Touch[] = [];\n const clones: Material[] = [];\n const mapped = new Map<Material, Material>();\n let swapped = false;\n\n for (const material of slots) {\n if (mapped.has(material)) continue;\n const shared = (materialUsers.get(material)?.size ?? 1) > 1;\n if (!shared) {\n mapped.set(material, material);\n touches.push(\n inPlaceMaterialTouch(\n material as LightMappable,\n texture,\n intensity,\n shading,\n ),\n );\n continue;\n }\n // Shared with another mesh, which has its own lightmap. Clone rather than\n // mutate: mutating would hand this object's lighting to every other mesh\n // that happens to use the same material, including ones with no `uv1` at\n // all, which is how you get a black object nobody can explain.\n const clone = material.clone() as LightMappable;\n markClone(clone, material);\n clone.lightMap = texture;\n clone.lightMapIntensity = intensity;\n // The clone is ours from birth to dispose, so the shading hooks go on\n // once and never come off.\n if (shading === 'replace') bakedShadingTouch(clone).on();\n clone.needsUpdate = true;\n mapped.set(material, clone);\n clones.push(clone);\n swapped = true;\n }\n\n if (swapped) {\n const applied = Array.isArray(original)\n ? original.map((material) => mapped.get(material) ?? material)\n : (mapped.get(original) ?? original);\n touches.push(materialSwapTouch(mesh, applied, clones));\n }\n\n return touches;\n}\n\nfunction inPlaceMaterialTouch(\n material: LightMappable,\n texture: Texture,\n intensity: number,\n shading: BakeShading,\n): Touch {\n const previousMap = material.lightMap;\n const previousIntensity = material.lightMapIntensity;\n const shadingTouch =\n shading === 'replace' ? bakedShadingTouch(material) : null;\n return {\n on() {\n material.lightMap = texture;\n material.lightMapIntensity = intensity;\n // Hooks first, then the rebuild they have to be part of.\n shadingTouch?.on();\n // Forces the program rebuild that turns USE_LIGHTMAP on (classic) or\n // re-runs setupLightMap (node materials). Safe under r3f: React does\n // not own `lightMap`, `lightMapIntensity` or `needsUpdate`.\n material.needsUpdate = true;\n },\n off() {\n shadingTouch?.off();\n material.lightMap = previousMap;\n material.lightMapIntensity = previousIntensity;\n material.needsUpdate = true;\n },\n dispose() {},\n };\n}\n\nfunction materialSwapTouch(\n mesh: Mesh,\n applied: Material | Material[],\n clones: Material[],\n): Touch {\n const previous = mesh.material;\n return {\n on() {\n mesh.material = applied;\n },\n off() {\n mesh.material = previous;\n },\n dispose() {\n for (const clone of clones) clone.dispose();\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Geometry planning\n// ---------------------------------------------------------------------------\n\ntype GeometryPlan =\n | { kind: 'in-place'; attribute: BufferAttribute }\n | { kind: 'rebuild'; geometry: BufferGeometry }\n /** The lightmap reads a uv set the mesh already has: nothing to write. */\n | { kind: 'channel'; channel: 0 | 1 }\n | { skip: BakeApplySkip };\n\nfunction planGeometry(input: {\n mesh: Mesh;\n uv: BakeUv;\n objectId: string;\n name?: string;\n geometryUsers: Map<BufferGeometry, Mesh[]>;\n uvById: Map<string, BakeUv>;\n}): GeometryPlan {\n const { mesh, uv, objectId } = input;\n const geometry = mesh.geometry;\n const skip = (\n code: string,\n message: string,\n why: string,\n fix: string,\n ): { skip: BakeApplySkip } => ({\n skip: {\n objectId,\n ...(input.name !== undefined ? { name: input.name } : {}),\n code,\n message,\n why,\n fix,\n },\n });\n\n if (!geometry) {\n return skip(\n 'BakeNoGeometry',\n `\"${input.name ?? objectId}\" has no geometry to put a second UV set on.`,\n 'The mesh that was baked is not the mesh that is in the scene now.',\n 'Bake again against the scene as it stands.',\n );\n }\n\n const position = geometry.getAttribute('position');\n if (!position) {\n return skip(\n 'BakeNoPosition',\n `\"${input.name ?? objectId}\" has no position attribute.`,\n 'Without vertices there is nothing for the unwrap to index.',\n 'Bake again against the scene as it stands.',\n );\n }\n\n if ('channel' in uv) {\n // The render worker laid the lightmap on the mesh's own layout. What has\n // to hold is only that the attribute is still there and still one uv per\n // vertex: its values are what the worker baked against, whatever the\n // vertex count, because they travelled in the file it was sent.\n const name = uv.channel === 0 ? 'uv' : 'uv1';\n const attribute = geometry.getAttribute(name);\n if (!attribute || attribute.count !== position.count) {\n return skip(\n 'BakeUvChannelMissing',\n `The lightmap for \"${input.name ?? objectId}\" is laid on its own \\`${name}\\`, and the mesh ${attribute ? 'has a different number of them now' : 'no longer has one'}.`,\n 'The bake reused the uv set the mesh was captured with instead of unwrapping it, so that set is what the lightmap lines up with.',\n 'Bake again against the scene as it stands.',\n );\n }\n return { kind: 'channel', channel: uv.channel };\n }\n\n if ('topology' in uv) {\n const { vertexSource, index, values } = uv.topology;\n if (values.length !== vertexSource.length * 2) {\n return skip(\n 'BakeUvLengthMismatch',\n `The unwrap for \"${input.name ?? objectId}\" has ${values.length / 2} UVs for ${vertexSource.length} vertices.`,\n 'The bundle is internally inconsistent, which means the render worker and this SDK disagree about the format.',\n 'Update @oeave/bakery3, or bake again.',\n );\n }\n for (const source of vertexSource) {\n if (!Number.isInteger(source) || source < 0 || source >= position.count) {\n return skip(\n 'BakeTopologyOutOfRange',\n `The rebuild for \"${input.name ?? objectId}\" refers to vertex ${source}, and the live geometry has ${position.count}.`,\n 'The geometry changed between the bake and now: a different subdivision, a different loader, or an edit.',\n 'Bake again against the scene as it stands.',\n );\n }\n }\n // Groups only select anything when the mesh has an array of materials:\n // `BoxGeometry` ships six of them and three ignores every one of them for\n // a single-material mesh. So the refusal is about multi-material meshes,\n // not about groups, and a cube still takes the rebuild path.\n if (Array.isArray(mesh.material) && geometry.groups.length > 1) {\n return skip(\n 'BakeTopologyGroupsUnsupported',\n `\"${input.name ?? objectId}\" needs a geometry rebuild and has ${geometry.groups.length} material groups.`,\n 'A rebuild renumbers the triangle index, and this version cannot prove which of your groups each new triangle belongs to. Guessing would assign the wrong material to part of the surface.',\n 'Split the mesh into one mesh per material, or bake it at a size whose unwrap does not need vertex splits.',\n );\n }\n if (\n geometry.drawRange.start !== 0 ||\n Number.isFinite(geometry.drawRange.count)\n ) {\n return skip(\n 'BakeDrawRangeUnsupported',\n `\"${input.name ?? objectId}\" needs a geometry rebuild and draws only part of its index.`,\n 'The rebuild renumbers the index, so the partial draw range would point at different triangles.',\n 'Clear setDrawRange() before baking, or split the mesh.',\n );\n }\n return {\n kind: 'rebuild',\n geometry: rebuildGeometry(geometry, uv.topology),\n };\n }\n\n const values = uv.values;\n if (values.length !== position.count * 2) {\n return skip(\n 'BakeVertexCountMismatch',\n `The bake has ${values.length / 2} UVs for \"${input.name ?? objectId}\", and the live geometry has ${position.count} vertices.`,\n 'The geometry changed between baking and applying, so the unwrap no longer describes this surface.',\n 'Bake again against the scene as it stands.',\n );\n }\n\n const attribute = new BufferAttribute(new Float32Array(values), 2);\n bakeWritten.add(attribute);\n\n const sharers = (input.geometryUsers.get(geometry) ?? []).filter(\n (other) => other !== mesh,\n );\n const conflicted = sharers.some((other) => {\n const otherUv = input.uvById.get(idOf(other));\n if (!otherUv) return false; // Unbaked sharer: an unused uv1 harms nothing.\n // A sharer reading the mesh's own `uv` does not care what uv1 holds; one\n // reading its own `uv1` would have it overwritten.\n if ('channel' in otherUv) return otherUv.channel === 1;\n if ('topology' in otherUv) return true;\n return !sameValues(otherUv.values, values);\n });\n\n if (!conflicted) return { kind: 'in-place', attribute };\n\n // Same geometry, two different unwraps. `clone()` keeps the groups, the\n // draw range and the morph targets that a `topology` rebuild has to refuse,\n // so this path stays available to multi-material meshes.\n const copy = geometry.clone();\n copy.setAttribute('uv1', attribute);\n return { kind: 'rebuild', geometry: copy };\n}\n\nfunction sameValues(a: number[], b: number[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/**\n * A new geometry over split vertices, carrying everything the old one had.\n *\n * Every named attribute is gathered through `vertexSource`, including\n * attributes this SDK has never heard of: your per-vertex `aWindStrength`\n * survives the rebuild, which is what makes a bake reversible rather than\n * destructive.\n *\n * Values are copied through `getComponent`/`setComponent` rather than by raw\n * array indexing so that normalized integer attributes (packed normals, byte\n * colors) round-trip through the same denormalize/normalize three would use.\n */\nexport function rebuildGeometry(\n source: BufferGeometry,\n topology: { vertexSource: number[]; index: number[]; values: number[] },\n): BufferGeometry {\n const { vertexSource, index, values } = topology;\n const target = new BufferGeometry();\n target.name = source.name;\n target.userData = { ...source.userData };\n\n for (const [name, attribute] of Object.entries(source.attributes)) {\n target.setAttribute(\n name,\n gather(attribute as BufferAttribute, vertexSource),\n );\n }\n\n // Morph targets are per-vertex too, so they gather through exactly the same\n // map. Indexed loosely because three types `morphAttributes` as three named\n // slots while the runtime happily carries any name.\n const morphs = target.morphAttributes as Record<string, BufferAttribute[]>;\n for (const [name, list] of Object.entries(\n source.morphAttributes as Record<string, BufferAttribute[]>,\n )) {\n morphs[name] = list.map((attribute) => gather(attribute, vertexSource));\n }\n target.morphTargetsRelative = source.morphTargetsRelative;\n\n const lightmapUv = new BufferAttribute(new Float32Array(values), 2);\n bakeWritten.add(lightmapUv);\n target.setAttribute('uv1', lightmapUv);\n\n const IndexArray = vertexSource.length > 65535 ? Uint32Array : Uint16Array;\n target.setIndex(new BufferAttribute(IndexArray.from(index), 1));\n\n // At most one group survives here by construction: `planGeometry` refuses\n // the rebuild for a multi-group geometry rather than guess.\n const group = source.groups[0];\n if (group) target.addGroup(0, index.length, group.materialIndex);\n\n return target;\n}\n\nfunction gather(\n attribute: BufferAttribute | InterleavedBufferAttribute,\n vertexSource: number[],\n): BufferAttribute {\n const itemSize = attribute.itemSize;\n const SourceArray = (attribute.array as Float32Array).constructor as {\n new (length: number): Float32Array;\n BYTES_PER_ELEMENT: number;\n };\n // A quantized glTF position is three int16s, padded to eight bytes inside\n // an interleaved buffer. Packed tight it is a six-byte stride, which WebGL\n // takes and WebGPU refuses (a vertex stride is a multiple of four), so an\n // item that would not align goes out as floats, denormalized on the way.\n const aligned = (SourceArray.BYTES_PER_ELEMENT * itemSize) % 4 === 0;\n const ArrayType = aligned ? SourceArray : Float32Array;\n const out = new BufferAttribute(\n new ArrayType(vertexSource.length * itemSize),\n itemSize,\n aligned && attribute.normalized,\n );\n out.name = attribute.name;\n for (let i = 0; i < vertexSource.length; i++) {\n const source = vertexSource[i]!;\n for (let component = 0; component < itemSize; component++) {\n out.setComponent(i, component, attribute.getComponent(source, component));\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n\n/** id → objects. An array, not a single object, so a duplicate declared id is\n * a reportable ambiguity rather than a silent first-wins. */\nexport function indexObjects(scene: Object3D): Map<string, Object3D[]> {\n const byId = new Map<string, Object3D[]>();\n scene.traverse((object) => {\n const id = idOf(object);\n const list = byId.get(id);\n if (list) list.push(object);\n else byId.set(id, [object]);\n });\n return byId;\n}\n","/**\n * The viewpoint a bake hides its seams from, and why it is not the camera.\n *\n * A lightmap has no viewpoint, and the bake cache key says so: orbit the\n * scene, bake again, and you land on the bake you already paid for. Seam\n * placement is the one part of a bake that does care where the viewer stands:\n * a UV island boundary on the front of a sphere is a visible line, and the\n * same boundary on its underside is not.\n *\n * Handing the render worker the exact camera would make every nudge of the\n * orbit a different seam layout, a different cache key and a new bill. So the\n * camera is quantized here into a `BakeView` that is stable across small\n * moves:\n *\n * - direction from the center of the baked objects, in 30° steps of azimuth\n * and elevation: a viewer who moves within a step sees the same seams, one\n * who walks round to the other side gets seams re-cut for that side;\n * - distance in octaves of the objects' radius: 3 m or 3.4 m away changes\n * nothing about which faces are visible, 3 m or 30 m changes the parallax\n * across a room.\n *\n * The bin center is what travels, so the worker's notion of \"facing away\" is\n * never more than half a step from the truth, and the unwrap keeps its own\n * margin beyond the silhouette on top of that. The center is the bounding box\n * of the objects being baked, not of the whole scene, so a hundred-meter floor\n * around a chair does not decide the chair's view.\n */\n\nimport { Box3, Vector3, type Camera, type Object3D } from 'three';\nimport type { BakeView } from '../protocol/index.js';\n\n/** Azimuth and elevation step, degrees. */\nexport const BAKE_VIEW_ANGLE_STEP = 30;\n/** Distance is snapped to `radius · 2^k` for integer k in this range. */\nconst OCTAVE_MIN = -3;\nconst OCTAVE_MAX = 8;\n\nconst scratchBox = new Box3();\nconst scratchCenter = new Vector3();\nconst scratchSize = new Vector3();\nconst scratchCamera = new Vector3();\nconst scratchDirection = new Vector3();\n\n/**\n * The world-space bounds of the objects a bake covers. Empty when none of them\n * has geometry, which the caller treats as \"the origin, one meter\".\n */\nexport function bakeBounds(objects: Iterable<Object3D>): Box3 {\n const bounds = new Box3();\n for (const object of objects) {\n scratchBox.setFromObject(object);\n if (!scratchBox.isEmpty()) bounds.union(scratchBox);\n }\n return bounds;\n}\n\n/**\n * The camera, quantized into a `BakeView` around `bounds`.\n *\n * Pure in the sense that matters for a cache: the same camera and bounds give\n * the same numbers, and cameras within one angular step and one distance\n * octave of each other give the same numbers.\n */\nexport function quantizeBakeView(camera: Camera, bounds: Box3): BakeView {\n const center = bounds.isEmpty()\n ? scratchCenter.set(0, 0, 0)\n : bounds.getCenter(scratchCenter);\n const radius = bounds.isEmpty()\n ? 1\n : Math.max(1e-3, bounds.getSize(scratchSize).length() / 2);\n\n camera.updateWorldMatrix(true, false);\n const position = camera.getWorldPosition(scratchCamera);\n const offset = scratchDirection.subVectors(position, center);\n let distance = offset.length();\n\n if (distance < 1e-6) {\n // Camera at the very center of what it bakes (a room, from its middle,\n // whose walls are the bake). Direction is then \"where it looks from\",\n // which is the opposite of where it looks.\n camera.getWorldDirection(offset).negate();\n distance = radius;\n } else {\n offset.divideScalar(distance);\n }\n\n // Spherical, Y-up: elevation from the horizon, azimuth around Y measured\n // from +Z, the direction a default three camera looks along.\n const elevation = toDegrees(Math.asin(clamp(offset.y, -1, 1)));\n const azimuth = toDegrees(Math.atan2(offset.x, offset.z));\n\n const step = BAKE_VIEW_ANGLE_STEP;\n const elevationBin = clamp(\n binCenter(elevation, step),\n -90 + step / 2,\n 90 - step / 2,\n );\n const azimuthBin = binCenter(azimuth, step);\n\n const octave = clamp(\n Math.round(Math.log2(distance / radius)),\n OCTAVE_MIN,\n OCTAVE_MAX,\n );\n const snappedDistance = radius * 2 ** octave;\n\n const el = toRadians(elevationBin);\n const az = toRadians(azimuthBin);\n const direction = scratchDirection.set(\n Math.cos(el) * Math.sin(az),\n Math.sin(el),\n Math.cos(el) * Math.cos(az),\n );\n const snapped = direction.multiplyScalar(snappedDistance).add(center);\n\n return {\n position: [round(snapped.x), round(snapped.y), round(snapped.z)],\n };\n}\n\n/** The center of the `step`-wide bin `value` falls in. */\nfunction binCenter(value: number, step: number): number {\n return (Math.floor(value / step) + 0.5) * step;\n}\n\n/** Four decimals (a tenth of a millimeter), so the JSON is short and the\n * same view never differs by floating-point dust. */\nfunction round(value: number): number {\n const rounded = Math.round(value * 1e4) / 1e4;\n return Object.is(rounded, -0) ? 0 : rounded;\n}\n\nconst clamp = (value: number, low: number, high: number) =>\n Math.min(high, Math.max(low, value));\nconst toDegrees = (radians: number) => (radians * 180) / Math.PI;\nconst toRadians = (degrees: number) => (degrees * Math.PI) / 180;\n","/**\n * Where a bake's reflection probe is taken, and what it hides. Decided here,\n * because only the browser can see the live materials.\n *\n * A lightmap replaces a baked surface's diffuse and leaves specular to the\n * live lights and `scene.environment`. The objects a bake is for (the product\n * on the plinth, kept live so it can turn and change finish) would therefore\n * reflect whatever environment the scene had, which in a baked room is the\n * sky behind the windows, or nothing. The render worker renders a small\n * equirect of the scene from where those objects stand, with them hidden, and\n * the session puts it on their materials. This module answers \"which objects\"\n * and \"from where\".\n *\n * The subject is every mesh that could have been baked and was deliberately\n * left out: bakeable, not in the include list, and not left out for being\n * glass or hidden (the `exclude` you wrote, the objects an explicit `include`\n * left off, a mesh marked `userData.bakery3.bake = false`). That is the\n * product. Everything a lightmap cannot help (glass, an instanced hedge, a\n * skinned figure, a mesh with no lightMap slot) is scenery: it stays in the\n * probe so the product reflects the vitrine beside it, and it is given the\n * probe too, so the vitrine refracts the room. A kept-live object far larger\n * than the rest of the subject (a backdrop, a room shell left unbaked) is\n * scenery as well, because hiding it would leave a hole where the room should\n * be. Believable, not exact: a probe is one point.\n *\n * With no subject at all the probe is taken from the middle of the baked\n * objects and hides nothing: a room as seen from its center, for the glass\n * and the instances in it.\n */\n\nimport { Box3, Vector3, type Mesh } from 'three';\nimport type { BakeProbe } from '../protocol/index.js';\nimport type { BakeCandidate } from './candidates.js';\nimport { bakeBounds } from './view.js';\n\n/** A kept-live object whose bounds diagonal is this many times the median of\n * the others is scenery, not subject. Four: a product and its stand differ\n * by two or three, a product and a backdrop by ten or more. */\nexport const PROBE_SCENERY_FACTOR = 4;\n\n/** Why a bakeable mesh was off by default, when the reason makes it scenery\n * rather than subject: glass refracts the room and belongs in the map, and a\n * hidden mesh is in nobody's frame. `BakeOptedOut` is deliberately absent:\n * an object marked to stay live is the product. */\nconst SCENERY_REASONS: ReadonlySet<string> = new Set([\n 'BakeTransmissiveMaterial',\n 'BakeObjectHidden',\n]);\n\nconst scratchBox = new Box3();\nconst scratchSize = new Vector3();\nconst scratchCenter = new Vector3();\n\n/**\n * The probe request for a bake: the objects it hides (and is for), and the\n * point it is taken from, in scene units. Pure over the classification the\n * include list came from, so the same scene and list give the same numbers\n * and the cache key holds.\n */\nexport function resolveProbe(\n candidates: BakeCandidate[],\n include: string[],\n): BakeProbe {\n const included = new Set(include);\n const keptLive = candidates.filter(\n (candidate) =>\n candidate.bakeable &&\n !included.has(candidate.objectId) &&\n !SCENERY_REASONS.has(candidate.reason?.code ?? ''),\n );\n const subject = withoutScenery(keptLive);\n\n const anchor = subject.length\n ? subject\n : candidates.filter((candidate) => included.has(candidate.objectId));\n const bounds = bakeBounds(anchor.map((candidate) => candidate.object));\n const center = bounds.isEmpty()\n ? scratchCenter.set(0, 0, 0)\n : bounds.getCenter(scratchCenter);\n\n return {\n position: [round(center.x), round(center.y), round(center.z)],\n hide: subject.map((candidate) => candidate.objectId),\n };\n}\n\n/**\n * Which meshes an applied probe goes on: every candidate the bake did not\n * light (the subject it was hidden from and the scenery it was not), so a\n * glass vitrine refracts the room and the product reflects it. Baked objects\n * keep their own environment for specular: their diffuse is the lightmap's,\n * and a room's floor is not well served by a probe taken a meter above it.\n */\nexport function probeTargets(\n candidates: BakeCandidate[],\n bakedIds: ReadonlySet<string>,\n): Mesh[] {\n return candidates\n .filter((candidate) => !bakedIds.has(candidate.objectId))\n .map((candidate) => candidate.object);\n}\n\nfunction withoutScenery(keptLive: BakeCandidate[]): BakeCandidate[] {\n if (keptLive.length < 2) return keptLive;\n const diagonals = keptLive.map((candidate) => {\n scratchBox.setFromObject(candidate.object);\n return scratchBox.isEmpty() ? 0 : scratchBox.getSize(scratchSize).length();\n });\n const sorted = [...diagonals].sort((a, b) => a - b);\n const median = sorted[Math.floor(sorted.length / 2)]!;\n if (median <= 0) return keptLive;\n return keptLive.filter(\n (_candidate, i) => diagonals[i]! <= median * PROBE_SCENERY_FACTOR,\n );\n}\n\nfunction round(value: number): number {\n return Math.round(value * 1e4) / 1e4;\n}\n"]}
|