@pixagram/renderart 0.2.0 → 0.2.2

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
@@ -4,15 +4,9 @@ High-performance pixel art rendering engines with GPU (WebGL2) and CPU (WASM) su
4
4
 
5
5
  ## Features
6
6
 
7
- - **CRT Effect** (2-32x) - Classic CRT display simulation with barrel distortion, scanlines, and shadow mask
8
- - **HEX Upscaling** (2-32x) - Transform pixel art into hexagonal grid representations
9
- - **XBRZ Scaling** (2-6x) - Edge-preserving pixel art scaling algorithm
10
-
11
- All engines support:
12
- - ⚡ **GPU acceleration** via WebGL2 (CRT, HEX)
13
- - 🦀 **CPU fallback** via Rust/WASM (all engines)
14
- - 🎨 **Customizable presets** and fine-grained options
15
- - 📦 **Zero dependencies** in core bundle
7
+ - **CRT Effect** (2-32x) - Classic CRT display simulation
8
+ - **HEX Upscaling** (2-32x) - Hexagonal grid transformation
9
+ - **XBRZ Scaling** (2-6x) - Edge-preserving pixel art scaling
16
10
 
17
11
  ## Installation
18
12
 
@@ -22,190 +16,130 @@ npm install @pixagram/renderart
22
16
 
23
17
  ## Quick Start
24
18
 
25
- ### GPU-Only Mode (Simplest - No WASM)
19
+ ### GPU-Only (Simplest - No WASM needed)
26
20
 
27
21
  ```typescript
28
- import { RenderArt } from '@pixagram/renderart';
29
-
30
- // Create GPU-only renderer (no WASM loading required)
31
- const renderer = RenderArt.createGpuOnly();
32
-
33
- // Get your image data
34
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
35
-
36
- // Apply CRT effect (GPU)
37
- const crtResult = renderer.crt.renderSync(imageData, { scale: 3 });
22
+ import { CrtGpuRenderer } from '@pixagram/renderart';
38
23
 
39
- // Apply HEX effect (GPU)
40
- const hexResult = renderer.hex.renderSync(imageData, { scale: 16 });
24
+ const crt = CrtGpuRenderer.create();
25
+ const result = crt.render(imageData, { scale: 3 });
41
26
 
42
27
  // Use the result
43
- ctx.putImageData(new ImageData(crtResult.data, crtResult.width, crtResult.height), 0, 0);
28
+ ctx.putImageData(new ImageData(result.data, result.width, result.height), 0, 0);
44
29
  ```
45
30
 
46
- ### With CPU Fallback (Requires WASM)
31
+ ### With CPU Fallback (Auto WASM loading)
47
32
 
48
33
  ```typescript
49
- import { RenderArt, initWasm } from '@pixagram/renderart';
50
- import init, * as wasm from '@pixagram/renderart/pkg/renderart_wasm.js';
34
+ import { RenderArt, setWasmUrl } from '@pixagram/renderart';
51
35
 
52
- // Initialize WASM module first
53
- await initWasm(() => init(), wasm);
36
+ // Configure WASM path (copy renderart_wasm.wasm to your public folder)
37
+ setWasmUrl('/wasm/renderart_wasm.wasm');
54
38
 
55
- // Create renderer with CPU fallback
56
39
  const renderer = RenderArt.create();
57
40
 
58
- // Now all engines work, including XBRZ (CPU-only)
59
- const xbrzResult = renderer.xbrz.render(imageData, { scale: 4 });
41
+ // GPU when available, auto-loads WASM for CPU fallback
42
+ const result = await renderer.crt.render(imageData, { scale: 3 });
43
+
44
+ // XBRZ is CPU-only (auto-loads WASM on first use)
45
+ const xbrzResult = await renderer.xbrz.render(imageData, { scale: 4 });
60
46
  ```
61
47
 
62
- ### Direct GPU Renderer Usage
48
+ ### Pre-load WASM
63
49
 
