A modern Rust + wgpu renderer for Resonite. Unofficial Renderide thread discussion here (in the Resonite Discord).
Also available as an AUR package.
If you're interested in supporting my work, please consider donating on Ko-Fi or GitHub Sponsors.
Renderide is experimental and may have visual bugs that are more severe or unexpected than Resonite's default Unity renderer, including flicker, flashing frames, incorrect brightness or contrast, broken post-processing, and rapidly changing patterns. These renderer artifacts, as well as user-created content, can trigger seizures or other symptoms in people with photosensitive epilepsy or related sensitivities. Stop using Renderide immediately and move away from the display if you feel dizzy, disoriented, nauseated, experience eye discomfort, or notice involuntary movement or vision changes.
Please report crashes, bugs, missing features, performance problems, and other feedback through whichever channel fits best:
Experimental: performance, stability, and platform support are still evolving. Visual bugs and missing features are expected.
Resonite ships with a Unity-based renderer driven by the FrooxEngine host. Renderide is a drop-in replacement for that renderer, written in Rust on top of wgpu and OpenXR. The host process is unchanged; Renderide attaches to it over shared-memory queues and takes over rendering, windowing, and XR.
The split lets the engine and renderer evolve independently and lets the renderer target Vulkan, Metal, and DirectX 12 from a single Rust codebase. OpenGL can also be selected as a fallback backend in the renderer config.
Prerequisites: a GPU with a wgpu-supported desktop backend (Vulkan, Metal, DirectX 12, or OpenGL fallback) and a Steam installation of Resonite. OpenXR VR startup currently uses Vulkan regardless of the configured desktop graphics API.
Renderide/ directory:bash
git clone https://github.com/DoubleStyx/Renderide.git
cd Renderide
bash
cargo build --release
bash
./target/release/renderide
The launcher will start the Resonite host and connect Renderide automatically.
Enable GPU validation layers in the config HUD to get more detailed error messages for GPU crashes. Requires a restart.
Logs are timestamped files under a selected logs root. Source builds normally resolve the active repository and write renderer logs to logs/renderer/. Installed release binaries fall back to the current user's platform log root: $XDG_STATE_HOME/renderide/logs or ~/.local/state/renderide/logs on Linux, ~/Library/Logs/Renderide on macOS, and %LOCALAPPDATA%\Renderide\logs on Windows. Set RENDERIDE_LOGS_ROOT to choose the root explicitly; component logs then live under renderer/, bootstrapper/, host/, renderer-test/, and SharedTypeGenerator/. The Renderer config HUD also shows the selected log folder and includes an "Open log folder" button.
You can add Steam-style launch arguments after the launcher to enable mods: <path-to-renderide> -LoadAssembly Libraries/ResoniteModLoader.dll
Renderide runs the Resonite Host from the Windows depot and renders natively through Metal. The launcher accepts an explicit Resonite install path, so local builds and release zips should not need hand-written symlinks or source edits.
bash
steamcmd +@sSteamCmdForcePlatformType windows \
+force_install_dir "$HOME/Games/ResoniteWindows" \
+login anonymous \
+app_update 2519830 validate \
+quit
If anonymous access is unavailable, use the Steam login that owns Resonite.
Install the .NET runtime requested by the Resonite Host so dotnet is available on PATH.
Run the launcher with the Windows depot path:
bash
./target/release/renderide --resonite-dir "$HOME/Games/ResoniteWindows"
Release zips use the same argument from the extracted folder:
bash
./renderide --resonite-dir "$HOME/Games/ResoniteWindows"
The macOS release zip contains renderide, renderide-renderer, shaders, xr, and the bundled OpenXR loader. If macOS quarantine blocks a downloaded zip, remove the quarantine attribute from the extracted Renderide folder:
xattr -dr com.apple.quarantine /path/to/renderide-folder
Leave RENDERIDE_INTERPROCESS_DIR unset unless every participating Renderide and Host process is configured to the same path. For host-limited framerates, Resonite's forced separation setting can improve throughput, but it is not required for startup.
unsafe is restricted to FFI and justified hot paths; library code avoids unwrap, expect, and panic!.Renderide runs as a sibling process to the Resonite host. The bootstrapper launches both and wires up the IPC channels:
Bootstrapper --shm queues--> Host (.NET / Resonite)
|
shm queues (Primary + Background)
|
v
Renderer (renderide-renderer)
Inside the renderer, work is organized by layer and supporting renderer subsystems:
Each tick: poll IPC, integrate a budgeted slice of pending assets, drain offscreen camera/reflection-probe tasks, run the optional OpenXR begin step, complete the lock-step exchange with the host, schedule and render views, present or submit the HMD frame, then update HUD and diagnostics state.
The workspace lives under crates/:
| Crate | Purpose |
|---|---|
bootstrapper |
Builds the renderide launcher. Launches the Resonite host and renderer, owns bootstrap IPC (heartbeats, clipboard, renderer argv), and ties child process lifetimes together. |
renderide |
Builds the renderide-renderer process and roundtrip helper. Owns winit, wgpu, OpenXR, scene mirroring, asset integration, materials, particles, render graph, diagnostics, and presentation. |
renderide-shared |
Generated IPC types, binary packing helpers, shared-memory accessors/writers, and dual-queue wrappers. |
interprocess |
Cloudtoid-compatible shared-memory ring queues used by every IPC channel. |
logger |
File-first logging used by the bootstrapper, host capture, and renderer. |
renderide-test |
Integration test harness that drives the renderer end-to-end. |
A C# generator under generators/SharedTypeGenerator emits crates/renderide-shared/src/shared.rs. Its test project lives under generators/SharedTypeGenerator.Tests and uses the roundtrip binary to compare C# and Rust packing. RenderideMod contains the host-side Resonite mod, crates/renderide/assets contains runtime XR bindings and the shipped skybox model, and third_party/openxr_loader contains vendored OpenXR loader binaries used by release artifacts on Windows and macOS.
The renderide crate exposes opt-in Cargo features for capabilities that depend on platform-specific system libraries or that are only useful in some workflows. Stock builds (cargo build) enable none of them.
Multiple features can be combined as a single space-separated argument:
cargo build --release --features "tracy video-textures"
tracyCPU and GPU profiling integration. Activates profiling::scope! zones, frame marks, and wgpu-profiler GPU timestamp queries that stream into the Tracy profiler GUI on port 8086. The Tracy client links statically, so this feature has no system-library prerequisites.
cargo build --release --features tracy
See Profiling for adapter requirements and connection details.
video-texturesGStreamer-backed video texture playback. With the feature off (the default), video texture IPC commands still allocate a GPU placeholder, but no decoding runs and the placeholder stays black.
System dependencies:
libgstreamer1.0-dev, libgstreamer-plugins-base1.0-dev, and gstreamer1.0-plugins-good on Debian/Ubuntu, or the equivalent GStreamer core/base development packages plus Good Plugins package on other distros. The Good Plugins package provides videoflip, which Renderide uses to match the renderer's texture orientation.brew install gstreamer.pkg-config (pkgconf rather than pkgconfiglite).cargo build --release --features video-textures
Renderide reads its settings from a TOML file discovered (or created) at startup. Set RENDERIDE_CONFIG to point at a specific file; otherwise Renderide uses the current user's platform config directory and writes Renderide/config.toml there on first launch when possible.
The in-renderer ImGui config HUD edits the shared in-memory settings and persists them back to the same TOML file. Manual file edits are not watched or hot-reloaded while the process is running. Some settings, including GPU validation layers, graphics API, adapter power preference, and watchdog settings, are startup-only and require a renderer restart after changing. Explicit desktop graphics API choices are used for screen and headless startup; OpenXR startup logs a warning for non-Vulkan choices and uses its Vulkan path.
The full schema lives next to the loader in crates/renderide/src/config.
Renderide integrates with Tracy for CPU and GPU profiling.
CPU spans come from the profiling crate; GPU timestamp queries come from wgpu-profiler.
CPU profiling only requires the tracy feature. Pass-level GPU profiling requires TIMESTAMP_QUERY adapter support; frame-bracket and encoder-level GPU timing also require TIMESTAMP_QUERY_INSIDE_ENCODERS.
If timestamp queries are unavailable, a warning is logged and Tracy still receives CPU spans.
cargo build --release --features tracy
Download the Tracy profiler GUI from the Tracy releases page and launch it.
Start Renderide normally (launcher or renderer directly).
In the Tracy GUI, connect to localhost on port 8086.
Renderide uses Tracy's ondemand mode: data is only streamed while the GUI is connected, so
profiled builds carry near-zero runtime cost when Tracy is not attached.
Linux, macOS, and Windows are all tier-1 targets and exercised in CI (.github/workflows/). iOS and Android are not yet supported, but the codebase avoids hard dependencies on desktop-only APIs where portable alternatives exist.
Contributions are welcome. The workspace builds with the standard Cargo commands listed above; lints (cargo clippy --all-targets, with feature coverage matching CI) and formatting (cargo fmt, plus `tapl
$ claude mcp add Renderide \
-- python -m otcore.mcp_server <graph>