A focused native-wgpu example that ports ShadeCore’s preview/presentation concepts into the Junkpile I/O track.
The renderer always draws into one authoritative offscreen texture. The local window is only a presentation sink and can independently use Fit, Fill, Stretch, Pixel, or Off without changing the source texture.
npm install
npm run dev
Two windows open:
640 × 480 · 4:3 as the source.Hotkeys work while the controls window has focus.
| Action | Default KeyboardEvent.code |
|---|---|
| Fit | Digit7, Numpad7 |
| Fill | Digit8, Numpad8 |
| Stretch | Digit9, Numpad9 |
| Pixel | Digit0, Numpad0 |
| Preview on/off | KeyP |
| Renderer fullscreen | KeyF |
The source template is included at:
config/preview.json
On first launch it is copied to the operating system’s application-config directory. The exact active path appears in the controls window.
Example:
{
"schema_version": 1,
"enabled": true,
"scale_mode": "fit",
"source": {
"width": 1280,
"height": 720
},
"hotkeys": {
"fit": ["Digit7", "Numpad7"],
"fill": ["Digit8", "Numpad8"],
"stretch": ["Digit9", "Numpad9"],
"pixel": ["Digit0", "Numpad0"],
"toggle_preview": ["KeyP"],
"fullscreen": ["KeyF"]
}
}
Edit the active file and click Reload JSON. Unknown fields, unsupported schema versions, invalid dimensions, and empty hotkey arrays are rejected. A failed reload does not replace the current working runtime state.
scale = min(window_width / source_width, window_height / source_height)
The complete source remains visible. Unused destination area is black.
scale = max(window_width / source_width, window_height / source_height)
The destination is covered completely. Source edges outside the window are cropped.
scale_x = window_width / source_width
scale_y = window_height / source_height
The source fills the window without preserving aspect ratio.
scale = 1.0
The source is centered without scaling. Source pixels outside a smaller window are cropped; unused area in a larger window is black.
WGSL source shader
↓
authoritative offscreen wgpu texture
↓
preview presentation shader
↓
Fit / Fill / Stretch / Pixel
↓
resizable native surface
Disabling preview removes only the final presentation stage:
WGSL source shader
↓
authoritative offscreen wgpu texture
↓
rendering continues; no local presentation
This is the same core separation used by ShadeCore: preview behavior belongs to a presenter and must not resize, crop, or otherwise redefine the authoritative render target.
This example does not record, stream, publish NDI, Syphon, or Spout. It isolates the local presentation contract so those outputs can continue to consume the authoritative texture independently in later unified-router examples.
npm run build
config/preview.json editable default configuration
src/index.html controls interface
src/app.js commands, telemetry, hotkeys
src/styles.css controls styling
src-tauri/src/config.rs strict JSON configuration
src-tauri/src/frame.rs authoritative frame descriptor
src-tauri/src/main.rs Tauri windows and commands
src-tauri/src/renderer.rs offscreen renderer and surface lifecycle
src-tauri/src/preview.rs preview sink and geometry telemetry
src-tauri/src/source.wgsl aspect-sensitive diagnostic source
src-tauri/src/preview.wgsl ShadeCore-style presentation shader