64
50
  ```typescript
65
- import { CrtGpuRenderer, HexGpuRenderer } from '@pixagram/renderart';
51
+ import { initWasm, setWasmUrl } from '@pixagram/renderart';
66
52
 
67
- // Use GPU renderers directly (no WASM needed)
68
- const crt = CrtGpuRenderer.create();
69
- const result = crt.render(imageData, {
70
- scale: 3,
71
- warpX: 0.02,
72
- scanOpacity: 0.6,
73
- });
74
-
75
- // Clean up
76
- crt.dispose();
53
+ // Pre-load WASM for faster first CPU render
54
+ setWasmUrl('/wasm/renderart_wasm.wasm');
55
+ await initWasm();
77
56
  ```
78
57
 
79
- ## API Reference
58
+ ## WASM Setup
80
59
 
81
- ### RenderArt (Unified API)
60
+ 1. Build the WASM module:
61
+ ```bash
62
+ cd node_modules/@pixagram/renderart
63
+ npm run build:wasm
64
+ ```
82
65
 
83
- ```typescript
84
- // GPU-only mode
85
- const renderer = RenderArt.createGpuOnly();
86
-
87
- // With CPU fallback (requires WASM init first)
88
- const renderer = RenderArt.create();
66
+ 2. Copy `wasm/renderart_wasm.wasm` to your public folder
89
67
 
90
- // Access capabilities
91
- console.log(renderer.capabilities);
92
- // { gpu: true, cpu: true, maxTextureSize: 16384, recommendedBackend: 'gpu' }
68
+ 3. Configure the path:
69
+ ```typescript
70
+ import { setWasmUrl } from '@pixagram/renderart';
71
+ setWasmUrl('/your/path/renderart_wasm.wasm');
72
+ ```
93
73
 
94
- // Cleanup
95
- renderer.dispose();
96
- ```
74
+ ## API Reference
97
75
 
98
- ### CRT Engine
76
+ ### CRT Options
99
77
 
100
78
  ```typescript
101
- // With options
102
- const result = renderer.crt.render(imageData, {
103
- scale: 3, // 2-32 (default: 3)
79
+ {
80
+ scale: 3, // 2-32
104
81
  warpX: 0.015, // Horizontal curvature
105
82
  warpY: 0.02, // Vertical curvature
106
83
  scanHardness: -4.0, // Scanline sharpness
107
84
  scanOpacity: 0.5, // Scanline intensity
108
85
  maskOpacity: 0.3, // Shadow mask intensity
109
- enableWarp: true, // Enable barrel distortion
110
- enableScanlines: true, // Enable scanlines
111
- enableMask: true, // Enable shadow mask
86
+ enableWarp: true,
87
+ enableScanlines: true,
88
+ enableMask: true,
112
89
  backend: 'auto', // 'gpu', 'cpu', or 'auto'
113
- });
114
-
115
- // With preset
116
- const result = renderer.crt.render(imageData, 'authentic');
117
- // Presets: 'default', 'authentic', 'subtle', 'flat'
118
-
119
- // Synchronous GPU-only rendering
120
- const result = renderer.crt.renderSync(imageData, { scale: 3 });
90
+ }
121
91
  ```
122
92
 
123
- ### HEX Engine
93
+ ### HEX Options
124
94
 
125
95
  ```typescript
126
- // With options
127
- const result = renderer.hex.render(imageData, {
128
- scale: 16, // 2-32 (default: 16)
96
+ {
97
+ scale: 16, // 2-32
129
98
  orientation: 'flat-top', // 'flat-top' or 'pointy-top'
130
- drawBorders: true, // Draw hexagon borders
131
- borderColor: '#282828', // Border color
132
- borderThickness: 1, // Border thickness
99
+ drawBorders: false,
100
+ borderColor: '#282828',
101
+ borderThickness: 1,
133
102
  backgroundColor: 'transparent',
134
103
  backend: 'auto',
135
- });
136
-
137
- // With preset
138
- const result = renderer.hex.render(imageData, 'bordered');
139
- // Presets: 'default', 'bordered', 'pointy'
140
-
141
- // Get output dimensions
142
- const dims = renderer.hex.getDimensions(64, 64, { scale: 16 });
104
+ }
143
105
  ```
