diff --git a/.cargo/config.toml b/.cargo/config.toml
deleted file mode 100644
index 7d6dd5a..0000000
--- a/.cargo/config.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[build]
-target = "wasm32-unknown-unknown"
-rustflags ="--cfg=web_sys_unstable_apis"
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..186dfe4
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+github: [simbleau]
+custom: ["buymeacoffee.com/simbleau"]
diff --git a/.github/renovate.json b/.github/renovate.json
new file mode 100644
index 0000000..a7aad4d
--- /dev/null
+++ b/.github/renovate.json
@@ -0,0 +1,14 @@
+{
+ "extends": [
+ "config:base"
+ ],
+ "packageRules": [
+ {
+ "matchUpdateTypes": [
+ "minor",
+ "patch"
+ ],
+ "automerge": true
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..6530762
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,47 @@
+name: build
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+env:
+ TOOLCHAIN: nightly
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ # Cargo cache
+ - name: Cargo cache
+ id: cache-cargo
+ uses: actions/cache@v3
+ with:
+ path: ~/.cargo/bin
+ key: cargo
+
+ # Install cargo deps
+ - name: Pull Cargo dependencies
+ if: steps.cache-cargo.outputs.cache-hit != 'true'
+ run: |
+ rustup update $TOOLCHAIN
+ rustup default $TOOLCHAIN
+ cargo install trunk
+
+ # Pull website
+ - name: Build cache
+ id: cache-build
+ uses: actions/cache@v3
+ with:
+ path: ./dist
+ key: dist-${{ hashFiles('./src') }}-${{ hashFiles('./assets') }}
+
+ # Install cargo deps
+ - name: Trunk build
+ if: steps.cache-build.outputs.cache-hit != 'true'
+ run: |
+ trunk build
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..698812f
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,39 @@
+name: release
+
+on:
+ push:
+ branches: [main]
+
+env:
+ TOOLCHAIN: nightly
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ # Pull website
+ - name: Build cache
+ id: cache-build
+ uses: actions/cache@v3
+ with:
+ path: ./dist
+ key: dist-${{ hashFiles('./src') }}-${{ hashFiles('./assets') }}
+
+ # Install cargo deps
+ - name: Trunk build
+ if: steps.cache-build.outputs.cache-hit != 'true'
+ run: |
+ rustup update $TOOLCHAIN
+ rustup default $TOOLCHAIN
+ cargo install trunk
+ trunk build --release
+
+ # Deploy, GitHub Pages
+ - name: Deploy
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./dist
diff --git a/Cargo.toml b/Cargo.toml
index 1a71a66..5e631b4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,7 +35,6 @@ nalgebra = "0.31.1"
[dependencies.rapier2d]
version = "0.14.0"
-opt-level = 3
features = [ "wasm-bindgen" ]
[dependencies.web-sys]
diff --git a/README.md b/README.md
index 2424d17..59a229e 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,46 @@
-# GPU-Accelerated 2D N-Body Simulation, in WASM
-An N-body WebAssembly simulation using WebGPU.
+
-# Run
-- `trunk serve`
+
GPU N-body WASM Simulation
+
+
++
+
++
+
+
-# Progress
-In progress. Currently a research project of [@seabass247](https://github.com/seabass247) and [@simbleau](https://github.com/simbleau).
+
Click here to demo the simulation.
-![image](https://user-images.githubusercontent.com/48108917/181005443-a6c96151-b7b9-4dee-8ba3-0aaf814ac2c9.png)
+
+
+---
+
+## 📖 Overview
+This repository is a 2D N-body simulation of a dynamical system of bodies, under the influence of physical forces such as gravity. The simulation is written completely in Rust with WebGPU and WGSL shading, exported to WebAssembly. We deploy the demo with GitHub Actions.
+
+🔸 Simulations like these are common in astrophysics and are used to understand the evolution of large-scale universal structures.
+
+---
+
+# 🚀 Serve Locally
+## Dependencies
+- [Rust](https://www.rust-lang.org/)
+- [trunk](https://trunkrs.dev/) (`cargo install trunk`)
+- [wasm32-unkown-unknown](https://yew.rs/docs/getting-started/introduction#install-webassembly-target) (`rustup target add wasm32-unknown-unknown`)
+## Serve
+- Run: `trunk serve`
+- Preview: [`http://localhost:8080/`](http://localhost:8080/)
+
+![Screenshot](https://user-images.githubusercontent.com/48108917/183275653-a2ee4f9c-a982-482e-8405-bd124d4bbcf5.png)
+
+---
+
+## 📁 Directories
+
+- [__`assets`__](./assets/): directory contains textures and shaders.
+- [__`src`__](./src/): directory contains the rust source code.
+
+---
+
+## 🔏 License
+This project is dual-licensed under both [Apache 2.0](LICENSE-APACHE) and [MIT](LICENSE-MIT) licenses.
\ No newline at end of file
diff --git a/assets/shaders/frag.wgsl b/assets/shaders/frag.wgsl
index 52ca692..45ef94d 100644
--- a/assets/shaders/frag.wgsl
+++ b/assets/shaders/frag.wgsl
@@ -1,6 +1,7 @@
struct Input {
@builtin(position) clip_position: vec4,
@location(0) uv: vec2,
+ @location(1) color: vec3,
};
struct Output {
@@ -16,9 +17,11 @@ var texture_sampler: sampler;
@fragment
fn fs_main(in: Input) -> Output {
var out: Output;
- out.color = textureSample(texture, texture_sampler, vec2(in.uv.x, 1.0 - in.uv.y));
+ out.color = textureSample(texture, texture_sampler, vec2(1.0 - in.uv.x, 1.0 - in.uv.y));
if ((pow(in.uv.x - 0.5, 2.0) + pow(in.uv.y - 0.5, 2.0)) > pow(0.5, 2.0)) {
out.color = vec4(0.0);
}
+
+ out.color *= vec4(in.color, 1.0);
return out;
}
diff --git a/assets/shaders/vert.wgsl b/assets/shaders/vert.wgsl
index 93834fe..6494b68 100644
--- a/assets/shaders/vert.wgsl
+++ b/assets/shaders/vert.wgsl
@@ -12,6 +12,7 @@ struct Input {
struct Output {
@builtin(position) clip_position: vec4,
@location(0) uv: vec2,
+ @location(1) color: vec3,
};
struct InstanceInput {
@@ -19,8 +20,19 @@ struct InstanceInput {
@location(3) model_matrix_1: vec4,
@location(4) model_matrix_2: vec4,
@location(5) model_matrix_3: vec4,
+ @location(6) radius: f32,
};
+struct WorldUniform {
+ radius: f32,
+ boundary_segments: u32,
+ rave: u32,
+ padding: u32,
+};
+
+@group(2) @binding(0)
+var world: WorldUniform;
+
// Vertex shader
@vertex
fn vs_main(
@@ -42,5 +54,32 @@ fn vs_main(
// World coords -> Device Coordinates
out.clip_position = camera.view_proj * world_vert;
+
+ var brightest: vec3 = vec3(0.97, 0.97, 1.0);
+ var blue: vec3 = vec3(0.33, 0.4, 1.0);
+ var yellow: vec3 = vec3(0.97, 0.98, 0.8);
+ var orange: vec3 = vec3(0.96, 0.6, 0.25);
+ var red: vec3 = vec3(0.99, 0.25, 0.25);
+
+ var star_color: vec3 = vec3(0.0);
+ if (instance.radius >= 0.75) {
+ star_color += mix(orange, red, (instance.radius - 0.75) * 4.0);
+ } else if (instance.radius >= 0.5) {
+ star_color += mix(yellow, orange, (instance.radius - 0.5) * 4.0);
+ } else if (instance.radius >= 0.25) {
+ star_color += mix(blue, yellow, (instance.radius - 0.25) * 4.0);
+ } else {
+ star_color += mix(brightest, blue, instance.radius * 4.0);
+ }
+
+ var tint: vec3 = vec3(1.0);
+ var twinkle: vec3 = vec3(1.0);
+ if (world.rave > 0u) {
+ tint = vec3(abs(world_vert.xyz) % 2.0);
+ twinkle = vec3(instance.model_matrix_0.x);
+ }
+
+ // Calculate color
+ out.color = star_color * tint * twinkle;
return out;
}
\ No newline at end of file
diff --git a/assets/shaders/world.vert.wgsl b/assets/shaders/world.vert.wgsl
index 2ed6d3b..11c1dc6 100644
--- a/assets/shaders/world.vert.wgsl
+++ b/assets/shaders/world.vert.wgsl
@@ -7,7 +7,8 @@ var camera: CameraUniform;
struct WorldUniform {
radius: f32,
boundary_segments: u32,
- padding: vec2,
+ rave: u32,
+ padding: u32,
};
@group(1) @binding(0)
diff --git a/assets/textures/cookie.png b/assets/textures/cookie.png
deleted file mode 100644
index 5a270b9..0000000
Binary files a/assets/textures/cookie.png and /dev/null differ
diff --git a/assets/textures/disco.jpg b/assets/textures/disco.jpg
new file mode 100644
index 0000000..91f637d
Binary files /dev/null and b/assets/textures/disco.jpg differ
diff --git a/assets/textures/moon.jpg b/assets/textures/moon.jpg
deleted file mode 100644
index 81e639c..0000000
Binary files a/assets/textures/moon.jpg and /dev/null differ
diff --git a/assets/textures/rust.png b/assets/textures/rust.png
new file mode 100644
index 0000000..a95ee96
Binary files /dev/null and b/assets/textures/rust.png differ
diff --git a/index.html b/index.html
index f485824..bbd4872 100644
--- a/index.html
+++ b/index.html
@@ -4,15 +4,95 @@
N-Body WASM Simulation
+
- FPS: 0
-
- Event Log
-
+
+
FPS: --
+
+ Instructions
+
+
+ WASD: Move Camera
+
+ ↕: Scale Camera
+
+ ↔: Rotate Camera
+
+ Q: Wireframe
+
+ E: Rave
+
+
+
+
+