@plasius/gpu-world-generator 0.0.11 → 0.0.13
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 +24 -0
- package/dist/index.cjs +166 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -1
- package/dist/index.d.ts +46 -1
- package/dist/index.js +163 -2
- package/dist/index.js.map +1 -1
- package/docs/adrs/adr-0005-render-representation-tiers-and-proxy-outputs.md +51 -0
- package/docs/adrs/index.md +2 -1
- package/docs/tdrs/index.md +1 -0
- package/docs/tdrs/tdr-0002-render-representation-tier-contract.md +60 -0
- package/package.json +8 -8
- package/src/tiles.ts +0 -2
- package/src/worker.ts +268 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# ADR-0005: Render Representation Tiers and Proxy Outputs
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The world architecture no longer assumes that every chunk is rendered from the
|
|
10
|
+
same live representation. Near, mid, far, and horizon content should be able to
|
|
11
|
+
use different visual and ray-tracing representations so the world scales in a
|
|
12
|
+
predictable way.
|
|
13
|
+
|
|
14
|
+
`@plasius/gpu-world-generator` already owns chunk and voxel generation, so it is
|
|
15
|
+
the natural package to plan how world chunks will expose render-oriented
|
|
16
|
+
representation tiers and proxy outputs before implementation begins.
|
|
17
|
+
|
|
18
|
+
## Decision
|
|
19
|
+
|
|
20
|
+
`@plasius/gpu-world-generator` will plan around formal representation tiers for
|
|
21
|
+
rendering and RT preparation:
|
|
22
|
+
|
|
23
|
+
- `near`: full live chunk output
|
|
24
|
+
- `mid`: simplified live chunk output
|
|
25
|
+
- `far`: HLOD, impostor, or proxy-driven chunk output
|
|
26
|
+
- `horizon`: shell, skyline, or large-scale background representation
|
|
27
|
+
|
|
28
|
+
The package should eventually be able to provide metadata or assets for:
|
|
29
|
+
|
|
30
|
+
- chunk-local full geometry
|
|
31
|
+
- simplified geometry or material reductions
|
|
32
|
+
- RT proxy or reduced-fidelity instance data
|
|
33
|
+
- merged or impostor-oriented distant proxies
|
|
34
|
+
- low-refresh far-field or horizon assets
|
|
35
|
+
|
|
36
|
+
## Consequences
|
|
37
|
+
|
|
38
|
+
- Positive: distant rendering becomes a formal output tier instead of an
|
|
39
|
+
ad-hoc optimization.
|
|
40
|
+
- Positive: renderer and world packages can coordinate around explicit chunk
|
|
41
|
+
representation bands.
|
|
42
|
+
- Positive: RT proxy planning can start from generated world assets instead of
|
|
43
|
+
being recreated in a later stage.
|
|
44
|
+
- Neutral: this ADR does not yet prescribe the final file format or buffer
|
|
45
|
+
layout for each proxy type.
|
|
46
|
+
|
|
47
|
+
## Follow-On Work
|
|
48
|
+
|
|
49
|
+
- Define the technical contract for chunk representation metadata and proxy
|
|
50
|
+
refresh policy.
|
|
51
|
+
- Add test-first contract and unit specs before implementing new proxy outputs.
|
package/docs/adrs/index.md
CHANGED
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
- [ADR-0001: GPU World Generator Package Scope](./adr-0001-package-scope.md)
|
|
4
4
|
- [ADR-0002: Tiled World Generation, LOD, and Stitching](./adr-0002-world-tiling-lod-stitching.md)
|
|
5
|
-
- [ADR-0004: Worker DAG Manifests for Chunk and Voxel Generation](./adr-0004-worker-dag-manifests-for-chunk-and-voxel-generation.md)
|
|
6
5
|
- [ADR-0003: Terrain Generation Style Mixing (Shader-Based)](./adr-0003-terrain-generation-style-mixing.md)
|
|
6
|
+
- [ADR-0004: Worker DAG Manifests for Chunk and Voxel Generation](./adr-0004-worker-dag-manifests-for-chunk-and-voxel-generation.md)
|
|
7
|
+
- [ADR-0005: Render Representation Tiers and Proxy Outputs](./adr-0005-render-representation-tiers-and-proxy-outputs.md)
|
package/docs/tdrs/index.md
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# TDR-0002: Render Representation Tier Contract
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Define the future contract for render and RT-oriented chunk representation tiers
|
|
10
|
+
in `@plasius/gpu-world-generator`.
|
|
11
|
+
|
|
12
|
+
## Planned Tier Outputs
|
|
13
|
+
|
|
14
|
+
Each chunk or region should eventually be able to describe one or more of:
|
|
15
|
+
|
|
16
|
+
- full live geometry output
|
|
17
|
+
- simplified live geometry output
|
|
18
|
+
- RT proxy output
|
|
19
|
+
- merged HLOD or impostor output
|
|
20
|
+
- horizon-shell or skyline output
|
|
21
|
+
|
|
22
|
+
## Planned Metadata
|
|
23
|
+
|
|
24
|
+
Representation descriptors should be able to carry:
|
|
25
|
+
|
|
26
|
+
- chunk or region identifier
|
|
27
|
+
- representation tier:
|
|
28
|
+
- `near`
|
|
29
|
+
- `mid`
|
|
30
|
+
- `far`
|
|
31
|
+
- `horizon`
|
|
32
|
+
- refresh policy or expected update cadence
|
|
33
|
+
- RT participation policy
|
|
34
|
+
- shadow relevance policy
|
|
35
|
+
- suggested ownership for renderer and worker scheduling
|
|
36
|
+
|
|
37
|
+
## Planned Tests
|
|
38
|
+
|
|
39
|
+
Contract tests should prove that:
|
|
40
|
+
|
|
41
|
+
- chunk descriptors can distinguish near, mid, far, and horizon output tiers
|
|
42
|
+
- proxy outputs can declare RT and shadow participation separately from the
|
|
43
|
+
live geometry output
|
|
44
|
+
- refresh expectations are explicit for far and horizon content
|
|
45
|
+
|
|
46
|
+
Unit tests should prove that:
|
|
47
|
+
|
|
48
|
+
- world-generation manifests can describe merged or impostor-driven far-field
|
|
49
|
+
outputs without losing chunk identity
|
|
50
|
+
- horizon representations can be low-frequency and still remain valid render
|
|
51
|
+
products
|
|
52
|
+
- RT proxy descriptors can differ from the raster-facing representation tier
|
|
53
|
+
|
|
54
|
+
## Implementation Notes
|
|
55
|
+
|
|
56
|
+
The first public implementation now ships as
|
|
57
|
+
`createWorldGeneratorRepresentationPlan(...)`. It publishes explicit near, mid,
|
|
58
|
+
far, and horizon descriptors, exposes distinct raster and RT proxy outputs,
|
|
59
|
+
retains chunk identity for proxy products, and includes refresh cadence,
|
|
60
|
+
shadow-source relevance, and scheduling metadata for downstream packages.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plasius/gpu-world-generator",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "GPU-assisted world generation with hex-grid terrain synthesis.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -38,15 +38,15 @@
|
|
|
38
38
|
"prepublishOnly": "npm run build && npm run pack:check"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@plasius/gpu-worker": "^0.1.
|
|
41
|
+
"@plasius/gpu-worker": "^0.1.11"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@eslint/js": "^
|
|
45
|
-
"@types/node": "^
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
47
|
-
"@typescript-eslint/parser": "^8.
|
|
48
|
-
"c8": "^
|
|
49
|
-
"eslint": "^
|
|
44
|
+
"@eslint/js": "^10.0.1",
|
|
45
|
+
"@types/node": "^24.12.0",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
|
47
|
+
"@typescript-eslint/parser": "^8.57.1",
|
|
48
|
+
"c8": "^11.0.0",
|
|
49
|
+
"eslint": "^10.1.0",
|
|
50
50
|
"globals": "^17.3.0",
|
|
51
51
|
"tsup": "^8.5.0",
|
|
52
52
|
"typescript": "^5.9.3"
|
package/src/tiles.ts
CHANGED
|
@@ -270,7 +270,6 @@ export function serializeTileAssetBinary(asset: TileAsset): ArrayBuffer {
|
|
|
270
270
|
view.setUint32(cursor, materialStride >>> 0, true);
|
|
271
271
|
cursor += 4;
|
|
272
272
|
view.setUint32(cursor, featureStride >>> 0, true);
|
|
273
|
-
cursor += 4;
|
|
274
273
|
|
|
275
274
|
let writeOffset = HEADER_BYTES;
|
|
276
275
|
new Float32Array(buffer, writeOffset, heightCount).set(asset.height);
|
|
@@ -351,7 +350,6 @@ export function parseTileAssetBinary(input: ArrayBuffer | ArrayBufferView): Tile
|
|
|
351
350
|
const materialStride = view.getUint32(cursor, true);
|
|
352
351
|
cursor += 4;
|
|
353
352
|
const featureStride = view.getUint32(cursor, true);
|
|
354
|
-
cursor += 4;
|
|
355
353
|
|
|
356
354
|
const heightBytes = heightCount * 4;
|
|
357
355
|
const fieldBytes = fieldCount * 4;
|
package/src/worker.ts
CHANGED
|
@@ -6,6 +6,69 @@ export type WorldGeneratorWorkerAuthority =
|
|
|
6
6
|
| "non-authoritative-simulation"
|
|
7
7
|
| "authoritative";
|
|
8
8
|
export type WorldGeneratorWorkerImportance = "medium" | "high" | "critical";
|
|
9
|
+
export type WorldGeneratorRepresentationBand =
|
|
10
|
+
| "near"
|
|
11
|
+
| "mid"
|
|
12
|
+
| "far"
|
|
13
|
+
| "horizon";
|
|
14
|
+
export type WorldGeneratorRepresentationOutput =
|
|
15
|
+
| "liveGeometry"
|
|
16
|
+
| "simplifiedGeometry"
|
|
17
|
+
| "rtProxy"
|
|
18
|
+
| "mergedProxy"
|
|
19
|
+
| "horizonShell";
|
|
20
|
+
export type WorldGeneratorRepresentationRtParticipation =
|
|
21
|
+
| "full"
|
|
22
|
+
| "selective"
|
|
23
|
+
| "proxy"
|
|
24
|
+
| "disabled";
|
|
25
|
+
export type WorldGeneratorRepresentationShadowRelevance =
|
|
26
|
+
| "ray-traced-primary"
|
|
27
|
+
| "selective-raster"
|
|
28
|
+
| "proxy-caster"
|
|
29
|
+
| "baked-impression";
|
|
30
|
+
|
|
31
|
+
export interface WorldGeneratorRepresentationCadence {
|
|
32
|
+
readonly kind: "per-frame" | "interval";
|
|
33
|
+
readonly divisor: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WorldGeneratorRepresentationDescriptor {
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly chunkId: string;
|
|
39
|
+
readonly profile: WorldGeneratorWorkerProfileName;
|
|
40
|
+
readonly band: WorldGeneratorRepresentationBand;
|
|
41
|
+
readonly output: WorldGeneratorRepresentationOutput;
|
|
42
|
+
readonly rasterMode:
|
|
43
|
+
| "full-live"
|
|
44
|
+
| "simplified-live"
|
|
45
|
+
| "proxy"
|
|
46
|
+
| "not-rendered"
|
|
47
|
+
| "horizon-shell";
|
|
48
|
+
readonly rtParticipation: WorldGeneratorRepresentationRtParticipation;
|
|
49
|
+
readonly shadowRelevance: WorldGeneratorRepresentationShadowRelevance;
|
|
50
|
+
readonly refreshCadence: WorldGeneratorRepresentationCadence;
|
|
51
|
+
readonly preservesChunkIdentity: boolean;
|
|
52
|
+
readonly sourceChunkIds: readonly string[];
|
|
53
|
+
readonly sourceJobKeys: readonly string[];
|
|
54
|
+
readonly suggestedAllocationIds: readonly string[];
|
|
55
|
+
readonly scheduling: Readonly<{
|
|
56
|
+
owner: "renderer";
|
|
57
|
+
queueClass: typeof worldGeneratorWorkerQueueClass;
|
|
58
|
+
priorityHint: number;
|
|
59
|
+
gameplayImportance: WorldGeneratorWorkerImportance;
|
|
60
|
+
representationBand: WorldGeneratorRepresentationBand;
|
|
61
|
+
}>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface WorldGeneratorRepresentationPlan {
|
|
65
|
+
readonly schemaVersion: 1;
|
|
66
|
+
readonly owner: typeof worldGeneratorDebugOwner;
|
|
67
|
+
readonly profile: WorldGeneratorWorkerProfileName;
|
|
68
|
+
readonly chunkId: string;
|
|
69
|
+
readonly representations: readonly WorldGeneratorRepresentationDescriptor[];
|
|
70
|
+
readonly bands: readonly WorldGeneratorRepresentationBand[];
|
|
71
|
+
}
|
|
9
72
|
|
|
10
73
|
export interface WorldGeneratorWorkerBudgetLevelConfig {
|
|
11
74
|
maxDispatchesPerFrame: number;
|
|
@@ -75,6 +138,28 @@ export interface WorldGeneratorWorkerManifest {
|
|
|
75
138
|
export const worldGeneratorDebugOwner = "world-generator";
|
|
76
139
|
export const worldGeneratorWorkerQueueClass = "voxel";
|
|
77
140
|
export const defaultWorldGeneratorWorkerProfile = "streaming";
|
|
141
|
+
export const worldGeneratorRepresentationBands = Object.freeze([
|
|
142
|
+
"near",
|
|
143
|
+
"mid",
|
|
144
|
+
"far",
|
|
145
|
+
"horizon",
|
|
146
|
+
]) as readonly WorldGeneratorRepresentationBand[];
|
|
147
|
+
export const worldGeneratorRepresentationOutputs = Object.freeze([
|
|
148
|
+
"liveGeometry",
|
|
149
|
+
"simplifiedGeometry",
|
|
150
|
+
"rtProxy",
|
|
151
|
+
"mergedProxy",
|
|
152
|
+
"horizonShell",
|
|
153
|
+
]) as readonly WorldGeneratorRepresentationOutput[];
|
|
154
|
+
|
|
155
|
+
const worldGeneratorRepresentationBandPriorityHints: Readonly<
|
|
156
|
+
Record<WorldGeneratorRepresentationBand, number>
|
|
157
|
+
> = Object.freeze({
|
|
158
|
+
near: 400,
|
|
159
|
+
mid: 300,
|
|
160
|
+
far: 200,
|
|
161
|
+
horizon: 100,
|
|
162
|
+
});
|
|
78
163
|
|
|
79
164
|
type WorkerLevelSpec = Omit<WorldGeneratorWorkerBudgetLevel, "config"> & {
|
|
80
165
|
config: Omit<WorldGeneratorWorkerBudgetLevelConfig, "metadata">;
|
|
@@ -96,6 +181,66 @@ type WorkerProfileSpec = {
|
|
|
96
181
|
jobs: Readonly<Record<string, WorkerJobSpec>>;
|
|
97
182
|
};
|
|
98
183
|
|
|
184
|
+
function assertWorldGeneratorIdentifier(name: string, value: unknown) {
|
|
185
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
186
|
+
throw new Error(`${name} must be a non-empty string.`);
|
|
187
|
+
}
|
|
188
|
+
return value.trim();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function normalizeWorldGeneratorImportance(
|
|
192
|
+
name: string,
|
|
193
|
+
value: unknown
|
|
194
|
+
): WorldGeneratorWorkerImportance {
|
|
195
|
+
if (value === "medium" || value === "high" || value === "critical") {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
throw new Error(`${name} must be one of: medium, high, critical.`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function buildWorldGeneratorRepresentationDescriptor(
|
|
202
|
+
options: {
|
|
203
|
+
profile: WorldGeneratorWorkerProfileName;
|
|
204
|
+
chunkId: string;
|
|
205
|
+
band: WorldGeneratorRepresentationBand;
|
|
206
|
+
output: WorldGeneratorRepresentationOutput;
|
|
207
|
+
rasterMode: WorldGeneratorRepresentationDescriptor["rasterMode"];
|
|
208
|
+
rtParticipation: WorldGeneratorRepresentationRtParticipation;
|
|
209
|
+
shadowRelevance: WorldGeneratorRepresentationShadowRelevance;
|
|
210
|
+
refreshCadence: WorldGeneratorRepresentationCadence;
|
|
211
|
+
preservesChunkIdentity: boolean;
|
|
212
|
+
sourceJobKeys: readonly string[];
|
|
213
|
+
gameplayImportance: WorldGeneratorWorkerImportance;
|
|
214
|
+
suggestedAllocationIds: readonly string[];
|
|
215
|
+
}
|
|
216
|
+
): WorldGeneratorRepresentationDescriptor {
|
|
217
|
+
return Object.freeze({
|
|
218
|
+
id: `${options.chunkId}.${options.band}.${options.output}`,
|
|
219
|
+
chunkId: options.chunkId,
|
|
220
|
+
profile: options.profile,
|
|
221
|
+
band: options.band,
|
|
222
|
+
output: options.output,
|
|
223
|
+
rasterMode: options.rasterMode,
|
|
224
|
+
rtParticipation: options.rtParticipation,
|
|
225
|
+
shadowRelevance: options.shadowRelevance,
|
|
226
|
+
refreshCadence: Object.freeze({
|
|
227
|
+
kind: options.refreshCadence.kind,
|
|
228
|
+
divisor: options.refreshCadence.divisor,
|
|
229
|
+
}),
|
|
230
|
+
preservesChunkIdentity: options.preservesChunkIdentity,
|
|
231
|
+
sourceChunkIds: Object.freeze([options.chunkId]),
|
|
232
|
+
sourceJobKeys: Object.freeze([...options.sourceJobKeys]),
|
|
233
|
+
suggestedAllocationIds: Object.freeze([...options.suggestedAllocationIds]),
|
|
234
|
+
scheduling: Object.freeze({
|
|
235
|
+
owner: "renderer",
|
|
236
|
+
queueClass: worldGeneratorWorkerQueueClass,
|
|
237
|
+
priorityHint: worldGeneratorRepresentationBandPriorityHints[options.band],
|
|
238
|
+
gameplayImportance: options.gameplayImportance,
|
|
239
|
+
representationBand: options.band,
|
|
240
|
+
}),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
99
244
|
function buildBudgetLevels(
|
|
100
245
|
jobType: string,
|
|
101
246
|
queueClass: WorldGeneratorWorkerQueueClass,
|
|
@@ -708,3 +853,126 @@ export function getWorldGeneratorWorkerManifest(
|
|
|
708
853
|
}
|
|
709
854
|
return manifest;
|
|
710
855
|
}
|
|
856
|
+
|
|
857
|
+
export function createWorldGeneratorRepresentationPlan(options: {
|
|
858
|
+
profile?: WorldGeneratorWorkerProfileName;
|
|
859
|
+
chunkId: string;
|
|
860
|
+
gameplayImportance?: WorldGeneratorWorkerImportance;
|
|
861
|
+
}): WorldGeneratorRepresentationPlan {
|
|
862
|
+
const profile =
|
|
863
|
+
options.profile ?? defaultWorldGeneratorWorkerProfile;
|
|
864
|
+
const spec = worldGeneratorWorkerProfileSpecs[profile];
|
|
865
|
+
if (!spec) {
|
|
866
|
+
const available = worldGeneratorWorkerProfileNames.join(", ");
|
|
867
|
+
throw new Error(
|
|
868
|
+
`Unknown world-generator worker profile "${profile}". Available: ${available}.`
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
const chunkId = assertWorldGeneratorIdentifier("chunkId", options.chunkId);
|
|
873
|
+
const gameplayImportance = normalizeWorldGeneratorImportance(
|
|
874
|
+
"gameplayImportance",
|
|
875
|
+
options.gameplayImportance ?? "high"
|
|
876
|
+
);
|
|
877
|
+
|
|
878
|
+
const highValueAllocations = spec.suggestedAllocationIds;
|
|
879
|
+
const farFieldAllocations = spec.suggestedAllocationIds.filter(
|
|
880
|
+
(allocationId) =>
|
|
881
|
+
allocationId.includes("mesh") ||
|
|
882
|
+
allocationId.includes("asset") ||
|
|
883
|
+
allocationId.includes("tile")
|
|
884
|
+
);
|
|
885
|
+
|
|
886
|
+
const bakeSourceJobKeys =
|
|
887
|
+
profile === "bake"
|
|
888
|
+
? ["meshBuild", "tileBake", "assetSerialize"]
|
|
889
|
+
: ["meshBuild", "tileBake"];
|
|
890
|
+
|
|
891
|
+
const representations = Object.freeze([
|
|
892
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
893
|
+
profile,
|
|
894
|
+
chunkId,
|
|
895
|
+
band: "near",
|
|
896
|
+
output: "liveGeometry",
|
|
897
|
+
rasterMode: "full-live",
|
|
898
|
+
rtParticipation: "full",
|
|
899
|
+
shadowRelevance: "ray-traced-primary",
|
|
900
|
+
refreshCadence: { kind: "per-frame", divisor: 1 },
|
|
901
|
+
preservesChunkIdentity: true,
|
|
902
|
+
sourceJobKeys: ["meshBuild"],
|
|
903
|
+
gameplayImportance:
|
|
904
|
+
gameplayImportance === "medium" ? "high" : gameplayImportance,
|
|
905
|
+
suggestedAllocationIds: highValueAllocations,
|
|
906
|
+
}),
|
|
907
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
908
|
+
profile,
|
|
909
|
+
chunkId,
|
|
910
|
+
band: "mid",
|
|
911
|
+
output: "simplifiedGeometry",
|
|
912
|
+
rasterMode: "simplified-live",
|
|
913
|
+
rtParticipation: "selective",
|
|
914
|
+
shadowRelevance: "selective-raster",
|
|
915
|
+
refreshCadence: { kind: "interval", divisor: 2 },
|
|
916
|
+
preservesChunkIdentity: true,
|
|
917
|
+
sourceJobKeys: ["meshBuild"],
|
|
918
|
+
gameplayImportance,
|
|
919
|
+
suggestedAllocationIds: highValueAllocations,
|
|
920
|
+
}),
|
|
921
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
922
|
+
profile,
|
|
923
|
+
chunkId,
|
|
924
|
+
band: "mid",
|
|
925
|
+
output: "rtProxy",
|
|
926
|
+
rasterMode: "not-rendered",
|
|
927
|
+
rtParticipation: "proxy",
|
|
928
|
+
shadowRelevance: "selective-raster",
|
|
929
|
+
refreshCadence: { kind: "interval", divisor: 2 },
|
|
930
|
+
preservesChunkIdentity: true,
|
|
931
|
+
sourceJobKeys: ["meshBuild", "tileBake"],
|
|
932
|
+
gameplayImportance,
|
|
933
|
+
suggestedAllocationIds: highValueAllocations,
|
|
934
|
+
}),
|
|
935
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
936
|
+
profile,
|
|
937
|
+
chunkId,
|
|
938
|
+
band: "far",
|
|
939
|
+
output: "mergedProxy",
|
|
940
|
+
rasterMode: "proxy",
|
|
941
|
+
rtParticipation: "proxy",
|
|
942
|
+
shadowRelevance: "proxy-caster",
|
|
943
|
+
refreshCadence: { kind: "interval", divisor: 8 },
|
|
944
|
+
preservesChunkIdentity: true,
|
|
945
|
+
sourceJobKeys: bakeSourceJobKeys,
|
|
946
|
+
gameplayImportance: "medium",
|
|
947
|
+
suggestedAllocationIds:
|
|
948
|
+
farFieldAllocations.length > 0 ? farFieldAllocations : highValueAllocations,
|
|
949
|
+
}),
|
|
950
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
951
|
+
profile,
|
|
952
|
+
chunkId,
|
|
953
|
+
band: "horizon",
|
|
954
|
+
output: "horizonShell",
|
|
955
|
+
rasterMode: "horizon-shell",
|
|
956
|
+
rtParticipation: "disabled",
|
|
957
|
+
shadowRelevance: "baked-impression",
|
|
958
|
+
refreshCadence: { kind: "interval", divisor: 60 },
|
|
959
|
+
preservesChunkIdentity: true,
|
|
960
|
+
sourceJobKeys:
|
|
961
|
+
profile === "bake" ? ["tileBake", "assetSerialize"] : ["tileBake"],
|
|
962
|
+
gameplayImportance: "medium",
|
|
963
|
+
suggestedAllocationIds:
|
|
964
|
+
farFieldAllocations.length > 0 ? farFieldAllocations : highValueAllocations,
|
|
965
|
+
}),
|
|
966
|
+
] satisfies readonly WorldGeneratorRepresentationDescriptor[]);
|
|
967
|
+
|
|
968
|
+
return Object.freeze({
|
|
969
|
+
schemaVersion: 1,
|
|
970
|
+
owner: worldGeneratorDebugOwner,
|
|
971
|
+
profile,
|
|
972
|
+
chunkId,
|
|
973
|
+
representations,
|
|
974
|
+
bands: Object.freeze(
|
|
975
|
+
[...new Set(representations.map((representation) => representation.band))]
|
|
976
|
+
),
|
|
977
|
+
});
|
|
978
|
+
}
|