144
106
 
145
- ### XBRZ Engine (CPU Only)
107
+ ### XBRZ Options
146
108
 
147
109
  ```typescript
148
- // Requires WASM initialization
149
- const result = renderer.xbrz.render(imageData, {
150
- scale: 4, // 2-6 (default: 2)
110
+ {
111
+ scale: 4, // 2-6
151
112
  luminanceWeight: 1.0,
152
113
  equalColorTolerance: 30,
153
114
  dominantDirectionThreshold: 4.4,
154
115
  steepDirectionThreshold: 2.2,
155
- });
156
-
157
- // With preset
158
- const result = renderer.xbrz.render(imageData, 'sharp');
159
- // Presets: 'default', 'sharp', 'smooth'
116
+ }
160
117
  ```
161
118
 
162
- ## Backend Selection
163
-
164
- | Engine | GPU (WebGL2) | CPU (WASM) |
165
- |--------|--------------|------------|
166
- | CRT | ✅ Primary | ✅ Fallback |
167
- | HEX | ✅ Primary | ✅ Fallback |
168
- | XBRZ | ❌ N/A | ✅ Only |
169
-
170
- ## WASM Loading with Custom Path
119
+ ## Presets
171
120
 
172
121
  ```typescript
173
- import { initWasm } from '@pixagram/renderart';
174
- import init, * as wasm from '@pixagram/renderart/pkg/renderart_wasm.js';
175
-
176
- // Load WASM from custom URL
177
- await initWasm(
178
- () => init('/static/wasm/renderart_wasm_bg.wasm'),
179
- wasm
180
- );
122
+ // CRT presets
123
+ renderer.crt.render(imageData, 'authentic'); // Strong CRT look
124
+ renderer.crt.render(imageData, 'subtle'); // Light CRT effect
125
+ renderer.crt.render(imageData, 'flat'); // No curvature
126
+
127
+ // HEX presets
128
+ renderer.hex.render(imageData, 'bordered'); // With borders
129
+ renderer.hex.render(imageData, 'pointy'); // Pointy-top orientation
130
+
131
+ // XBRZ presets
132
+ renderer.xbrz.render(imageData, 'sharp'); // Sharp edges
133
+ renderer.xbrz.render(imageData, 'smooth'); // Smoother output
181
134
  ```
182
135
 
183
- ## Browser Support
184
-
185
- - Chrome 79+
186
- - Firefox 75+
187
- - Safari 15+
188
- - Edge 79+
189
-
190
- Requires:
191
- - WebGL2 for GPU rendering
192
- - WebAssembly for CPU rendering
193
-
194
- ## Building from Source
195
-
196
- ```bash
197
- # Install dependencies
198
- npm install
199
-
200
- # Build WASM module (requires Rust + wasm-pack)
201
- npm run build:wasm
202
-
203
- # Build TypeScript
204
- npm run build:ts
136
+ ## Backend Selection
205
137
 
206
- # Full build
207
- npm run build
208
- ```
138
+ | Engine | GPU | CPU |
139
+ |--------|-----|-----|
140
+ | CRT | ✅ | ✅ |
141
+ | HEX | ✅ | ✅ |
142
+ | XBRZ | ❌ | ✅ |
209
143
 
210
144
  ## License
211
145
 
package/dist/index.d.mts CHANGED
@@ -190,80 +190,56 @@ declare const HEX_PRESETS: Record<string, Partial<HexOptions>>;
190
190
  /**
191
191
  * WASM Module Loader
192
192
  *
193
- * Handles loading and initialization of the Rust WASM module.
194
- * Requires explicit initialization - does NOT auto-import WASM.
195
- *
196
- * @example
197
- * ```typescript
198
- * import { initWasm } from '@pixagram/renderart';
199
- * import init from '@pixagram/renderart/pkg/renderart_wasm.js';
200
- *
201
- * // Initialize with the WASM module
202
- * await initWasm(init);
203
- * ```
193
+ * Auto-initializes WASM from URL. Works with any bundler.
204
194
  */
