rayzee 9.4.2 → 9.5.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 +223 -21
- package/dist/ActiveColor-YvuQq44O.js +13 -0
- package/dist/ArchiveImporter-xuUJiklP.js +4301 -0
- package/dist/AssetConfig-DSEntE65.js +30 -0
- package/dist/BidirectionalIntegrator-C5PKjJoT.js +934 -0
- package/dist/ColorManagement-CheBCPaW.js +1488 -0
- package/dist/EngineDefaults-DH3bI5t-.js +844 -0
- package/dist/EngineEvents-Ci8dVWCP.js +73 -0
- package/dist/EngineIssues-CIZnXHsF.js +72 -0
- package/dist/FileFormats-sPGJeCRc.js +102 -0
- package/dist/Logger-BnHghprG.js +97 -0
- package/dist/{NeuralRetouch-vkdXXyK2.js → NeuralRetouch-CW11yLZ_.js} +8 -6
- package/dist/{NeuralSuperRes-FVqRJKQV.js → NeuralSuperRes-BekaecYg.js} +55 -120
- package/dist/PathTracer-Ccl9KOuF.js +29729 -0
- package/dist/PhysicalSky-Dv2PMFGW.js +1219 -0
- package/dist/RayzeeRenderer-BQxnzCTD.js +3542 -0
- package/dist/SolarLimb-ken-JbDK.js +721 -0
- package/dist/ToneMapGPU-BHi5JzIq.js +177 -0
- package/dist/ViewTransforms-D0rTLBsX.js +255 -0
- package/dist/WorkingMatrix-C6y233hT.js +27 -0
- package/dist/ZipReader-gDSWr0I5.js +98 -0
- package/dist/addons/archives.es.js +3 -0
- package/dist/addons/bidirectional.es.js +2 -0
- package/dist/addons/color.es.js +3 -0
- package/dist/addons/formats.es.js +2 -0
- package/dist/addons/physical-sky.es.js +2 -0
- package/dist/addons/storage.es.js +3 -0
- package/dist/archiveFormats-BZw7TiDp.js +75 -0
- package/dist/identity-DrQsGT2o.js +39 -0
- package/dist/openStorage-DwcBRUj7.js +820 -0
- package/dist/rayzee-core.es.js +12 -0
- package/dist/rayzee.es.js +2266 -44079
- package/dist/rayzee.umd.js +485 -473
- package/dist/sceneCachePolicy-BmwYOYDu.js +183 -0
- package/dist/shared-BGBcSxBQ.js +17 -0
- package/package.json +23 -2
- package/src/Color/ActiveColor.js +34 -0
- package/src/Color/BasicColor.js +147 -0
- package/src/Color/ColorManagement.js +7 -31
- package/src/EngineDefaults.js +22 -8
- package/src/EngineEvents.js +2 -0
- package/src/EngineIssues.js +1 -0
- package/src/PathTracerApp.js +617 -4016
- package/src/Pipeline/PipelineContext.js +0 -4
- package/src/Platform.js +36 -0
- package/src/Processor/ArchiveCache.js +1 -1
- package/src/Processor/ArchiveImporter.js +1259 -0
- package/src/Processor/AssetLoader.js +322 -1746
- package/src/Processor/AtmosphereModel.js +1 -2
- package/src/Processor/BVHBuilder.js +4 -95
- package/src/Processor/EnvironmentExactTable.js +187 -0
- package/src/Processor/EquirectHDRInfo.js +30 -223
- package/src/Processor/FileFormats.js +116 -0
- package/src/Processor/GLTFDecoders.js +85 -0
- package/src/Processor/GLTFDiffuseTransmission.js +63 -0
- package/src/Processor/GeometryExtractor.js +12 -1
- package/src/Processor/IESParser.js +47 -35
- package/src/Processor/KernelManager.js +35 -2
- package/src/Processor/MaterialPacking.js +8 -7
- package/src/Processor/PBRT/PBRTMaterials.js +129 -41
- package/src/Processor/PBRT/PBRTParser.js +30 -17
- package/src/Processor/PBRT/PBRTSceneBuilder.js +548 -37
- package/src/Processor/PBRT/PBRTTextureBake.js +154 -0
- package/src/Processor/PBRT/PFM.js +59 -0
- package/src/Processor/PackedRayBuffer.js +116 -9
- package/src/Processor/ParallelBVHBuilder.js +3 -6
- package/src/Processor/PhysicalSky.js +5 -4
- package/src/Processor/PlatformImageLoader.js +50 -6
- package/src/Processor/QueueManager.js +12 -3
- package/src/Processor/ReinsertionOptimizer.js +2 -2
- package/src/Processor/SceneProcessor.js +15 -55
- package/src/Processor/ShaderBuilder.js +6 -16
- package/src/Processor/SolarLimb.js +3 -0
- package/src/Processor/TextureCreator.js +1 -1
- package/src/Processor/Workers/BVHSubtreeWorker.js +1 -34
- package/src/Processor/Workers/BVHWorker.js +5 -18
- package/src/Processor/Workers/CDFWorker.js +6 -183
- package/src/Processor/archiveFormats.js +7 -0
- package/src/Processor/utils.js +2 -1
- package/src/RayzeeRenderer.js +3902 -0
- package/src/RenderSettings.js +49 -41
- package/src/Stages/ASVGF.js +5 -7
- package/src/Stages/AutoExposure.js +3 -12
- package/src/Stages/Compositor.js +8 -23
- package/src/Stages/NRD.js +9 -2
- package/src/Stages/NormalDepth.js +9 -6
- package/src/Stages/PathTracer.js +254 -38
- package/src/Stages/PathTracerStage.js +11 -16
- package/src/Storage/BLASCache.js +1 -1
- package/src/Storage/CDFCache.js +18 -17
- package/src/Storage/DownloadCache.js +1 -1
- package/src/Storage/SceneGraphCodec.js +46 -3
- package/src/Storage/SpillStore.js +1 -1
- package/src/Storage/StorageManager.js +2 -4
- package/src/Storage/areas.js +4 -0
- package/src/TSL/BVHTraversal.js +62 -24
- package/src/TSL/Bidirectional.js +204 -0
- package/src/TSL/BidirectionalLamps.js +132 -0
- package/src/TSL/Clearcoat.js +15 -6
- package/src/TSL/Common.js +19 -14
- package/src/TSL/ConnectKernel.js +147 -0
- package/src/TSL/Debugger.js +1 -1
- package/src/TSL/Displacement.js +4 -3
- package/src/TSL/EmissiveSampling.js +64 -17
- package/src/TSL/Environment.js +77 -106
- package/src/TSL/EnvironmentCDF.js +85 -39
- package/src/TSL/ExtendKernel.js +8 -3
- package/src/TSL/FinalWriteKernel.js +4 -4
- package/src/TSL/GenerateKernel.js +18 -4
- package/src/TSL/HitFacet.js +35 -5
- package/src/TSL/LightBVHSampling.js +40 -9
- package/src/TSL/LightGenerateKernel.js +293 -0
- package/src/TSL/LightGuide.js +198 -0
- package/src/TSL/LightSplatKernel.js +165 -0
- package/src/TSL/LightsCore.js +13 -38
- package/src/TSL/LightsDirect.js +28 -29
- package/src/TSL/LightsIndirect.js +3 -1
- package/src/TSL/LightsSampling.js +90 -38
- package/src/TSL/MaterialEvaluation.js +113 -31
- package/src/TSL/MaterialProperties.js +44 -17
- package/src/TSL/MaterialTransmission.js +52 -47
- package/src/TSL/MergeKernel.js +218 -0
- package/src/TSL/PathTracerCore.js +65 -29
- package/src/TSL/Random.js +4 -0
- package/src/TSL/SceneResources.js +51 -0
- package/src/TSL/ShadeKernel.js +881 -103
- package/src/TSL/Struct.js +10 -0
- package/src/TSL/Sun.js +1 -1
- package/src/TSL/TextureSampling.js +65 -60
- package/src/addons/archives.js +14 -0
- package/src/addons/bidirectional.js +13 -0
- package/src/addons/color.js +32 -0
- package/src/addons/formats.js +16 -0
- package/src/addons/physicalSky.js +14 -0
- package/src/addons/storage.js +19 -0
- package/src/core.js +35 -0
- package/src/index.js +3 -1
- package/src/integrators/BidirectionalIntegrator.js +832 -0
- package/src/managers/EnvironmentManager.js +85 -33
- package/src/managers/MaterialDataManager.js +42 -0
- package/src/managers/UniformManager.js +0 -1
- package/dist/ToneMapGPU-DKQM1pMd.js +0 -552
- package/dist/rolldown-runtime-CAFD8bLK.js +0 -11
- package/src/Processor/TreeletOptimizer.js +0 -574
package/README.md
CHANGED
|
@@ -21,6 +21,8 @@ A real-time WebGPU path tracing engine built on Three.js. Framework-agnostic —
|
|
|
21
21
|
- [API Reference](#api-reference)
|
|
22
22
|
- [Configuring Assets (CDN URLs & cache namespace)](#configuring-assets-cdn-urls--cache-namespace)
|
|
23
23
|
- [PathTracerApp](#pathtracerapp)
|
|
24
|
+
- [Renderer core (`rayzee/core`)](#renderer-core-rayzeecore)
|
|
25
|
+
- [Add-ons](#add-ons)
|
|
24
26
|
- [engine.cameraManager](#enginecameramanager)
|
|
25
27
|
- [Camera Projection (Orthographic, 360° Panorama)](#camera-projection-orthographic-360-panorama)
|
|
26
28
|
- [engine.lightManager](#enginelightmanager)
|
|
@@ -39,6 +41,9 @@ A real-time WebGPU path tracing engine built on Three.js. Framework-agnostic —
|
|
|
39
41
|
- [Memory Monitoring](#memory-monitoring)
|
|
40
42
|
- [Logging](#logging)
|
|
41
43
|
- [Deterministic & Headless Rendering](#deterministic--headless-rendering)
|
|
44
|
+
- [On-disk Storage (OPFS)](#on-disk-storage-opfs)
|
|
45
|
+
- [Saving Scene State](#saving-scene-state)
|
|
46
|
+
- [Render Checkpoints](#render-checkpoints)
|
|
42
47
|
- [Events](#events)
|
|
43
48
|
- [Advanced: Custom Pipeline Stages](#advanced-custom-pipeline-stages)
|
|
44
49
|
- [All Exports](#all-exports)
|
|
@@ -55,7 +60,7 @@ A real-time WebGPU path tracing engine built on Three.js. Framework-agnostic —
|
|
|
55
60
|
npm install rayzee three
|
|
56
61
|
```
|
|
57
62
|
|
|
58
|
-
`three` (>=0.
|
|
63
|
+
`three` (>=0.186.0) is a required peer dependency.
|
|
59
64
|
|
|
60
65
|
## Getting Started
|
|
61
66
|
|
|
@@ -137,10 +142,10 @@ A single HTML file — no Node.js, no build step. Uses [ES module import maps](h
|
|
|
137
142
|
<script type="importmap">
|
|
138
143
|
{
|
|
139
144
|
"imports": {
|
|
140
|
-
"three": "https://cdn.jsdelivr.net/npm/three@0.
|
|
141
|
-
"three/tsl": "https://cdn.jsdelivr.net/npm/three@0.
|
|
142
|
-
"three/webgpu": "https://cdn.jsdelivr.net/npm/three@0.
|
|
143
|
-
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.
|
|
145
|
+
"three": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.webgpu.js",
|
|
146
|
+
"three/tsl": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.tsl.js",
|
|
147
|
+
"three/webgpu": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.webgpu.js",
|
|
148
|
+
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.0/examples/jsm/",
|
|
144
149
|
"oidn-web": "https://cdn.jsdelivr.net/npm/oidn-web@0.4.0/dist/oidn.js",
|
|
145
150
|
"rayzee": "https://cdn.jsdelivr.net/npm/rayzee/dist/rayzee.es.js"
|
|
146
151
|
}
|
|
@@ -306,7 +311,7 @@ All keys are optional — only what you pass is overridden. Call `getAssetConfig
|
|
|
306
311
|
|
|
307
312
|
### PathTracerApp
|
|
308
313
|
|
|
309
|
-
The main engine class. Extends
|
|
314
|
+
The main engine class. Extends `RayzeeRenderer`, the [renderer core](#renderer-core-rayzeecore), which extends three.js's `EventDispatcher`. Related functionality is grouped into **namespaced managers** accessed via `engine.cameraManager`, `engine.lightManager`, etc., or as direct methods on the engine instance.
|
|
310
315
|
|
|
311
316
|
```js
|
|
312
317
|
const engine = new PathTracerApp(canvas, options?)
|
|
@@ -346,12 +351,15 @@ Constructing a new `PathTracerApp` on a canvas that already has an active instan
|
|
|
346
351
|
#### Loading Assets
|
|
347
352
|
|
|
348
353
|
```js
|
|
349
|
-
await engine.loadModel(url) // Load GLB/GLTF
|
|
354
|
+
await engine.loadModel(url) // Load a GLB/GLTF by URL
|
|
355
|
+
await engine.loadFile(fileOrUrl) // Any supported file: GLB/GLTF/FBX/OBJ/STL/PLY/DAE/3MF/USD/USDZ, archives, HDR/EXR
|
|
350
356
|
await engine.loadObject3D(object3d, name?) // Load a Three.js Object3D directly (name is optional, defaults to 'object3d')
|
|
351
357
|
await engine.loadEnvironment(url) // Load HDR/EXR environment map
|
|
352
358
|
engine.cancelLoad() // Abort an in-flight download (network phase only; no-op once processing starts)
|
|
353
359
|
```
|
|
354
360
|
|
|
361
|
+
On `rayzee/core`, formats other than glTF and `.hdr` need the `rayzee/addons/formats` add-on — see [Add-ons](#add-ons).
|
|
362
|
+
|
|
355
363
|
`loadModel` / `loadObject3D` **replace** the current scene. To add or remove objects from a live scene without a full reload (and without reframing the camera):
|
|
356
364
|
|
|
357
365
|
```js
|
|
@@ -368,6 +376,8 @@ engine.setSceneObjectVisibility(id, visible) // Toggle visi
|
|
|
368
376
|
|
|
369
377
|
##### Loading part of a scene archive
|
|
370
378
|
|
|
379
|
+
On `rayzee/core`, archives and pbrt need the `rayzee/addons/archives` add-on — see [Renderer core](#renderer-core-rayzeecore).
|
|
380
|
+
|
|
371
381
|
A pbrt-v4 scene archive (`.tar`, `.tar.gz`, `.zip`) is usually a root `.pbrt` file that includes one
|
|
372
382
|
subtree per element, and the whole thing rarely fits in a browser tab — Moana is 29 GB unpacked.
|
|
373
383
|
The archive can be inspected without retaining any of it, then loaded one element at a time:
|
|
@@ -437,6 +447,7 @@ Key settings:
|
|
|
437
447
|
| `environmentRotation` | `number` | 0 | Environment Y-rotation (degrees); 0 shows the HDRI as authored, as Blender's unmapped world does |
|
|
438
448
|
| `showBackground` | `boolean` | true | Show the environment as a visible backdrop for camera-miss rays (vs. a solid/transparent background) |
|
|
439
449
|
| `samplingTechnique` | `number` | 2 | Sampler: `0` PCG, `1` scrambled Halton, `2` Owen-scrambled Sobol |
|
|
450
|
+
| `integrator` | `string` | 'path' | `'path'` \| `'bidirectional'` \| `'vcm'` (on the core, needs the bidirectional add-on). Bidirectional also traces light subpaths from every light — emissive surfaces, rect/disk, point, spot and directional lights, the sun and the environment — far faster for caustics and light through small openings, about 2× the cost per sample. On a lamp-lit interior with an HDRI it is ~20 % less noisy at equal time; a room lit only through a window stays better path traced. `'vcm'` adds photon merging, for caustics seen in mirrors and through glass. Switching rebuilds the kernels |
|
|
440
451
|
| `fireflyThreshold` | `number` | 3.0 | Firefly clamping threshold |
|
|
441
452
|
| `shadowTerminatorOffset` | `number` | 0.1 | Cycles' Shadow Terminator → Geometry Offset: near the light's terminator on a smooth-shaded low-poly mesh, light and environment shadow rays start on the smooth surface the vertex normals describe, not the flat facet. Blender's default; `0` disables |
|
|
442
453
|
| `transmissiveBounces` | `number` | 5 | Max bounces for transmissive materials |
|
|
@@ -451,7 +462,7 @@ Key settings:
|
|
|
451
462
|
| `unitsPerMetre` | `number` | 1 | Physical mode: scene units per real metre, for files whose units are not metres. It carries over between model loads — reset it when the new file's units differ |
|
|
452
463
|
| `transparentBackground` | `boolean` | false | Transparent canvas background |
|
|
453
464
|
| `interactionModeEnabled` | `boolean` | true | Render at lower resolution while the camera moves, keeping the full bounce budget ("Fast Navigation" in the app) |
|
|
454
|
-
| `interactionRenderScale` | `number` | 0.5 | Per-axis render scale while the camera moves (0.5 = a quarter of the pixels); `1` turns the drop off. Ignored while OIDN is the live denoiser |
|
|
465
|
+
| `interactionRenderScale` | `number` | 0.5 | Per-axis render scale while the camera moves (0.5 = a quarter of the pixels); `1` turns the drop off. Ignored while OIDN is the live denoiser. `PathTracerApp` only |
|
|
455
466
|
| `renderMode` | `number` | 0 | Internal preview(0)/production(1) flag driving accumulation & ASVGF behavior — normally set via `configureForMode()`, not written directly |
|
|
456
467
|
| `visMode` | `number` | 0 | Debug visualization mode (0 = off) |
|
|
457
468
|
| `environmentMode` | `string` | 'hdri' | Sky mode: `'hdri'` \| `'procedural'` \| `'color'` — not routed through `engine.settings`; use `engine.environmentManager.setMode()` instead |
|
|
@@ -460,14 +471,14 @@ Key settings:
|
|
|
460
471
|
| `panoramaLatRange` | `[number, number]` | `[-90, 90]` | Panorama latitude sweep, degrees, bottom→top |
|
|
461
472
|
| `panoramaLevelHorizon` | `boolean` | true | Yaw-only panorama basis, so orbit pitch/roll can't tilt the horizon |
|
|
462
473
|
| `useAdaptiveSampling` | `boolean` | true | Whole-frame early-stop once convergence reaches `adaptiveStopFraction` |
|
|
463
|
-
| `noiseThreshold` | `number` | 0.
|
|
474
|
+
| `noiseThreshold` | `number` | 0.1 | √-luminance-normalized per-pixel noise below which a pixel counts as converged (the production preset uses 0.02) |
|
|
464
475
|
| `adaptiveMinSamples` | `number` | 8 | Minimum samples before adaptive sampling can trigger |
|
|
465
|
-
| `adaptiveStopFraction` | `number` | 0.
|
|
476
|
+
| `adaptiveStopFraction` | `number` | 0.90 | Fraction of pixels that must converge before the frame retires (the production preset uses 0.94) |
|
|
466
477
|
| `usePixelFreeze` | `boolean` | true | Per-pixel freeze (Tier-2): skip individually-converged pixels via active-list compaction |
|
|
467
478
|
| `pixelFreezeThreshold` | `number` | 0.02 | Relative-error threshold for a pixel to become a freeze candidate |
|
|
468
479
|
| `pixelFreezeStability` | `number` | 8 | Consecutive candidate frames required before a pixel freezes |
|
|
469
480
|
|
|
470
|
-
See `ENGINE_DEFAULTS` for the full list with default values. The default look is AgX (`toneMapping: 6`) at neutral saturation; tone mapping is chosen through [Colour Management](#colour-management) (`engine.color.setActiveView( id )`), not `settings`.
|
|
481
|
+
See `ENGINE_DEFAULTS` for the full list with default values. The default look is AgX (`toneMapping: 6`) at neutral saturation; tone mapping is chosen through [Colour Management](#colour-management) (`engine.color.setActiveView( id )`), not `settings`. On the core without the colour add-on, set `renderer.renderer.toneMapping`.
|
|
471
482
|
|
|
472
483
|
#### Rendering Modes
|
|
473
484
|
|
|
@@ -480,6 +491,168 @@ To pause rendering for image-viewing UI, set `engine.pauseRendering = true` and
|
|
|
480
491
|
|
|
481
492
|
---
|
|
482
493
|
|
|
494
|
+
### Renderer core (`rayzee/core`)
|
|
495
|
+
|
|
496
|
+
`PathTracerApp` is built on `RayzeeRenderer`, the renderer without the viewer: a scene and camera in, path-traced samples accumulated, the image out. The denoisers, camera controls, gizmo, overlays, timeline and animation playback exist only in `PathTracerApp`; six capabilities come as add-ons — file formats beyond glTF and `.hdr`, the physical sky, scene archives, bidirectional path tracing, OpenColorIO colour and on-disk storage. Its entry point downloads about 40 % less (249 KB against 418 KB compressed). It takes the same constructor options except `container`, and renders the same pixels.
|
|
497
|
+
|
|
498
|
+
```js
|
|
499
|
+
import { RayzeeRenderer } from 'rayzee/core';
|
|
500
|
+
|
|
501
|
+
const renderer = await new RayzeeRenderer(canvas).init();
|
|
502
|
+
await renderer.loadModel('/models/scene.glb');
|
|
503
|
+
renderer.camera.position.set(0, 2, 6); // the camera it renders from; reset() after moving it
|
|
504
|
+
renderer.camera.lookAt(0, 0, 0);
|
|
505
|
+
renderer.reset();
|
|
506
|
+
await renderer.renderFrames(256);
|
|
507
|
+
const image = await renderer.renderToBuffer({ colorSpace: 'srgb' });
|
|
508
|
+
renderer.dispose();
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
Two runnable examples live in the repository: `rayzee/examples/core-node.mjs` (the core alone, in Node, writing a PNG)
|
|
512
|
+
and `rayzee/examples/core-browser/` (the core plus the physical sky, accumulating on a canvas).
|
|
513
|
+
|
|
514
|
+
#### Add-ons
|
|
515
|
+
|
|
516
|
+
Six capabilities install on the core explicitly. `PathTracerApp` installs all six itself, so nothing in this
|
|
517
|
+
section applies to it.
|
|
518
|
+
|
|
519
|
+
| Add-on | Import | Install | When | Without it |
|
|
520
|
+
|---|---|---|---|---|
|
|
521
|
+
| File formats | `fbxFormat`, `objFormat`, `stlFormat`, `plyFormat`, `colladaFormat`, `threeMFFormat`, `usdFormat`, `exrFormat` or `allFormats` from `rayzee/addons/formats` | `renderer.assetLoader.registerFormat(objFormat, exrFormat)` | after `init()` | only glTF/GLB, `.hdr` and images load; any other file's error names the add-on |
|
|
522
|
+
| Physical sky | `PhysicalSky` from `rayzee/addons/physical-sky` | `renderer.environmentManager.setProceduralSky(PhysicalSky)` | after `init()` | `'procedural'` mode records `capability.missing` (throws under `strict`) |
|
|
523
|
+
| Scene archives and pbrt | `ArchiveImporter` from `rayzee/addons/archives` | `renderer.assetLoader.setArchiveImporter(new ArchiveImporter(renderer.assetLoader))` | after `init()` | `.zip`, `.tar` and `.tgz` are not supported formats, and the error names the add-on |
|
|
524
|
+
| Bidirectional and VCM | `BidirectionalIntegrator` from `rayzee/addons/bidirectional` | `renderer.stages.pathTracer.registerIntegrator(['bidirectional', 'vcm'], pt => new BidirectionalIntegrator(pt))` | after `init()` | choosing either integrator records `capability.missing` (throws under `strict`) and keeps the current one |
|
|
525
|
+
| OpenColorIO colour | `ColorManagement` from `rayzee/addons/color` | `renderer.setColorManagement(ColorManagement)` | before or after `init()` | linear Rec.709 through three.js's own tone mappers; `loadColorConfig()` records `capability.missing` and rejects |
|
|
526
|
+
| On-disk storage | `acquireSharedStorage` from `rayzee/addons/storage` | `renderer.setStorageOpener(acquireSharedStorage)` | **before** `init()` | downloads land in memory and nothing is cached between visits |
|
|
527
|
+
|
|
528
|
+
`init()` creates the asset loader, the environment manager and the path tracer stage, which is why four of them come
|
|
529
|
+
after it. Storage is opened during `init()`, so its opener has to be set first.
|
|
530
|
+
|
|
531
|
+
All six, in that order:
|
|
532
|
+
|
|
533
|
+
```js
|
|
534
|
+
import { RayzeeRenderer, configureAssets } from 'rayzee/core';
|
|
535
|
+
import { acquireSharedStorage } from 'rayzee/addons/storage';
|
|
536
|
+
import { ColorManagement } from 'rayzee/addons/color';
|
|
537
|
+
import { ArchiveImporter } from 'rayzee/addons/archives';
|
|
538
|
+
import { PhysicalSky } from 'rayzee/addons/physical-sky';
|
|
539
|
+
import { BidirectionalIntegrator } from 'rayzee/addons/bidirectional';
|
|
540
|
+
import { allFormats } from 'rayzee/addons/formats';
|
|
541
|
+
|
|
542
|
+
configureAssets({ ocioRuntimeFactory: () => import('@bb-studio/ocio') });
|
|
543
|
+
|
|
544
|
+
const renderer = new RayzeeRenderer(canvas);
|
|
545
|
+
renderer.setStorageOpener(acquireSharedStorage); // before init()
|
|
546
|
+
renderer.setColorManagement(ColorManagement);
|
|
547
|
+
await renderer.init();
|
|
548
|
+
renderer.assetLoader.registerFormat(...allFormats);
|
|
549
|
+
renderer.assetLoader.setArchiveImporter(new ArchiveImporter(renderer.assetLoader));
|
|
550
|
+
renderer.environmentManager.setProceduralSky(PhysicalSky);
|
|
551
|
+
renderer.stages.pathTracer.registerIntegrator(['bidirectional', 'vcm'], pt => new BidirectionalIntegrator(pt));
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
**Loading on first use.** The physical sky and the archive importer can be installed as loaders instead, so their code
|
|
555
|
+
is fetched only the first time the sky is baked or an archive is read — `PathTracerApp` does this. The archive loader
|
|
556
|
+
takes the formats it reads, which `rayzee/core` exports, so the loader recognises an archive before its code exists:
|
|
557
|
+
|
|
558
|
+
```js
|
|
559
|
+
import { ARCHIVE_FORMATS } from 'rayzee/core';
|
|
560
|
+
|
|
561
|
+
renderer.environmentManager.setProceduralSkyLoader(() => import('rayzee/addons/physical-sky').then((m) => m.PhysicalSky));
|
|
562
|
+
renderer.assetLoader.setArchiveImporterLoader(
|
|
563
|
+
() => import('rayzee/addons/archives').then((m) => new m.ArchiveImporter(renderer.assetLoader)),
|
|
564
|
+
ARCHIVE_FORMATS,
|
|
565
|
+
);
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
Colour, storage and the integrators have no loader: colour and storage are used at startup, and an integrator applies
|
|
569
|
+
the moment it is chosen (a lazy one would trace plain frames meanwhile and break reproducible renders).
|
|
570
|
+
|
|
571
|
+
**File formats.** The core reads glTF/GLB (Draco, KTX2 and meshopt decoders are fetched only for a file that uses
|
|
572
|
+
them), `.hdr` and LDR images. FBX, OBJ, STL, PLY, Collada, 3MF, USD/USDZ and EXR are formats to register — import only
|
|
573
|
+
those you read and a bundler leaves the rest out; each three.js loader is downloaded the first time its format is read:
|
|
574
|
+
|
|
575
|
+
```js
|
|
576
|
+
import { objFormat, usdFormat, exrFormat } from 'rayzee/addons/formats';
|
|
577
|
+
|
|
578
|
+
renderer.assetLoader.registerFormat(objFormat, usdFormat, exrFormat);
|
|
579
|
+
await renderer.loadFile(objFile);
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
A format of your own registers the same way. A model format's `parse` gets the file and resolves to the model; an
|
|
583
|
+
environment format's `createLoader` returns a three.js loader whose `loadAsync` resolves to a texture:
|
|
584
|
+
|
|
585
|
+
```js
|
|
586
|
+
renderer.assetLoader.registerFormat({
|
|
587
|
+
name: 'Point cloud (XYZ)', label: 'XYZ', type: 'model', extensions: ['xyz'],
|
|
588
|
+
async parse(file, { filename }) {
|
|
589
|
+
return { model: buildPoints(await file.text(), filename) };
|
|
590
|
+
},
|
|
591
|
+
});
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**Physical sky**, for `environmentMode: 'procedural'`:
|
|
595
|
+
|
|
596
|
+
```js
|
|
597
|
+
renderer.environmentManager.setProceduralSky(PhysicalSky);
|
|
598
|
+
await renderer.environmentManager.setMode('procedural');
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
**Bidirectional path tracing and vertex merging**, for `integrator: 'bidirectional' | 'vcm'`:
|
|
602
|
+
|
|
603
|
+
```js
|
|
604
|
+
renderer.stages.pathTracer.registerIntegrator(['bidirectional', 'vcm'], pt => new BidirectionalIntegrator(pt));
|
|
605
|
+
renderer.settings.set('integrator', 'bidirectional');
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
Its controls are on the active integrator (the same on `PathTracerApp`):
|
|
609
|
+
|
|
610
|
+
```js
|
|
611
|
+
const integrator = renderer.stages.pathTracer.activeIntegrator;
|
|
612
|
+
integrator.setMergeRadius(1); // 'vcm': gather radius in pixels
|
|
613
|
+
integrator.setMergeTrust(0.25); // 'vcm': how far merging is trusted against the other strategies
|
|
614
|
+
integrator.setLightGuiding(true); // learn where light paths from the sky and sun start
|
|
615
|
+
integrator.setBidirectionalStrategy('connect', { alone: true }); // keep one strategy, for verification
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
**Scene archives** (`.zip`, `.tar`, `.tar.gz`) and the pbrt scenes in them:
|
|
619
|
+
|
|
620
|
+
```js
|
|
621
|
+
renderer.assetLoader.setArchiveImporter(new ArchiveImporter(renderer.assetLoader));
|
|
622
|
+
await renderer.loadFile(archiveFile);
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
**OpenColorIO colour management** — configs, their views and looks, working spaces and export spaces. The host supplies
|
|
626
|
+
the OCIO runtime (the engine never names the package). Without the add-on, pick a tone mapper on the three.js renderer
|
|
627
|
+
instead (`renderer.renderer.toneMapping = AgXToneMapping`):
|
|
628
|
+
|
|
629
|
+
```js
|
|
630
|
+
configureAssets({ ocioRuntimeFactory: () => import('@bb-studio/ocio') });
|
|
631
|
+
renderer.setColorManagement(ColorManagement);
|
|
632
|
+
await renderer.loadColorConfig({ builtin: 'ocio://cg-config-v4.0.0_aces-v2.0_ocio-v2.5' });
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
**On-disk storage** (the browser's origin private file system), for the download, environment and scene caches and
|
|
636
|
+
the `memorySpill` option. Asking for it without the add-on (`storage: 'auto'`) records a `capability.missing` warning;
|
|
637
|
+
`storage: false` turns it off either way:
|
|
638
|
+
|
|
639
|
+
```js
|
|
640
|
+
const renderer = new RayzeeRenderer(canvas);
|
|
641
|
+
renderer.setStorageOpener(acquireSharedStorage);
|
|
642
|
+
await renderer.init();
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
Several renderers, core or full, can live in one page; they share only the colour management and the on-disk storage,
|
|
646
|
+
which are page-wide.
|
|
647
|
+
|
|
648
|
+
Code of your own that adds a setting declares it on the renderer's settings, so it gets the same provenance, change
|
|
649
|
+
events and session saving as the built-in ones:
|
|
650
|
+
|
|
651
|
+
```js
|
|
652
|
+
renderer.settings.define('myGlowStrength', { apply: (value) => glow.setStrength(value), reset: true });
|
|
653
|
+
renderer.settings.set('myGlowStrength', 2);
|
|
654
|
+
```
|
|
655
|
+
|
|
483
656
|
### engine.cameraManager
|
|
484
657
|
|
|
485
658
|
Camera switching, auto-focus, DOF, and direct Three.js access.
|
|
@@ -641,6 +814,8 @@ A property a three.js material lacks falls back to `MATERIAL_DEFAULTS` (exported
|
|
|
641
814
|
|
|
642
815
|
### Colour Management
|
|
643
816
|
|
|
817
|
+
On `rayzee/core` this is the `rayzee/addons/color` add-on — see [Renderer core](#renderer-core-rayzeecore).
|
|
818
|
+
|
|
644
819
|
`engine.color` is an OpenColorIO pipeline: what textures and lights mean, what the render happens in, and what it is shown and saved as. **It is inert until a config is loaded** — the render stays linear Rec.709 and the view transforms are three.js's own seven, so a host that never loads one sees no change. The host supplies the runtime (`ocioRuntimeFactory` or `ocioRuntimeUrl` in [`configureAssets`](#configuring-assets-cdn-urls--cache-namespace)).
|
|
645
820
|
|
|
646
821
|
```js
|
|
@@ -679,7 +854,7 @@ engine.environmentManager.texture // The loaded environment texture
|
|
|
679
854
|
await engine.loadEnvironment(url) // Load HDR/EXR environment map (method on engine)
|
|
680
855
|
await engine.environmentManager.setEnvironmentMap(tex) // Set a custom environment texture
|
|
681
856
|
await engine.environmentManager.setMode(mode) // 'hdri' | 'procedural' | 'color'
|
|
682
|
-
await engine.environmentManager.generateProcedural() // Physical sky: spectral, multiple scattering, analytic sun
|
|
857
|
+
await engine.environmentManager.generateProcedural() // Physical sky: spectral, multiple scattering, analytic sun (core: needs rayzee/addons/physical-sky)
|
|
683
858
|
await engine.environmentManager.generateSolid() // Solid color sky
|
|
684
859
|
engine.environmentManager.markDirty() // Flag environment for GPU re-upload
|
|
685
860
|
```
|
|
@@ -707,15 +882,15 @@ Denoiser strategy, ASVGF, OIDN, upscaler, and auto-exposure.
|
|
|
707
882
|
|
|
708
883
|
```js
|
|
709
884
|
// Strategy
|
|
710
|
-
engine.denoisingManager.setStrategy('asvgf', 'medium') // 'none' | 'asvgf' | 'edgeaware'
|
|
885
|
+
engine.denoisingManager.setStrategy('asvgf', 'medium') // 'none' | 'asvgf' | 'nrd' | 'edgeaware' | 'oidn'
|
|
711
886
|
engine.denoisingManager.denoiserStrategy // read back the active strategy (derived from stage state)
|
|
712
887
|
engine.denoisingManager.setASVGFEnabled(true, 'medium')
|
|
713
888
|
engine.denoisingManager.applyASVGFPreset('high') // 'low' | 'medium' | 'high'
|
|
714
889
|
engine.denoisingManager.setAutoExposure(true)
|
|
715
890
|
|
|
716
891
|
// Fine-grained parameters
|
|
717
|
-
engine.denoisingManager.setASVGFParams({ temporalAlpha: 0.1,
|
|
718
|
-
engine.denoisingManager.setEdgeAwareParams({
|
|
892
|
+
engine.denoisingManager.setASVGFParams({ temporalAlpha: 0.1, maxAccumFrames: 16 })
|
|
893
|
+
engine.denoisingManager.setEdgeAwareParams({ phiLuminance: 4.0, atrousIterations: 5 })
|
|
719
894
|
engine.denoisingManager.setAutoExposureParams({ keyValue: 0.18 })
|
|
720
895
|
|
|
721
896
|
// OIDN & Upscaler
|
|
@@ -726,7 +901,7 @@ engine.denoisingManager.setTemporalHistory(false) // live OIDN without th
|
|
|
726
901
|
engine.denoisingManager.continuousDenoiseInterval = 250 // cap refreshes at 4/sec (default 8 = uncapped)
|
|
727
902
|
engine.denoisingManager.setUpscalerEnabled(true)
|
|
728
903
|
engine.denoisingManager.setUpscalerScaleFactor(2) // 2 or 4
|
|
729
|
-
engine.denoisingManager.setUpscalerQuality('
|
|
904
|
+
engine.denoisingManager.setUpscalerQuality('quality') // 'fast' | 'balanced' | 'quality'
|
|
730
905
|
```
|
|
731
906
|
|
|
732
907
|
### engine.interactionManager
|
|
@@ -832,6 +1007,9 @@ surface** — pin a version and branch on the strings; they are never renamed or
|
|
|
832
1007
|
| `output.source_fallback` | `renderToBuffer( { source: 'display' } )` found no denoised picture and returned the raw accumulation |
|
|
833
1008
|
| `output.tonemap_fallback` | `renderToBuffer`'s `'srgb'` bytes were tone-mapped on the CPU, not the GPU — the picture is the same within a level, only slower (a warning: strict does not throw) |
|
|
834
1009
|
| `light.placeholder_skipped` | a `RectAreaLightPlaceholder` node lacked `userData.name` or `userData.type: 'RectAreaLight'`, so no light was made for it |
|
|
1010
|
+
| `capability.missing` | a feature was asked for whose add-on is not installed on the core (procedural sky, an unregistered integrator, a colour config, storage) — names the add-on |
|
|
1011
|
+
| `color.config_load_failed` / `viewTransform.bake_failed` / `viewTransform.display_mismatch` | a colour config failed to load (the previous one stays), a view could not be rebaked, or a view targets a display the canvas cannot show (a saved buffer is still right) — warnings |
|
|
1012
|
+
| `storage.unavailable` / `storage.quota_exceeded` / `storage.write_failed` / `storage.read_failed` / `storage.entry_corrupt` / `storage.cache_mismatch` | on-disk storage is off or failed; the engine carries on in memory — warnings |
|
|
835
1013
|
|
|
836
1014
|
`asset.unreachable` also covers what the engine fetches for itself: OIDN weights, IES profiles and
|
|
837
1015
|
gobos (`detail.asset` says which).
|
|
@@ -1101,7 +1279,9 @@ app.dispose();
|
|
|
1101
1279
|
JPEG or WebP to RGBA8, straight alpha, top row first — since the engine carries no decoder. It decodes
|
|
1102
1280
|
every glTF image, embedded or not, and JPEG/PNG skies. PNGs with bytes after `IEND`, which browsers
|
|
1103
1281
|
accept and strict decoders refuse, are trimmed first; a texture that still fails is recorded as
|
|
1104
|
-
`texture.build_failed` rather than dropped.
|
|
1282
|
+
`texture.build_failed` rather than dropped. Without `decodeImage`, each glTF image is recorded that way with what to
|
|
1283
|
+
configure (a strict host's load throws), and the model loads untextured. KTX2 (Basis) textures need no
|
|
1284
|
+
`decodeImage`: three's KTX2 loader decodes them, in a `NodeWorker` the engine lends it. Measured on a 91-texture model: `sharp` and
|
|
1105
1285
|
`@napi-rs/canvas` (`await loadImage()`, then a 2D canvas) both decode in parallel, ~0.3 s against
|
|
1106
1286
|
pngjs's 2.5 s serial. The canvas route premultiplies, which zeroes colour under alpha 0 and loses
|
|
1107
1287
|
it under low alpha; `sharp` is exact. `jpeg-js` differs from libjpeg-turbo by up to 63 levels.
|
|
@@ -1115,8 +1295,9 @@ app.dispose();
|
|
|
1115
1295
|
memory): on the main thread it held up the BVH workers, and a 1.9M-triangle, 91-texture model
|
|
1116
1296
|
loaded in 4.1–4.9 s. It now loads in 2.1 s, against Chrome's 2.9 s on the same machine.
|
|
1117
1297
|
- `nodePlatform()` also defines `ProgressEvent`, which three.js's `FileLoader` constructs while
|
|
1118
|
-
streaming; that is the only global it sets. three.js's own Draco and KTX2
|
|
1119
|
-
`Worker
|
|
1298
|
+
streaming; that is the only global it sets. three.js's own Draco and KTX2 loaders call the global
|
|
1299
|
+
`Worker`; the engine lends them `NodeWorker` for the length of each glTF parse, so a Draco or KTX2
|
|
1300
|
+
model loads with nothing set by the host.
|
|
1120
1301
|
|
|
1121
1302
|
Measured on this bench's corpus: all 29 scenes match the Chrome goldens (`npm run bench:node`, RMSE
|
|
1122
1303
|
≤ 0.0036, no pixel over 0.02 — the readback's tone map accounts for most of it), and a textured glTF with an
|
|
@@ -1151,6 +1332,8 @@ list. Both need `timestamp-query`, and `getDenoiseProfile()` returns `null` when
|
|
|
1151
1332
|
|
|
1152
1333
|
### On-disk Storage (OPFS)
|
|
1153
1334
|
|
|
1335
|
+
On `rayzee/core`, storage needs the `rayzee/addons/storage` add-on (`setStorageOpener`) — see [Renderer core](#renderer-core-rayzeecore).
|
|
1336
|
+
|
|
1154
1337
|
`engine.storage` is a `StorageManager` over the browser's origin private file system, or `null` where
|
|
1155
1338
|
there is none (a private window, Node) — everything works without it, only slower. The engine keeps
|
|
1156
1339
|
its caches there: downloads (models, skies, OIDN weights — revalidated at most daily with a 1-byte `Range` request, and served from the cache meanwhile),
|
|
@@ -1247,6 +1430,7 @@ engine.addEventListener(EngineEvents.RENDER_COMPLETE, (e) => {
|
|
|
1247
1430
|
| Event | Fired when |
|
|
1248
1431
|
|---|---|
|
|
1249
1432
|
| `RENDER_COMPLETE` | Rendering has converged |
|
|
1433
|
+
| `SHADERS_COMPILING` | The path tracer compiles its shaders in the background (`event.compiling` true, then false) — after a model load, a new material layer, a light transport switch. The page stays responsive; the canvas keeps its last frame until they are ready, and `renderFrames()` waits for them |
|
|
1250
1434
|
| `RENDER_RESET` | Accumulation buffer is reset |
|
|
1251
1435
|
| `FRAME` | Fires once per `animate()` tick — hook external instrumentation (stats panels, telemetry) here |
|
|
1252
1436
|
| `DENOISING_START` / `DENOISING_END` | Denoiser runs. `event.continuous` is `true` for a cadence denoise of the still-accumulating image, `false` for the one that ends a render |
|
|
@@ -1300,12 +1484,30 @@ class MyCustomStage extends RenderStage {
|
|
|
1300
1484
|
}
|
|
1301
1485
|
```
|
|
1302
1486
|
|
|
1487
|
+
To run between the path tracer and the compositor, subclass the renderer and return the stage from
|
|
1488
|
+
`_createExtraStages()` (call the parent's and add yours); for the compositor to show its picture, list
|
|
1489
|
+
`'my-stage:output'` in `_displaySources()`. `pipeline.addStage()` after `init()` appends after the
|
|
1490
|
+
compositor. A stage that needs an extra path-tracer output asks for it with
|
|
1491
|
+
`stages.pathTracer.requestOutput( name, options )` — `'gBuffer'` (the normal/depth and albedo a denoiser reads; the
|
|
1492
|
+
viewer asks for it itself) or `'hitDistance'`. Each is compiled into the path tracer only while asked for.
|
|
1493
|
+
|
|
1303
1494
|
### All Exports
|
|
1304
1495
|
|
|
1305
1496
|
```js
|
|
1306
|
-
//
|
|
1497
|
+
// The full engine (it also exports RayzeeRenderer)
|
|
1307
1498
|
import { PathTracerApp, EngineEvents, LEGACY_EVENT_NAMES } from 'rayzee';
|
|
1308
1499
|
|
|
1500
|
+
// The renderer core and its add-ons (see Renderer core)
|
|
1501
|
+
import { RayzeeRenderer } from 'rayzee/core';
|
|
1502
|
+
import { PhysicalSky } from 'rayzee/addons/physical-sky';
|
|
1503
|
+
import { ArchiveImporter } from 'rayzee/addons/archives';
|
|
1504
|
+
import { BidirectionalIntegrator } from 'rayzee/addons/bidirectional';
|
|
1505
|
+
import { ColorManagement } from 'rayzee/addons/color';
|
|
1506
|
+
import { acquireSharedStorage } from 'rayzee/addons/storage';
|
|
1507
|
+
|
|
1508
|
+
// Headless rendering (see Deterministic & Headless Rendering)
|
|
1509
|
+
import { renderHeadless, openHeadless, captureHeadless } from 'rayzee';
|
|
1510
|
+
|
|
1309
1511
|
// Platform services for hosts without a browser (see Running in Node)
|
|
1310
1512
|
import { configurePlatform, getPlatform } from 'rayzee';
|
|
1311
1513
|
import { nodePlatform, NodeWorker } from 'rayzee/node';
|
|
@@ -1430,7 +1632,7 @@ import { setBindingAudit, getBindingAuditFindings, clearBindingAuditFindings } f
|
|
|
1430
1632
|
OIDN provides high-quality AI denoising. It runs automatically once the render converges (reaches
|
|
1431
1633
|
`maxSamples`), and — in `'interactive'` mode — also on a cadence while the image is still
|
|
1432
1634
|
accumulating, so a preview shows a clean picture as it refines instead of only at the end. See
|
|
1433
|
-
[
|
|
1635
|
+
[When the denoiser runs](#when-the-denoiser-runs).
|
|
1434
1636
|
|
|
1435
1637
|
1. **Install the package**
|
|
1436
1638
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/Color/ActiveColor.js
|
|
2
|
+
var e = "Linear Rec.709 (sRGB)", t = null;
|
|
3
|
+
function n() {
|
|
4
|
+
return t;
|
|
5
|
+
}
|
|
6
|
+
function r(e) {
|
|
7
|
+
t = e, e?._publishWorkingMatrix?.();
|
|
8
|
+
}
|
|
9
|
+
function i(e) {
|
|
10
|
+
t === null && (t = e);
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { r as i, i as n, n as r, e as t };
|