Files
gpupaper/README.md
T

123 lines
4.7 KiB
Markdown
Raw Permalink Normal View History

2026-06-09 11:16:47 +02:00
# gpupaper
Wayland layer-surface wallpaper runner powered by GLSL/WGSL fragment shaders, built on [wgpu](https://wgpu.rs).
Runs shaders full-screen on one or all monitors as a proper compositor layer surface (via `zwlr-layer-shell-v1`). Supports Vulkan and OpenGL backends, with automatic fallback for drivers that misbehave at device creation (e.g. Mesa V3DV on Raspberry Pi).
## Features
- **GLSL and WGSL shaders** — use `.frag`/`.glsl` for GLSL or `.wgsl` for WGSL
- **ShaderToy-compatible GLSL** — shaders using `mainImage(out vec4, in vec2)` work without modification
- **glpaper-compatible GLSL** — shaders using `void main()` and `gl_FragColor` work as-is
- **Multi-monitor support** — target a specific output by name or use `all` to run on every connected display simultaneously
- **Hotplug** — new outputs are picked up automatically when using `all`
- **Vulkan-first with GL fallback** — prefers discrete Vulkan, falls back gracefully to integrated or GL
- **Layer selection** — place the shader on any compositor layer: `background`, `bottom`, `top`, or `overlay`
- **FPS cap** — optionally limit frame rate; defaults to vsync
## Shader uniforms
The following uniforms are available in all shaders:
| Uniform | Type | Description |
|--------------|---------|------------------------------------|
| `time` | `float` | Seconds since program start |
| `resolution` | `vec2` | Output dimensions in pixels |
| `mouse` | `vec2` | Mouse position (currently `0,0`) |
**WGSL** shaders receive these via a uniform buffer:
```wgsl
struct Uniforms {
time: f32,
_pad: f32,
resolution: vec2<f32>,
mouse: vec2<f32>,
}
@group(0) @binding(0) var<uniform> u: Uniforms;
```
**GLSL** shaders can declare them as bare `uniform` variables — gpupaper strips those declarations and injects the UBO automatically, so existing ShaderToy-style shaders need no changes.
## Usage
```
gpupaper <output> <shader_file> [--fps <n>] [--layer <layer>]
```
| Argument | Description |
|-----------------|----------------------------------------------------------------|
| `<output>` | Wayland output name (e.g. `HDMI-A-1`) or `all` / `*` |
| `<shader_file>` | Path to a `.frag`, `.glsl`, or `.wgsl` shader file |
| `--fps <n>` | Target frame rate; `0` = vsync (default) |
| `--layer` | Compositor layer: `background` (default), `bottom`, `top`, `overlay` |
**Examples:**
```bash
# Run on all outputs, vsync
gpupaper all /usr/share/gpupaper/shaders/wave.frag
# Run on a specific monitor, capped at 30 fps
gpupaper DP-1 ~/shaders/my_shader.frag --fps 30
# Run on the bottom layer (above wallpaper managers that use background)
gpupaper all /usr/share/gpupaper/shaders/fireflies.frag --layer bottom
```
Output names can be found with `wlr-randr`, `hyprctl monitors`, or `wayland-info`.
## Bundled shaders
A collection of example shaders is installed to `/usr/share/gpupaper/shaders/`:
`black_hole` · `building` · `cloud` · `cloudninja` · `cubes` · `fireflies` · `firering` ·
`flags` · `fluid_spiral` · `green_lines` · `light_line` · `light_wave` · `matrix` · `mickey` ·
`rainbow_donut` · `rainbow_lights` · `rainbow_ring` · `rainbow_triangle` · `red_lines` ·
`slinky` · `snake_torus` · `space` · `spiral` · `torus` · `trippy_cube` · `tunnel` ·
`twisty` · `water` · `wave` · `white_hole` · `yellow_lines`
## Installation
### Arch Linux (AUR)
Binary package for `x86_64` and `aarch64` (no build dependencies required):
```bash
yay -S gpupaper
```
Or build from source:
```bash
yay -S gpupaper-git
```
### From source
Dependencies: Rust stable, `libwayland`, `libxkbcommon`, `pkg-config`
```bash
cargo build --release
./target/release/gpupaper --help
```
## Compatibility
| Platform | Backend | Notes |
|-----------------------|-----------------|-----------------------------------------|
| AMD / Intel (desktop) | Vulkan | |
| NVIDIA | Vulkan | Requires `nvidia-utils` |
| Raspberry Pi 4/5 | OpenGL (EGL) | V3DV Vulkan driver skipped automatically|
| Most other hardware | Vulkan or GL | Whichever wgpu can initialise first |
Requires a Wayland compositor that implements `zwlr-layer-shell-v1` (Sway, Hyprland, river, labwc, and most wlroots-based compositors).
2026-06-09 11:26:02 +02:00
## Acknowledgements
Inspired by [glpaper](https://hg.sr.ht/~scoopta/glpaper) by Scoopta. gpupaper extends the concept with multi-monitor support, WGSL, a wgpu backend, and compatibility with both glpaper-style and ShaderToy-style GLSL shaders.
2026-06-09 11:16:47 +02:00
## License
MIT