rayzee 8.5.0 → 8.6.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 +60 -4
- package/dist/{DLSSNeural-BNSJ8V3z.js → DLSSNeural-BhBCBgKf.js} +5 -5
- package/dist/{DLSSSuperRes-BoEW89Cl.js → DLSSSuperRes-BCA7F_k5.js} +5 -5
- package/dist/ToneMapGPU-BzcLheoR.js +533 -0
- package/dist/rayzee.es.js +27198 -9047
- package/dist/rayzee.umd.js +255 -187
- package/package.json +1 -1
- package/src/AssetConfig.js +15 -2
- package/src/Color/BakedViews.js +134 -0
- package/src/Color/BuiltinViews.js +261 -0
- package/src/Color/ColorManagement.js +1130 -0
- package/src/Color/ColorSpaces.js +432 -0
- package/src/Color/Displays.js +19 -0
- package/src/Color/InputColorSpaces.js +243 -0
- package/src/Color/LutBake.js +371 -0
- package/src/Color/OcioRuntime.js +338 -0
- package/src/Color/OcioViews.js +419 -0
- package/src/Color/ViewTransforms.js +323 -0
- package/src/Color/WorkingMatrix.js +86 -0
- package/src/EngineDefaults.js +55 -3
- package/src/EngineIssues.js +3 -0
- package/src/Passes/AIUpscaler.js +16 -7
- package/src/PathTracerApp.js +227 -7
- package/src/Processor/AssetLoader.js +1 -2
- package/src/Processor/EmissiveTriangleBuilder.js +34 -2
- package/src/Processor/GeometryExtractor.js +151 -138
- package/src/Processor/LightSerializer.js +8 -3
- package/src/Processor/MaterialPacking.js +168 -0
- package/src/Processor/PackedRayBuffer.js +6 -2
- package/src/Processor/ProceduralSky.js +4 -0
- package/src/Processor/SceneProcessor.js +25 -1
- package/src/Processor/SimpleSky.js +8 -0
- package/src/Processor/TextureCreator.js +137 -91
- package/src/Processor/TextureReadback.js +92 -0
- package/src/Processor/ToneMapCPU.js +80 -165
- package/src/Processor/ToneMapGPU.js +122 -151
- package/src/RenderSettings.js +1 -0
- package/src/Stages/Compositor.js +11 -2
- package/src/Stages/PathTracer.js +2 -0
- package/src/Stages/PathTracerStage.js +1 -1
- package/src/TSL/Common.js +15 -0
- package/src/TSL/Debugger.js +2 -3
- package/src/TSL/EmissiveSampling.js +6 -8
- package/src/TSL/ExtendKernel.js +9 -0
- package/src/TSL/Fresnel.js +23 -1
- package/src/TSL/HitFacet.js +102 -0
- package/src/TSL/LightsDirect.js +12 -33
- package/src/TSL/LightsSampling.js +15 -7
- package/src/TSL/MaterialEvaluation.js +26 -19
- package/src/TSL/MaterialProperties.js +74 -37
- package/src/TSL/MaterialTransmission.js +2 -3
- package/src/TSL/ShadeKernel.js +34 -21
- package/src/TSL/ShadowTerminator.js +125 -0
- package/src/TSL/Struct.js +9 -0
- package/src/TSL/Subsurface.js +2 -3
- package/src/index.js +29 -1
- package/src/managers/EnvironmentManager.js +20 -0
- package/src/managers/MaterialDataManager.js +118 -208
- package/src/managers/UniformManager.js +1 -0
- package/dist/ToneMapGPU-DzqSyzTx.js +0 -341
package/README.md
CHANGED
|
@@ -26,6 +26,7 @@ A real-time WebGPU path tracing engine built on Three.js. Framework-agnostic —
|
|
|
26
26
|
- [engine.lightManager](#enginelightmanager)
|
|
27
27
|
- [engine.animationManager](#engineanimationmanager)
|
|
28
28
|
- [Materials](#materials)
|
|
29
|
+
- [Colour Management](#colour-management)
|
|
29
30
|
- [engine.environmentManager](#engineenvironmentmanager)
|
|
30
31
|
- [engine.denoisingManager](#enginedenoisingmanager)
|
|
31
32
|
- [engine.interactionManager](#engineinteractionmanager)
|
|
@@ -292,6 +293,11 @@ configureAssets({
|
|
|
292
293
|
dlssRuntimeUrl: '/dlss/dlss-runtime.js',
|
|
293
294
|
dlssAssetBaseUrl: '/dlss/',
|
|
294
295
|
|
|
296
|
+
// OpenColorIO runtime (~6 MB of WebAssembly) — the engine never names the package, so a host
|
|
297
|
+
// that loads colour configs supplies it, bundled or served. Unset, colour management stays inert.
|
|
298
|
+
ocioRuntimeFactory: () => import('@bb-studio/ocio'), // or: ocioRuntimeUrl: '/vendor/ocio/index.js'
|
|
299
|
+
ocioWasmUrl: '/vendor/ocio/ocio-wasm.wasm', // optional override for the .wasm
|
|
300
|
+
|
|
295
301
|
// Prefix for engine-managed IndexedDB stores. Set to a unique value if multiple
|
|
296
302
|
// apps embed the engine on the same origin to avoid cache collisions.
|
|
297
303
|
cacheNamespace: 'my-app',
|
|
@@ -414,13 +420,14 @@ Key settings:
|
|
|
414
420
|
| `maxBounces` | `number` | 3 | Max ray bounce depth |
|
|
415
421
|
| `maxSamples` | `number` | 60 | Max accumulated samples before stopping |
|
|
416
422
|
| `exposure` | `number` | 1.0 | Exposure value |
|
|
417
|
-
| `saturation` | `number` | 1.
|
|
423
|
+
| `saturation` | `number` | 1.0 | Color saturation (1 = no grade) |
|
|
418
424
|
| `enableEnvironment` | `boolean` | true | Use environment lighting |
|
|
419
425
|
| `environmentIntensity` | `number` | 1.0 | Environment light strength |
|
|
420
|
-
| `environmentRotation` | `number` |
|
|
426
|
+
| `environmentRotation` | `number` | 0 | Environment Y-rotation (degrees); 0 shows the HDRI as authored, as Blender's unmapped world does |
|
|
421
427
|
| `showBackground` | `boolean` | true | Show the environment as a visible backdrop for camera-miss rays (vs. a solid/transparent background) |
|
|
422
428
|
| `samplingTechnique` | `number` | 2 | Sampler: `0` PCG, `1` scrambled Halton, `2` Owen-scrambled Sobol |
|
|
423
429
|
| `fireflyThreshold` | `number` | 3.0 | Firefly clamping threshold |
|
|
430
|
+
| `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 |
|
|
424
431
|
| `transmissiveBounces` | `number` | 5 | Max bounces for transmissive materials |
|
|
425
432
|
| `maxSubsurfaceSteps` | `number` | 8 | Max random-walk steps for subsurface scattering (raised to 64 by `configureForMode('production')`) |
|
|
426
433
|
| `enableAlphaShadows` | `boolean` | false | Alpha-tested shadow rays (enabled by `configureForMode('production')`) |
|
|
@@ -429,7 +436,8 @@ Key settings:
|
|
|
429
436
|
| `aperture` | `number` | 5.6 | DOF aperture (f-stop) |
|
|
430
437
|
| `focalLength` | `number` | 50 | DOF focal length (mm) |
|
|
431
438
|
| `transparentBackground` | `boolean` | false | Transparent canvas background |
|
|
432
|
-
| `interactionModeEnabled` | `boolean` | true |
|
|
439
|
+
| `interactionModeEnabled` | `boolean` | true | Render at lower resolution while the camera moves, keeping the full bounce budget ("Fast Navigation" in the app) |
|
|
440
|
+
| `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 |
|
|
433
441
|
| `renderMode` | `number` | 0 | Internal preview(0)/production(1) flag driving accumulation & ASVGF behavior — normally set via `configureForMode()`, not written directly |
|
|
434
442
|
| `visMode` | `number` | 0 | Debug visualization mode (0 = off) |
|
|
435
443
|
| `environmentMode` | `string` | 'hdri' | Sky mode: `'hdri'` \| `'procedural'` \| `'gradient'` \| `'color'` — not routed through `engine.settings`; use `engine.environmentManager.setMode()` instead |
|
|
@@ -445,7 +453,7 @@ Key settings:
|
|
|
445
453
|
| `pixelFreezeThreshold` | `number` | 0.02 | Relative-error threshold for a pixel to become a freeze candidate |
|
|
446
454
|
| `pixelFreezeStability` | `number` | 8 | Consecutive candidate frames required before a pixel freezes |
|
|
447
455
|
|
|
448
|
-
See `ENGINE_DEFAULTS` for the full list with default values.
|
|
456
|
+
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`.
|
|
449
457
|
|
|
450
458
|
#### Rendering Modes
|
|
451
459
|
|
|
@@ -552,8 +560,43 @@ engine.updateAllMeshVisibility() // re-sync after manual object
|
|
|
552
560
|
|
|
553
561
|
// Read access to the active scene (returns the mesh-bearing scene)
|
|
554
562
|
engine.getScene()
|
|
563
|
+
|
|
564
|
+
// Where a packed value came from: 'material' | 'mapped' | 'default' | 'host'
|
|
565
|
+
engine.getMaterialPropertySource(index, 'ior')
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
A property a three.js material lacks falls back to `MATERIAL_DEFAULTS` (exported) — MeshPhysicalMaterial's own values, so a glTF metallic material gets IOR 1.5, not a guess derived from its metalness. Weights and roughnesses (metalness, roughness, transmission, opacity, clearcoat, sheen, iridescence, …) are clamped to [0, 1] on upload and on `setMaterialProperty`.
|
|
569
|
+
|
|
570
|
+
### Colour Management
|
|
571
|
+
|
|
572
|
+
`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)).
|
|
573
|
+
|
|
574
|
+
```js
|
|
575
|
+
configureAssets({ ocioRuntimeFactory: () => import('@bb-studio/ocio') });
|
|
576
|
+
|
|
577
|
+
await engine.loadColorConfig({ builtin: 'ocio://cg-config-v4.0.0_aces-v2.0_ocio-v2.5' }); // a runtime built-in
|
|
578
|
+
await engine.loadColorConfig({ files, configPath: 'config.ocio', id: 'studio' }); // or a folder: [{ relativePath, data }]
|
|
579
|
+
|
|
580
|
+
engine.color.setView({ display: 'sRGB - Display', view: 'ACES 2.0 - SDR 100 nits (Rec.709)', look: null });
|
|
581
|
+
engine.color.setLook(look); // a look from status().config.looks, on the active view
|
|
582
|
+
engine.color.setActiveView(id); // any registered view, OCIO or built-in (three.js constant)
|
|
583
|
+
engine.color.setContext({ SHOT: '010' }); // $SHOT in the config resolves to this
|
|
584
|
+
engine.color.status(); // config, working space, active view, registered views
|
|
585
|
+
|
|
586
|
+
engine.color.setWorkingSpace('ACEScg'); // render in the config's space…
|
|
587
|
+
await engine.applyColorWorkingSpace(); // …which rebuilds textures, materials and the environment
|
|
588
|
+
|
|
589
|
+
await engine.setTextureColorSpace(texture, 'srgb'); // null (auto), 'srgb', 'linear' or a config space
|
|
590
|
+
const { data } = await engine.renderToBuffer({ colorSpace: 'ACES2065-1', source: 'display' }); // float delivery buffer
|
|
591
|
+
await engine.unloadColorConfig();
|
|
555
592
|
```
|
|
556
593
|
|
|
594
|
+
- **Load and unload through `engine.loadColorConfig()` / `unloadColorConfig()`** once a scene exists: they undo an adopted working space while the config that converted the environment is still loaded.
|
|
595
|
+
- A view is baked to a log2 shaper and a 65³ table, interpolated tetrahedrally; the same table drives the canvas, the GPU and CPU readbacks and the menu (`listViewTransforms()`, `onRegistryChange()`). An OCIO view returns display-encoded colour, so the engine switches the output pass to linear while one is active.
|
|
596
|
+
- **Baked views.** `await engine.color.saveBakedView(id)` writes a view's table to a file (157 KB gzip for 65³), and `await engine.color.loadBakedView(bytes, { expect })` registers it with no runtime and no config — show the look on the first frame, load the config later. When that config loads, a baked view whose files match the fingerprint it was baked from is kept as is: no rebake, no new id, no restart.
|
|
597
|
+
- `renderToBuffer({ colorSpace })` takes `'srgb'` (display bytes through the active view), `'linear'` (the working-space accumulation) or a config colour space; `source: 'display'` reads what the viewport shows, denoised, instead of the raw accumulation.
|
|
598
|
+
- Degradations (a view that cannot bake, a display the canvas cannot show) are recorded as warnings in the [degradation contract](#degradation-contract).
|
|
599
|
+
|
|
557
600
|
### engine.environmentManager
|
|
558
601
|
|
|
559
602
|
Environment maps, sky modes, and procedural generation.
|
|
@@ -954,6 +997,18 @@ import {
|
|
|
954
997
|
PRODUCTION_RENDER_CONFIG,
|
|
955
998
|
INTERACTIVE_RENDER_CONFIG,
|
|
956
999
|
MAX_RESERVABLE_RENDER_SIZE,
|
|
1000
|
+
RENDER_PROFILES,
|
|
1001
|
+
MATERIAL_DEFAULTS,
|
|
1002
|
+
} from 'rayzee';
|
|
1003
|
+
|
|
1004
|
+
// Colour management — engine.color is the instance a host normally uses; these build UI against
|
|
1005
|
+
// it, or reach the view-transform registry without an app
|
|
1006
|
+
import {
|
|
1007
|
+
ColorManagement, getActiveColorManagement, isColorManaged, DEFAULT_WORKING_SPACE,
|
|
1008
|
+
listViewTransforms, getViewTransform, addViewTransform, removeViewTransform, onRegistryChange,
|
|
1009
|
+
buildOcioView, addOcioView, addAllOcioViews,
|
|
1010
|
+
convertColor, convertPixelsF32, extractMatrix, hasColorSpace,
|
|
1011
|
+
displayCanvasFit,
|
|
957
1012
|
} from 'rayzee';
|
|
958
1013
|
|
|
959
1014
|
// Leveled/namespaced logging, shared with the workers
|
|
@@ -1017,6 +1072,7 @@ import { setBindingAudit, getBindingAuditFindings, clearBindingAuditFindings } f
|
|
|
1017
1072
|
|---|---|---|
|
|
1018
1073
|
| `oidn-web` | Intel Open Image Denoise for high-quality final renders | Yes — `npm install oidn-web` (**>=0.4.0**) |
|
|
1019
1074
|
| `onnxruntime-web` | AI-powered upscaling | No — loaded from CDN at runtime |
|
|
1075
|
+
| `@bb-studio/ocio` | OpenColorIO runtime for [Colour Management](#colour-management) (~6 MB WebAssembly) | Only to load colour configs — `npm install @bb-studio/ocio`, then pass it as `ocioRuntimeFactory` |
|
|
1020
1076
|
|
|
1021
1077
|
> **Note:** `onnxruntime-web` is also listed in `package.json` under `optionalDependencies` for bundler compatibility, but the engine's own runtime path always fetches it from a CDN (see `ortRuntimeUrl` / `ortWasmPaths` in [Configuring Assets](#configuring-assets-cdn-urls--cache-namespace)) rather than importing the installed package — installing it locally has no effect unless you also override those URLs to point at your own copy.
|
|
1022
1078
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./rolldown-runtime-CAFD8bLK.js";
|
|
2
|
-
import {
|
|
2
|
+
import { S as t, t as n, y as r } from "./ToneMapGPU-BzcLheoR.js";
|
|
3
3
|
//#region src/dlss/DLSSNeural.js
|
|
4
4
|
var i = /* @__PURE__ */ e({
|
|
5
5
|
DLSSNeural: () => m,
|
|
@@ -39,7 +39,7 @@ var s = t("dlss"), c = 2048 * 2048, l = Object.freeze({
|
|
|
39
39
|
}), u = null;
|
|
40
40
|
function d() {
|
|
41
41
|
if (u) return u;
|
|
42
|
-
let { dlssRuntimeUrl: e, dlssAssetBaseUrl: t } =
|
|
42
|
+
let { dlssRuntimeUrl: e, dlssAssetBaseUrl: t } = r();
|
|
43
43
|
return globalThis.__DLSS5_ASSET_BASE__ = t, u = new Promise((t, n) => {
|
|
44
44
|
if (globalThis.DLSSRuntime?.getSrNrChain) return t(globalThis.DLSSRuntime.getSrNrChain());
|
|
45
45
|
let r = document.createElement("script");
|
|
@@ -139,15 +139,15 @@ var f = "\n@group(0) @binding(0) var src: texture_2d<f32>;\n@group(0) @binding(1
|
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
141
|
async readOutputToned(e) {
|
|
142
|
-
let { validWidth: t, validHeight:
|
|
143
|
-
return await this._packHDR(t,
|
|
142
|
+
let { validWidth: t, validHeight: r } = this.chain.pipeline.geometry;
|
|
143
|
+
return await this._packHDR(t, r), this._toneMapper ??= new n(this.device, "rayzee:dlss-nr-tonemap"), this._toneMapper.ensureSize(t, r), {
|
|
144
144
|
rgba8: await this._toneMapper.toRGBA8(this._hdrStorage, {
|
|
145
145
|
exposure: e.exposure ?? 1,
|
|
146
146
|
toneMapping: e.toneMapping ?? 0,
|
|
147
147
|
saturation: e.saturation ?? 1
|
|
148
148
|
}),
|
|
149
149
|
width: t,
|
|
150
|
-
height:
|
|
150
|
+
height: r
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
async readOutput() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./rolldown-runtime-CAFD8bLK.js";
|
|
2
|
-
import {
|
|
2
|
+
import { S as t, t as n, y as r } from "./ToneMapGPU-BzcLheoR.js";
|
|
3
3
|
//#region src/EngineEvents.js
|
|
4
4
|
var i = {
|
|
5
5
|
RENDER_COMPLETE: "engine:renderComplete",
|
|
@@ -45,7 +45,7 @@ var i = {
|
|
|
45
45
|
}), o = 2, s = t("dlss"), c = 2048, l = null;
|
|
46
46
|
function u() {
|
|
47
47
|
if (l) return l;
|
|
48
|
-
let { dlssRuntimeUrl: e, dlssAssetBaseUrl: t } =
|
|
48
|
+
let { dlssRuntimeUrl: e, dlssAssetBaseUrl: t } = r();
|
|
49
49
|
return globalThis.__DLSS5_ASSET_BASE__ = t, l = new Promise((t, n) => {
|
|
50
50
|
if (globalThis.DLSSRuntime?.getNativeSR) return t(globalThis.DLSSRuntime.getNativeSR());
|
|
51
51
|
let r = document.createElement("script");
|
|
@@ -174,11 +174,11 @@ var g = class e {
|
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
176
|
async upscaleToRGBA8(e, t = {}) {
|
|
177
|
-
let { result:
|
|
178
|
-
this._toneMapper ??= new
|
|
177
|
+
let { result: r, ms: i } = await this._run(e), { outputWidth: a, outputHeight: o } = this.geometry;
|
|
178
|
+
this._toneMapper ??= new n(this.sr.device, "rayzee:dlss-sr-tonemap"), this._toneMapper.ensureSize(a, o);
|
|
179
179
|
let s = performance.now();
|
|
180
180
|
return {
|
|
181
|
-
rgba8: await this._toneMapper.toRGBA8(
|
|
181
|
+
rgba8: await this._toneMapper.toRGBA8(r.hdr.buffer ?? r.hdr, {
|
|
182
182
|
exposure: t.exposure ?? 1,
|
|
183
183
|
toneMapping: t.toneMapping ?? 0,
|
|
184
184
|
saturation: t.saturation ?? 1,
|