@plasius/gpu-worker 0.1.1 → 0.1.3

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/CHANGELOG.md CHANGED
@@ -20,6 +20,46 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
20
20
  - **Security**
21
21
  - (placeholder)
22
22
 
23
+ ## [0.1.3] - 2026-02-28
24
+
25
+ - **Added**
26
+ - (placeholder)
27
+
28
+ - **Changed**
29
+ - (placeholder)
30
+
31
+ - **Fixed**
32
+ - (placeholder)
33
+
34
+ - **Security**
35
+ - (placeholder)
36
+
37
+ ## [0.1.2] - 2026-01-24
38
+
39
+ - **Added**
40
+ - `loadJobWgsl` to register multiple job WGSL modules and receive `job_type` ids.
41
+ - Job-aware `assembleWorkerWgsl` that appends registered jobs and generates a dispatch wrapper.
42
+ - Optional debug mode for WGSL identifier clash detection during assembly.
43
+ - `loadQueueWgsl` helper that can apply queue compatibility renames during load.
44
+ - `createWorkerLoop` helper to drive worker/job compute dispatch at max or throttled rates.
45
+ - Demo denoise job WGSL (`demo/jobs/denoise.wgsl`) with a compute pass + present shader.
46
+ - Temporal denoise history buffer in the demo to stabilize jittered lighting.
47
+
48
+ - **Changed**
49
+ - Demo visuals now render a campfire scene with deferred lighting (G-buffer + fullscreen lighting pass).
50
+ - Demo now builds per-type worklists from queue jobs and uses indirect draws for render jobs alongside physics jobs.
51
+ - `src/worker.wgsl` is now a minimal worker template; demo kernels live in `demo/jobs/*.wgsl`.
52
+ - Demo job shaders are split into `demo/jobs/common.wgsl`, `demo/jobs/physics.job.wgsl`, and `demo/jobs/render.job.wgsl`.
53
+ - Demo lighting sampling now uses screen-space jitter to avoid world-space banding artifacts.
54
+ - `assembleWorkerWgsl` can now consume a registry or explicit job list and emit a dispatching `process_job`.
55
+ - `assembleWorkerWgsl` now applies queue compatibility renames (e.g., `JobMeta` -> `JobDesc`) by default.
56
+
57
+ - **Fixed**
58
+ - Reduced diagonal banding artifacts in the demo lighting pass.
59
+
60
+ - **Security**
61
+ - (placeholder)
62
+
23
63
  ## [0.1.1] - 2026-01-23
24
64
 
25
65
  - **Added**
@@ -88,9 +128,22 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
88
128
 
89
129
  ---
90
130
 
91
- [Unreleased]: https://github.com/Plasius-LTD/gpu-worker/compare/v0.1.1...HEAD
131
+ [Unreleased]: https://github.com/Plasius-LTD/gpu-worker/compare/v0.1.3...HEAD
92
132
  [0.1.0-beta.1]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.0-beta.1
93
133
  [0.1.0]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.0
