Skip to content

Releases: Patrickjaillet/Videotoy

v2.4.1 — WGSL support now working end-to-end

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 25 Sep 09:17

Fixed

  • WGSL shaders failed to render: the fragment entry point renaming logic looked for a : SV_Target annotation directly on the function signature, a form Tint's HLSL writer never actually produces. Real Tint output always wraps the entry point in a pair of <name>_inputs/<name>_outputs structs, with the output struct's field carrying the SV_Target0 annotation instead — so the renaming to PSMain (required by MultiPassRenderer) silently never triggered.
  • Found and fixed by compiling tint.exe from the Dawn/Tint source and running a real WGSL-to-HLSL conversion through it — the first time the actual output of Tint's HLSL writer was observed rather than assumed from documentation.

This release includes a working, verified tint.exe in the installer, so .wgsl shaders now load and render correctly for the first time.

See CHANGELOG.md for full details.

v2.4.0 — Vitamin UI/UX redesign

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 25 Sep 08:13

Added

  • Full "vitamin" UI/UX redesign: a saturated, contextual color palette (violet for editing, cyan-blue for video export, orange for the render queue, turquoise for history, pink for errors/warnings) replaces the previous single-accent blue theme, applied consistently across the main toolbar, Shader Issues/Export History/Render Queue/editor panels, and the About window
  • Icons are now colored and, where their geometry has closed sub-paths (clock, warning triangle, render queue, loop logo, etc.), filled with a matching gradient instead of a plain monochrome outline
  • Gradient backgrounds and soft drop-shadow glows on primary buttons, cards, and active filter chips; a subtle tiled grain texture behind the main window
  • Hover/press micro-interactions (scale + glow) on icon buttons and filter chips; a continuous pulse animation on the export/render-queue icons while a render is running, and on the editor's unsaved-changes indicator
  • Fade-in transitions when opening the Shader Issues, Export History, Render Queue, and editor panels
  • The Edit menu (previously empty) now exposes Undo/Redo

Fixed

  • The About window always showed a stale "v2.0.0" instead of the app's actual version
  • Toggling the render settings panel's collapse chevron immediately crashed the app; fixed the same way the editor panel's width animation was fixed previously

See CHANGELOG.md for full details.

v2.3.0

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 25 Sep 07:13

Added

  • Integrated code editor panel (side-by-side with the live preview) with GLSL/HLSL/WGSL syntax highlighting, per-pass tabs for multi-pass projects (Image/Buffer A-D/Common), New/Save/Save As, an unsaved-changes indicator, and on-the-fly compile-and-preview (Ctrl+Enter) without touching the file on disk until explicitly saved
  • .txt files are now accepted as shader source (detected by syntax heuristic rather than extension), for code copied from shadertoy.com and pasted into a plain text file before importing
  • iChannelTime[4] and iFrameRate uniforms
  • cubemap and volume (3D texture) iChannel input types, with 6-face cubemap loading and volume-atlas slicing
  • Per-input sampler settings from Shadertoy JSON exports (filter, wrap) now applied per channel instead of one fixed setting for every iChannel; vflip applied at texture load time
  • Clear Shader Issues warnings (instead of a silent dropped channel or an opaque failure) for a shader using an unsupported-by-design iChannel type (Keyboard, Mic) or any channel type not recognized at all
  • A "Shadertoy compatibility" section in the README documenting exactly what's fully supported, what's supported with a deliberate determinism-driven limitation, and what's out of scope

Fixed

  • Inter-pass buffer links in a real shadertoy.com JSON export were resolved by the input's src thumbnail path instead of the opaque id that actually links outputs[] to inputs[], so a genuine Shadertoy export could fail to find its own buffer
  • texelFetch/textureLod were rewritten to HLSL identifiers that were never actually declared anywhere, so any shader using either failed to compile
  • mat2/mat3/mat4 multiplied by a vector translated to HLSL's * operator, which is component-wise rather than a real matrix multiplication, producing a compile error or a wrong result instead of the intended transform
  • A scalar-broadcast vector constructor (vec3(x)) nested inside another multi-argument constructor was never expanded, causing an "incorrect number of arguments" compile error
  • iSampleRate always reported a fixed 44100 Hz instead of the loaded audio file's actual sample rate
  • The live preview's iFrame advanced once per real display refresh instead of tracking the selected export frame rate, so a shader seeding pseudo-randomness from iFrame could look inconsistent between preview and export

Full Changelog: v2.2.3...v2.3.0

v2.2.3

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 24 Sep 13:07

Changed

  • Lowered the minimum supported OS from Windows 11 (build 22000) to Windows 10 version 2004 / build 19041 — the same baseline already required by the app's target framework. Nothing in the render/export pipeline actually required Windows 11; the installer's MinVersion was the only real blocker. The Windows 11 Mica backdrop and rounded window corners degrade gracefully to a standard window on Windows 10.

Full Changelog: v2.2.2...v2.2.3

v2.2.2

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 24 Sep 12:55

