@rydr/game-sdk 9.10.0 → 9.12.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/README.md +1 -0
- package/dist/client/PlatformClient.d.ts +31 -2
- package/dist/client/PlatformClient.d.ts.map +1 -1
- package/dist/client/PlatformClient.js +42 -0
- package/dist/client/PlatformClient.js.map +1 -1
- package/dist/host/PlatformHost.d.ts +16 -1
- package/dist/host/PlatformHost.d.ts.map +1 -1
- package/dist/host/PlatformHost.js +18 -1
- package/dist/host/PlatformHost.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/protocol/guards.d.ts.map +1 -1
- package/dist/protocol/guards.js +1 -0
- package/dist/protocol/guards.js.map +1 -1
- package/dist/protocol/messages.d.ts +11 -2
- package/dist/protocol/messages.d.ts.map +1 -1
- package/dist/protocol/rideHud.d.ts +33 -0
- package/dist/protocol/rideHud.d.ts.map +1 -1
- package/dist/protocol/rideHud.js +37 -0
- package/dist/protocol/rideHud.js.map +1 -1
- package/dist/protocol/version.d.ts +2 -2
- package/dist/protocol/version.d.ts.map +1 -1
- package/dist/protocol/version.js +13 -2
- package/dist/protocol/version.js.map +1 -1
- package/dist/protocol/worlds.d.ts +181 -0
- package/dist/protocol/worlds.d.ts.map +1 -1
- package/dist/protocol/worlds.js +9 -0
- package/dist/protocol/worlds.js.map +1 -1
- package/dist/three/README.md +25 -0
- package/dist/three/baked-lighting.d.ts +144 -0
- package/dist/three/baked-lighting.d.ts.map +1 -0
- package/dist/three/baked-lighting.js +289 -0
- package/dist/three/baked-lighting.js.map +1 -0
- package/dist/three/index.d.ts +2 -0
- package/dist/three/index.d.ts.map +1 -1
- package/dist/three/index.js +2 -0
- package/dist/three/index.js.map +1 -1
- package/dist/three/preset-lighting.d.ts +65 -0
- package/dist/three/preset-lighting.d.ts.map +1 -0
- package/dist/three/preset-lighting.js +163 -0
- package/dist/three/preset-lighting.js.map +1 -0
- package/dist/world-lighting.d.ts +105 -0
- package/dist/world-lighting.d.ts.map +1 -0
- package/dist/world-lighting.js +230 -0
- package/dist/world-lighting.js.map +1 -0
- package/package.json +1 -1
|
@@ -62,6 +62,157 @@ export interface WorldMapDelta {
|
|
|
62
62
|
* Applied by `applyWorld`; absent on worlds saved before it existed.
|
|
63
63
|
*/
|
|
64
64
|
worldTransform?: WorldTransform;
|
|
65
|
+
/**
|
|
66
|
+
* Lights placed in the world (lamps, spots, extra suns, area lights). Optional: absent on worlds
|
|
67
|
+
* saved before lights existed. The SUN is not here: it belongs to a lighting preset
|
|
68
|
+
* ({@link WorldLightingPreset.sun}), because Day and Night each have their own.
|
|
69
|
+
*
|
|
70
|
+
* These are authored in the platform world editor and exist so a bake can light the world with
|
|
71
|
+
* them. A game renders them LIVE only when it opts in (`createWorldLights`, capped), since dozens of
|
|
72
|
+
* real-time lights are unplayable in WebGL; in a baked scene their light is already in the lightmap.
|
|
73
|
+
*/
|
|
74
|
+
lights?: WorldLight[];
|
|
75
|
+
}
|
|
76
|
+
/** The kinds of light a world can hold. `area` is bake-only: glTF and live three.js have no match. */
|
|
77
|
+
export type WorldLightType = "directional" | "point" | "spot" | "area";
|
|
78
|
+
/**
|
|
79
|
+
* One light placed in a world.
|
|
80
|
+
*
|
|
81
|
+
* **Units are three.js's physical units**, so a light looks the same live and baked:
|
|
82
|
+
* `directional` in lux-like irradiance (a noon sun is ~3), `point`/`spot` in candela (a street lamp is
|
|
83
|
+
* ~40-150 at a few metres), `area` in Blender watts (it has no live counterpart). The bake script
|
|
84
|
+
* converts them to Cycles once, in one place.
|
|
85
|
+
*
|
|
86
|
+
* **Transforms are absolute, in world (map) space, like `WorldAddedObject`.** To make a lamp move with
|
|
87
|
+
* its post, group the two in the editor (object groups are editor metadata); the light is still
|
|
88
|
+
* stored with its own absolute transform.
|
|
89
|
+
*/
|
|
90
|
+
export interface WorldLight {
|
|
91
|
+
id: string;
|
|
92
|
+
type: WorldLightType;
|
|
93
|
+
/** Shown in the editor's outliner. */
|
|
94
|
+
name?: string;
|
|
95
|
+
position: [number, number, number];
|
|
96
|
+
/**
|
|
97
|
+
* Orientation quaternion `[x, y, z, w]`. The light shines down its local -Y axis (a lamp hanging
|
|
98
|
+
* from its post points down with the identity rotation). Ignored by `point`.
|
|
99
|
+
*/
|
|
100
|
+
rotation?: [number, number, number, number];
|
|
101
|
+
/** `#rrggbb`, sRGB — the same string `THREE.Color.set` takes. */
|
|
102
|
+
color: string;
|
|
103
|
+
intensity: number;
|
|
104
|
+
/** Metres; the light has no effect past it. Absent or 0 = physically unbounded (inverse square). */
|
|
105
|
+
range?: number;
|
|
106
|
+
/** Spot only: outer cone half-angle, radians. */
|
|
107
|
+
angle?: number;
|
|
108
|
+
/** Spot only: 0 (hard edge) .. 1 (fully soft). */
|
|
109
|
+
penumbra?: number;
|
|
110
|
+
/** Area: side of the square emitter (m). Point/spot: radius of the emitter for soft shadows (m). */
|
|
111
|
+
size?: number;
|
|
112
|
+
/** Default true. */
|
|
113
|
+
castShadow?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* The light group a preset scales ({@link WorldLightingPreset.groups}), e.g. `"street-lamps"`: Night
|
|
116
|
+
* sets it to 1, Day to 0. Absent = always on at full intensity.
|
|
117
|
+
*/
|
|
118
|
+
group?: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* One way of lighting a world — "Day", "Dusk", "Night". A world holds several; a game (or one track of
|
|
122
|
+
* it) picks one, and a bake is made per preset.
|
|
123
|
+
*
|
|
124
|
+
* The fields are exactly a live rig's, so a game can light itself from a preset with no translation:
|
|
125
|
+
* sun + unshadowed fill opposite it + hemisphere + flat ambient + a gradient sky used as both the
|
|
126
|
+
* background and the environment probe, then fog and exposure. Colours are sRGB `#rrggbb`.
|
|
127
|
+
*/
|
|
128
|
+
export interface WorldLightingPreset {
|
|
129
|
+
id: string;
|
|
130
|
+
name: string;
|
|
131
|
+
/** The shadow-casting sun (or moon). `intensity: 0` for none. Degrees; azimuth is measured from +X toward +Z. */
|
|
132
|
+
sun: {
|
|
133
|
+
azimuthDeg: number;
|
|
134
|
+
elevationDeg: number;
|
|
135
|
+
color: string;
|
|
136
|
+
intensity: number;
|
|
137
|
+
};
|
|
138
|
+
/** Unshadowed rim light from the sun's opposite side. */
|
|
139
|
+
fill?: {
|
|
140
|
+
color: string;
|
|
141
|
+
intensity: number;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Gradient sky, straight up → horizon → below it. It is the background AND the environment light
|
|
145
|
+
* (`scene.environment`, scaled by `intensity`), which is also how the bake lights the world with it.
|
|
146
|
+
*/
|
|
147
|
+
sky: {
|
|
148
|
+
zenith: string;
|
|
149
|
+
horizon: string;
|
|
150
|
+
ground: string;
|
|
151
|
+
intensity: number;
|
|
152
|
+
};
|
|
153
|
+
hemisphere?: {
|
|
154
|
+
sky: string;
|
|
155
|
+
ground: string;
|
|
156
|
+
intensity: number;
|
|
157
|
+
};
|
|
158
|
+
ambient?: {
|
|
159
|
+
color: string;
|
|
160
|
+
intensity: number;
|
|
161
|
+
};
|
|
162
|
+
fog?: {
|
|
163
|
+
color: string;
|
|
164
|
+
near: number;
|
|
165
|
+
far: number;
|
|
166
|
+
};
|
|
167
|
+
/** Tone-mapping exposure (ACES filmic). Default 1. */
|
|
168
|
+
exposure?: number;
|
|
169
|
+
/** Multiplier per {@link WorldLight.group}. A group not listed is at 1. */
|
|
170
|
+
groups?: Record<string, number>;
|
|
171
|
+
}
|
|
172
|
+
/** A world's lighting: its presets, and which one a game gets when it asks for none. */
|
|
173
|
+
export interface WorldLighting {
|
|
174
|
+
presets: WorldLightingPreset[];
|
|
175
|
+
defaultPresetId: string;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* A baked scene: a scene's lighting cooked into lightmaps by Blender (see the platform's
|
|
179
|
+
* `docs/baked-lighting.md`), stored as ONE self-contained glb whose materials carry the
|
|
180
|
+
* `RYDR_lightmap` extension.
|
|
181
|
+
*
|
|
182
|
+
* It is a derived output, never a source: it records the fingerprints of what it was built from, and
|
|
183
|
+
* the moment either changes (a prop moved, a lamp added, a route re-drawn) it is **stale** and a game
|
|
184
|
+
* ignores it and renders live. `isBakeFresh` / `pickBake` decide that.
|
|
185
|
+
*
|
|
186
|
+
* Where it is stored says what it covers: on the world (`CoreWorld.bakes`) it covers the world alone;
|
|
187
|
+
* in a game's own document (a racing track) it also covers that game's layer — the road, barriers and
|
|
188
|
+
* kerbs the game generates — and `layer` identifies it.
|
|
189
|
+
*/
|
|
190
|
+
export interface SceneBake {
|
|
191
|
+
/** Format of the baked glb. 1 = `RYDR_lightmap` v1. */
|
|
192
|
+
format: 1;
|
|
193
|
+
id: string;
|
|
194
|
+
/** The {@link WorldLightingPreset.id} it was lit with. */
|
|
195
|
+
presetId: string;
|
|
196
|
+
glbUrl: string;
|
|
197
|
+
/** The {@link CoreWorld.id} it was built on. */
|
|
198
|
+
worldId: string;
|
|
199
|
+
/** `worldFingerprint(world, presetId)` at export time. */
|
|
200
|
+
worldFingerprint: string;
|
|
201
|
+
/** The game layer baked with it, when there is one. `fingerprint` is the game's own `layerFingerprint`. */
|
|
202
|
+
layer?: {
|
|
203
|
+
game: string;
|
|
204
|
+
docId: string;
|
|
205
|
+
fingerprint: string;
|
|
206
|
+
};
|
|
207
|
+
bakedAt: number;
|
|
208
|
+
stats?: {
|
|
209
|
+
atlases?: number;
|
|
210
|
+
atlasSize?: number;
|
|
211
|
+
bytes?: number;
|
|
212
|
+
samples?: number;
|
|
213
|
+
minutes?: number;
|
|
214
|
+
blender?: string;
|
|
215
|
+
};
|
|
65
216
|
}
|
|
66
217
|
/** Optional lighting/fog for a world. */
|
|
67
218
|
export interface WorldEnv {
|
|
@@ -86,6 +237,13 @@ export interface CoreWorld {
|
|
|
86
237
|
name: string;
|
|
87
238
|
env?: WorldEnv;
|
|
88
239
|
map: WorldMapDelta;
|
|
240
|
+
/**
|
|
241
|
+
* Lighting presets (Day, Night…). Optional: a world without it has at most the legacy `env`, which
|
|
242
|
+
* `lightingPresets()` reads as an implicit `"default"` preset.
|
|
243
|
+
*/
|
|
244
|
+
lighting?: WorldLighting;
|
|
245
|
+
/** World-only bakes, one per preset (see {@link SceneBake}). A game's own layer keeps its bakes itself. */
|
|
246
|
+
bakes?: SceneBake[];
|
|
89
247
|
createdAt: number;
|
|
90
248
|
updatedAt: number;
|
|
91
249
|
}
|
|
@@ -100,4 +258,27 @@ export interface CatalogItem {
|
|
|
100
258
|
}
|
|
101
259
|
/** The objectName used for the root of a baked single-object catalog glb. */
|
|
102
260
|
export declare const CATALOG_ROOT_OBJECT = "root";
|
|
261
|
+
/**
|
|
262
|
+
* The shared-content collection a game publishes its **reference layers** to (one doc per layer, in the
|
|
263
|
+
* game's own `shared` scope, which every client can read).
|
|
264
|
+
*
|
|
265
|
+
* A reference layer is a lightweight glb of what a GAME builds on top of a world — racing's road,
|
|
266
|
+
* barriers and kerbs — so the platform world editor can show it as a read-only ghost. That is what
|
|
267
|
+
* lets a world author place street lamps along a road that otherwise exists only in the game's code.
|
|
268
|
+
*/
|
|
269
|
+
export declare const WORLD_REFERENCES_COLLECTION = "world-references";
|
|
270
|
+
/** One doc in {@link WORLD_REFERENCES_COLLECTION}. */
|
|
271
|
+
export interface WorldReferenceLayer {
|
|
272
|
+
/** The {@link CoreWorld.id} it sits on. */
|
|
273
|
+
coreWorldId: string;
|
|
274
|
+
/** The publishing game's slug. */
|
|
275
|
+
game: string;
|
|
276
|
+
/** The game document it comes from (a racing track id). */
|
|
277
|
+
docId: string;
|
|
278
|
+
/** Shown in the editor's layer list, e.g. "Racing · Paris GP". */
|
|
279
|
+
label: string;
|
|
280
|
+
/** World-space glb (same frame as the world's own geometry). */
|
|
281
|
+
glbUrl: string;
|
|
282
|
+
updatedAt: number;
|
|
283
|
+
}
|
|
103
284
|
//# sourceMappingURL=worlds.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worlds.d.ts","sourceRoot":"","sources":["../../src/protocol/worlds.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,kGAAkG;AAClG,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iGAAiG;AACjG,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,cAAc,EAAE,CAAC;IAChC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,iFAAiF;IACjF,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC5B;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,yCAAyC;AACzC,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,aAAa,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kGAAkG;AAClG,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,6EAA6E;AAC7E,eAAO,MAAM,mBAAmB,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"worlds.d.ts","sourceRoot":"","sources":["../../src/protocol/worlds.ts"],"names":[],"mappings":"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"}
|
package/dist/protocol/worlds.js
CHANGED
|
@@ -7,4 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/** The objectName used for the root of a baked single-object catalog glb. */
|
|
9
9
|
export const CATALOG_ROOT_OBJECT = "root";
|
|
10
|
+
/**
|
|
11
|
+
* The shared-content collection a game publishes its **reference layers** to (one doc per layer, in the
|
|
12
|
+
* game's own `shared` scope, which every client can read).
|
|
13
|
+
*
|
|
14
|
+
* A reference layer is a lightweight glb of what a GAME builds on top of a world — racing's road,
|
|
15
|
+
* barriers and kerbs — so the platform world editor can show it as a read-only ghost. That is what
|
|
16
|
+
* lets a world author place street lamps along a road that otherwise exists only in the game's code.
|
|
17
|
+
*/
|
|
18
|
+
export const WORLD_REFERENCES_COLLECTION = "world-references";
|
|
10
19
|
//# sourceMappingURL=worlds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worlds.js","sourceRoot":"","sources":["../../src/protocol/worlds.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"worlds.js","sourceRoot":"","sources":["../../src/protocol/worlds.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2OH,6EAA6E;AAC7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,kBAAkB,CAAC"}
|
package/dist/three/README.md
CHANGED
|
@@ -166,6 +166,31 @@ dispose();
|
|
|
166
166
|
Handles GLB loading, DRACO decompression, placement transforms, and a shared cache so the same world
|
|
167
167
|
isn't re-downloaded. Prefer this over a per-game `GLTFLoader`. `clearWorldCache(id?)` evicts.
|
|
168
168
|
|
|
169
|
+
## Baked lighting — `loadBakedScene`, presets, shadow catcher
|
|
170
|
+
|
|
171
|
+
A platform world can carry lights and lighting presets (Day, Night…), and a scene baked from it in Blender
|
|
172
|
+
(the platform's `docs/baked-lighting.md`). Show the bake while it still matches, live otherwise:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { pickBake, resolvePreset, layerFingerprint } from "@rydr/game-sdk";
|
|
176
|
+
import { loadBakedScene, createShadowCatcher, applyLightingPreset, loadWorld } from "@rydr/game-sdk/three";
|
|
177
|
+
|
|
178
|
+
const preset = resolvePreset(world, myPresetId);
|
|
179
|
+
const bake = pickBake(myBakes, { world, presetId: preset?.id, layerFingerprint: layerFingerprint(myLayer) });
|
|
180
|
+
if (bake) {
|
|
181
|
+
const baked = await loadBakedScene(bake); // unlit albedo × lightmap, cached by URL
|
|
182
|
+
baked.attach(scene);
|
|
183
|
+
createShadowCatcher(baked.receivers); // moving things' live shadows on the baked road
|
|
184
|
+
} else {
|
|
185
|
+
(await loadWorld(world)).attach(scene);
|
|
186
|
+
}
|
|
187
|
+
if (preset) applyLightingPreset(scene, preset, { renderer, shadows: true }); // lights the moving things
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
A baked material ignores live lights, so `createWorldLights(world, preset, { max, near })` can light a car
|
|
191
|
+
with the world's lamps at no cost to the world. `RydrLightmapPlugin` is the `RYDR_lightmap` GLTFLoader
|
|
192
|
+
plugin, for a loader of your own.
|
|
193
|
+
|
|
169
194
|
## `mergeByMaterial` — cut draw calls
|
|
170
195
|
|
|
171
196
|
```ts
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* baked-lighting — load a BAKED scene ({@link SceneBake}) and render it with its lightmaps.
|
|
3
|
+
*
|
|
4
|
+
* A baked scene is one self-contained glb produced by the platform's bake pipeline (Blender, see the
|
|
5
|
+
* platform repo's `docs/baked-lighting.md`): the world plus whatever a game baked with it, every static
|
|
6
|
+
* mesh carrying a second UV set (`TEXCOORD_1`) and a material extension, `RYDR_lightmap`, that points at
|
|
7
|
+
* the lightmap atlas it was baked into.
|
|
8
|
+
*
|
|
9
|
+
* ## What a lightmap holds, and how it is shown
|
|
10
|
+
*
|
|
11
|
+
* The light each surface RECEIVES (sun, sky, lamps, bounce) — not its colour. So a baked material is
|
|
12
|
+
* `albedo × lightmap`, which keeps the full detail of the colour textures at a low lightmap resolution,
|
|
13
|
+
* and it is a `MeshBasicMaterial`: the scene's live lights must not light it a second time. That is
|
|
14
|
+
* also why a baked world is CHEAPER than a live one — no per-pixel lighting at all.
|
|
15
|
+
*
|
|
16
|
+
* The atlas is an 8-bit sRGB PNG: the bake divides the light by a per-atlas `scale` before encoding,
|
|
17
|
+
* the GPU's sRGB decode undoes the curve for free, and `intensity` (= π × scale, the π cancelling
|
|
18
|
+
* `MeshBasicMaterial`'s Lambert term) puts the range back. No custom shader, no alpha channel for
|
|
19
|
+
* a browser to premultiply.
|
|
20
|
+
*
|
|
21
|
+
* ## What stays live
|
|
22
|
+
*
|
|
23
|
+
* Anything that moves. A car is still lit by the game's own sun + environment, and its shadow is put
|
|
24
|
+
* on the baked ground by a SHADOW CATCHER ({@link createShadowCatcher}): a `ShadowMaterial` overlay on
|
|
25
|
+
* the meshes the export marked as receivers (the road, the ground around it). Everything else in the
|
|
26
|
+
* baked scene casts and receives nothing live — its shadows are in the lightmap.
|
|
27
|
+
*/
|
|
28
|
+
import * as THREE from "three";
|
|
29
|
+
import { GLTFLoader, type GLTFLoaderPlugin, type GLTFParser } from "three/addons/loaders/GLTFLoader.js";
|
|
30
|
+
import { type GlbLoaderOptions } from "./world-loader.js";
|
|
31
|
+
import type { SceneBake } from "../protocol/worlds.js";
|
|
32
|
+
/** The glTF material extension a baked glb carries. */
|
|
33
|
+
export declare const RYDR_LIGHTMAP_EXTENSION = "RYDR_lightmap";
|
|
34
|
+
/** `materials[i].extensions.RYDR_lightmap`. */
|
|
35
|
+
export interface RydrLightmapDef {
|
|
36
|
+
/** Index into the glb's `textures`. */
|
|
37
|
+
index: number;
|
|
38
|
+
/** Which UV set samples it. Always 1 from the pipeline. */
|
|
39
|
+
texCoord?: number;
|
|
40
|
+
/** `lightMapIntensity`: π × the atlas's encode scale. */
|
|
41
|
+
intensity: number;
|
|
42
|
+
}
|
|
43
|
+
/** Node extras the export writes and the bake carries through (see the platform's bake docs). */
|
|
44
|
+
export declare const BAKE_EXTRAS: {
|
|
45
|
+
/** `"static"` (gets a lightmap) or `"occluder"` (casts in the bake, then dropped). */
|
|
46
|
+
readonly role: "rydr_role";
|
|
47
|
+
/** true on meshes a moving object's live shadow must land on (a road). */
|
|
48
|
+
readonly receiveShadow: "rydr_receive_shadow";
|
|
49
|
+
/** Texels per metre wanted for this mesh. */
|
|
50
|
+
readonly density: "rydr_lm_density";
|
|
51
|
+
/** Atlas preference, e.g. `"near-road"`. */
|
|
52
|
+
readonly atlasHint: "rydr_atlas_hint";
|
|
53
|
+
/** Written BY the bake: the atlas a mesh ended up in. */
|
|
54
|
+
readonly lightmap: "rydr_lightmap";
|
|
55
|
+
/**
|
|
56
|
+
* `"world"` (the platform world's geometry) or `"game"` (what the game added: a road, walls). Lets a
|
|
57
|
+
* game tell the two apart in a baked scene — racing probes the drivable height off the WORLD alone.
|
|
58
|
+
*/
|
|
59
|
+
readonly layer: "rydr_layer";
|
|
60
|
+
};
|
|
61
|
+
/** Name of the empty node carrying the bake manifest (a JSON string in its extras). */
|
|
62
|
+
export declare const BAKE_MANIFEST_NODE = "RYDR_BAKE_MANIFEST";
|
|
63
|
+
/** The extras key on {@link BAKE_MANIFEST_NODE}. */
|
|
64
|
+
export declare const BAKE_MANIFEST_KEY = "rydr_bake_manifest";
|
|
65
|
+
/**
|
|
66
|
+
* GLTFLoader plugin for `RYDR_lightmap`: assigns the atlas as the material's `lightMap` on UV channel 1
|
|
67
|
+
* with the extension's intensity. Register it on any GLTFLoader that may meet a baked glb:
|
|
68
|
+
* `loader.register((parser) => new RydrLightmapPlugin(parser))`.
|
|
69
|
+
*/
|
|
70
|
+
export declare class RydrLightmapPlugin implements GLTFLoaderPlugin {
|
|
71
|
+
private readonly parser;
|
|
72
|
+
readonly name = "RYDR_lightmap";
|
|
73
|
+
constructor(parser: GLTFParser);
|
|
74
|
+
extendMaterialParams(materialIndex: number, materialParams: Record<string, unknown>): Promise<unknown>;
|
|
75
|
+
}
|
|
76
|
+
/** Add the {@link RydrLightmapPlugin} to a loader (idempotent per loader instance is the caller's job). */
|
|
77
|
+
export declare function registerBakedLighting(loader: GLTFLoader): GLTFLoader;
|
|
78
|
+
/**
|
|
79
|
+
* The material a baked mesh renders with: `albedo × lightmap`, unlit by the live rig.
|
|
80
|
+
*
|
|
81
|
+
* Returns `src` untouched when it has no lightmap (a mesh the bake skipped stays lit live, rather than
|
|
82
|
+
* turning black). Emissive surfaces keep their glow — a lit window IS its emission — via a two-line
|
|
83
|
+
* shader addition, since `MeshBasicMaterial` has no emissive of its own.
|
|
84
|
+
*/
|
|
85
|
+
export declare function toBakedMaterial(src: THREE.Material): THREE.Material;
|
|
86
|
+
export interface LoadBakedSceneOptions extends GlbLoaderOptions {
|
|
87
|
+
/** Merge the static meshes by material (≈ one draw per material), as `loadWorld({ mergeStatics })`. */
|
|
88
|
+
mergeStatics?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/** A loaded baked scene. Same lifecycle contract as `LoadedWorld`. */
|
|
91
|
+
export interface LoadedBakedScene {
|
|
92
|
+
/** The glb's path — the cache key. */
|
|
93
|
+
readonly id: string;
|
|
94
|
+
readonly group: THREE.Group;
|
|
95
|
+
/** Meshes the export marked `rydr_receive_shadow` — hand them to {@link createShadowCatcher}. */
|
|
96
|
+
readonly receivers: THREE.Mesh[];
|
|
97
|
+
/** The manifest the export embedded (fingerprints, preset…), or null for a glb without one. */
|
|
98
|
+
readonly manifest: BakeManifest | null;
|
|
99
|
+
attach(parent: THREE.Object3D): void;
|
|
100
|
+
detach(): void;
|
|
101
|
+
dispose(): void;
|
|
102
|
+
}
|
|
103
|
+
/** What the export embeds in {@link BAKE_MANIFEST_NODE}. Parsed as-is; fields may grow. */
|
|
104
|
+
export interface BakeManifest {
|
|
105
|
+
format: number;
|
|
106
|
+
worldId?: string;
|
|
107
|
+
presetId?: string;
|
|
108
|
+
worldFingerprint?: string;
|
|
109
|
+
layer?: {
|
|
110
|
+
game: string;
|
|
111
|
+
docId: string;
|
|
112
|
+
fingerprint: string;
|
|
113
|
+
};
|
|
114
|
+
[key: string]: unknown;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Load (and cache by glb path) a baked scene, with every lightmapped material swapped for its
|
|
118
|
+
* {@link toBakedMaterial}. Pass the {@link SceneBake} (or its url). Rejects if the glb fails to load —
|
|
119
|
+
* the caller falls back to rendering live.
|
|
120
|
+
*/
|
|
121
|
+
export declare function loadBakedScene(bake: SceneBake | string, opts?: LoadBakedSceneOptions): Promise<LoadedBakedScene>;
|
|
122
|
+
/** Drop cached baked scenes (all, or one glb path) and free them. */
|
|
123
|
+
export declare function clearBakedSceneCache(url?: string): void;
|
|
124
|
+
export interface ShadowCatcherOptions {
|
|
125
|
+
/** How dark a live shadow gets on the baked ground. Default 0.45. */
|
|
126
|
+
opacity?: number;
|
|
127
|
+
}
|
|
128
|
+
/** A shadow-catcher overlay; `dispose` removes and frees it. */
|
|
129
|
+
export interface ShadowCatcher {
|
|
130
|
+
readonly meshes: THREE.Mesh[];
|
|
131
|
+
setOpacity(opacity: number): void;
|
|
132
|
+
dispose(): void;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Put a moving object's LIVE shadow on baked ground: one `ShadowMaterial` overlay per receiver, sharing
|
|
136
|
+
* its geometry and parented to it (so it follows exactly, at zero extra memory), drawn just in front
|
|
137
|
+
* of it with a polygon offset.
|
|
138
|
+
*
|
|
139
|
+
* It only darkens, which is the point — the receiver's own lighting is the lightmap and must not
|
|
140
|
+
* change. The catcher needs the game's sun to cast shadows as it already does; nothing else about the
|
|
141
|
+
* live rig changes.
|
|
142
|
+
*/
|
|
143
|
+
export declare function createShadowCatcher(receivers: readonly THREE.Mesh[], opts?: ShadowCatcherOptions): ShadowCatcher;
|
|
144
|
+
//# sourceMappingURL=baked-lighting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baked-lighting.d.ts","sourceRoot":"","sources":["../../src/three/baked-lighting.ts"],"names":[],"mappings":"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"}
|