rayzee 10.0.0 → 11.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 +252 -44
- package/dist/ActiveColor-YvuQq44O.js +13 -0
- package/dist/ArchiveImporter-Hn35o6Z5.js +5145 -0
- package/dist/AssetConfig-DSEntE65.js +30 -0
- package/dist/BidirectionalIntegrator-CBw8hkeu.js +946 -0
- package/dist/BufferLayout-D_IBo2ci.js +150 -0
- package/dist/ColorManagement-oeEk7oSu.js +1488 -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-dDDGj9Av.js +97 -0
- package/dist/{NeuralRetouch-CYgkQY8Z.js → NeuralRetouch-BzNpiVHZ.js} +8 -6
- package/dist/{NeuralSuperRes-PkgDLQcD.js → NeuralSuperRes-Bk7bHg2B.js} +55 -120
- package/dist/PathTracer-72XufKAr.js +29976 -0
- package/dist/PhysicalSky-BgjdV88k.js +1219 -0
- package/dist/RayzeeRenderer-1QRO97eq.js +3551 -0
- package/dist/SolarLimb-CPaeZVwz.js +721 -0
- package/dist/ToneMapGPU-CjU3osDd.js +177 -0
- package/dist/ViewTransforms-CYN7bq2w.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-tnAoUL1j.js +94 -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 +2551 -44024
- package/dist/rayzee.umd.js +528 -487
- package/dist/sceneCachePolicy-C67jbci-.js +443 -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/Color/ViewTransforms.js +5 -1
- package/src/EngineDefaults.js +62 -1029
- package/src/EngineEvents.js +2 -0
- package/src/EngineIssues.js +2 -0
- package/src/Headless.js +6 -5
- package/src/Passes/AIUpscaler.js +58 -141
- package/src/Passes/OIDNDenoiser.js +92 -65
- package/src/Passes/OIDNTemporalHistory.js +1 -1
- package/src/PathTracerApp.js +620 -4026
- package/src/Pipeline/PipelineContext.js +0 -4
- package/src/Platform.js +36 -0
- package/src/Processor/ArchiveCache.js +20 -7
- package/src/Processor/ArchiveImporter.js +1265 -0
- package/src/Processor/ArchiveReader.js +22 -4
- package/src/Processor/AssetLoader.js +327 -1763
- package/src/Processor/AtmosphereModel.js +1 -2
- package/src/Processor/BVHBuilder.js +14 -126
- package/src/Processor/BVHLeafFold.js +4 -6
- package/src/Processor/BVHRefitter.js +67 -46
- package/src/Processor/BufferLayout.js +291 -0
- package/src/Processor/EmissiveTriangleBuilder.js +1 -1
- 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 +15 -5
- package/src/Processor/HostMemory.js +7 -1
- package/src/Processor/IESParser.js +47 -35
- package/src/Processor/InstanceTable.js +1 -1
- package/src/Processor/KernelManager.js +35 -2
- package/src/Processor/MaterialPacking.js +10 -8
- package/src/Processor/PBRT/PBRTMaterials.js +254 -42
- package/src/Processor/PBRT/PBRTParser.js +49 -19
- package/src/Processor/PBRT/PBRTScattering.js +93 -0
- package/src/Processor/PBRT/PBRTSceneBuilder.js +1050 -75
- package/src/Processor/PBRT/PBRTTextureBake.js +179 -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 +39 -5
- package/src/Processor/ReinsertionOptimizer.js +2 -2
- package/src/Processor/SceneMetadata.js +30 -5
- package/src/Processor/SceneProcessor.js +53 -62
- package/src/Processor/ShaderBuilder.js +6 -16
- package/src/Processor/SimpleSky.js +1 -62
- package/src/Processor/SolarLimb.js +3 -0
- package/src/Processor/SplitBLAS.js +1 -1
- package/src/Processor/StorageTexturePool.js +22 -1
- package/src/Processor/TLASBuilder.js +1 -3
- package/src/Processor/TextureBuckets.js +237 -0
- package/src/Processor/TextureCreator.js +181 -8
- package/src/Processor/ToneMapGPU.js +64 -15
- package/src/Processor/Workers/BVHRefitWorker.js +5 -2
- 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/Workers/TexturesWorker.js +103 -18
- package/src/Processor/archiveFormats.js +7 -0
- package/src/Processor/utils.js +2 -1
- package/src/RayzeeRenderer.js +3900 -0
- package/src/RenderSettings.js +68 -62
- package/src/Stages/ASVGF.js +13 -14
- package/src/Stages/AutoExposure.js +17 -17
- package/src/Stages/BilateralFilter.js +2 -1
- package/src/Stages/Compositor.js +8 -23
- package/src/Stages/DenoiserSettings.js +182 -0
- package/src/Stages/EdgeFilter.js +2 -1
- package/src/Stages/MotionVector.js +1 -1
- package/src/Stages/NRD.js +11 -5
- package/src/Stages/NormalDepth.js +12 -8
- package/src/Stages/PathTracer.js +336 -43
- package/src/Stages/PathTracerStage.js +69 -66
- package/src/Stages/Variance.js +1 -1
- 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 +45 -9
- package/src/Storage/areas.js +4 -0
- package/src/TSL/BVHTraversal.js +50 -25
- package/src/TSL/Bidirectional.js +208 -0
- package/src/TSL/BidirectionalLamps.js +132 -0
- package/src/TSL/Clearcoat.js +15 -6
- package/src/TSL/Common.js +20 -15
- package/src/TSL/ConnectKernel.js +167 -0
- package/src/TSL/Debugger.js +1 -1
- package/src/TSL/Displacement.js +4 -3
- package/src/TSL/EmissiveSampling.js +65 -18
- 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 +180 -0
- package/src/TSL/LightVisibility.js +111 -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 +239 -51
- 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 +224 -0
- package/src/TSL/PathTracerCore.js +65 -29
- package/src/TSL/Random.js +5 -1
- package/src/TSL/SceneResources.js +51 -0
- package/src/TSL/ShadeKernel.js +985 -101
- package/src/TSL/Struct.js +10 -0
- package/src/TSL/Sun.js +1 -1
- package/src/TSL/TextureSampling.js +66 -61
- 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 +31 -0
- package/src/index.js +13 -23
- package/src/integrators/BidirectionalIntegrator.js +838 -0
- package/src/managers/AnimationManager.js +88 -6
- package/src/managers/CameraManager.js +103 -46
- package/src/managers/DenoisingManager.js +14 -10
- package/src/managers/EnvironmentManager.js +125 -103
- package/src/managers/GoboManager.js +9 -0
- package/src/managers/MaterialDataManager.js +48 -37
- package/src/managers/UniformManager.js +32 -10
- package/dist/ToneMapGPU-B6XIe3DU.js +0 -544
- 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?)
|
|
@@ -320,7 +325,6 @@ const engine = new PathTracerApp(canvas, options?)
|
|
|
320
325
|
| `options.autoResize` | `boolean` | Auto-resize on window resize (default: `true`; always off headless) |
|
|
321
326
|
| `options.container` | `HTMLElement` | Single DOM parent the engine mounts auxiliary elements into — HUD overlay (tile borders, helpers) and denoiser canvas. Defaults to `canvas.parentNode`. |
|
|
322
327
|
| `options.strict` | `boolean` | Throw an `EngineIssueError` where the engine would otherwise degrade and carry on (default: `false`). See [Degradation contract](#degradation-contract). |
|
|
323
|
-
| `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. |
|
|
324
328
|
| `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). |
|
|
325
329
|
| `options.hostMemoryGB` | `number` | The host's memory, for runtimes without Chrome's `navigator.deviceMemory` (which then read as 4 GB and cap the render reserve at 2048). Sizes the reserve and the path pool. |
|
|
326
330
|
| `options.storage` | `false \| 'auto' \| StorageManager` | On-disk storage (default: `configureAssets( { storage } )`; off under `strict` unless you set it there or here). A manager you pass stays yours to dispose. See [On-disk storage](#on-disk-storage-opfs). |
|
|
@@ -346,12 +350,15 @@ Constructing a new `PathTracerApp` on a canvas that already has an active instan
|
|
|
346
350
|
#### Loading Assets
|
|
347
351
|
|
|
348
352
|
```js
|
|
349
|
-
await engine.loadModel(url) // Load GLB/GLTF
|
|
353
|
+
await engine.loadModel(url) // Load a GLB/GLTF by URL
|
|
354
|
+
await engine.loadFile(fileOrUrl) // Any supported file: GLB/GLTF/FBX/OBJ/STL/PLY/DAE/3MF/USD/USDZ, archives, HDR/EXR
|
|
350
355
|
await engine.loadObject3D(object3d, name?) // Load a Three.js Object3D directly (name is optional, defaults to 'object3d')
|
|
351
356
|
await engine.loadEnvironment(url) // Load HDR/EXR environment map
|
|
352
357
|
engine.cancelLoad() // Abort an in-flight download (network phase only; no-op once processing starts)
|
|
353
358
|
```
|
|
354
359
|
|
|
360
|
+
On `rayzee/core`, formats other than glTF and `.hdr` need the `rayzee/addons/formats` add-on — see [Add-ons](#add-ons).
|
|
361
|
+
|
|
355
362
|
`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
363
|
|
|
357
364
|
```js
|
|
@@ -368,6 +375,8 @@ engine.setSceneObjectVisibility(id, visible) // Toggle visi
|
|
|
368
375
|
|
|
369
376
|
##### Loading part of a scene archive
|
|
370
377
|
|
|
378
|
+
On `rayzee/core`, archives and pbrt need the `rayzee/addons/archives` add-on — see [Renderer core](#renderer-core-rayzeecore).
|
|
379
|
+
|
|
371
380
|
A pbrt-v4 scene archive (`.tar`, `.tar.gz`, `.zip`) is usually a root `.pbrt` file that includes one
|
|
372
381
|
subtree per element, and the whole thing rarely fits in a browser tab — Moana is 29 GB unpacked.
|
|
373
382
|
The archive can be inspected without retaining any of it, then loaded one element at a time:
|
|
@@ -435,15 +444,19 @@ Key settings:
|
|
|
435
444
|
| `enableEnvironment` | `boolean` | true | Use environment lighting |
|
|
436
445
|
| `environmentIntensity` | `number` | 1.0 | Environment light strength |
|
|
437
446
|
| `environmentRotation` | `number` | 0 | Environment Y-rotation (degrees); 0 shows the HDRI as authored, as Blender's unmapped world does |
|
|
447
|
+
| `areaLightIntensityScale` | `number` | 0.1 | Power of a glTF model's placeholder area lights (RectAreaLight extras), read when the model loads, so set it first; 1 is the authored power |
|
|
448
|
+
| `maxTextureSize` | `number` | 4096 | Longest edge of a material texture, read when a model loads (clamped to the hardware ceiling); `setMaxTextureSize()` applies it to the current scene too |
|
|
449
|
+
| `wavefrontSortMaterials` | `boolean` | true | Sort rays by material before shading, above 8 materials; read when the shaders next build |
|
|
438
450
|
| `showBackground` | `boolean` | true | Show the environment as a visible backdrop for camera-miss rays (vs. a solid/transparent background) |
|
|
439
451
|
| `samplingTechnique` | `number` | 2 | Sampler: `0` PCG, `1` scrambled Halton, `2` Owen-scrambled Sobol |
|
|
452
|
+
| `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
453
|
| `fireflyThreshold` | `number` | 3.0 | Firefly clamping threshold |
|
|
441
454
|
| `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
455
|
| `transmissiveBounces` | `number` | 5 | Max bounces for transmissive materials |
|
|
443
456
|
| `maxSubsurfaceSteps` | `number` | 8 | Max random-walk steps for subsurface scattering (raised to 64 by `configureForMode('production')`) |
|
|
444
457
|
| `enableAlphaShadows` | `boolean` | false | Alpha-tested shadow rays (enabled by `configureForMode('production')`) |
|
|
445
458
|
| `enableDOF` | `boolean` | false | Enable depth of field |
|
|
446
|
-
| `dofMode` | `string` | 'look' | `'look'`: the blur is set by `dofBlur`, the same at any scene scale; `'physical'`: a real lens set by `aperture`, `focalLength` and `unitsPerMetre`.
|
|
459
|
+
| `dofMode` | `string` | 'look' | `'look'`: the blur is set by `dofBlur`, the same at any scene scale; `'physical'`: a real lens set by `aperture`, `focalLength` and `unitsPerMetre`. |
|
|
447
460
|
| `dofBlur` | `number` | 0.05 | Look mode: how far a distant background blurs, as a fraction of the image height |
|
|
448
461
|
| `focusDistance` | `number` | 0.8 | DOF focus distance in scene units — depth along the view axis (the focal plane is flat) |
|
|
449
462
|
| `aperture` | `number` | 5.6 | Physical mode: f-stop |
|
|
@@ -451,23 +464,23 @@ Key settings:
|
|
|
451
464
|
| `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
465
|
| `transparentBackground` | `boolean` | false | Transparent canvas background |
|
|
453
466
|
| `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 |
|
|
467
|
+
| `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
468
|
| `renderMode` | `number` | 0 | Internal preview(0)/production(1) flag driving accumulation & ASVGF behavior — normally set via `configureForMode()`, not written directly |
|
|
456
469
|
| `visMode` | `number` | 0 | Debug visualization mode (0 = off) |
|
|
457
|
-
| `environmentMode` | `string` | 'hdri' | Sky mode: `'hdri'` \| `'procedural'` \| `'
|
|
470
|
+
| `environmentMode` | `string` | 'hdri' | Sky mode: `'hdri'` \| `'procedural'` \| `'color'` — not routed through `engine.settings`; use `engine.environmentManager.setMode()` instead |
|
|
458
471
|
| `cameraProjection` | `string` | 'perspective' | `'perspective'` \| `'orthographic'` \| `'equirectangular'` — see [Camera Projection](#camera-projection-orthographic-360-panorama) |
|
|
459
472
|
| `panoramaLonRange` | `[number, number]` | `[-180, 180]` | Panorama longitude sweep, degrees, left→right |
|
|
460
473
|
| `panoramaLatRange` | `[number, number]` | `[-90, 90]` | Panorama latitude sweep, degrees, bottom→top |
|
|
461
474
|
| `panoramaLevelHorizon` | `boolean` | true | Yaw-only panorama basis, so orbit pitch/roll can't tilt the horizon |
|
|
462
475
|
| `useAdaptiveSampling` | `boolean` | true | Whole-frame early-stop once convergence reaches `adaptiveStopFraction` |
|
|
463
|
-
| `noiseThreshold` | `number` | 0.
|
|
476
|
+
| `noiseThreshold` | `number` | 0.1 | √-luminance-normalized per-pixel noise below which a pixel counts as converged (the production preset uses 0.02) |
|
|
464
477
|
| `adaptiveMinSamples` | `number` | 8 | Minimum samples before adaptive sampling can trigger |
|
|
465
|
-
| `adaptiveStopFraction` | `number` | 0.
|
|
478
|
+
| `adaptiveStopFraction` | `number` | 0.90 | Fraction of pixels that must converge before the frame retires (the production preset uses 0.94) |
|
|
466
479
|
| `usePixelFreeze` | `boolean` | true | Per-pixel freeze (Tier-2): skip individually-converged pixels via active-list compaction |
|
|
467
480
|
| `pixelFreezeThreshold` | `number` | 0.02 | Relative-error threshold for a pixel to become a freeze candidate |
|
|
468
481
|
| `pixelFreezeStability` | `number` | 8 | Consecutive candidate frames required before a pixel freezes |
|
|
469
482
|
|
|
470
|
-
See `ENGINE_DEFAULTS` for the full list with default values. The default look is AgX (`
|
|
483
|
+
See `ENGINE_DEFAULTS` for the full list with default values — every key in it is a setting of the same name. The default look is AgX (`DEFAULT_VIEW`) 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
484
|
|
|
472
485
|
#### Rendering Modes
|
|
473
486
|
|
|
@@ -480,6 +493,168 @@ To pause rendering for image-viewing UI, set `engine.pauseRendering = true` and
|
|
|
480
493
|
|
|
481
494
|
---
|
|
482
495
|
|
|
496
|
+
### Renderer core (`rayzee/core`)
|
|
497
|
+
|
|
498
|
+
`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.
|
|
499
|
+
|
|
500
|
+
```js
|
|
501
|
+
import { RayzeeRenderer } from 'rayzee/core';
|
|
502
|
+
|
|
503
|
+
const renderer = await new RayzeeRenderer(canvas).init();
|
|
504
|
+
await renderer.loadModel('/models/scene.glb');
|
|
505
|
+
renderer.camera.position.set(0, 2, 6); // the camera it renders from; reset() after moving it
|
|
506
|
+
renderer.camera.lookAt(0, 0, 0);
|
|
507
|
+
renderer.reset();
|
|
508
|
+
await renderer.renderFrames(256);
|
|
509
|
+
const image = await renderer.renderToBuffer({ colorSpace: 'srgb' });
|
|
510
|
+
renderer.dispose();
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
Two runnable examples live in the repository: `rayzee/examples/core-node.mjs` (the core alone, in Node, writing a PNG)
|
|
514
|
+
and `rayzee/examples/core-browser/` (the core plus the physical sky, accumulating on a canvas).
|
|
515
|
+
|
|
516
|
+
#### Add-ons
|
|
517
|
+
|
|
518
|
+
Six capabilities install on the core explicitly. `PathTracerApp` installs all six itself, so nothing in this
|
|
519
|
+
section applies to it.
|
|
520
|
+
|
|
521
|
+
| Add-on | Import | Install | When | Without it |
|
|
522
|
+
|---|---|---|---|---|
|
|
523
|
+
| 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 |
|
|
524
|
+
| Physical sky | `PhysicalSky` from `rayzee/addons/physical-sky` | `renderer.environmentManager.setProceduralSky(PhysicalSky)` | after `init()` | `'procedural'` mode records `capability.missing` (throws under `strict`) |
|
|
525
|
+
| 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 |
|
|
526
|
+
| 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 |
|
|
527
|
+
| 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 |
|
|
528
|
+
| On-disk storage | `acquireSharedStorage` from `rayzee/addons/storage` | `renderer.setStorageOpener(acquireSharedStorage)` | **before** `init()` | downloads land in memory and nothing is cached between visits |
|
|
529
|
+
|
|
530
|
+
`init()` creates the asset loader, the environment manager and the path tracer stage, which is why four of them come
|
|
531
|
+
after it. Storage is opened during `init()`, so its opener has to be set first.
|
|
532
|
+
|
|
533
|
+
All six, in that order:
|
|
534
|
+
|
|
535
|
+
```js
|
|
536
|
+
import { RayzeeRenderer, configureAssets } from 'rayzee/core';
|
|
537
|
+
import { acquireSharedStorage } from 'rayzee/addons/storage';
|
|
538
|
+
import { ColorManagement } from 'rayzee/addons/color';
|
|
539
|
+
import { ArchiveImporter } from 'rayzee/addons/archives';
|
|
540
|
+
import { PhysicalSky } from 'rayzee/addons/physical-sky';
|
|
541
|
+
import { BidirectionalIntegrator } from 'rayzee/addons/bidirectional';
|
|
542
|
+
import { allFormats } from 'rayzee/addons/formats';
|
|
543
|
+
|
|
544
|
+
configureAssets({ ocioRuntimeFactory: () => import('@bb-studio/ocio') });
|
|
545
|
+
|
|
546
|
+
const renderer = new RayzeeRenderer(canvas);
|
|
547
|
+
renderer.setStorageOpener(acquireSharedStorage); // before init()
|
|
548
|
+
renderer.setColorManagement(ColorManagement);
|
|
549
|
+
await renderer.init();
|
|
550
|
+
renderer.assetLoader.registerFormat(...allFormats);
|
|
551
|
+
renderer.assetLoader.setArchiveImporter(new ArchiveImporter(renderer.assetLoader));
|
|
552
|
+
renderer.environmentManager.setProceduralSky(PhysicalSky);
|
|
553
|
+
renderer.stages.pathTracer.registerIntegrator(['bidirectional', 'vcm'], pt => new BidirectionalIntegrator(pt));
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
**Loading on first use.** The physical sky and the archive importer can be installed as loaders instead, so their code
|
|
557
|
+
is fetched only the first time the sky is baked or an archive is read — `PathTracerApp` does this. The archive loader
|
|
558
|
+
takes the formats it reads, which `rayzee/core` exports, so the loader recognises an archive before its code exists:
|
|
559
|
+
|
|
560
|
+
```js
|
|
561
|
+
import { ARCHIVE_FORMATS } from 'rayzee/core';
|
|
562
|
+
|
|
563
|
+
renderer.environmentManager.setProceduralSkyLoader(() => import('rayzee/addons/physical-sky').then((m) => m.PhysicalSky));
|
|
564
|
+
renderer.assetLoader.setArchiveImporterLoader(
|
|
565
|
+
() => import('rayzee/addons/archives').then((m) => new m.ArchiveImporter(renderer.assetLoader)),
|
|
566
|
+
ARCHIVE_FORMATS,
|
|
567
|
+
);
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
Colour, storage and the integrators have no loader: colour and storage are used at startup, and an integrator applies
|
|
571
|
+
the moment it is chosen (a lazy one would trace plain frames meanwhile and break reproducible renders).
|
|
572
|
+
|
|
573
|
+
**File formats.** The core reads glTF/GLB (Draco, KTX2 and meshopt decoders are fetched only for a file that uses
|
|
574
|
+
them), `.hdr` and LDR images. FBX, OBJ, STL, PLY, Collada, 3MF, USD/USDZ and EXR are formats to register — import only
|
|
575
|
+
those you read and a bundler leaves the rest out; each three.js loader is downloaded the first time its format is read:
|
|
576
|
+
|
|
577
|
+
```js
|
|
578
|
+
import { objFormat, usdFormat, exrFormat } from 'rayzee/addons/formats';
|
|
579
|
+
|
|
580
|
+
renderer.assetLoader.registerFormat(objFormat, usdFormat, exrFormat);
|
|
581
|
+
await renderer.loadFile(objFile);
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
A format of your own registers the same way. A model format's `parse` gets the file and resolves to the model; an
|
|
585
|
+
environment format's `createLoader` returns a three.js loader whose `loadAsync` resolves to a texture:
|
|
586
|
+
|
|
587
|
+
```js
|
|
588
|
+
renderer.assetLoader.registerFormat({
|
|
589
|
+
name: 'Point cloud (XYZ)', label: 'XYZ', type: 'model', extensions: ['xyz'],
|
|
590
|
+
async parse(file, { filename }) {
|
|
591
|
+
return { model: buildPoints(await file.text(), filename) };
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
**Physical sky**, for `environmentMode: 'procedural'`:
|
|
597
|
+
|
|
598
|
+
```js
|
|
599
|
+
renderer.environmentManager.setProceduralSky(PhysicalSky);
|
|
600
|
+
await renderer.environmentManager.setMode('procedural');
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
**Bidirectional path tracing and vertex merging**, for `integrator: 'bidirectional' | 'vcm'`:
|
|
604
|
+
|
|
605
|
+
```js
|
|
606
|
+
renderer.stages.pathTracer.registerIntegrator(['bidirectional', 'vcm'], pt => new BidirectionalIntegrator(pt));
|
|
607
|
+
renderer.settings.set('integrator', 'bidirectional');
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
Its controls are on the active integrator (the same on `PathTracerApp`):
|
|
611
|
+
|
|
612
|
+
```js
|
|
613
|
+
const integrator = renderer.stages.pathTracer.activeIntegrator;
|
|
614
|
+
integrator.setMergeRadius(1); // 'vcm': gather radius in pixels
|
|
615
|
+
integrator.setMergeTrust(0.25); // 'vcm': how far merging is trusted against the other strategies
|
|
616
|
+
integrator.setLightGuiding(true); // learn where light paths from the sky and sun start
|
|
617
|
+
integrator.setBidirectionalStrategy('connect', { alone: true }); // keep one strategy, for verification
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
**Scene archives** (`.zip`, `.tar`, `.tar.gz`) and the pbrt scenes in them:
|
|
621
|
+
|
|
622
|
+
```js
|
|
623
|
+
renderer.assetLoader.setArchiveImporter(new ArchiveImporter(renderer.assetLoader));
|
|
624
|
+
await renderer.loadFile(archiveFile);
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
**OpenColorIO colour management** — configs, their views and looks, working spaces and export spaces. The host supplies
|
|
628
|
+
the OCIO runtime (the engine never names the package). Without the add-on, pick a tone mapper on the three.js renderer
|
|
629
|
+
instead (`renderer.renderer.toneMapping = AgXToneMapping`):
|
|
630
|
+
|
|
631
|
+
```js
|
|
632
|
+
configureAssets({ ocioRuntimeFactory: () => import('@bb-studio/ocio') });
|
|
633
|
+
renderer.setColorManagement(ColorManagement);
|
|
634
|
+
await renderer.loadColorConfig({ builtin: 'ocio://cg-config-v4.0.0_aces-v2.0_ocio-v2.5' });
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
**On-disk storage** (the browser's origin private file system), for the download, environment and scene caches and
|
|
638
|
+
the `memorySpill` option. Asking for it without the add-on (`storage: 'auto'`) records a `capability.missing` warning;
|
|
639
|
+
`storage: false` turns it off either way:
|
|
640
|
+
|
|
641
|
+
```js
|
|
642
|
+
const renderer = new RayzeeRenderer(canvas);
|
|
643
|
+
renderer.setStorageOpener(acquireSharedStorage);
|
|
644
|
+
await renderer.init();
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
Several renderers, core or full, can live in one page; they share only the colour management and the on-disk storage,
|
|
648
|
+
which are page-wide.
|
|
649
|
+
|
|
650
|
+
Code of your own that adds a setting declares it on the renderer's settings, with its default, so it gets the same
|
|
651
|
+
provenance, change events and session saving as the built-in ones:
|
|
652
|
+
|
|
653
|
+
```js
|
|
654
|
+
renderer.settings.define('myGlowStrength', { default: 1, apply: (value) => glow.setStrength(value), reset: true });
|
|
655
|
+
renderer.settings.set('myGlowStrength', 2);
|
|
656
|
+
```
|
|
657
|
+
|
|
483
658
|
### engine.cameraManager
|
|
484
659
|
|
|
485
660
|
Camera switching, auto-focus, DOF, and direct Three.js access.
|
|
@@ -617,7 +792,8 @@ engine.stages.pathTracer.materialData.updateMaterial(index, mat) // Replace a m
|
|
|
617
792
|
await engine.rebuildMaterials(scene) // Full rebuild (after texture changes)
|
|
618
793
|
|
|
619
794
|
// Cap the longest edge of processed material textures (clamped to the hardware max).
|
|
620
|
-
// Larger = sharper textures, ~quadratic VRAM. Reprocesses the current scene by default
|
|
795
|
+
// Larger = sharper textures, ~quadratic VRAM. Reprocesses the current scene by default;
|
|
796
|
+
// settings.set('maxTextureSize', n) stores it for the next load instead.
|
|
621
797
|
await engine.setMaxTextureSize(2048)
|
|
622
798
|
await engine.setMaxTextureSize(4096, { reprocess: false })
|
|
623
799
|
|
|
@@ -641,6 +817,8 @@ A property a three.js material lacks falls back to `MATERIAL_DEFAULTS` (exported
|
|
|
641
817
|
|
|
642
818
|
### Colour Management
|
|
643
819
|
|
|
820
|
+
On `rayzee/core` this is the `rayzee/addons/color` add-on — see [Renderer core](#renderer-core-rayzeecore).
|
|
821
|
+
|
|
644
822
|
`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
823
|
|
|
646
824
|
```js
|
|
@@ -678,9 +856,8 @@ engine.environmentManager.params // Current environment parameters
|
|
|
678
856
|
engine.environmentManager.texture // The loaded environment texture
|
|
679
857
|
await engine.loadEnvironment(url) // Load HDR/EXR environment map (method on engine)
|
|
680
858
|
await engine.environmentManager.setEnvironmentMap(tex) // Set a custom environment texture
|
|
681
|
-
await engine.environmentManager.setMode(mode) // 'hdri' | 'procedural' | '
|
|
682
|
-
await engine.environmentManager.generateProcedural() // Physical sky: spectral, multiple scattering, analytic sun
|
|
683
|
-
await engine.environmentManager.generateGradient() // Gradient sky
|
|
859
|
+
await engine.environmentManager.setMode(mode) // 'hdri' | 'procedural' | 'color'
|
|
860
|
+
await engine.environmentManager.generateProcedural() // Physical sky: spectral, multiple scattering, analytic sun (core: needs rayzee/addons/physical-sky)
|
|
684
861
|
await engine.environmentManager.generateSolid() // Solid color sky
|
|
685
862
|
engine.environmentManager.markDirty() // Flag environment for GPU re-upload
|
|
686
863
|
```
|
|
@@ -708,15 +885,15 @@ Denoiser strategy, ASVGF, OIDN, upscaler, and auto-exposure.
|
|
|
708
885
|
|
|
709
886
|
```js
|
|
710
887
|
// Strategy
|
|
711
|
-
engine.denoisingManager.setStrategy('asvgf', 'medium') // 'none' | 'asvgf' | 'edgeaware'
|
|
888
|
+
engine.denoisingManager.setStrategy('asvgf', 'medium') // 'none' | 'asvgf' | 'nrd' | 'edgeaware' | 'oidn'
|
|
712
889
|
engine.denoisingManager.denoiserStrategy // read back the active strategy (derived from stage state)
|
|
713
890
|
engine.denoisingManager.setASVGFEnabled(true, 'medium')
|
|
714
891
|
engine.denoisingManager.applyASVGFPreset('high') // 'low' | 'medium' | 'high'
|
|
715
892
|
engine.denoisingManager.setAutoExposure(true)
|
|
716
893
|
|
|
717
894
|
// Fine-grained parameters
|
|
718
|
-
engine.denoisingManager.setASVGFParams({ temporalAlpha: 0.1,
|
|
719
|
-
engine.denoisingManager.setEdgeAwareParams({
|
|
895
|
+
engine.denoisingManager.setASVGFParams({ temporalAlpha: 0.1, maxAccumFrames: 16 })
|
|
896
|
+
engine.denoisingManager.setEdgeAwareParams({ phiLuminance: 4.0, atrousIterations: 5 })
|
|
720
897
|
engine.denoisingManager.setAutoExposureParams({ keyValue: 0.18 })
|
|
721
898
|
|
|
722
899
|
// OIDN & Upscaler
|
|
@@ -727,7 +904,7 @@ engine.denoisingManager.setTemporalHistory(false) // live OIDN without th
|
|
|
727
904
|
engine.denoisingManager.continuousDenoiseInterval = 250 // cap refreshes at 4/sec (default 8 = uncapped)
|
|
728
905
|
engine.denoisingManager.setUpscalerEnabled(true)
|
|
729
906
|
engine.denoisingManager.setUpscalerScaleFactor(2) // 2 or 4
|
|
730
|
-
engine.denoisingManager.setUpscalerQuality('
|
|
907
|
+
engine.denoisingManager.setUpscalerQuality('quality') // 'fast' | 'balanced' | 'quality'
|
|
731
908
|
```
|
|
732
909
|
|
|
733
910
|
### engine.interactionManager
|
|
@@ -831,7 +1008,11 @@ surface** — pin a version and branch on the strings; they are never renamed or
|
|
|
831
1008
|
| `refit.shared_geometry` | a deform was asked for on a mesh that shares its triangles, and was skipped |
|
|
832
1009
|
| `denoiser.unavailable` | a requested denoise or upscale produced nothing — the denoiser was not built, OIDN was off while accumulating, or the pass needs a canvas in a document |
|
|
833
1010
|
| `output.source_fallback` | `renderToBuffer( { source: 'display' } )` found no denoised picture and returned the raw accumulation |
|
|
1011
|
+
| `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
1012
|
| `light.placeholder_skipped` | a `RectAreaLightPlaceholder` node lacked `userData.name` or `userData.type: 'RectAreaLight'`, so no light was made for it |
|
|
1013
|
+
| `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 |
|
|
1014
|
+
| `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 |
|
|
1015
|
+
| `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
1016
|
|
|
836
1017
|
`asset.unreachable` also covers what the engine fetches for itself: OIDN weights, IES profiles and
|
|
837
1018
|
gobos (`detail.asset` says which).
|
|
@@ -1021,7 +1202,7 @@ auto-exposure, if you turn it on.
|
|
|
1021
1202
|
#### Batch rendering
|
|
1022
1203
|
|
|
1023
1204
|
The supported entry point for a render farm is `rayzee/src/Headless.js`, exported from the package.
|
|
1024
|
-
Its defaults are a batch renderer's — `strict`,
|
|
1205
|
+
Its defaults are a batch renderer's — `strict`, deterministic, storage off —
|
|
1025
1206
|
so a degraded render throws instead of shipping:
|
|
1026
1207
|
|
|
1027
1208
|
```js
|
|
@@ -1045,19 +1226,26 @@ it back with `renderToBuffer( { source: 'display' } )`. Driving it yourself is t
|
|
|
1045
1226
|
`'display'` was asked for, a denoiser is in use, and nothing had published — so a strict host cannot
|
|
1046
1227
|
ship a noisy image by mistake. Its `'srgb'` bytes are tone-mapped on the GPU — 9 ms at 4096×2160,
|
|
1047
1228
|
where the CPU pass it replaced took 1.4 s on an M-series Mac and 10 s on a cloud host — and match the
|
|
1048
|
-
canvas to within one level (it rounds half a level up); `'linear'` is exact.
|
|
1229
|
+
canvas to within one level (it rounds half a level up); `'linear'` is exact. When the GPU pass is
|
|
1230
|
+
unavailable or fails, the CPU does it instead: the result's `toneMappedOn` says `'cpu'` rather than
|
|
1231
|
+
`'gpu'`, and `output.tonemap_fallback` is recorded with the reason.
|
|
1049
1232
|
|
|
1050
1233
|
Constructing `PathTracerApp` yourself instead: pass `strict: true`; storage is then off unless you
|
|
1051
1234
|
set it. Outside Chrome, pass `hostMemoryGB`.
|
|
1052
1235
|
|
|
1236
|
+
The engine has one set of defaults, the viewer's. For lens-accurate depth of field and glTF placeholder area
|
|
1237
|
+
lights at their authored power, set `dofMode: 'physical'` and `areaLightIntensityScale: 1` — through `settings`
|
|
1238
|
+
here, or `engine.settings` before loading the model.
|
|
1239
|
+
|
|
1053
1240
|
**Provenance.** `engine.getProvenance()` — also `frame.provenance` from `captureHeadless` — is plain
|
|
1054
|
-
JSON naming what produced the image: engine and three.js versions, the
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
render and "what made this?" has an answer without rendering
|
|
1241
|
+
JSON naming what produced the image: engine and three.js versions, the adapter, every live setting with its source, the colour pipeline, the render size and
|
|
1242
|
+
samples, and whether it ran headless, strict, deterministic or lockstepped. `mode.lockstep` says
|
|
1243
|
+
whether the current image was traced in lockstep, so it stays true after `renderUntilComplete` turns
|
|
1244
|
+
lockstep back off. Store it beside each render and "what made this?" has an answer without rendering
|
|
1245
|
+
again.
|
|
1058
1246
|
|
|
1059
1247
|
**Pinning a look.** A change to what a render looks like when a host sets nothing — a default
|
|
1060
|
-
setting, a mode preset,
|
|
1248
|
+
setting, a mode preset, light units — is released as a **major**, with the
|
|
1061
1249
|
change described under BREAKING CHANGES in the release notes. Pin a major to pin a look; read the
|
|
1062
1250
|
notes before moving to the next one.
|
|
1063
1251
|
|
|
@@ -1097,7 +1285,9 @@ app.dispose();
|
|
|
1097
1285
|
JPEG or WebP to RGBA8, straight alpha, top row first — since the engine carries no decoder. It decodes
|
|
1098
1286
|
every glTF image, embedded or not, and JPEG/PNG skies. PNGs with bytes after `IEND`, which browsers
|
|
1099
1287
|
accept and strict decoders refuse, are trimmed first; a texture that still fails is recorded as
|
|
1100
|
-
`texture.build_failed` rather than dropped.
|
|
1288
|
+
`texture.build_failed` rather than dropped. Without `decodeImage`, each glTF image is recorded that way with what to
|
|
1289
|
+
configure (a strict host's load throws), and the model loads untextured. KTX2 (Basis) textures need no
|
|
1290
|
+
`decodeImage`: three's KTX2 loader decodes them, in a `NodeWorker` the engine lends it. Measured on a 91-texture model: `sharp` and
|
|
1101
1291
|
`@napi-rs/canvas` (`await loadImage()`, then a 2D canvas) both decode in parallel, ~0.3 s against
|
|
1102
1292
|
pngjs's 2.5 s serial. The canvas route premultiplies, which zeroes colour under alpha 0 and loses
|
|
1103
1293
|
it under low alpha; `sharp` is exact. `jpeg-js` differs from libjpeg-turbo by up to 63 levels.
|
|
@@ -1111,12 +1301,13 @@ app.dispose();
|
|
|
1111
1301
|
memory): on the main thread it held up the BVH workers, and a 1.9M-triangle, 91-texture model
|
|
1112
1302
|
loaded in 4.1–4.9 s. It now loads in 2.1 s, against Chrome's 2.9 s on the same machine.
|
|
1113
1303
|
- `nodePlatform()` also defines `ProgressEvent`, which three.js's `FileLoader` constructs while
|
|
1114
|
-
streaming; that is the only global it sets. three.js's own Draco and KTX2
|
|
1115
|
-
`Worker
|
|
1304
|
+
streaming; that is the only global it sets. three.js's own Draco and KTX2 loaders call the global
|
|
1305
|
+
`Worker`; the engine lends them `NodeWorker` for the length of each glTF parse, so a Draco or KTX2
|
|
1306
|
+
model loads with nothing set by the host.
|
|
1116
1307
|
|
|
1117
1308
|
Measured on this bench's corpus: all 29 scenes match the Chrome goldens (`npm run bench:node`, RMSE
|
|
1118
1309
|
≤ 0.0036, no pixel over 0.02 — the readback's tone map accounts for most of it), and a textured glTF with an
|
|
1119
|
-
HDR
|
|
1310
|
+
HDR or a PNG sky matches Chrome block for block within 0.05 of a level. Not available
|
|
1120
1311
|
without a browser: on-disk storage (OPFS), gobo libraries (they draw on a 2D canvas), and the AI
|
|
1121
1312
|
upscaler.
|
|
1122
1313
|
|
|
@@ -1147,6 +1338,8 @@ list. Both need `timestamp-query`, and `getDenoiseProfile()` returns `null` when
|
|
|
1147
1338
|
|
|
1148
1339
|
### On-disk Storage (OPFS)
|
|
1149
1340
|
|
|
1341
|
+
On `rayzee/core`, storage needs the `rayzee/addons/storage` add-on (`setStorageOpener`) — see [Renderer core](#renderer-core-rayzeecore).
|
|
1342
|
+
|
|
1150
1343
|
`engine.storage` is a `StorageManager` over the browser's origin private file system, or `null` where
|
|
1151
1344
|
there is none (a private window, Node) — everything works without it, only slower. The engine keeps
|
|
1152
1345
|
its caches there: downloads (models, skies, OIDN weights — revalidated at most daily with a 1-byte `Range` request, and served from the cache meanwhile),
|
|
@@ -1243,6 +1436,7 @@ engine.addEventListener(EngineEvents.RENDER_COMPLETE, (e) => {
|
|
|
1243
1436
|
| Event | Fired when |
|
|
1244
1437
|
|---|---|
|
|
1245
1438
|
| `RENDER_COMPLETE` | Rendering has converged |
|
|
1439
|
+
| `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 |
|
|
1246
1440
|
| `RENDER_RESET` | Accumulation buffer is reset |
|
|
1247
1441
|
| `FRAME` | Fires once per `animate()` tick — hook external instrumentation (stats panels, telemetry) here |
|
|
1248
1442
|
| `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 |
|
|
@@ -1296,12 +1490,30 @@ class MyCustomStage extends RenderStage {
|
|
|
1296
1490
|
}
|
|
1297
1491
|
```
|
|
1298
1492
|
|
|
1493
|
+
To run between the path tracer and the compositor, subclass the renderer and return the stage from
|
|
1494
|
+
`_createExtraStages()` (call the parent's and add yours); for the compositor to show its picture, list
|
|
1495
|
+
`'my-stage:output'` in `_displaySources()`. `pipeline.addStage()` after `init()` appends after the
|
|
1496
|
+
compositor. A stage that needs an extra path-tracer output asks for it with
|
|
1497
|
+
`stages.pathTracer.requestOutput( name, options )` — `'gBuffer'` (the normal/depth and albedo a denoiser reads; the
|
|
1498
|
+
viewer asks for it itself) or `'hitDistance'`. Each is compiled into the path tracer only while asked for.
|
|
1499
|
+
|
|
1299
1500
|
### All Exports
|
|
1300
1501
|
|
|
1301
1502
|
```js
|
|
1302
|
-
//
|
|
1503
|
+
// The full engine (it also exports RayzeeRenderer)
|
|
1303
1504
|
import { PathTracerApp, EngineEvents, LEGACY_EVENT_NAMES } from 'rayzee';
|
|
1304
1505
|
|
|
1506
|
+
// The renderer core and its add-ons (see Renderer core)
|
|
1507
|
+
import { RayzeeRenderer } from 'rayzee/core';
|
|
1508
|
+
import { PhysicalSky } from 'rayzee/addons/physical-sky';
|
|
1509
|
+
import { ArchiveImporter } from 'rayzee/addons/archives';
|
|
1510
|
+
import { BidirectionalIntegrator } from 'rayzee/addons/bidirectional';
|
|
1511
|
+
import { ColorManagement } from 'rayzee/addons/color';
|
|
1512
|
+
import { acquireSharedStorage } from 'rayzee/addons/storage';
|
|
1513
|
+
|
|
1514
|
+
// Headless rendering (see Deterministic & Headless Rendering)
|
|
1515
|
+
import { renderHeadless, openHeadless, captureHeadless } from 'rayzee';
|
|
1516
|
+
|
|
1305
1517
|
// Platform services for hosts without a browser (see Running in Node)
|
|
1306
1518
|
import { configurePlatform, getPlatform } from 'rayzee';
|
|
1307
1519
|
import { nodePlatform, NodeWorker } from 'rayzee/node';
|
|
@@ -1309,22 +1521,18 @@ import { nodePlatform, NodeWorker } from 'rayzee/node';
|
|
|
1309
1521
|
// Configuration & presets
|
|
1310
1522
|
import {
|
|
1311
1523
|
ENGINE_DEFAULTS,
|
|
1524
|
+
DENOISER_DEFAULTS,
|
|
1525
|
+
AUTO_EXPOSURE_DEFAULTS,
|
|
1526
|
+
AUTO_FOCUS_DEFAULTS,
|
|
1312
1527
|
ASVGF_QUALITY_PRESETS,
|
|
1313
|
-
|
|
1314
|
-
CAMERA_RANGES,
|
|
1315
|
-
SKY_PRESETS,
|
|
1528
|
+
SKY_DEFAULTS,
|
|
1316
1529
|
DEFAULT_SUN_PATH,
|
|
1317
|
-
|
|
1318
|
-
AF_DEFAULTS,
|
|
1530
|
+
DEFAULT_VIEW,
|
|
1319
1531
|
TRIANGLE_DATA_LAYOUT,
|
|
1320
1532
|
BVH_LEAF_MARKERS,
|
|
1321
|
-
TEXTURE_CONSTANTS,
|
|
1322
|
-
DEFAULT_TEXTURE_MATRIX,
|
|
1323
|
-
MEMORY_CONSTANTS,
|
|
1324
1533
|
PRODUCTION_RENDER_CONFIG,
|
|
1325
1534
|
INTERACTIVE_RENDER_CONFIG,
|
|
1326
1535
|
MAX_RESERVABLE_RENDER_SIZE,
|
|
1327
|
-
RENDER_PROFILES,
|
|
1328
1536
|
MATERIAL_DEFAULTS,
|
|
1329
1537
|
} from 'rayzee';
|
|
1330
1538
|
|
|
@@ -1426,7 +1634,7 @@ import { setBindingAudit, getBindingAuditFindings, clearBindingAuditFindings } f
|
|
|
1426
1634
|
OIDN provides high-quality AI denoising. It runs automatically once the render converges (reaches
|
|
1427
1635
|
`maxSamples`), and — in `'interactive'` mode — also on a cadence while the image is still
|
|
1428
1636
|
accumulating, so a preview shows a clean picture as it refines instead of only at the end. See
|
|
1429
|
-
[
|
|
1637
|
+
[When the denoiser runs](#when-the-denoiser-runs).
|
|
1430
1638
|
|
|
1431
1639
|
1. **Install the package**
|
|
1432
1640
|
|
|
@@ -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 };
|