Fixed

  • FFmpeg Process leak when Process.Start() throws, which left the export service permanently stuck until the app was restarted
  • Video texture cache key ignoring target resolution — a real GPU memory corruption risk when previewing then exporting a shader with a video texture at a different resolution
  • "Disk full" error incorrectly reclassified as transient, causing pointless export retries
  • FFmpeg SHA-256 integrity check only performed once at startup (TOCTOU); now re-verified before every launch
  • iMouse, iDate, and iChannelResolution uniforms always reading zero
  • Render queue's export loop running on the UI thread, freezing the interface during batch exports
  • No global unhandled-exception handlers
  • ShadertoyJsonParser crashing on valid but unexpectedly-shaped JSON
  • Path traversal in iChannel asset resolution
  • No handling of GPU device loss (DXGI device removed/reset)
  • Output filename not guarded against CLI flag confusion
  • Hardware encoder probe failures silently swallowed
  • Transient COM pixel shader leak on shader compilation failure
  • Unprotected async void handler for video drag-and-drop
  • MainWindowViewModel memory leak from never unsubscribing its event handlers
  • Removed dead, unused single-pass rendering duplication

Added

  • New Videotoy.Tests xUnit project (wired into CI) with regression tests for the FFmpeg transient-error classifier, the resolution-aware video frame cache key, and Shadertoy JSON parsing

Full Changelog: v2.2.1...v2.2.2

v2.2.1

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 24 Sep 12:48
eca1fb3

Added

  • Configurable preview viewport background, completing the item deferred from Phase v2.1.0's alpha-channel export work: a "Preview background" panel section offers a transparent checkerboard (default), a solid color, or a reference image, so a shader exporting with a straight alpha channel can be visually checked against something other than the fixed opaque viewport background. New Videotoy.Media.ViewportBackgroundSettingsService persists the choice globally (%AppData%\Videotoy\viewport-background.json), mirroring OnboardingStateService's storage pattern. Purely a live-preview visualization aid — the exported file always uses the shader's rendered alpha as-is, unaffected by this setting
  • Implemented entirely in XAML: three background layers (a tiled DrawingBrush checkerboard, a bindable SolidColorBrush, or an Image bound to the chosen reference image) stacked behind the existing preview Image, which is already Bgra32 with real per-pixel alpha — WPF's normal compositing handles the blend, so no change was needed to the D3D11 render pipeline or MultiPassRenderer

Full Changelog: v2.2.0...v2.2.1

v2.2.0

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 14 Sep 21:26

Added

  • New "Image Sequence" export mode, alongside Video and Animated Image:
    each rendered frame is written as an individual image file rather than
    muxed into a video container, for direct import into an external
    compositing/editing pipeline. New ImageSequenceExportPipeline
    (Videotoy.Ffmpeg) launches one dedicated FFmpeg encode invocation per
    frame (-frames:v 1, not a single continuous stdin stream like the video/
    animated-image pipelines) — the deliberate reason being that this makes
    resuming an interrupted export trivial: already-encoded frame files are
    simply skipped
  • Four sequence formats, all alpha-carrying: PNG 8-bit (-pix_fmt rgba),
    PNG 16-bit (-pix_fmt rgba64be), TIFF 16-bit with optional LZW
    compression (-pix_fmt rgba64le, -compression_algo lzw), and EXR 16-bit
    half-float (-pix_fmt gbrapf16le, not re-verified against a live
    ffmpeg.exe in this environment — see the code comment on
    FfmpegImageSequenceOptions). Scoping note: the render pipeline is
    currently 8-bit RGBA only (no HDR float render target — planned for
    v2.3.0), so the 16-bit PNG/TIFF and EXR formats are produced by
    bit-depth-expanding the existing 8-bit source, not genuine wider dynamic
    range; Domain.ImageSequenceFormat's doc comment states this plainly, and
    the written metadata JSON's colorspace note is honest about it too
    ("Linear half-float (expanded from 8-bit sRGB source — not true HDR; see v2.3.0)" for EXR)
  • Configurable frame naming: a printf-style pattern (frame_%05d.png) or a
    token pattern ({index}/{time}, e.g. shot_{index}_{time}.png) via
    Domain.ImageSequenceNamingMode, validated to always contain a
    frame-distinguishing specifier/token (ImageSequenceExportSettingsValidator
    rejects a pattern that would make every frame overwrite the same file).
    Collision detection scans the output directory before starting; if
    matching frame files already exist, the render settings panel shows an
    inline confirmation prompt offering to resume or to overwrite
  • Resume of an interrupted sequence export: when frame files already exist
    and the user chooses "Resume", already-encoded frame indices are skipped
    rather than re-rendered — the frame is still rendered (the deterministic
    renderer has no arbitrary-index resume API), only the FFmpeg
    encode/disk-write step is skipped, which stays far cheaper than the
    per-frame FFmpeg invocation it avoids
  • A <sequence-name>.metadata.json file written in the output directory at
    the end of a successful export: resolution, FPS, first/last frame index
    actually written, colorspace note, alpha mode, and format — for import
    into external compositing/editing tools
  • Integration with the render queue: RenderQueueItemKind.ImageSequence
    alongside the existing Video/AnimatedImage kinds, with its own
    persisted settings group in RenderQueueItem
  • New Core modules: ImageSequenceExportSettingsValidator (validation,
    naming-pattern resolution/substitution, format/naming-mode key
    round-tripping) and ImageSequenceFileSizeEstimator (coarse per-format
    bytes-per-pixel estimate — PNG/TIFF/EXR have no bitrate/CRF concept, so
    this is intentionally coarser than the video estimator)