A standalone Tauri v2 + raw WebGL example for compositing two independent image or video sources in one fragment-shader pass.
The exact folder name is:
18-tauri-v2-texture-mixer
npm install
npm run dev
The project contains an explicit Cargo workspace boundary, so it remains independent from any parent Cargo.toml.
Layer A and Layer B each support images or videos. Use Native open, Browser open, or drop a file onto the corresponding layer card. When a native drop occurs outside a card, it is routed to the currently active layer.
Supported extensions include:
Actual decoding support is determined by the operating-system WebView.
Images and videos use different secure loading paths:
Native image → Rust binary read → IPC Response → Blob URL → WebGL texture
Native video → runtime asset authorization → convertFileSrc() → HTML video → WebGL texture
This prevents the WebKit SecurityError: The operation is insecure problem that can occur when an asset-protocol image is uploaded directly to WebGL.
Videos are muted, looped, and played inline. Each video has independent play/pause and playback-speed controls.
The app launches with two generated images, so the complete mixer can be tested before loading media.
Select Layer A or Layer B, then adjust:
Swap A ↔ B exchanges the complete source state, including media, transform, opacity, and video transport.
The Mix control determines how strongly Layer B and the selected blend operation affect the result. Auto crossfade animates that amount in the shader without moving the slider.
Layer B can be limited by:
Mask controls include threshold, feathering, scale, angle, center position, and inversion. The mask inspection view displays the final mask in grayscale.
Layer A image/video ─► texture A ─► transform A ─┐
├─► blend ─► mask ─► canvas
Layer B image/video ─► texture B ─► transform B ─┘
No CPU pixel compositing occurs during normal rendering. Video frames are uploaded before drawing; still images remain resident as GPU textures.
The current composition can be exported as PNG or JPEG at:
Large exports are written to Rust in sequential 1 MiB chunks. Browser download is retained as a fallback outside Tauri.
withGlobalTauri exposes the vanilla JavaScript APIstauri::ipc::Response18-tauri-v2-texture-mixer/
├── package.json
├── README.md
├── V2-FOLDER-MAP.md
├── src/
│ ├── index.html
│ ├── styles.css
│ └── app.js
└── src-tauri/
├── Cargo.toml
├── build.rs
├── tauri.conf.json
├── capabilities/default.json
├── icons/
└── src/main.rs