205
195
 
206
196
  /**
207
- * Initialize WASM module
197
+ * Configure WASM loading path
198
+ * Call this before using any CPU renderer if you need a custom path.
208
199
  *
209
- * @param wasmInit - The init function from renderart_wasm.js
210
- * @param wasmUrl - Optional URL to the .wasm file (for custom loading)
200
+ * @param url - URL to the renderart_wasm_bg.wasm file
211
201
  *
212
202
  * @example
213
203
  * ```typescript
214
- * // Option 1: Let wasm-pack handle loading
215
- * import init, * as wasm from '@pixagram/renderart/pkg/renderart_wasm.js';
216
- * await initWasm(init, wasm);
217
- *
218
- * // Option 2: With custom WASM URL
219
- * import init, * as wasm from '@pixagram/renderart/pkg/renderart_wasm.js';
220
- * await initWasm(() => init('/path/to/renderart_wasm_bg.wasm'), wasm);
204
+ * setWasmUrl('/static/wasm/renderart_wasm_bg.wasm');
221
205
  * ```
222
206
  */
223
- declare function initWasm(wasmInit: () => Promise<void>, wasm: any): Promise<void>;
207
+ declare function setWasmUrl(url: string): void;
208
+ /**
209
+ * Initialize WASM module
210
+ * Called automatically on first CPU renderer use.
211
+ * Can be called manually for preloading.
212
+ */
213
+ declare function initWasm(customUrl?: string): Promise<void>;
224
214
  /** Check if WASM is loaded */
225
215
  declare function isWasmLoaded(): boolean;
226
- /** Get the WASM module (throws if not initialized) */
227
- declare function getWasmModule(): any;
228
216
  /** CRT CPU Renderer using WASM */
229
217
  declare class CrtCpuRenderer {
230
218
  private ready;
231
- /** Create renderer (WASM must be initialized first via initWasm) */
232
- static create(): CrtCpuRenderer;
233
- /** Check if renderer is ready */
219
+ /** Create and initialize renderer (auto-loads WASM) */
220
+ static create(): Promise<CrtCpuRenderer>;
234
221
  isReady(): boolean;
235
- /** Render CRT effect */
236
222
  render(input: ImageInput | ImageData, options?: CrtOptions): ImageOutput;
237
- /** Dispose resources */
238
223
  dispose(): void;
239
224
  }
240
225
  /** HEX CPU Renderer using WASM */
241
226
  declare class HexCpuRenderer {
242
227
  private ready;
243
- /** Create renderer (WASM must be initialized first via initWasm) */
244
- static create(): HexCpuRenderer;
245
- /** Check if renderer is ready */
228
+ static create(): Promise<HexCpuRenderer>;
246
229
  isReady(): boolean;
247
- /** Render hexagonal effect */
248
230
  render(input: ImageInput | ImageData, options?: HexOptions): ImageOutput;
249
- /** Get output dimensions */
250
231
  getDimensions(srcWidth: number, srcHeight: number, scale: number, orientation?: HexOrientation): {
251
232
  width: number;
252
233
  height: number;
253
234
  };
254
- /** Dispose resources */
255
235
  dispose(): void;
256
236
  }
257
237
  /** XBRZ CPU Renderer using WASM */
258
238
  declare class XbrzCpuRenderer {
259
239
  private ready;
260
- /** Create renderer (WASM must be initialized first via initWasm) */
261
- static create(): XbrzCpuRenderer;
262
- /** Check if renderer is ready */
240
+ static create(): Promise<XbrzCpuRenderer>;
263
241
  isReady(): boolean;
264
- /** Render xBRZ scaling */
265
242
  render(input: ImageInput | ImageData, options?: XbrzOptions): ImageOutput;
266
- /** Dispose resources */
267
243
  dispose(): void;
268
244
  }
