-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
83 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
--- | ||
layout: post | ||
title: wgpu-rs on the web | ||
--- | ||
|
||
[gfx-rs](https://github.com/gfx-rs/gfx) is a Rust project aiming to make low-level GPU programming portable with low overhead. It's a single Vulkan-like Rust API with multiple backends that implement it: Direct3D 12/11, Metal, Vulkan, and even OpenGL. | ||
|
||
[wgpu-rs](https://github.com/gfx-rs/wgpu-rs) is a Rust project on top of gfx-rs that provides safety, accessibility, and even stronger portability. | ||
|
||
## Running wgpu-rs natively | ||
|
||
As we previously discussed in [The rise of wgpu](http://gfx-rs.github.io/2019/03/06/wgpu.html), the gfx team has been busy with development of `wgpu-native` (a C API which implements the [WebGPU specification](https://gpuweb.github.io/gpuweb/)) and `wgpu-rs` (an idiomatic Rust wrapper around `wgpu-native`). | ||
|
||
Even though these crates are still relatively new, it's been very exciting to watch people build all kinds of neat projects which use them, including: | ||
|
||
- a [GUI library](https://github.com/hecrj/iced) | ||
- a [pixel editor](https://github.com/cloudhead/rx) | ||
- [tutorials](https://sotrh.github.io/learn-wgpu/) | ||
- [multiple](https://github.com/hecrj/coffee) [game](https://github.com/Ruddle/oxidator) [engines](https://github.com/StarArawn/harmony) | ||
- a [creative-coding toolkit](https://github.com/nannou-org/nannou) | ||
- a [sailing navigation application](https://github.com/Yatekii/sailor) | ||
- a [Brawl character file parser](https://github.com/rukai/brawllib_rs) | ||
- a [hardware-accelerated pixel buffer](https://github.com/parasyte/pixels) | ||
- [Python bindings](https://github.com/almarklein/wgpu-py) | ||
- a [Rust vangers clone](https://github.com/kvark/vange-rs) | ||
- a [Chinese calligraphy app](https://apps.apple.com/us/app/id1492608770) | ||
- [Scopes bindings](https://nest.pijul.com/porky11/wgpu) | ||
- and many more interesting projects! | ||
|
||
There is even an [awesome-wgpu list](https://github.com/rofrol/awesome-wgpu) that the community has started in order to aggregate wgpu-related learning resources and examples in one place. | ||
|
||
Because `wgpu-rs` is cross-platform, all of these projects can run natively on top of Vulkan, Metal, DX12, and DX11. Internally `wgpu-rs` automatically selects a graphics API for the user based on which graphics APIs are available at runtime, although users may specify which graphics API to use if they prefer. For older devices which don't support these modern APIs, limited GL support is also [actively being worked on](https://github.com/gfx-rs/wgpu/issues/450). | ||
|
||
## Running wgpu-rs on the web | ||
|
||
When we started the `wgpu-rs` crate, we wanted to eventually support two backends: | ||
|
||
- a "native" backend implemented with `wgpu-native`/`gfx` | ||
- a "web" backend which uses the WebGPU API provided by the browser | ||
|
||
Until recently, `wgpu-rs` was only able to run on the native backend, simply because the WebGPU API wasn't available in any browsers. But now that's changing, because browser vendors have been making [rapid progress on implementations of WebGPU](https://github.com/gpuweb/gpuweb/wiki/Implementation-Status#implementation-status). | ||
|
||
With the WebGPU API beginning to become available in Firefox Nightly and Chrome Canary behind experimental flags, we decided it was time to add a web backend. We [mapped the existing `wgpu-rs` API to the browser API](https://github.com/gfx-rs/wgpu-rs/pull/193), compiled our examples using the `wasm32-unknown-unknown` target, and were quickly able to run our examples on the web: | ||
|
||
![Boids](/img/wgpu-boids.png) | ||
|
||
In the above screenshot, the same example is running inside of Firefox Nightly (top left), Chrome Canary (bottom left), and natively (right). [This example](https://github.com/gfx-rs/wgpu-rs/tree/master/examples/boids) uses a compute shader to [simulate flocking](https://en.wikipedia.org/wiki/Boids) and renders the result. macOS is used in the screenshot, but this example also runs on Windows and Linux without any code changes. | ||
|
||
All `wgpu-rs` examples are currently available at <https://wgpu.rs/examples/>. [The WebGPU API has to be enabled in the browser](https://github.com/gfx-rs/wgpu-rs/pull/193#issuecomment-613182772) in order to run these examples. Note that browser WebGPU support is still experimental and a work in progress, so attempting to run them may cause the browser to crash or they may fail to run/render. | ||
|
||
## Getting started with wgpu-rs on the web | ||
|
||
To take advantage of the new web backend in `wgpu-rs` and run on the web, crates can be compiled using the `wasm32-unknown-unknown` target. Because the WebGPU API is experimental, for now an unstable APIs flag (`--cfg=web_sys_unstable_apis`) must be provided in the `RUSTFLAGS` environment variable in order to use WebGPU from `web-sys` (the crate which exposes web APIs to Rust). | ||
|
||
After the crate has been compiled with `wasm32-unknown-unknown`, the WebAssembly can be executed within a browser. [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) can be used to generate JavaScript bindings, or the WebAssembly can be called manually. | ||
|
||
For example, to compile the [`hello-triangle`](https://github.com/gfx-rs/wgpu-rs/tree/master/examples/hello-triangle) example and generate bindings with `wasm-bindgen`: | ||
|
||
```bash | ||
# Build with the wasm target | ||
RUSTFLAGS=--cfg=web_sys_unstable_apis cargo build --target wasm32-unknown-unknown --example hello-triangle | ||
# Generate bindings with wasm-bindgen-cli into a `generated` directory | ||
cargo install -f wasm-bindgen-cli && wasm-bindgen --out-dir generated --web target/wasm32-unknown-unknown/debug/examples/hello-triangle.wasm | ||
``` | ||
|
||
Then add a simple `index.html` inside the `generated` directory to run the WebAssembly: | ||
|
||
```html | ||
<html> | ||
<body> | ||
<script type="module"> | ||
import init from "./hello-triangle.js"; | ||
init(); | ||
</script> | ||
</body> | ||
</html> | ||
``` | ||
|
||
Now run a web server from the `generated` directory to see `hello-triangle` in the browser: | ||
|
||
![Hello Triangle](/img/wgpu-hello-triangle.png) | ||
|
||
We are really excited to see `wgpu-rs` projects running on the web. Even though it's still early days for WebGPU, we look forward to the new possibilities in high-performance, portable graphics and compute that this will enable. Please let us know on [the wgpu-rs Matrix channel (#wgpu:matrix.org)](https://matrix.to/#/#wgpu:matrix.org) or [through the wgpu-rs issue tracker](https://github.com/gfx-rs/wgpu-rs/issues) if your project takes advantage of this new web backend. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.