rayzee 9.0.0 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -8
- package/dist/{NeuralRetouch-CYOJ21Wn.js → NeuralRetouch-BRquqfmZ.js} +1 -1
- package/dist/{NeuralSuperRes-CQLCLpcC.js → NeuralSuperRes-CbNvQjCw.js} +3 -2
- package/dist/{ToneMapGPU-BVE852iN.js → ToneMapGPU-DpUZDMbQ.js} +2 -1
- package/dist/rayzee.es.js +10344 -5334
- package/dist/rayzee.umd.js +265 -265
- package/package.json +1 -1
- package/src/AssetConfig.js +4 -0
- package/src/EngineDefaults.js +38 -56
- package/src/EngineEvents.js +3 -0
- package/src/EngineIssues.js +6 -0
- package/src/Headless.js +3 -1
- package/src/Passes/AIUpscaler.js +2 -1
- package/src/Passes/OIDNDenoiser.js +3 -6
- package/src/PathTracerApp.js +290 -19
- package/src/Processor/ArchiveCache.js +120 -0
- package/src/Processor/ArchiveReader.js +179 -32
- package/src/Processor/AssetLoader.js +514 -76
- package/src/Processor/AtmosphereModel.js +465 -0
- package/src/Processor/BVHBuilder.js +4 -1
- package/src/Processor/BVHLeafFold.js +100 -0
- package/src/Processor/BVHRefitter.js +98 -214
- package/src/Processor/ChunkedRecords.js +189 -4
- package/src/Processor/EmissiveTriangleBuilder.js +8 -0
- package/src/Processor/GeometryExtractor.js +238 -40
- package/src/Processor/InstanceTable.js +55 -37
- package/src/Processor/PBRT/PBRTCurves.js +104 -27
- package/src/Processor/PBRT/PBRTParser.js +132 -22
- package/src/Processor/PBRT/PBRTSceneBuilder.js +192 -49
- package/src/Processor/PBRT/buffers.js +27 -0
- package/src/Processor/PBRT/index.js +55 -15
- package/src/Processor/PackedRayBuffer.js +10 -13
- package/src/Processor/ParallelBVHBuilder.js +36 -15
- package/src/Processor/PhysicalSky.js +308 -0
- package/src/Processor/QueueManager.js +1 -0
- package/src/Processor/SceneProcessor.js +1132 -181
- package/src/Processor/SplitBLAS.js +249 -0
- package/src/Processor/SunPosition.js +41 -0
- package/src/Processor/TextureCreator.js +21 -0
- package/src/Processor/Workers/AIUpscalerWorker.js +79 -52
- package/src/Processor/Workers/BVHWorker.js +17 -13
- package/src/Processor/ZipReader.js +207 -0
- package/src/RenderSettings.js +38 -0
- package/src/SceneState/SceneState.js +367 -0
- package/src/SceneState/portable.js +52 -0
- package/src/Stages/NormalDepth.js +7 -6
- package/src/Stages/PathTracer.js +108 -4
- package/src/Stages/PathTracerStage.js +251 -104
- package/src/Storage/BLASCache.js +190 -0
- package/src/Storage/CDFCache.js +77 -0
- package/src/Storage/DownloadCache.js +266 -0
- package/src/Storage/GeometrySpill.js +217 -0
- package/src/Storage/SceneGraphCodec.js +503 -0
- package/src/Storage/SpillStore.js +112 -0
- package/src/Storage/StorageManager.js +934 -0
- package/src/Storage/StorageOps.js +137 -0
- package/src/Storage/StorageWorker.js +37 -0
- package/src/Storage/events.js +29 -0
- package/src/Storage/identity.js +77 -0
- package/src/Storage/index.js +9 -0
- package/src/Storage/inlineTransport.js +24 -0
- package/src/Storage/locks.js +99 -0
- package/src/Storage/openStorage.js +87 -0
- package/src/Storage/sceneCachePolicy.js +12 -0
- package/src/Storage/shared.js +9 -0
- package/src/Storage/transport.js +62 -0
- package/src/TSL/Atmosphere.js +684 -0
- package/src/TSL/BVHTraversal.js +288 -239
- package/src/TSL/Common.js +11 -2
- package/src/TSL/Displacement.js +6 -6
- package/src/TSL/EmissiveSampling.js +5 -5
- package/src/TSL/EnvironmentCDF.js +176 -0
- package/src/TSL/GenerateKernel.js +3 -3
- package/src/TSL/HitFacet.js +4 -4
- package/src/TSL/LightsDirect.js +8 -8
- package/src/TSL/LightsSampling.js +55 -37
- package/src/TSL/Random.js +1 -0
- package/src/TSL/ShadeKernel.js +75 -19
- package/src/TSL/Sun.js +40 -0
- package/src/TSL/TextureSampling.js +6 -7
- package/src/index.js +18 -0
- package/src/managers/CameraManager.js +169 -1
- package/src/managers/EnvironmentManager.js +263 -33
- package/src/managers/GoboManager.js +19 -8
- package/src/managers/IESManager.js +3 -3
- package/src/managers/LightManager.js +98 -5
- package/src/managers/MaterialDataManager.js +22 -2
- package/src/managers/TransformManager.js +26 -0
- package/src/managers/UniformManager.js +5 -3
- package/src/managers/VideoRenderManager.js +3 -1
- package/src/managers/timeline/CameraTrack.js +22 -0
- package/src/managers/timeline/TimelineManager.js +14 -0
- package/src/version.js +3 -0
- package/src/Processor/ProceduralSky.js +0 -291
package/README.md
CHANGED
|
@@ -294,9 +294,12 @@ configureAssets({
|
|
|
294
294
|
ocioRuntimeFactory: () => import('@bb-studio/ocio'), // or: ocioRuntimeUrl: '/vendor/ocio/index.js'
|
|
295
295
|
ocioWasmUrl: '/vendor/ocio/ocio-wasm.wasm', // optional override for the .wasm
|
|
296
296
|
|
|
297
|
-
//
|
|
298
|
-
// apps embed the engine on the same origin
|
|
297
|
+
// Names the engine's on-disk storage (an OPFS directory). Set a unique value if several
|
|
298
|
+
// apps embed the engine on the same origin, so their caches stay apart.
|
|
299
299
|
cacheNamespace: 'my-app',
|
|
300
|
+
|
|
301
|
+
// On-disk storage: 'auto' (default) where the browser has it, false for none.
|
|
302
|
+
storage: 'auto',
|
|
300
303
|
});
|
|
301
304
|
|
|
302
305
|
const engine = new PathTracerApp(canvas);
|
|
@@ -321,6 +324,8 @@ const engine = new PathTracerApp(canvas, options?)
|
|
|
321
324
|
| `options.strict` | `boolean` | Throw an `EngineIssueError` where the engine would otherwise degrade and carry on (default: `false`). See [Degradation contract](#degradation-contract). |
|
|
322
325
|
| `options.profile` | `string` | `'viewer'` (default) or `'physical'` — product tuning that is not a physical constant: area-light scale, environment rotation, tone mapping, saturation. An unknown name throws. |
|
|
323
326
|
| `options.maxSceneBytes` | `number` | Raise or lower the CPU memory ceiling a scene may need before the engine refuses it (default 9,216 MB). See [Memory monitoring](#memory-monitoring). |
|
|
327
|
+
| `options.storage` | `false \| 'auto' \| StorageManager` | On-disk storage (default: `configureAssets( { storage } )`). A manager you pass stays yours to dispose. See [On-disk storage](#on-disk-storage-opfs). |
|
|
328
|
+
| `options.memorySpill` | `boolean` | Experimental, default `false`: build a large static scene through disk — triangle records, BLAS nodes and the three.js geometry are written out as the build finishes with them — and raise the pbrt triangle and placement caps to 60M / 8M. See [On-disk storage](#on-disk-storage-opfs). |
|
|
324
329
|
|
|
325
330
|
The engine creates and mounts everything it needs (denoiser canvas, tile/HUD overlay) into a single parent on `init()`. Performance HUDs (e.g. `stats-gl`) are not bundled — listen to `EngineEvents.FRAME` and tick your own panel.
|
|
326
331
|
|
|
@@ -392,10 +397,20 @@ try {
|
|
|
392
397
|
}
|
|
393
398
|
```
|
|
394
399
|
|
|
395
|
-
Per-load options for pbrt archives:
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
400
|
+
Per-load options for pbrt archives:
|
|
401
|
+
|
|
402
|
+
| Option | Default | Effect |
|
|
403
|
+
|---|---|---|
|
|
404
|
+
| `promptBytes` | 4 GB | moves the line past which a multi-element archive asks for elements |
|
|
405
|
+
| `maxTriangles` | 45M (60M with `memorySpill`) | past it, placements are skipped and the build reports itself truncated |
|
|
406
|
+
| `maxPlacements` | 6M (8M with `memorySpill`) | the same, for placements |
|
|
407
|
+
| `curveTolerance` | 0.05 | how far a curve segment may stray, × the curve's half-width; curves become strips with adaptive segments. `0` gives the old uniform strips bit for bit |
|
|
408
|
+
| `instanceIncludes` | `true` | a file included again under the same material, with no side effects, is placed as an instance of its first reading instead of being read and stored again |
|
|
409
|
+
|
|
410
|
+
45M is the highest rung measured to survive without the spill; raising either cap is a deliberate
|
|
411
|
+
act on a fresh browser tab. With `memorySpill`, 80M stored triangles (4.35M placements) have loaded
|
|
412
|
+
and rendered; an 89M load ran out of memory while parsing, and WebGPU's 4 GB buffer limit stops the
|
|
413
|
+
triangle data at 89.5M in any case.
|
|
399
414
|
|
|
400
415
|
#### Settings
|
|
401
416
|
|
|
@@ -659,12 +674,29 @@ engine.environmentManager.texture // The loaded environment texture
|
|
|
659
674
|
await engine.loadEnvironment(url) // Load HDR/EXR environment map (method on engine)
|
|
660
675
|
await engine.environmentManager.setEnvironmentMap(tex) // Set a custom environment texture
|
|
661
676
|
await engine.environmentManager.setMode(mode) // 'hdri' | 'procedural' | 'gradient' | 'color'
|
|
662
|
-
await engine.environmentManager.generateProcedural() //
|
|
677
|
+
await engine.environmentManager.generateProcedural() // Physical sky: spectral, multiple scattering, analytic sun
|
|
663
678
|
await engine.environmentManager.generateGradient() // Gradient sky
|
|
664
679
|
await engine.environmentManager.generateSolid() // Solid color sky
|
|
665
680
|
engine.environmentManager.markDirty() // Flag environment for GPU re-upload
|
|
666
681
|
```
|
|
667
682
|
|
|
683
|
+
The physical sky (mode `'procedural'`) is set through `params`, then baked. It is baked and
|
|
684
|
+
importance-sampled entirely on the GPU (~1.6 ms per sun move), so bake on every slider event rather
|
|
685
|
+
than debouncing: requests made in one task become one bake, and the promise resolves once the
|
|
686
|
+
environment has caught up. The sun is drawn and sampled as a light of its own, not from the texture.
|
|
687
|
+
|
|
688
|
+
```js
|
|
689
|
+
import { sunPosition, dayOfYearForMonth } from 'rayzee';
|
|
690
|
+
|
|
691
|
+
const p = engine.environmentManager.params;
|
|
692
|
+
const { azimuth, elevation } = sunPosition( { hours: 17.5, dayOfYear: dayOfYearForMonth( 6 ), latitude: 40 } );
|
|
693
|
+
const az = ( 180 - azimuth ) * Math.PI / 180, el = elevation * Math.PI / 180; // north along −Z, east along +X
|
|
694
|
+
p.skySunDirection.set( Math.cos( el ) * Math.sin( az ), Math.sin( el ), Math.cos( el ) * Math.cos( az ) );
|
|
695
|
+
p.skyTurbidity = 3; // haze, 1–10; also skyOzone (Dobson units), skyAirDensity (× Earth's),
|
|
696
|
+
// skyGroundAlbedo (Color), skyAltitude (m), skySunSize (°), skySunStrength
|
|
697
|
+
await engine.environmentManager.generateProcedural();
|
|
698
|
+
```
|
|
699
|
+
|
|
668
700
|
### engine.denoisingManager
|
|
669
701
|
|
|
670
702
|
Denoiser strategy, ASVGF, OIDN, upscaler, and auto-exposure.
|
|
@@ -897,7 +929,8 @@ Before extraction the engine prices the scene and applies two lines, both record
|
|
|
897
929
|
|
|
898
930
|
Raise or lower the hard line with `new PathTracerApp(canvas, { maxSceneBytes })`. The estimate runs
|
|
899
931
|
low at the very top of its range, so the per-load `maxTriangles` cap (45M) is the more reliable
|
|
900
|
-
guard on a scene of that size.
|
|
932
|
+
guard on a scene of that size. With `memorySpill` the estimate leaves out what the build keeps on
|
|
933
|
+
disk (the BVH, and triangle records past what a streamed build holds at once).
|
|
901
934
|
|
|
902
935
|
---
|
|
903
936
|
|
|
@@ -968,6 +1001,87 @@ precision, the model, kernel capabilities, tile state and resource counts — wh
|
|
|
968
1001
|
confirm FP16 actually engaged on a given GPU rather than inferring it from the device's feature
|
|
969
1002
|
list. Both need `timestamp-query`, and `getDenoiseProfile()` returns `null` when OIDN is not set up.
|
|
970
1003
|
|
|
1004
|
+
### On-disk Storage (OPFS)
|
|
1005
|
+
|
|
1006
|
+
`engine.storage` is a `StorageManager` over the browser's origin private file system, or `null` where
|
|
1007
|
+
there is none (a private window, Node) — everything works without it, only slower. The engine keeps
|
|
1008
|
+
its caches there: downloads (models, skies, OIDN weights, STBN atlases — revalidated with `HEAD`),
|
|
1009
|
+
unpacked `.tar.gz` archives and archive indexes, built scenes (reopened without rebuilding BVHs when
|
|
1010
|
+
the first build took ≥ 10 s), and environment sampling tables. Caches share a budget of 30 % of the
|
|
1011
|
+
quota and are evicted least-recently-used; `engine.storage.usage()` reports each area.
|
|
1012
|
+
|
|
1013
|
+
A host keeps its own data beside them:
|
|
1014
|
+
|
|
1015
|
+
```js
|
|
1016
|
+
import { STORAGE_KIND } from 'rayzee';
|
|
1017
|
+
|
|
1018
|
+
engine.storage.defineArea( 'renders', { kind: STORAGE_KIND.USER } ); // never evicted
|
|
1019
|
+
const writer = await engine.storage.area( 'renders' ).create( 'render:42', { label: 'Render 42' } );
|
|
1020
|
+
await writer.writeFile( 'image.png', blob );
|
|
1021
|
+
await writer.commit(); // meta.json last: all or nothing
|
|
1022
|
+
|
|
1023
|
+
const entry = await engine.storage.area( 'renders' ).open( 'render:42' );
|
|
1024
|
+
const file = await entry.file( 'image.png' );
|
|
1025
|
+
entry.release();
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
`loadFile( url )` and `loadModel( url, { cacheKey } )` download through the cache — pass `cacheKey` for
|
|
1029
|
+
a link that expires (a signed URL). `fetchFile( url, storage )` / `cachedObjectURL( url )` do the same
|
|
1030
|
+
for a host's own assets. Failures record `storage.*` issues and fall back to memory; storage never
|
|
1031
|
+
throws for being absent or full.
|
|
1032
|
+
|
|
1033
|
+
**Memory spill (experimental).** With `memorySpill: true`, a static scene of more than one 64 MB chunk
|
|
1034
|
+
is built through disk, so its large arrays are never all in memory at once:
|
|
1035
|
+
|
|
1036
|
+
- Extraction and BVH building run together. Each stored range of triangles goes to a BLAS worker as
|
|
1037
|
+
soon as it is written, and extraction waits while more than 1.5 GB of triangle records are held.
|
|
1038
|
+
On the 55.7M-triangle Moana subset the build peak fell from 6.6 to 4.1 GB.
|
|
1039
|
+
- The three.js geometry goes to disk after the build last reads it, and comes back when the build
|
|
1040
|
+
ends. On a 70M-triangle scene the page held 0.84 GB after extraction instead of 4.07 GB.
|
|
1041
|
+
- Each triangle chunk and BLAS goes to the GPU, then to disk. At 50M triangles the page settles at
|
|
1042
|
+
7.2 GB instead of 9.1 GB.
|
|
1043
|
+
|
|
1044
|
+
With or without the spill, a mesh past 2M triangles is built as spatial pieces of ≤ 512k triangles
|
|
1045
|
+
on a worker pool and joined under the tree that split them, so no build holds a second copy of it.
|
|
1046
|
+
|
|
1047
|
+
The render is unchanged. Visibility and rigid moves need nothing read back. Material edits that
|
|
1048
|
+
rewrite triangles (side, transparency, emission), and refits, read it back first. `refitBLASes`
|
|
1049
|
+
throws on a spilled scene until `await engine.ensureSceneResident()`.
|
|
1050
|
+
|
|
1051
|
+
### Saving Scene State
|
|
1052
|
+
|
|
1053
|
+
```js
|
|
1054
|
+
const state = engine.exportSceneState(); // JSON-safe: settings, sky, colour, lights, cameras,
|
|
1055
|
+
// timeline keys, material edits, hidden and moved objects
|
|
1056
|
+
const source = engine.sceneSource; // { kind: 'url', url, cacheKey } | { kind: 'local-file', file } | ...
|
|
1057
|
+
|
|
1058
|
+
// later, after loading the same model again:
|
|
1059
|
+
const { skipped } = await engine.importSceneState( state, {
|
|
1060
|
+
resolve: async ( request ) => {
|
|
1061
|
+
// { kind: 'environment', source } → a File, a URL or null (the engine loads URL skies itself)
|
|
1062
|
+
// { kind: 'colorConfig', config } → true once you have loaded it (built-in configs load themselves)
|
|
1063
|
+
return null;
|
|
1064
|
+
},
|
|
1065
|
+
} );
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
Objects, materials and cameras are matched by position in the scene plus a name check — UUIDs
|
|
1069
|
+
change on every load — so a different model keeps its own objects and materials and the rest still
|
|
1070
|
+
applies; `skipped` lists what could not be put back. Texture swaps on materials are not included yet.
|
|
1071
|
+
|
|
1072
|
+
### Render Checkpoints
|
|
1073
|
+
|
|
1074
|
+
```js
|
|
1075
|
+
const checkpoint = await engine.captureRenderCheckpoint(); // accumulation + the counters that pick the next sample
|
|
1076
|
+
// ...a reload later, the same scene state restored and one frame rendered at the same size:
|
|
1077
|
+
engine.restoreRenderCheckpoint( checkpoint );
|
|
1078
|
+
engine.wake(); // or await engine.renderFrames( n, { reset: false } )
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
In deterministic mode the continued render is bit-identical to one that never stopped. A checkpoint
|
|
1082
|
+
is ~60 bytes a pixel (252 MB at 2048²): the accumulated colour and aux buffers as RGBA32F plus three
|
|
1083
|
+
per-pixel convergence buffers.
|
|
1084
|
+
|
|
971
1085
|
---
|
|
972
1086
|
|
|
973
1087
|
### Events
|
|
@@ -1039,6 +1153,7 @@ import {
|
|
|
1039
1153
|
CAMERA_PRESETS,
|
|
1040
1154
|
CAMERA_RANGES,
|
|
1041
1155
|
SKY_PRESETS,
|
|
1156
|
+
DEFAULT_SUN_PATH,
|
|
1042
1157
|
AUTO_FOCUS_MODES,
|
|
1043
1158
|
AF_DEFAULTS,
|
|
1044
1159
|
TRIANGLE_DATA_LAYOUT,
|
|
@@ -1063,12 +1178,28 @@ import {
|
|
|
1063
1178
|
displayCanvasFit,
|
|
1064
1179
|
} from 'rayzee';
|
|
1065
1180
|
|
|
1181
|
+
// Where the sun stands for a solar time, date and latitude (degrees; azimuth clockwise from north)
|
|
1182
|
+
import { sunPosition, timeForSunElevation, dayOfYearForMonth } from 'rayzee';
|
|
1183
|
+
|
|
1066
1184
|
// Leveled/namespaced logging, shared with the workers
|
|
1067
1185
|
import { Logger, createLogger, fmt, LOG_LEVELS } from 'rayzee';
|
|
1068
1186
|
|
|
1069
1187
|
// Asset URL / cache namespace overrides
|
|
1070
1188
|
import { configureAssets, getAssetConfig } from 'rayzee';
|
|
1071
1189
|
|
|
1190
|
+
// On-disk storage (OPFS): caches, host areas, downloads, file identity
|
|
1191
|
+
import {
|
|
1192
|
+
openStorage, StorageManager, STORAGE_KIND, ENGINE_AREAS, acquireLock, heldLockNames,
|
|
1193
|
+
fileIdentity, identityKey, sameIdentity,
|
|
1194
|
+
DownloadCache, DOWNLOAD_POLICY, fetchFile, nameFromUrl, cachedObjectURL,
|
|
1195
|
+
} from 'rayzee';
|
|
1196
|
+
|
|
1197
|
+
// Archives read in place, one entry at a time
|
|
1198
|
+
import { openZip, readZipDirectory } from 'rayzee';
|
|
1199
|
+
|
|
1200
|
+
// Scene state as plain data (engine.exportSceneState), and the engine version as built
|
|
1201
|
+
import { SCENE_STATE_VERSION, toPortable, fromPortable, VERSION } from 'rayzee';
|
|
1202
|
+
|
|
1072
1203
|
// Advanced: managers & pipeline
|
|
1073
1204
|
import {
|
|
1074
1205
|
RenderSettings,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./rolldown-runtime-CAFD8bLK.js";
|
|
2
|
-
import { S as t, t as n, y as r } from "./ToneMapGPU-
|
|
2
|
+
import { S as t, t as n, y as r } from "./ToneMapGPU-DpUZDMbQ.js";
|
|
3
3
|
//#region src/neural/NeuralRetouch.js
|
|
4
4
|
var i = /* @__PURE__ */ e({
|
|
5
5
|
NeuralRetouch: () => m,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./rolldown-runtime-CAFD8bLK.js";
|
|
2
|
-
import { S as t, t as n, y as r } from "./ToneMapGPU-
|
|
2
|
+
import { S as t, t as n, y as r } from "./ToneMapGPU-DpUZDMbQ.js";
|
|
3
3
|
//#region src/EngineEvents.js
|
|
4
4
|
var i = {
|
|
5
5
|
RENDER_COMPLETE: "engine:renderComplete",
|
|
@@ -35,7 +35,8 @@ var i = {
|
|
|
35
35
|
DISPOSE: "engine:dispose",
|
|
36
36
|
DEVICE_LOST: "engine:deviceLost",
|
|
37
37
|
ISSUE: "engine:issue",
|
|
38
|
-
SCENE_METADATA_APPLIED: "engine:sceneMetadataApplied"
|
|
38
|
+
SCENE_METADATA_APPLIED: "engine:sceneMetadataApplied",
|
|
39
|
+
STORAGE_CHANGED: "engine:storageChanged"
|
|
39
40
|
}, a = /* @__PURE__ */ e({
|
|
40
41
|
NeuralSuperRes: () => g,
|
|
41
42
|
SR_MAX_INPUT: () => c,
|
|
@@ -110,7 +110,8 @@ var D = {
|
|
|
110
110
|
upscalerModelBaseUrl: "https://huggingface.co/notaneimu/onnx-image-models/resolve/main/",
|
|
111
111
|
neuralRuntimeUrl: "/neural/neural-runtime.js",
|
|
112
112
|
neuralAssetBaseUrl: null,
|
|
113
|
-
cacheNamespace: "rayzee"
|
|
113
|
+
cacheNamespace: "rayzee",
|
|
114
|
+
storage: "auto"
|
|
114
115
|
};
|
|
115
116
|
function O(e) {
|
|
116
117
|
e && Object.assign(D, e);
|