94
- [0.2.0]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.2.0
95
- [0.3.0]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.3.0
96
- [0.1.1]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.1
134
+ [0.1.2]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.2
135
+
136
+ ## [0.1.2] - 2026-02-11
137
+
138
+ - **Added**
139
+ - Initial release.
140
+
141
+ - **Changed**
142
+ - (placeholder)
143
+
144
+ - **Fixed**
145
+ - (placeholder)
146
+
147
+ - **Security**
148
+ - (placeholder)
149
+ [0.1.3]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.3
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # @plasius/gpu-worker
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@plasius/gpu-worker)](https://www.npmjs.com/package/@plasius/gpu-worker)
3
+ [![npm version](https://img.shields.io/npm/v/@plasius/gpu-worker.svg)](https://www.npmjs.com/package/@plasius/gpu-worker)
4
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/Plasius-LTD/gpu-worker/ci.yml?branch=main&label=build&style=flat)](https://github.com/Plasius-LTD/gpu-worker/actions/workflows/ci.yml)
5
+ [![coverage](https://img.shields.io/codecov/c/github/Plasius-LTD/gpu-worker)](https://codecov.io/gh/Plasius-LTD/gpu-worker)
6
+ [![License](https://img.shields.io/github/license/Plasius-LTD/gpu-worker)](./LICENSE)
7
+ [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-yes-blue.svg)](./CODE_OF_CONDUCT.md)
8
+ [![Security Policy](https://img.shields.io/badge/security%20policy-yes-orange.svg)](./SECURITY.md)
9
+ [![Changelog](https://img.shields.io/badge/changelog-md-blue.svg)](./CHANGELOG.md)
10
+
4
11
  [![CI](https://github.com/Plasius-LTD/gpu-worker/actions/workflows/ci.yml/badge.svg)](https://github.com/Plasius-LTD/gpu-worker/actions/workflows/ci.yml)
5
12
  [![license](https://img.shields.io/github/license/Plasius-LTD/gpu-worker)](./LICENSE)
6
13
 
@@ -15,15 +22,68 @@ npm install @plasius/gpu-worker
15
22
 
16
23
  ## Usage
17
24
  ```js
18
- import { assembleWorkerWgsl, loadWorkerWgsl } from "@plasius/gpu-worker";
25
+ import {
26
+ assembleWorkerWgsl,
27
+ createWorkerLoop,
28
+ loadJobWgsl,
29
+ loadWorkerWgsl,
30
+ } from "@plasius/gpu-worker";
19
31
 
20
32
  const workerWgsl = await loadWorkerWgsl();
21
- const shaderCode = await assembleWorkerWgsl(workerWgsl);
33
+ const jobType = await loadJobWgsl({
34
+ wgsl: `
35
+ fn process_job(job_index: u32, job_type: u32, payload_words: u32) {
36
+ // job logic here
37
+ }
38
+ `,
39
+ label: "physics",
40
+ });
41
+
42
+ const shaderCode = await assembleWorkerWgsl(workerWgsl, { debug: true });
22
43
  // Pass shaderCode to device.createShaderModule({ code: shaderCode })
23
44
  ```
24
45
 
25
- `assembleWorkerWgsl` also accepts an optional second argument to override the queue WGSL source:
26
- `assembleWorkerWgsl(workerWgsl, { queueWgsl, queueUrl, fetcher })`.
46
+ `loadJobWgsl` registers job WGSL and returns the assigned `job_type` index.
47
+ Call `assembleWorkerWgsl` again after registering new jobs to rebuild the
48
+ combined WGSL. Job types are assigned in registration order, so keep the
49
+ registration order stable across rebuilds if you need deterministic ids.
50
+
51
+ `assembleWorkerWgsl` also accepts an optional second argument to override the
52
+ queue WGSL source: `assembleWorkerWgsl(workerWgsl, { queueWgsl, queueUrl, fetcher })`.
53
+ By default it applies queue compatibility renames (for example `JobMeta` -> `JobDesc`);
54
+ set `queueCompat: false` to disable that behavior.
55
+ If you are concatenating WGSL manually, `loadQueueWgsl` provides the same
56
+ compatibility renames by default: `loadQueueWgsl({ url, fetcher, queueCompat: false })`.
57
+
58
+ To bypass the registry, pass jobs directly:
59
+ ```js
60
+ const shaderCode = await assembleWorkerWgsl(workerWgsl, {
61
+ jobs: [{ wgsl: jobA }, { wgsl: jobB, label: "lighting" }],
62
+ debug: true,
63
+ });
64
+ ```
65
+
66
+ When assembling jobs, each job WGSL must define
67
+ `process_job(job_index, job_type, payload_words)`. The assembler rewrites each
68
+ job's `process_job` to a unique name and generates a dispatcher based on
69
+ `job_type`. Set `debug: true` to detect identifier clashes across appended WGSL.
70
+
71
+ To run the worker loop at the highest practical rate (or a target rate), use the
72
+ helper:
73
+ ```js
74
+ const loop = createWorkerLoop({
75
+ device,
76
+ worker: { pipeline: workerPipeline, bindGroups: [queueBindGroup, simBindGroup] },
77
+ jobs: [
78
+ { pipeline: physicsPipeline, bindGroups: [queueBindGroup, simBindGroup], workgroups: physicsWorkgroups },
79
+ { pipeline: renderIndirectPipeline, bindGroups: [queueBindGroup, simBindGroup], workgroups: 1 },
80
+ ],
81
+ workgroupSize: 64,
82
+ maxJobsPerDispatch: queueCapacity,
83
+ // rateHz: 120, // optional throttle; omit for animation-frame cadence
84
+ });
85
+ loop.start();
86
+ ```
27
87
 
28
88
  ## What this is
29
89
  - A minimal GPU worker layer that combines a lock-free queue with user WGSL jobs.
@@ -31,8 +91,9 @@ const shaderCode = await assembleWorkerWgsl(workerWgsl);
31
91
  - A reference job format for fixed-size job dispatch (u32 indices).
32
92
 
33
93
  ## Demo
34
- The demo enqueues ray tracing tile jobs on the GPU and renders a simple scene. Install
35
- dependencies first so the lock-free queue package is available for the browser import map.
94
+ The demo enqueues physics and render jobs on the GPU, builds per-type worklists, runs the
95
+ physics kernel, and uses an indirect draw for the particle pass. Install dependencies first
96
+ so the lock-free queue package is available for the browser import map.
36
97
 
37
98
  ```
38
99
  npm install
@@ -61,9 +122,12 @@ certificate for that name and set `DEMO_HOST`, `DEMO_PORT`, `DEMO_TLS_CERT`, and
61
122
  `npm run build` emits `dist/index.js`, `dist/index.cjs`, and `dist/worker.wgsl`.
62
123
 
63
124
  ## Files
64
- - `demo/index.html`: Loads the ray tracing demo.
65
- - `demo/main.js`: WebGPU setup, enqueue, and ray tracing kernel.
66
- - `src/worker.wgsl`: Worker entry points that dequeue jobs and run a ray tracer.
125
+ - `demo/index.html`: Loads the WebGPU demo.
126
+ - `demo/main.js`: WebGPU setup, queue jobs, physics worklists, and indirect draw.
127
+ - `demo/jobs/common.wgsl`: Shared WGSL definitions for demo jobs.
128
+ - `demo/jobs/physics.job.wgsl`: Physics job kernel (worklist + integration).
129
+ - `demo/jobs/render.job.wgsl`: Render job kernel (worklist + indirect args).
130
+ - `src/worker.wgsl`: Minimal worker entry point template (dequeue + `process_job` hook).
67
131
  - `src/index.js`: Helper functions to load/assemble WGSL.
68
132
 
69
133
  ## Job shape