One of the most requested features for vange-rs was to have binary releases. It turned out that glsl-to-spirv that we used was completely unportable. It expected to be present on the target machine at the same directory as the developer one had at build time. This happened to be blocking both the binary releases, and a proper Web port in the future.

WGSL

Recently, we finished migrating the essential majority of the shaders to WebGPU Shading Language. This allowed the shaders to be written in a more modern way, with multiple entry points and type inference. For example, this is how the scattering shader looks like now:

[[block]]
struct Storage {
    data: array<atomic<u32>>;
};
[[group(2), binding(0)]] var<storage, read_write> s_Storage: Storage;

[[stage(compute), workgroup_size(16, 16, 1)]]
fn clear([[builtin(global_invocation_id)]] pos: vec3<u32>) {
    if (pos.x < u_Locals.screen_size.x && pos.y < u_Locals.screen_size.y) {
        //TODO: 0xFFFFFF00U when hex is supported
        atomicStore(&s_Storage.data[pos.y * u_Locals.screen_size.x + pos.x], 4294967040u);
    }
}

[[stage(vertex)]]
fn copy_vs([[builtin(vertex_index)]] index: u32) -> [[builtin(position)]] vec4<f32> {
    return vec4<f32>(
        select(-1.0, 1.0, index < 2u),
        select(-1.0, 1.0, (index & 1u) == 1u),
        0.0, 1.0,
    );
}

struct CopyOutput {
    [[location(0)]] color: vec4<f32>;
    [[builtin(frag_depth)]] depth: f32;
};

[[stage(fragment)]]
fn copy_fs([[builtin(position)]] pos: vec4<f32>) -> CopyOutput {
    ...
}

[[stage(compute), workgroup_size(16,16,1)]]
fn main(
    [[builtin(global_invocation_id)]] global_id: vec3<u32>,
    [[builtin(num_workgroups)]] num_workgroups: vec3<u32>,
) {
    ...
}

Today, all of the terrain shaders are ported over, and same goes for the object rendering and debugging. Everything except GPU physics is running WGSL path now, which is pure Rust from text to the target user drivers. We haven’t figured out if the GPU physics path is worth maintaining/supporting. It’s unlikely that physics is going to be a big issue in performance any time soon.

Releases

With glsl-to-spirv out of the way, and vange-rs ported on wgpu-0.10 release, the native dependencies (including SPIRV-Cross) are gone. Game is building faster, running faster, and is much easier to maintain.

It took a few rounds of fixes to get the game to a state where it can be ran consistently on all platforms. It’s not flawless by any means: there are frame pacing issues on some, and driver bugs on some other. But the general idea, the concept of having a single sane code base in Rust that is efficiently running on all platforms - that is there. And it runs fast, given how light the wgpu abstraction has become.

3rd-person rendering

We’ve set up an automated releasing workflow, so the binaries can be created and uploaded whenever we feel necessary. Check out Rusty Vangers 0.2 release!

Finally, as the executables are both hosted and portable, we decided it’s time to reach out to wider audience. We created a small page for the game on Itch.io. Hopefully, the running instructions aren’t too complicated.

The future frontier now is publishing directly on the Web, using WebGPU backend.