@framecast/rt 1.0.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.
Files changed (6) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +78 -0
  3. package/index.d.ts +57 -0
  4. package/package.json +43 -0
  5. package/rt.js +1254 -0
  6. package/sr.js +205 -0
package/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ @framecast/rt - the Framecast WebGPU inference runtime (rt.js, sr.js)
2
+
3
+ Copyright (C) 2026 MONZik
4
+
5
+ This library is free software: you can redistribute it and/or modify it
6
+ under the terms of the GNU Lesser General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or (at your
8
+ option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful, but WITHOUT
11
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13
+ for more details: https://www.gnu.org/licenses/lgpl-3.0.html
14
+
15
+ Note: this LGPL grant covers the runtime library as distributed in this
16
+ package. The Framecast repository as a whole (extension, tools, training
17
+ code) remains AGPL-3.0; the model weights are licensed separately (see
18
+ WEIGHTS_LICENSE.md in the repository).
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # @framecast/rt
2
+
3
+ Real-time neural frame interpolation on **raw WebGPU** - the runtime behind
4
+ the [Framecast](https://github.com/MONZikWasTaken/Framecast) extension,
5
+ packaged as a library. Hand-written WGSL compute kernels, no ML framework,
6
+ ~3 ms per generated frame at 720p on a mid-range GPU (RTX 4060 Ti).
7
+
8
+ Requires a browser with WebGPU and `shader-f16` (Chrome 121+; Apple Silicon
9
+ works).
10
+
11
+ ## Install
12
+
13
+ ```
14
+ npm i @framecast/rt
15
+ ```
16
+
17
+ Weights are **not** bundled - fetch them once from the Framecast release
18
+ (2.9 MB) and cache as you like:
19
+
20
+ ```js
21
+ const BASE = 'https://github.com/MONZikWasTaken/Framecast/releases/download/v1.0.0';
22
+ const [bin, manifest] = await Promise.all([
23
+ fetch(`${BASE}/rt_v7s.bin`).then(r => r.arrayBuffer()),
24
+ fetch(`${BASE}/rt_v7s.json`).then(r => r.json()),
25
+ ]);
26
+ ```
27
+
28
+ ## Interpolate between two frames
29
+
30
+ ```js
31
+ import { createRT } from '@framecast/rt';
32
+
33
+ const adapter = await navigator.gpu.requestAdapter();
34
+ const device = await adapter.requestDevice({
35
+ requiredFeatures: adapter.features.has('shader-f16') ? ['shader-f16'] : [],
36
+ });
37
+
38
+ // dimensions must be divisible by 16
39
+ const rt = await createRT(device, {
40
+ w: 1280, h: 720,
41
+ weightsBin: bin, weightsManifest: manifest,
42
+ textureInput: true, textureOutput: true,
43
+ });
44
+
45
+ // frameA/frameB are GPUTextures (rgba8unorm, TEXTURE_BINDING);
46
+ // out is rgba8unorm with STORAGE_BINDING
47
+ rt.prepPair(frameA, frameB); // t-free trunk, once per pair
48
+ rt.runT(0.5, out); // one mid; call again with any t in (0,1)
49
+ ```
50
+
51
+ `prepPair` + `runT` is the real-time path: the trunk runs once per frame
52
+ pair, each additional mid costs only the small t-conditioned head - that is
53
+ what makes 4x-6x factors affordable.
54
+
55
+ For one-off use (benchmarks, offline tools) there is also a buffer-mode API:
56
+ `rt.run(rgbaA, rgbaB, t)` takes and returns `Uint8Array` RGBA pixels.
57
+
58
+ ## Squeeze the last 20%
59
+
60
+ Kernel shapes are GPU-specific. Run the autotuner once per machine and pass
61
+ the result in:
62
+
63
+ ```js
64
+ import { createRT, tuneConvRB } from '@framecast/rt';
65
+
66
+ const tune = await tuneConvRB(device, { ci: 192, co: 192, w16: 80, h16: 45 });
67
+ localStorage.setItem('fcTune', JSON.stringify(tune));
68
+ // ...next session:
69
+ const rt = await createRT(device, { ...opts, convTune: JSON.parse(localStorage.getItem('fcTune')) });
70
+ ```
71
+
72
+ ## License
73
+
74
+ **LGPL-3.0-or-later.** Embed it in anything, including commercial products;
75
+ modifications to the library itself must be published. The model weights are
76
+ licensed separately (non-commercial - see
77
+ [WEIGHTS_LICENSE](https://github.com/MONZikWasTaken/Framecast/blob/main/WEIGHTS_LICENSE.md));
78
+ for commercial weight licensing, get in touch.
package/index.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ /** Kernel autotune result for the register-blocked conv (per GPU + shape). */
2
+ export interface ConvTune {
3
+ coc: number;
4
+ slab: number;
5
+ sg?: boolean;
6
+ ms?: number;
7
+ }
8
+
9
+ export interface CreateRTOptions {
10
+ /** Output width in pixels. Must be divisible by 16. */
11
+ w: number;
12
+ /** Output height in pixels. Must be divisible by 16. */
13
+ h: number;
14
+ /** Raw weights blob (the released .bin file). */
15
+ weightsBin: ArrayBuffer;
16
+ /** Weights manifest (the released .json file, parsed). */
17
+ weightsManifest: Record<string, { offset: number; shape: number[] }>;
18
+ /** Kernel tune from tuneConvRB; omit for safe defaults. */
19
+ convTune?: ConvTune | null;
20
+ /** Inputs are GPUTextures instead of RGBA8 CPU buffers. */
21
+ textureInput?: boolean;
22
+ /** Mids are written into GPUTextures instead of read back to CPU. */
23
+ textureOutput?: boolean;
24
+ /** Bake the static-region guard into the flow kernel. */
25
+ staticGuard?: boolean;
26
+ }
27
+
28
+ export interface RT {
29
+ /** Buffer mode only: interpolate one mid between two RGBA8 frames. */
30
+ run(rgbaA: Uint8Array, rgbaB: Uint8Array, t?: number): Promise<Uint8Array>;
31
+ /**
32
+ * Batched mids for every t. Buffer mode returns RGBA8 arrays; texture mode
33
+ * writes into outTexs and resolves null (nothing crosses the bus).
34
+ */
35
+ runMulti(
36
+ a: Uint8Array | GPUTexture,
37
+ b: Uint8Array | GPUTexture,
38
+ ts: number[],
39
+ outTexs?: GPUTexture[],
40
+ ): Promise<Uint8Array[] | null>;
41
+ /** Texture mode: run the t-free trunk once for a frame pair. */
42
+ prepPair(a: GPUTexture, b: GPUTexture): void;
43
+ /** Texture mode: one mid at timestep t into outTex (call prepPair first). */
44
+ runT(t: number, outTex: GPUTexture): void;
45
+ /** Per-pass GPU timings (requires timestamp-query). */
46
+ profile(rgbaA: Uint8Array, rgbaB: Uint8Array): Promise<string>;
47
+ readonly w: number;
48
+ readonly h: number;
49
+ }
50
+
51
+ export function createRT(device: GPUDevice, opts: CreateRTOptions): Promise<RT>;
52
+
53
+ /** Bench conv kernel variants on the real shape; persist the result per GPU. */
54
+ export function tuneConvRB(
55
+ device: GPUDevice,
56
+ shape: { ci: number; co: number; w16: number; h16: number },
57
+ ): Promise<ConvTune>;
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@framecast/rt",
3
+ "version": "1.0.0",
4
+ "description": "Real-time neural frame interpolation on raw WebGPU: hand-written WGSL kernels, 2.9 MB model, ~3 ms per generated frame on a mid-range GPU. The runtime behind the Framecast extension.",
5
+ "type": "module",
6
+ "main": "./rt.js",
7
+ "exports": {
8
+ ".": "./rt.js",
9
+ "./sr": "./sr.js"
10
+ },
11
+ "types": "./index.d.ts",
12
+ "files": [
13
+ "rt.js",
14
+ "sr.js",
15
+ "index.d.ts",
16
+ "LICENSE",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "prepack": "node prepack.mjs"
21
+ },
22
+ "license": "LGPL-3.0-or-later",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/MONZikWasTaken/Framecast.git",
26
+ "directory": "packages/rt"
27
+ },
28
+ "homepage": "https://github.com/MONZikWasTaken/Framecast#readme",
29
+ "bugs": "https://github.com/MONZikWasTaken/Framecast/issues",
30
+ "keywords": [
31
+ "webgpu",
32
+ "wgsl",
33
+ "frame-interpolation",
34
+ "video",
35
+ "rife",
36
+ "machine-learning",
37
+ "real-time"
38
+ ],
39
+ "author": "MONZik",
40
+ "engines": {
41
+ "node": ">=18"
42
+ }
43
+ }