@plasius/gpu-world-generator 0.0.11 → 0.0.12
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 -0
- 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 -0
- 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 +1 -1
- package/src/worker.ts +268 -0
package/README.md
CHANGED
|
@@ -81,6 +81,30 @@ console.log(bake.jobs.find((job) => job.key === "assetSerialize"));
|
|
|
81
81
|
debug allocation tags for integration with `@plasius/gpu-performance` and
|
|
82
82
|
`@plasius/gpu-debug`.
|
|
83
83
|
|
|
84
|
+
## Render Representation Plans
|
|
85
|
+
|
|
86
|
+
`@plasius/gpu-world-generator` now also publishes explicit chunk
|
|
87
|
+
representation-tier plans so renderer and worker packages can coordinate near,
|
|
88
|
+
mid, far, and horizon outputs without guessing from distance alone.
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
import { createWorldGeneratorRepresentationPlan } from "@plasius/gpu-world-generator";
|
|
92
|
+
|
|
93
|
+
const plan = createWorldGeneratorRepresentationPlan({
|
|
94
|
+
chunkId: "hex-12-9",
|
|
95
|
+
profile: "streaming",
|
|
96
|
+
gameplayImportance: "critical",
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
console.log(plan.bands);
|
|
100
|
+
console.log(plan.representations.find((entry) => entry.output === "rtProxy"));
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Each plan exposes raster-facing and RT-facing outputs separately, plus refresh
|
|
104
|
+
cadence, shadow relevance, chunk-identity preservation, and scheduling metadata
|
|
105
|
+
that downstream renderer and worker packages can prioritize by band and
|
|
106
|
+
importance.
|
|
107
|
+
|
|
84
108
|
## Demo
|
|
85
109
|
The WebGPU mixed-forest demo lives in `demo/`. Run it with:
|
|
86
110
|
|
package/dist/index.cjs
CHANGED
|
@@ -57,6 +57,7 @@ __export(index_exports, {
|
|
|
57
57
|
createFractalPrepassRunner: () => createFractalPrepassRunner,
|
|
58
58
|
createMeshBuilder: () => createMeshBuilder,
|
|
59
59
|
createPerfMonitor: () => createPerfMonitor,
|
|
60
|
+
createWorldGeneratorRepresentationPlan: () => createWorldGeneratorRepresentationPlan,
|
|
60
61
|
defaultFieldParams: () => defaultFieldParams,
|
|
61
62
|
defaultFractalMandelSettings: () => defaultFractalMandelSettings,
|
|
62
63
|
defaultWorldGeneratorWorkerProfile: () => defaultWorldGeneratorWorkerProfile,
|
|
@@ -94,6 +95,8 @@ __export(index_exports, {
|
|
|
94
95
|
unpackTerrain: () => unpackTerrain,
|
|
95
96
|
validateTileAssetPayload: () => validateTileAssetPayload,
|
|
96
97
|
worldGeneratorDebugOwner: () => worldGeneratorDebugOwner,
|
|
98
|
+
worldGeneratorRepresentationBands: () => worldGeneratorRepresentationBands,
|
|
99
|
+
worldGeneratorRepresentationOutputs: () => worldGeneratorRepresentationOutputs,
|
|
97
100
|
worldGeneratorWorkerManifests: () => worldGeneratorWorkerManifests,
|
|
98
101
|
worldGeneratorWorkerProfileNames: () => worldGeneratorWorkerProfileNames,
|
|
99
102
|
worldGeneratorWorkerProfiles: () => worldGeneratorWorkerProfiles,
|
|
@@ -1890,6 +1893,64 @@ function createMeshBuilder(sizeOrOptions = 1) {
|
|
|
1890
1893
|
var worldGeneratorDebugOwner = "world-generator";
|
|
1891
1894
|
var worldGeneratorWorkerQueueClass = "voxel";
|
|
1892
1895
|
var defaultWorldGeneratorWorkerProfile = "streaming";
|
|
1896
|
+
var worldGeneratorRepresentationBands = Object.freeze([
|
|
1897
|
+
"near",
|
|
1898
|
+
"mid",
|
|
1899
|
+
"far",
|
|
1900
|
+
"horizon"
|
|
1901
|
+
]);
|
|
1902
|
+
var worldGeneratorRepresentationOutputs = Object.freeze([
|
|
1903
|
+
"liveGeometry",
|
|
1904
|
+
"simplifiedGeometry",
|
|
1905
|
+
"rtProxy",
|
|
1906
|
+
"mergedProxy",
|
|
1907
|
+
"horizonShell"
|
|
1908
|
+
]);
|
|
1909
|
+
var worldGeneratorRepresentationBandPriorityHints = Object.freeze({
|
|
1910
|
+
near: 400,
|
|
1911
|
+
mid: 300,
|
|
1912
|
+
far: 200,
|
|
1913
|
+
horizon: 100
|
|
1914
|
+
});
|
|
1915
|
+
function assertWorldGeneratorIdentifier(name, value) {
|
|
1916
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
1917
|
+
throw new Error(`${name} must be a non-empty string.`);
|
|
1918
|
+
}
|
|
1919
|
+
return value.trim();
|
|
1920
|
+
}
|
|
1921
|
+
function normalizeWorldGeneratorImportance(name, value) {
|
|
1922
|
+
if (value === "medium" || value === "high" || value === "critical") {
|
|
1923
|
+
return value;
|
|
1924
|
+
}
|
|
1925
|
+
throw new Error(`${name} must be one of: medium, high, critical.`);
|
|
1926
|
+
}
|
|
1927
|
+
function buildWorldGeneratorRepresentationDescriptor(options) {
|
|
1928
|
+
return Object.freeze({
|
|
1929
|
+
id: `${options.chunkId}.${options.band}.${options.output}`,
|
|
1930
|
+
chunkId: options.chunkId,
|
|
1931
|
+
profile: options.profile,
|
|
1932
|
+
band: options.band,
|
|
1933
|
+
output: options.output,
|
|
1934
|
+
rasterMode: options.rasterMode,
|
|
1935
|
+
rtParticipation: options.rtParticipation,
|
|
1936
|
+
shadowRelevance: options.shadowRelevance,
|
|
1937
|
+
refreshCadence: Object.freeze({
|
|
1938
|
+
kind: options.refreshCadence.kind,
|
|
1939
|
+
divisor: options.refreshCadence.divisor
|
|
1940
|
+
}),
|
|
1941
|
+
preservesChunkIdentity: options.preservesChunkIdentity,
|
|
1942
|
+
sourceChunkIds: Object.freeze([options.chunkId]),
|
|
1943
|
+
sourceJobKeys: Object.freeze([...options.sourceJobKeys]),
|
|
1944
|
+
suggestedAllocationIds: Object.freeze([...options.suggestedAllocationIds]),
|
|
1945
|
+
scheduling: Object.freeze({
|
|
1946
|
+
owner: "renderer",
|
|
1947
|
+
queueClass: worldGeneratorWorkerQueueClass,
|
|
1948
|
+
priorityHint: worldGeneratorRepresentationBandPriorityHints[options.band],
|
|
1949
|
+
gameplayImportance: options.gameplayImportance,
|
|
1950
|
+
representationBand: options.band
|
|
1951
|
+
})
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1893
1954
|
function buildBudgetLevels(jobType, queueClass, levels) {
|
|
1894
1955
|
return Object.freeze(
|
|
1895
1956
|
levels.map(
|
|
@@ -2470,6 +2531,108 @@ function getWorldGeneratorWorkerManifest(name = defaultWorldGeneratorWorkerProfi
|
|
|
2470
2531
|
}
|
|
2471
2532
|
return manifest;
|
|
2472
2533
|
}
|
|
2534
|
+
function createWorldGeneratorRepresentationPlan(options) {
|
|
2535
|
+
const profile = options.profile ?? defaultWorldGeneratorWorkerProfile;
|
|
2536
|
+
const spec = worldGeneratorWorkerProfileSpecs[profile];
|
|
2537
|
+
if (!spec) {
|
|
2538
|
+
const available = worldGeneratorWorkerProfileNames.join(", ");
|
|
2539
|
+
throw new Error(
|
|
2540
|
+
`Unknown world-generator worker profile "${profile}". Available: ${available}.`
|
|
2541
|
+
);
|
|
2542
|
+
}
|
|
2543
|
+
const chunkId = assertWorldGeneratorIdentifier("chunkId", options.chunkId);
|
|
2544
|
+
const gameplayImportance = normalizeWorldGeneratorImportance(
|
|
2545
|
+
"gameplayImportance",
|
|
2546
|
+
options.gameplayImportance ?? "high"
|
|
2547
|
+
);
|
|
2548
|
+
const highValueAllocations = spec.suggestedAllocationIds;
|
|
2549
|
+
const farFieldAllocations = spec.suggestedAllocationIds.filter(
|
|
2550
|
+
(allocationId) => allocationId.includes("mesh") || allocationId.includes("asset") || allocationId.includes("tile")
|
|
2551
|
+
);
|
|
2552
|
+
const bakeSourceJobKeys = profile === "bake" ? ["meshBuild", "tileBake", "assetSerialize"] : ["meshBuild", "tileBake"];
|
|
2553
|
+
const representations = Object.freeze([
|
|
2554
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
2555
|
+
profile,
|
|
2556
|
+
chunkId,
|
|
2557
|
+
band: "near",
|
|
2558
|
+
output: "liveGeometry",
|
|
2559
|
+
rasterMode: "full-live",
|
|
2560
|
+
rtParticipation: "full",
|
|
2561
|
+
shadowRelevance: "ray-traced-primary",
|
|
2562
|
+
refreshCadence: { kind: "per-frame", divisor: 1 },
|
|
2563
|
+
preservesChunkIdentity: true,
|
|
2564
|
+
sourceJobKeys: ["meshBuild"],
|
|
2565
|
+
gameplayImportance: gameplayImportance === "medium" ? "high" : gameplayImportance,
|
|
2566
|
+
suggestedAllocationIds: highValueAllocations
|
|
2567
|
+
}),
|
|
2568
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
2569
|
+
profile,
|
|
2570
|
+
chunkId,
|
|
2571
|
+
band: "mid",
|
|
2572
|
+
output: "simplifiedGeometry",
|
|
2573
|
+
rasterMode: "simplified-live",
|
|
2574
|
+
rtParticipation: "selective",
|
|
2575
|
+
shadowRelevance: "selective-raster",
|
|
2576
|
+
refreshCadence: { kind: "interval", divisor: 2 },
|
|
2577
|
+
preservesChunkIdentity: true,
|
|
2578
|
+
sourceJobKeys: ["meshBuild"],
|
|
2579
|
+
gameplayImportance,
|
|
2580
|
+
suggestedAllocationIds: highValueAllocations
|
|
2581
|
+
}),
|
|
2582
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
2583
|
+
profile,
|
|
2584
|
+
chunkId,
|
|
2585
|
+
band: "mid",
|
|
2586
|
+
output: "rtProxy",
|
|
2587
|
+
rasterMode: "not-rendered",
|
|
2588
|
+
rtParticipation: "proxy",
|
|
2589
|
+
shadowRelevance: "selective-raster",
|
|
2590
|
+
refreshCadence: { kind: "interval", divisor: 2 },
|
|
2591
|
+
preservesChunkIdentity: true,
|
|
2592
|
+
sourceJobKeys: ["meshBuild", "tileBake"],
|
|
2593
|
+
gameplayImportance,
|
|
2594
|
+
suggestedAllocationIds: highValueAllocations
|
|
2595
|
+
}),
|
|
2596
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
2597
|
+
profile,
|
|
2598
|
+
chunkId,
|
|
2599
|
+
band: "far",
|
|
2600
|
+
output: "mergedProxy",
|
|
2601
|
+
rasterMode: "proxy",
|
|
2602
|
+
rtParticipation: "proxy",
|
|
2603
|
+
shadowRelevance: "proxy-caster",
|
|
2604
|
+
refreshCadence: { kind: "interval", divisor: 8 },
|
|
2605
|
+
preservesChunkIdentity: true,
|
|
2606
|
+
sourceJobKeys: bakeSourceJobKeys,
|
|
2607
|
+
gameplayImportance: "medium",
|
|
2608
|
+
suggestedAllocationIds: farFieldAllocations.length > 0 ? farFieldAllocations : highValueAllocations
|
|
2609
|
+
}),
|
|
2610
|
+
buildWorldGeneratorRepresentationDescriptor({
|
|
2611
|
+
profile,
|
|
2612
|
+
chunkId,
|
|
2613
|
+
band: "horizon",
|
|
2614
|
+
output: "horizonShell",
|
|
2615
|
+
rasterMode: "horizon-shell",
|
|
2616
|
+
rtParticipation: "disabled",
|
|
2617
|
+
shadowRelevance: "baked-impression",
|
|
2618
|
+
refreshCadence: { kind: "interval", divisor: 60 },
|
|
2619
|
+
preservesChunkIdentity: true,
|
|
2620
|
+
sourceJobKeys: profile === "bake" ? ["tileBake", "assetSerialize"] : ["tileBake"],
|
|
2621
|
+
gameplayImportance: "medium",
|
|
2622
|
+
suggestedAllocationIds: farFieldAllocations.length > 0 ? farFieldAllocations : highValueAllocations
|
|
2623
|
+
})
|
|
2624
|
+
]);
|
|
2625
|
+
return Object.freeze({
|
|
2626
|
+
schemaVersion: 1,
|
|
2627
|
+
owner: worldGeneratorDebugOwner,
|
|
2628
|
+
profile,
|
|
2629
|
+
chunkId,
|
|
2630
|
+
representations,
|
|
2631
|
+
bands: Object.freeze(
|
|
2632
|
+
[...new Set(representations.map((representation) => representation.band))]
|
|
2633
|
+
)
|
|
2634
|
+
});
|
|
2635
|
+
}
|
|
2473
2636
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2474
2637
|
0 && (module.exports = {
|
|
2475
2638
|
DEFAULT_TILE_SIZE_WORLD,
|
|
@@ -2498,6 +2661,7 @@ function getWorldGeneratorWorkerManifest(name = defaultWorldGeneratorWorkerProfi
|
|
|
2498
2661
|
createFractalPrepassRunner,
|
|
2499
2662
|
createMeshBuilder,
|
|
2500
2663
|
createPerfMonitor,
|
|
2664
|
+
createWorldGeneratorRepresentationPlan,
|
|
2501
2665
|
defaultFieldParams,
|
|
2502
2666
|
defaultFractalMandelSettings,
|
|
2503
2667
|
defaultWorldGeneratorWorkerProfile,
|
|
@@ -2535,6 +2699,8 @@ function getWorldGeneratorWorkerManifest(name = defaultWorldGeneratorWorkerProfi
|
|
|
2535
2699
|
unpackTerrain,
|
|
2536
2700
|
validateTileAssetPayload,
|
|
2537
2701
|
worldGeneratorDebugOwner,
|
|
2702
|
+
worldGeneratorRepresentationBands,
|
|
2703
|
+
worldGeneratorRepresentationOutputs,
|
|
2538
2704
|
worldGeneratorWorkerManifests,
|
|
2539
2705
|
worldGeneratorWorkerProfileNames,
|
|
2540
2706
|
worldGeneratorWorkerProfiles,
|