• Stars
    star
    138
  • Rank 263,006 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 3 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A tiny WebGPU renderer written in Rust

Build Status Crate

wgpu-rust-renderer

wgpu-rust-renderer is a tiny WebGPU Renderer written in Rust.

Demo

Online WebAssembly Demo

Rust code is compiled to WebAssembly with wasm-bindgen and it runs even in web browsers.

Screenshots

Desktop application.

Desktop app

Web application.

Web app

Features

  • Tiny WebGPU Renderling library
  • Easy to use
  • Memory safe with Rust
  • glTF support
  • Good flexibility and extensibility of materials with node-based material system
  • Web application compatible by compiling to WebAssembly

Documentation

T.B.D.

Sample Code

use winit::{
  event::{Event, WindowEvent},
  event_loop::{ControlFlow, EventLoop},
  window::Window,
};
use wgpu_rust_renderer::{
  math::color::Color,
  renderer::wgpu_renderer::{
    WGPURenderer,
    WGPURendererOptions,
  },
  resource::resource::{
    ResourceId,
    ResourcePools,
  },
  scene::{
    camera::PerspectiveCamera,
    mesh::Mesh,
    node::Node,
    scene::Scene,
  },
  utils::{
    geometry_helper::GeometryHelper,
    material_helper::MaterialHelper,
  },
};

fn create_scene(
  window: &Window,
  pools: &mut ResourcePools,
) -> (ResourceId<Scene>, ResourceId<PerspectiveCamera>) {
  let mut scene = Scene::new();

  let geometry = GeometryHelper::create_triangle(
    pools,
    1.0,
    1.0,
  );

  let material = MaterialHelper::create_basic_material(
    pools,
    Color::set(&mut Color::create(), 1.0, 0.0, 0.0),
  );

  let mesh = pools.borrow_mut::<Mesh>()
    .add(Mesh::new(geometry, material));
  let node = pools.borrow_mut::<Node>()
    .add(Node::new());
  scene.add_node(&node);
  scene.assign(&node, &mesh);

  let window_size = window.inner_size();
  let camera = pools.borrow_mut::<PerspectiveCamera>().add(
    PerspectiveCamera::new(
      60.0_f32.to_radians(),
      window_size.width as f32 / window_size.height as f32,
      0.1,
      1000.0,
    ),
  );

  let mut node = Node::new();
  node.borrow_position_mut()[2] = 1.0;

  let node = pools.borrow_mut::<Node>().add(node);
  scene.add_node(&node);
  scene.assign(&node, &camera);

  (pools.borrow_mut::<Scene>().add(scene), camera)
}

fn resize(
  renderer: &mut WGPURenderer,
  pools: &mut ResourcePools,
  camera: &ResourceId<PerspectiveCamera>,
  width: u32,
  height: u32,
) {
  pools
    .borrow_mut::<PerspectiveCamera>()
    .borrow_mut(camera)
    .unwrap()
    .set_aspect(width as f32 / height as f32);
  renderer.set_size(width as f64, height as f64);
}

fn update(
  pools: &mut ResourcePools,
  scene: &ResourceId<Scene>,
) {
  pools.borrow::<Scene>()
    .borrow(scene)
    .unwrap()
    .update_matrices(pools);
}

fn render(
  renderer: &mut WGPURenderer,
  pools: &ResourcePools,
  scene: &ResourceId<Scene>,
  camera: &ResourceId<PerspectiveCamera>,
) {
  renderer.render(pools, scene, camera);
}

#[tokio::main]
async fn main() {
  let event_loop = EventLoop::new();
  let window = Window::new(&event_loop).unwrap();

  let window_size = window.inner_size();
  let pixel_ratio = window.scale_factor();

  let mut renderer = WGPURenderer::new(
    &window,
    WGPURendererOptions::default(),
  ).await;
  renderer.set_size(window_size.width as f64, window_size.height as f64);
  renderer.set_pixel_ratio(pixel_ratio);

  let mut pools = ResourcePools::new();
  let (scene, camera) = create_scene(&window, &mut pools);

  event_loop.run(move |event, _, control_flow| {
    *control_flow = ControlFlow::Wait;
    match event {
      Event::WindowEvent {
        event: WindowEvent::Resized(size),
        ..
      } => {
        resize(&mut renderer, &mut pools, &camera, size.width, size.height);
        update(&mut pools, &scene);
        render(&mut renderer, &mut pools, &scene, &camera);
      },
      Event::RedrawRequested(_) => {
        update(&mut pools, &scene);
        render(&mut renderer, &mut pools, &scene, &camera);
      },
      Event::WindowEvent {
        event: WindowEvent::CloseRequested,
        ..
      } => {
        *control_flow = ControlFlow::Exit;
      },
      _ => {}
    }
  });
}

How to import

The library is released at crates.io. Add the following line into Cargo.toml of your Rust project.

[dependencies]
wgpu_rust_renderer = "0.0.4"

And add the following lines in your Rust code to import the library.

use wgpu_rust_renderer::{
  geometry::{
    attribute::Attribute,
    geometry::Geometry,
    index::Index,
  },
  material::material::Material,
  resource::resource::{
    ResourceId,
    ResourcePools,
  },
  scene::{
    camera::PerspectiveCamera,
    mesh::Mesh,
    node::Node,
    scene::Scene,
  },
  web::wgpu_web_renderer::WGPUWebRenderer, // for web
  renderer::wgpu_renderer::{
    WGPURenderer, // for others
    WGPURendererOptions,
  },
};

How to build the library locally

$ git clone https://github.com/takahirox/wgpu-rust-renderer.git
$ cd wgpu-rust-renderer
$ cargo build

