forked from nannou-org/nannou
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
435c0b2
commit ca17a79
Showing
9 changed files
with
254 additions
and
38 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
struct Particle { | ||
position: vec2<f32>, | ||
velocity: vec2<f32>, | ||
color: vec4<f32>, | ||
}; | ||
|
||
@group(0) @binding(0) var<storage, read_write> particles: array<Particle>; | ||
@group(0) @binding(1) var<uniform> mouse: vec2<f32>; | ||
@group(0) @binding(2) var<uniform> resolution: vec2<f32>; | ||
|
||
|
||
struct VertexOutput { | ||
@builtin(position) clip_position: vec4<f32>, | ||
@location(0) color: vec4<f32>, | ||
}; | ||
|
||
@vertex | ||
fn vertex(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { | ||
let particle = particles[vertex_index]; | ||
|
||
var out: VertexOutput; | ||
out.clip_position = vec4<f32>(particle.position, 0.0, 1.0); | ||
out.color = particle.color; | ||
return out; | ||
} | ||
|
||
@fragment | ||
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> { | ||
return in.color; | ||
} | ||
|
||
fn random(seed: vec2<f32>) -> f32 { | ||
return fract(sin(dot(seed, vec2(12.9898, 78.233))) * 43758.5453); | ||
} | ||
|
||
@compute @workgroup_size(64) | ||
fn init(@builtin(global_invocation_id) global_id: vec3<u32>) { | ||
let index = global_id.x; | ||
var particle: Particle; | ||
|
||
// Initialize position randomly within the window | ||
particle.position = vec2<f32>( | ||
(random(vec2<f32>(f32(index), 0.0)) - 0.5) * resolution.x, | ||
(random(vec2<f32>(0.0, f32(index))) - 0.5) * resolution.y | ||
); | ||
|
||
// Initialize velocity randomly | ||
particle.velocity = vec2<f32>( | ||
(random(vec2<f32>(f32(index), 1.0)) - 0.5) * 0.1, | ||
(random(vec2<f32>(1.0, f32(index))) - 0.5) * 0.1 | ||
); | ||
|
||
// Initialize color randomly | ||
particle.color = vec4<f32>( | ||
random(vec2<f32>(f32(index), 2.0)), | ||
random(vec2<f32>(2.0, f32(index))), | ||
random(vec2<f32>(f32(index), 3.0)), | ||
1.0 | ||
); | ||
|
||
particles[index] = particle; | ||
} | ||
|
||
@compute @workgroup_size(64) | ||
fn update(@builtin(global_invocation_id) global_id: vec3<u32>) { | ||
let index = global_id.x; | ||
var particle = particles[index]; | ||
|
||
// Update particle position | ||
particle.position = particle.position + particle.velocity; | ||
|
||
// Attract particles to mouse | ||
let to_mouse = mouse - particle.position; | ||
particle.velocity = particle.velocity + normalize(to_mouse) * 0.0001; | ||
|
||
// Bounce off screen edges | ||
if (particle.position.x < -1.0 || particle.position.x > 1.0) { | ||
particle.velocity.x = -particle.velocity.x; | ||
} | ||
if (particle.position.y < -1.0 || particle.position.y > 1.0) { | ||
particle.velocity.y = -particle.velocity.y; | ||
} | ||
|
||
// Update color based on velocity | ||
particle.color = vec4<f32>(abs(particle.velocity), 1.0, 1.0); | ||
|
||
particles[index] = particle; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
use bytemuck::{Pod, Zeroable}; | ||
use nannou::prelude::bevy_render::renderer::RenderDevice; | ||
use nannou::prelude::*; | ||
use std::sync::Arc; | ||
|
||
const NUM_PARTICLES: u32 = 10000; | ||
const WORKGROUP_SIZE: u32 = 64; | ||
|
||
fn main() { | ||
nannou::app(model).compute(compute).update(update).run(); | ||
} | ||
|
||
struct Model { | ||
particles: Buffer, | ||
} | ||
|
||
#[derive(Default, Clone, Copy, Pod, Zeroable)] | ||
#[repr(C)] | ||
struct Particle { | ||
position: Vec2, | ||
velocity: Vec2, | ||
color: Vec4, | ||
} | ||
|
||
#[derive(Default, Debug, Eq, PartialEq, Hash, Clone)] | ||
enum State { | ||
#[default] | ||
Init, | ||
Update, | ||
} | ||
|
||
#[derive(AsBindGroup, Clone)] | ||
struct ComputeModel { | ||
#[storage(0, buffer, visibility(compute, vertex))] | ||
particles: Buffer, | ||
#[uniform(1)] | ||
mouse: Vec2, | ||
#[uniform(2)] | ||
resolution: Vec2, | ||
} | ||
|
||
impl Compute for ComputeModel { | ||
type State = State; | ||
|
||
fn shader() -> ShaderRef { | ||
"shaders/particle_mouse.wgsl".into() | ||
} | ||
|
||
fn shader_entry(state: &Self::State) -> &'static str { | ||
match state { | ||
State::Init => "init", | ||
State::Update => "update", | ||
} | ||
} | ||
|
||
fn workgroup_size(_state: &Self::State) -> (u32, u32, u32) { | ||
(WORKGROUP_SIZE, 1, 1) | ||
} | ||
} | ||
|
||
#[derive(AsBindGroup, Asset, TypePath, Clone)] | ||
struct DrawMaterial { | ||
#[storage(0, buffer, visibility(compute, vertex))] | ||
particles: Buffer, | ||
} | ||
|
||
|
||
|
||
impl Material for DrawMaterial { | ||
fn vertex_shader() -> ShaderRef { | ||
"shaders/particle_mouse.wgsl".into() | ||
} | ||
|
||
fn fragment_shader() -> ShaderRef { | ||
"shaders/particle_mouse.wgsl".into() | ||
} | ||
} | ||
|
||
fn model(app: &App) -> Model { | ||
let _window_id = app | ||
.new_window() | ||
.primary() | ||
.size(1024, 768) | ||
.view(view) | ||
.build(); | ||
let device = app.resource_mut::<RenderDevice>(); | ||
|
||
let particles = device.create_buffer_with_data(&BufferInitDescriptor { | ||
label: Some("ParticleBuffer"), | ||
contents: bytemuck::cast_slice(&vec![Particle::default(); NUM_PARTICLES as usize]), | ||
usage: BufferUsages::STORAGE | BufferUsages::VERTEX, | ||
}); | ||
|
||
Model { particles } | ||
} | ||
|
||
fn update(app: &App, model: &mut Model) {} | ||
|
||
fn compute(app: &App, model: &Model, state: State, view: Entity) -> (State, ComputeModel) { | ||
let window = app.main_window(); | ||
let window_rect = window.rect(); | ||
|
||
let mouse_pos = app.mouse(); | ||
let compute_model = ComputeModel { | ||
particles: model.particles.clone(), | ||
mouse: mouse_pos, | ||
resolution: Vec2::new(window_rect.w(), window_rect.h()), | ||
}; | ||
|
||
match state { | ||
State::Init => (State::Update, compute_model), | ||
State::Update => (State::Update, compute_model), | ||
} | ||
} | ||
|
||
fn view(app: &App, model: &Model) { | ||
let draw = app.draw() | ||
.material(DrawMaterial { | ||
particles: model.particles.clone(), | ||
}); | ||
draw.background() | ||
.color(BLACK); | ||
draw.polyline() | ||
.points(vec![Vec2::ZERO; NUM_PARTICLES as usize]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.