4 ms·
I'm curious if there are technical benefits to interfacing with WebGPU via JS or via WASM (Rust, specifically)? I am currently teaching myself Rust + Bevy with
by SeanAnderson 4y ago
I'm curious if there are technical benefits to interfacing with WebGPU via JS or via WASM (Rust, specifically)?
I am currently teaching myself Rust + Bevy with the intent of shipping some proof-of-concept game following the ECS paradigm rendered using WebGPU. This is going fine and I am excited to learn the tech, but my bread-and-butter is JavaScript and I only desire targeting the web. At time of writing, Bevy's (WebGL) examples don't run on Android devices which is a bit concerning.
There is some compelling JS tooling out there for rendering - Babylon, AFrame, UseGPU, etc, but they all have their issues.
Babylon: not designed with ECS in mind, same as ThreeJS, declarative programming can be achieved through plugins, but it's fragile and significantly less performant than if built natively into the framework.
AFrame: powered by Three, but ECS-first and I assume it does a good job at it. Not practical for 2D rendering and really intends to be VR-first with a nod to non-VR 3d.
UseGPU: truly what I would like to be using as it's declarative by design, but it's so new that 2D Sprite is still on the TODO list. I'm not skillful enough in low-level graphics programming (yet!) to assist in the development.
I really want to be ready for this technological shift. I fully intend to build something as complex as RimWorld that runs in your browser. I'm taking baby steps, as quickly as I can, to get there, but am not sure what tools to be adopting to best prepare.
At the moment I'm betting on Bevy because it has a lot of wind behind its sails, its all-in on ECS, and I suspect avoiding GC for compute-heavy gaming will be beneficial. I don't know what interfacing to WebGPU via JS gets me aside from a potentially more rapid prototyping environment. I'd love to hear others' takes on this to ensure I don't burn months looking in the wrong direction.
- rootw0rm 4y agoIf you're okay with voxels, check out veloren.net ECS based game engine in Rust, wgpu rendering, and I've been really impressed with the code quality. I've been trying to find something to inspire me to really go all in with Rust, and I think I found it with Veloren
- SeanAnderson 4y agoThanks for the suggestion! I will check it out. Voxels are definitely interesting :) At first glance, this does look like it will be a great resource. Even just having high-quality examples of how to configure Cargo and etc. boilerplate will save me a lot of hours. Doesn't look like they target WASM at all, though. I wonder what the main concerns were/are?
- rootw0rm 4y agoI know WASM is used for the scripting system. WASM isn't really on my radar right now, so I can't offer advice, but I do know there are at least good Rust resources regarding WASM. Also, the Veloren team is really responsive on Discord, so that might be worth looking into. The rendering systems are fully separated from game logic systems, so it's at least got that going for it
- sxp 4y agoOne drawback I ran into with wgpu.rs was that targeting WASM builds would result in a much weaker set of GPU features on the browser than a native Rust build. I don't know if this affect Bevy or your specific use cases, but it annoyed me enough that I decided to only focus on native wgpu development instead of supporting both native & the browser.
- SeanAnderson 4y agoThanks for the feedback. Indeed, I'm not of the impression that I will be able to perfectly compete with native, but hoping WebGPU is still a marked improvement over WebGL2. I am heavily prioritizing accessibility as I'm trying to build a game that users use for only a couple of minutes each day. So, a really really low barrier to entry is important as I do not see my player base being willing to open Steam for a couple of minutes of gameplay, but I do think they'll open a tab. I'm OK losing polish in exchange.
- eyelidlessness 4y agoAs a general rule of thumb, WASM (and therefor Rust) will perform: - better for compute heavy workloads which don’t need to interop with JS and JS-only APIs - roughly the same or worse for mixed workloads with highly optimized interop - worse for JS heavy workloads, no matter how much you optimize Partly this is because interop has a steep cost that negates the perf benefits in such workloads. Mostly it’s because JS runtimes have very good performance characteristics, beating that is a big feat. There are certainly performance focused mixed native/JS projects with great potential. Almost all of them are either very light on interop or very heavy on deep understanding of both the native language’s performance advantages and that of the JS runtime (which is often itself very runtime specific). If you have a lucky workload that doesn’t need to cross interop boundaries much, the world is your oyster. If you have any other workload, you’re probably better off working with whatever you feel most comfortable to deliver and optimize for your use case.
- SeanAnderson 4y agoI thought I had read something in the past ~6 months implying that performance gap had become less of an issue, but I'd have to dig for a bit to find it. I understand that I should always expect crossing the WASM boundary to be slow. I'm basically trying to build something that's like a colony sim meets idleRPG. You define a strategy once per day, submit it, and the colony sim chews on the instructions and plays forward. The user can just observe and devise a plan for adjusting their strategy the next day. I think this makes it an especially good candidate for WASM as I can simulate hundreds of semi-intelligent entities and don't ask for responsive user input. I think there's also benefits with garbage collecting, right? I can avoid GC entirely with WASM but would inherently be subject to it with JS which then pushes me into a more imperative/mutable style of coding in an effort to preserve object lifetimes. I'd really rather stick to a declarative style if I can get away with the performance.
- flohofwoe 4y agoCalling between JS and WASM isn't really a performance bottleneck anymore in itself [1] (but it is an 'optimization boundary' for the compiler, the same way that a DLL call would be in a native application). [1] https://hacks.mozilla.org/2018/10/calls-between-javascript-and-webassembly-are-finally-fast-%F0%9F%8E%89/ https://hacks.mozilla.org/2018/10/calls-between-javascript-a...
- jspdown 4y agoThere is one clear benefit to me. Targeting native platforms allow the use of RenderDoc or equivalent. This is of a tremendous help when debugging or profiling. I've been working on a realtime softbody simulation in WebGPU for a while. After trying it in JS, C++ and Rust, wgpu is by far the best experience I got with WebGPU
- panic 4y agoIn my experience, avoiding GC is necessary to hit consistent a 60 FPS. GC pauses will mean randomly dropped frames.
- flohofwoe 4y ago> I'm curious if there are technical benefits to interfacing with WebGPU via JS or via WASM (Rust, specifically)? In general WASM vs (well-written) JS shouldn't matter much for most scenarios, but there's one important drawback when using WebGPU via WASM: any buffer mapping operation needs to do an extra copy to get the data in and out of the WASM heap (e.g. there's currently no way to directly access (another) JS ArrayBuffer object from WASM). It's not a show stopper of course, but something to keep in mind when shuffling a lot of data between the CPU side and WebGPU. PS: IMHO the biggest downside of using WebGPU natively is that it comes with a builtin shader compiler and/or cross-compiler to translate either WGSL or SPIRV to the shader dialects used by the various backend APIs. This adds a couple of complex dependencies and quite a bit of binary size (much more than "just" the WebGPU implementation). It would be nice if the native WebGPU implementations would allow to move all that shader compile/transpile stuff offline, and feed the WebGPU API with backend-specific shader blobs.
- Jasper_ 4y agoI believe both Dawn and wgpu are planning on supporting SPIR-V ingestion for native use cases,
- flohofwoe 4y agoYep, but at least for the D3D12 and Metal backend the input SPIRV needs to be translated to HLSL (or maybe directly to DXIL?) and MSL. Not sure if the Vulkan backends accept the input SPIRV directly or whether there's also some translation happening.
- Jasper_ 4y agowgpu supports both a SPIR-V passthrough mode [0] and a regular SPIR-V mode where it will get some transformations added to it (e.g. bounds checks are added on backends without VK_KHR_robustness). I don't believe Dawn has a similar passthrough mode, only a SPIR-V -> transform -> SPIR-V path. [0] https://docs.rs/wgpu/latest/wgpu/struct.Features.html#associatedconstant.SPIRV_SHADER_PASSTHROUGH https://docs.rs/wgpu/latest/wgpu/struct.Features.html#associ...
- Narishma 4y agoFor something like RimWorld WebGL 1 should be more than enough, no? I don't think it's doing anything complex graphically. As a bonus, you'll be able to run on a lot more devices.
- SeanAnderson 4y agoHonestly, I am not sure, lol. I guess my thoughts were: - Dwarf Fortress has existed since forever and neither DF nor RimWorld nor anything remotely similar seems to exist as browser-first software. Clearly it's not due to graphics limitations, but perhaps market economics? - WebGPU isn't just about graphical performance. It's also about GPGPU. I was thinking some of the in-game algorithms would become more viable to run in this environment. I'm learning a few pieces of tech at the same time, though. It might be the case that I find that avoiding GC with Rust/WASM and gaining memory locality perf benefits with ECS address the main limiting factors. I think I'm just a bit caught up in the hype of WebGPU coming out, too, and so am assuming it must be relevant to my solution. It might not be!