269
245
  /** XBRZ presets */
@@ -272,77 +248,47 @@ declare const XBRZ_PRESETS: Record<string, Partial<XbrzOptions>>;
272
248
  /**
273
249
  * RenderArt - Unified Pixel Art Rendering Engine
274
250
  *
275
- * Provides a unified API for all rendering engines (CRT, HEX, XBRZ)
276
- * with automatic backend selection (GPU/CPU).
277
- *
278
- * GPU renderers work standalone. CPU renderers require WASM initialization.
279
- *
280
- * @example
281
- * ```typescript
282
- * // GPU-only (no WASM needed)
283
- * const renderer = RenderArt.createGpuOnly();
284
- * const result = renderer.crt.renderSync(imageData, { scale: 3 });
285
- *
286
- * // With CPU fallback (requires WASM init)
287
- * import init, * as wasm from '@pixagram/renderart/pkg/renderart_wasm.js';
288
- * await initWasm(init, wasm);
289
- * const renderer = RenderArt.create();
290
- * ```
251
+ * GPU renderers work standalone. CPU renderers auto-initialize WASM.
291
252
  */
292
253
 
293
- /** CRT rendering engine with GPU/CPU backend support */
254
+ /** CRT rendering engine */
294
255
  declare class CrtEngine {
295
256
  private gpuRenderer;
296
257
  private cpuRenderer;
297
258
  private gpuAvailable;
298
- private cpuAvailable;
299
- constructor(gpuAvailable: boolean, cpuAvailable: boolean);
300
- /** Initialize GPU renderer */
259
+ constructor(gpuAvailable: boolean);
301
260
  private ensureGpu;
302
- /** Initialize CPU renderer */
303
261
  private ensureCpu;
304
262
  /** Render with automatic backend selection */
305
- render(input: ImageInput | ImageData, options?: CrtOptions): ImageOutput;
306
- /** Render with preset */
307
- render(input: ImageInput | ImageData, preset: CrtPreset, overrides?: Partial<CrtOptions>): ImageOutput;
263
+ render(input: ImageInput | ImageData, options?: CrtOptions): Promise<ImageOutput>;
264
+ render(input: ImageInput | ImageData, preset: CrtPreset, overrides?: Partial<CrtOptions>): Promise<ImageOutput>;
308
265
  /** Render synchronously (GPU only) */
309
266
  renderSync(input: ImageInput | ImageData, options?: CrtOptions): ImageOutput;
310
- /** Dispose resources */
311
267
  dispose(): void;
312
268
  }
313
- /** HEX rendering engine with GPU/CPU backend support */
269
+ /** HEX rendering engine */
314
270
  declare class HexEngine {
315
271
  private gpuRenderer;
316
272
  private cpuRenderer;
317
273
  private gpuAvailable;
318
- private cpuAvailable;
319
- constructor(gpuAvailable: boolean, cpuAvailable: boolean);
274
+ constructor(gpuAvailable: boolean);
320
275
  private ensureGpu;
321
276
  private ensureCpu;
322
- /** Render with automatic backend selection */
323
- render(input: ImageInput | ImageData, options?: HexOptions): ImageOutput;
324
- /** Render with preset */
325
- render(input: ImageInput | ImageData, preset: HexPreset, overrides?: Partial<HexOptions>): ImageOutput;
326
- /** Render synchronously (GPU only) */
277
+ render(input: ImageInput | ImageData, options?: HexOptions): Promise<ImageOutput>;
278
+ render(input: ImageInput | ImageData, preset: HexPreset, overrides?: Partial<HexOptions>): Promise<ImageOutput>;
327
279
  renderSync(input: ImageInput | ImageData, options?: HexOptions): ImageOutput;
328
- /** Get output dimensions */
329
280
  getDimensions(srcWidth: number, srcHeight: number, options?: HexOptions): {
330
281
  width: number;
331
282
  height: number;
332
283
  };
333
284
  dispose(): void;
334
285
  }