How to run desktop examples locally

$ cd wgpu-rust-renderer
$ cargo run --example example_name

How to run web examples locally

Prerequirements

  • Install wasm-bindgen client
  • Install Rust wasm32-unknown-unknown target with $ rustup target add wasm32-unknown-unknown
  • Install http-server with $ npm install -g http-server, or other local servers
$ cd wgpu-rust-renderer/web
$ bash build_examples.sh
$ http-server . -p 8080 -c-1
# Access http://localhost:8080/examples/index.html on your web browser

How to run tests

T.B.D.

More Repositories

1

riscv-rust

RISC-V processor emulator written in Rust+WASM
Rust
595
star
2

nes-js

JavaScript NES(Famicom) emulator
JavaScript
205
star
3

nes-rust

NES emulator written in Rust + WASM
Rust
204
star
4

toho-like-js

Touhou style danmaku shooter game which runs on your chrome.
JavaScript
176
star
5

online-wgsl-editor

A tiny WGSL online editor
JavaScript
174
star
6

webgpu-devtools

JavaScript
172
star
7

mmd-viewer-js

MMD model dances on your chrome with WebGL.
JavaScript
158
star
8

THREE.WebGPURenderer

Experimental Three.js WebGPU renderer
JavaScript
132
star
9

three-gltf-extensions

Unofficial Three.js glTF loader/exporter plugins
JavaScript
118
star
10

tiny-web-metaverse

A web-based 3D virtual space lightweight framework with high flexibility, extensibility, and easy hosting, built on ECS architecture
JavaScript
117
star
11

MMDLoader-app

sample applications for THREE.MMDLoader
HTML
111
star
12

WebAssembly-benchmark

HTML
89
star
13

a-mmd

A-Frame MMD component
JavaScript
83
star
14

ThreeNetwork

Network sync library for Three.js
JavaScript
72
star
15

glTF-Blender-IO-materials-variants

Blender3D addon for glTF KHR_materials_variants extension
Python
71
star
16

ecs-rust

Tiny ECS library in Rust
JavaScript
60
star
17

three.wasm-experimental

Experimental Three.js WASM (WIP)
JavaScript
55
star
18

glTF-Blender-IO-EXT-mesh-gpu-instancing

Python
52
star
19

mmd-parser

NPM MMD parser package
JavaScript
48
star
20

webgpu-trial

WebGPU trial
HTML
48
star
21

pdp11-js

PDP-11 emulator implemented with JavaScript. UNIX V6 runs on your chrome.
JavaScript
43
star
22

aframe-rain

A-Frame Rainfall effect component
JavaScript
41
star
23

aframe-outline

Two-pass Outline effect component for A-Frame
JavaScript
34
star
24

aframe-instancing

A-Frame instancing component
JavaScript
24
star
25

EXT_skeleton_humanoid

21
star
26

THREE.Math-WASM

Three.js Math library in WASM
JavaScript
20
star
27

aframe-webrtc

A-Frame WebRTC component
JavaScript
17
star
28

takahirox.github.io

JavaScript
16
star
29

glTF-Blender-IO-MSFT-lod

Python
16
star
30

glTF-Transform-lod-script

JavaScript
15
star
31

aframe-deferred-renderer

A-Frame Deferred Renderer component
JavaScript
15
star
32

THREE.ZipLoader

Zip archived model file Loading helper for Three.js
JavaScript
14
star
33

THREE.TextureUploader

Experimental Less-blocking Texture uploader for Three.js
10
star
34

EXT_texture_video

8
star
35

nes-rust-ecsy

NES emulator + ECSY + Webpack bundle
JavaScript
7
star
36

KHR_lights_shadows

glTF exntension to specify which nodes can cast or receive shadows
6
star
37

EXT_copyrights

glTF copyrights extension
5
star
38

AsyncGLTFLoader

JavaScript
5
star
39

binary-viewer

Easy online binary dump tool.
HTML
5
star
40

Basis-Texture-Viewer

JavaScript
4
star
41

Vulkan-glTF-viewer-trial

C++
4
star
42

WebWorkers-benchmark

HTML
4
star
43

Hubs-glTF-Test-Models

3
star
44

WebAssemblyThread-benchmark

JavaScript
3
star
45

vr-tours

3
star
46

WebGL-CPU-Profiler-Extension

WebExtension profiling CPU elapsed time for WebGL
JavaScript
3
star
47

web_ai_chat

AI chat with on-device and in-browser inference
TypeScript
3
star
48

EXT_mesh_lod

2
star
49

charset-encoder-js

Simple charset encoder with JavaScript
JavaScript
2
star
50

KHR_parallel_shader_compile_test

GLSL
2
star
51

custom-shader

2
star
52

YouTube-Auto-Ad-Skipper

JavaScript
2
star
53

license-info-js

JavaScript
2
star
54

js-arguments-test

HTML
2
star
55

rust-tiny-os

Rust
2
star
56

libsquish-js

JavaScript libsquish compiled with emscripten
C++
2
star
57

EXT_text

glTF text extension
2
star
58

whisper-web-extension

JavaScript
2
star
59

ios-webaudio-test

JavaScript
1
star
60

ios-video-test

Test purpose
HTML
1
star
61

MyPersonalTodos

1
star
62

texImage2D-gl-test

HTML
1
star
63

SIMDJS-benchmark

HTML
1
star
64

pannernode-test

HTML
1
star
65

MOZ_lightmap

1
star
66

system_trade

Easy algorithmic trading tool on Lubuntu for myself.
Shell
1
star