Coder Social home page Coder Social logo

wgpu-rust-renderer's Introduction

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.

wgpu-rust-renderer's People

Contributors

takahirox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

wgpu-rust-renderer's Issues

The examples crash if you minimize the window

The examples crash if you minimize the window.

How to reproduce

  1. $ cargo run --example triangle
  2. Minimize the window
  3. Crashes

The error log

thread 'main' panicked at 'Error in Surface::configure: Both `Surface` width and height must be non-zero. Wait to recreate the `Surface` until the window has non-zero area.', C:\Users\Takahiro\.cargo\git\checkouts\wgpu-53e70f8674b08dd4\c3d9068\wgpu\src\backend\direct.rs:197:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\examples\rotation.exe` (exit code: 101)

Mac Os issue with PBR example

Hello, I have the following error compiling the pbr example on mac (10.11.6, El Capitan).

   Compiling wgpu_rust_renderer v0.0.3 (/Users/da1/Sources/rust/wgpu-rust-renderer)
    Finished dev [unoptimized + debuginfo] target(s) in 1m 48s
     Running `target/debug/examples/pbr`
thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
    Internal error in VERTEX shader: Metal: Compilation failed:

<program source>:20:5: error: unknown type name 'packed_float3'; did you mean 'metal::packed_float3'?
    packed_float3 vec3_color;
    ^~~~~~~~~~~~~
    metal::packed_float3
/System/Library/PrivateFrameworks/GPUCompiler.framework/Versions/A/lib/clang/3.5/include/metal/metal_types.h:88:32: note: 'metal::packed_float3' declared here
  typedef packed_vec<float, 3> packed_float3;
                               ^
<program source>:25:7: warning: no previous prototype for function 'd_ggx'
float d_ggx(
      ^
<program source>:34:7: warning: no previous prototype for function 'v_smith_ggx_correlated_fast'
float v_smith_ggx_correlated_fast(
      ^
<program source>:44:15: warning: no previous prototype for function 'brdf'
metal::float3 brdf(
              ^


', /Users/da1/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.0/src/backend/direct.rs:2195:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

the examples cube and rotation works, although the cube is not positioned in the middle of the screen, but in the bottom right corner of the screen.

Project status

@takahirox Hi, any plans to continue on this project? Also I'm interested in wgpu related consulting with funding, can you be up for this?

Directly load WGSL?

I'm looking for something which directly takes WGSL as input and displays the result in a window. Is wgpu-rust-renderer not the correct project for this? I thought at first maybe it was correct, but after looking at the examples, it appears to just use WGSL in the background to render things like cubes and models.

Do you know of a project which would fit my usecase? Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.