@actis/core 26.3.0 → 26.9.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 CHANGED
@@ -32,7 +32,7 @@ yarn add @actis/core
32
32
  Here's a simple example to get you started:
33
33
 
34
34
  ```tsx
35
- import WebGLRenderer from '@actis/core'
35
+ import { WebGLRenderer } from '@actis/core'
36
36
  import React, { useEffect, useRef } from 'react'
37
37
 
38
38
  // Main React functional component
@@ -100,7 +100,6 @@ function App() {
100
100
  textures: ['bufferB'],
101
101
  },
102
102
  ],
103
- textures: [],
104
103
  }
105
104
  rendererRef.current.setup(passes) // Setup the renderer with the passes
106
105
  requestAnimationFrame(rendererRef.current.render) // Start the rendering loop
@@ -117,6 +116,65 @@ export default App
117
116
 
118
117
  For more advanced usage, such as adding multiple passes and using textures, refer to the [API documentation](#advanced-usage) ~in a near future~.
119
118
 
119
+ ### Offscreen rendering (workers)
120
+
121
+ `createRenderer` runs the same renderer inside a dedicated worker against an
122
+ `OffscreenCanvas`, keeping shader compilation, uniform resolution, and the
123
+ pass loop off the main thread. It is worker-first by default and falls back
124
+ to the main-thread `WebGLRenderer` automatically:
125
+
126
+ ```ts
127
+ import { createRenderer } from '@actis/core'
128
+
129
+ const renderer = await createRenderer(canvas, {
130
+ mode: 'auto', // 'auto' | 'worker' | 'main'
131
+ onFallback: reason => console.info('main-thread fallback:', reason),
132
+ })
133
+
134
+ renderer.setup({ passes: [/* ... */] }) // same API on both paths
135
+ renderer.play()
136
+ ```
137
+
138
+ When your bundler owns worker bundling (recommended for apps), pass a
139
+ pre-constructed worker instead of a URL — this is correct in both dev and
140
+ prod builds (Vite example):
141
+
142
+ ```ts
143
+ import RendererWorker from './worker-entry.ts?worker' // or an aliased path
144
+
145
+ const renderer = await createRenderer(canvas, {
146
+ worker: new RendererWorker(),
147
+ })
148
+ ```
149
+
150
+ Fallback order: worker + WebGL2 → worker + WebGL1 → main thread. The
151
+ `onFallback` reason is one of `no-worker`, `no-offscreen-canvas`, `no-webgl`,
152
+ `worker-spawn-failed`, `worker-handshake-timeout`, `worker-version-mismatch`,
153
+ or `worker-gl-unavailable`. `mode: 'worker'` throws `WorkerUnsupportedError`
154
+ instead of falling back; `mode: 'main'` pins the legacy path (also used
155
+ automatically for pinned CDN builds, where the worker entry cannot be
156
+ resolved reliably). If the worker dies _after_ the canvas was transferred
157
+ (the surface cannot be recovered), creation throws even in `auto` mode and
158
+ `onFallback` reports `worker-transferred-fatal`.
159
+
160
+ One canvas, one renderer: `transferControlToOffscreen` is irreversible. Mount
161
+ a fresh canvas element per renderer (e.g. on framework remounts/HMR) and
162
+ dispose the previous renderer first — reusing a transferred canvas throws
163
+ `WorkerUnsupportedError` (`canvas-already-bound`) instead of failing obscurely.
164
+
165
+ Worker-path notes:
166
+
167
+ - Reads (`getMetrics`, `getPassNames`, `getContextState`) are served from
168
+ caches the worker pushes — same sync signatures, ≤ ~500ms staleness.
169
+ - `capturePassDataURL` returns the last pushed thumbnail; call
170
+ `requestPassCapture(name)` first (e.g. on a poll interval) for fresh frames.
171
+ - Uniform providers cross the boundary only as static descriptors:
172
+ `registerUniformProvider({ id, values })`. Function providers, `Pass`
173
+ objects (`addPass`/`getPass`/`getPasses`/`forEachPass`), and direct
174
+ `new WebGLRenderer(canvas)` (deprecated, still supported) require the main
175
+ thread.
176
+ - Dispose with `renderer.dispose()` to terminate the worker.
177
+
120
178
  ## Contributing
121
179
 
122
180
  Contributions are welcome! Please open an issue or submit a pull request on GitHub.