335
- /** XBRZ rendering engine (CPU only - algorithm too complex for efficient GPU) */
286
+ /** XBRZ rendering engine (CPU only) */
336
287
  declare class XbrzEngine {
337
288
  private cpuRenderer;
338
- private cpuAvailable;
339
- constructor(cpuAvailable: boolean);
340
289
  private ensureCpu;
341
- /** Render xBRZ scaling */
342
- render(input: ImageInput | ImageData, options?: XbrzOptions): ImageOutput;
343
- /** Render with preset */
344
- render(input: ImageInput | ImageData, preset: XbrzPreset, overrides?: Partial<XbrzOptions>): ImageOutput;
345
- /** Get output dimensions */
290
+ render(input: ImageInput | ImageData, options?: XbrzOptions): Promise<ImageOutput>;
291
+ render(input: ImageInput | ImageData, preset: XbrzPreset, overrides?: Partial<XbrzOptions>): Promise<ImageOutput>;
346
292
  getDimensions(srcWidth: number, srcHeight: number, scale?: number): {
347
293
  width: number;
348
294
  height: number;
@@ -351,29 +297,19 @@ declare class XbrzEngine {
351
297
  }
352
298
  /** RenderArt - Unified Pixel Art Rendering Engine */
353
299
  declare class RenderArt {
354
- /** CRT effect renderer */
355
300
  readonly crt: CrtEngine;
356
- /** Hexagonal pixel renderer */
357
301
  readonly hex: HexEngine;
358
- /** xBRZ scaling renderer */
359
302
  readonly xbrz: XbrzEngine;
360
303
  private _capabilities;
361
304
  private constructor();
362
- /**
363
- * Create RenderArt instance
364
- * GPU renderers always available if WebGL2 supported.
365
- * CPU renderers require WASM to be initialized via initWasm() first.
366
- */
305
+ /** Create RenderArt instance */
367
306
  static create(): RenderArt;
368
- /**
369
- * Create GPU-only RenderArt instance (no WASM required)
370
- * CPU fallback will not be available.
371
- */
307
+ /** Create GPU-only instance */
372
308
  static createGpuOnly(): RenderArt;
373
- /** Get renderer capabilities */
309
+ /** Pre-initialize WASM for faster first CPU render */
310
+ preloadWasm(wasmUrl?: string): Promise<void>;
374
311
  get capabilities(): RendererCapabilities;
375
- /** Dispose all resources */
376
312
  dispose(): void;
377
313
  }
378
314
 
379
- export { type Backend, CRT_PRESETS, CrtCpuRenderer, CrtEngine, CrtGpuRenderer, type CrtOptions, type CrtPreset, HEX_PRESETS, HexCpuRenderer, HexEngine, HexGpuRenderer, type HexOptions, type HexOrientation, type HexPreset, type ImageInput, type ImageOutput, type PixelData, RenderArt, type RenderStats, type Renderer, type RendererCapabilities, XBRZ_PRESETS, XbrzCpuRenderer, XbrzEngine, type XbrzOptions, type XbrzPreset, getWasmModule, hexGetDimensions, initWasm, isWasmLoaded };
315
+ export { type Backend, CRT_PRESETS, CrtCpuRenderer, CrtEngine, CrtGpuRenderer, type CrtOptions, type CrtPreset, HEX_PRESETS, HexCpuRenderer, HexEngine, HexGpuRenderer, type HexOptions, type HexOrientation, type HexPreset, type ImageInput, type ImageOutput, type PixelData, RenderArt, type RenderStats, type Renderer, type RendererCapabilities, XBRZ_PRESETS, XbrzCpuRenderer, XbrzEngine, type XbrzOptions, type XbrzPreset, hexGetDimensions, initWasm, isWasmLoaded, setWasmUrl };