Skip to content

Commit

Permalink
asahi2
Browse files Browse the repository at this point in the history
  • Loading branch information
altunenes committed Mar 14, 2024
1 parent 5dd39a2 commit c78d381
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,8 @@ path = "src/voronoiwgpu2.rs"

[[bin]]
name = "fluid"
path = "src/fluid.rs"
path = "src/fluid.rs"

[[bin]]
name = "asahi2"
path = "src/asahi2.rs"
80 changes: 80 additions & 0 deletions shaders/asahi2.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//see my shadertoy code: https://www.shadertoy.com/view/MX23Wz;
//note, I used petal polar GLSL function from the user BenoitArbelot, (2020): https://www.shadertoy.com/view/ttySz3
// Global constants
const PI: f32 = 3.141592653589793;
struct TimeUniform {
time: f32,
};
@group(1) @binding(0)
var<uniform> u_time: TimeUniform;
fn rot(a: f32) -> mat2x2<f32> {
return mat2x2<f32>(
cos(a), -sin(a),
sin(a), cos(a)
);
}

fn DrawPetalPolar(uv: vec2<f32>, pos: vec2<f32>, size: f32, dir: vec2<f32>, colorDirection: f32) -> vec4<f32> {
var dist: vec2<f32> = uv - pos;

let angle: f32 = -atan2(dir.y, dir.x);
dist = dist * (rot(angle) * 0.8);

dist.x = dist.x - (size * 0.25);

let r: f32 = length(dist) * 1.5;
let a: f32 = atan2(dist.y, dist.x);

var f: f32 = -1.0;
if (a > PI * 0.5 || a < -PI * 0.5) {
f = size * cos(a * 2.0);
}

let petalMask: f32 = smoothstep(0.0, -1.0, (r - f) / fwidth(r - f));

var color: vec3<f32>;
if (colorDirection > 0.0) {
color = mix(vec3<f32>(1.0, 1.0, 0.0), vec3<f32>(0.0, 0.0, 0.0), r / (size * 1.0));
} else {
color = mix(vec3<f32>(0.0, 0.0, 0.0), vec3<f32>(1.0, 1.0, 0.0), r / (size * 1.0));
}

return vec4<f32>(color, petalMask);
}

@fragment
fn main(@builtin(position) FragCoord: vec4<f32>) -> @location(0) vec4<f32> {
let resolution: vec2<f32> = vec2<f32>(800.0, 450.0);
var uv: vec2<f32> = 1.3 * (FragCoord.xy - 0.5 * resolution) / resolution.y;
let bgColor: vec3<f32> = vec3<f32>(1.0, 1.0, 1.0);
var fragColor: vec4<f32> = vec4<f32>(bgColor, 1.0);

let petalSize: f32 = 0.40;
let space: f32 = (2.5 * PI / 15.0) * (1.0 + 0.2);
let phase: f32 = sin(u_time.time / 2.0) * PI;

let left: vec2<f32> = vec2<f32>(-0.5, 0.0);
let right: vec2<f32> = vec2<f32>(0.5, 0.0);

// Left side
for (var i: f32 = 0.0; i < 2.0 * PI; i = i + space) {
let pos: vec2<f32> = left + vec2<f32>(cos(i), sin(i)) * 0.25;
let angle: f32 = i + phase;
let dir: vec2<f32> = vec2<f32>(cos(angle), sin(angle));

let leftcolor: vec4<f32> = DrawPetalPolar(uv, pos, petalSize, dir, 1.0);
fragColor = mix(fragColor, leftcolor, leftcolor.a);
}

// Right side
for (var i: f32 = 0.0; i < 2.0 * PI; i = i + space) {
let pos: vec2<f32> = right + vec2<f32>(cos(i), sin(i)) * 0.25;
let angle: f32 = i - phase;
let dir: vec2<f32> = vec2<f32>(cos(angle), sin(angle));

let colors: vec4<f32> = DrawPetalPolar(uv, pos, petalSize, dir, -1.0);
fragColor = mix(fragColor, colors, colors.a);
}

return fragColor;
}
122 changes: 122 additions & 0 deletions src/asahi2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
use nannou::prelude::*;
struct Model {
bind_group: wgpu::BindGroup,
render_pipeline: wgpu::RenderPipeline,
vertex_buffer: wgpu::Buffer,
time_uniform: wgpu::Buffer,
time_bind_group: wgpu::BindGroup,
}
#[repr(C)]
#[derive(Clone, Copy)]
struct Vertex {
position: [f32; 2],
}
const VERTICES: [Vertex; 6] = [
Vertex { position: [-1.0, -1.0] },
Vertex { position: [ 1.0, -1.0] },
Vertex { position: [-1.0, 1.0] },
Vertex { position: [ 1.0, -1.0] },
Vertex { position: [ 1.0, 1.0] },
Vertex { position: [-1.0, 1.0] },
];
fn main() {
nannou::app(model).run();
}
fn model(app: &App) -> Model {
let w_id = app.new_window().size(800, 450).view(view).build().unwrap();
let window = app.window(w_id).unwrap();
let device = window.device();
let format = Frame::TEXTURE_FORMAT;
let sample_count = window.msaa_samples();
let vs_desc = wgpu::include_wgsl!("../shaders/vs.wgsl");
let fs_desc = wgpu::include_wgsl!("../shaders/asahi2.wgsl");
let vs_mod = device.create_shader_module(vs_desc);
let fs_mod = device.create_shader_module(fs_desc);
let vertices_bytes = vertices_as_bytes(&VERTICES[..]);
let usage = wgpu::BufferUsages::VERTEX;
let vertex_buffer = device.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: vertices_bytes,
usage,
});
let time_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: wgpu::BufferSize::new(std::mem::size_of::<f32>() as _),
},
count: None,
},
],
label: Some("time_bind_group_layout"),
});
let bind_group_layout = wgpu::BindGroupLayoutBuilder::new().build(device);
let bind_group = wgpu::BindGroupBuilder::new().build(device, &bind_group_layout);
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Pipeline Layout"),
bind_group_layouts: &[&bind_group_layout, &time_bind_group_layout],
push_constant_ranges: &[],
});
let render_pipeline = wgpu::RenderPipelineBuilder::from_layout(&pipeline_layout, &vs_mod)
.fragment_shader(&fs_mod)
.color_format(format)
.add_vertex_buffer::<Vertex>(&wgpu::vertex_attr_array![0 => Float32x2])
.sample_count(sample_count)
.build(device);
let time_uniform = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Time Uniform Buffer"),
size: std::mem::size_of::<f32>() as wgpu::BufferAddress,
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});
let time_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &time_bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: time_uniform.as_entire_binding(),
},
],
label: Some("time_bind_group"),
});
Model {
bind_group,
vertex_buffer,
render_pipeline,
time_uniform,
time_bind_group,
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let mut encoder = frame.command_encoder();
let time = app.time as f32;
let time_bytes = time.to_ne_bytes();
let binding = app.main_window();
let queue = binding.queue();
queue.write_buffer(&model.time_uniform, 0, &time_bytes);
let mut render_pass = wgpu::RenderPassBuilder::new()
.color_attachment(frame.texture_view(), |color| color)
.begin(&mut encoder);
render_pass.set_bind_group(0, &model.bind_group, &[]);
render_pass.set_bind_group(1, &model.time_bind_group, &[]);
render_pass.set_pipeline(&model.render_pipeline);
render_pass.set_vertex_buffer(0, model.vertex_buffer.slice(..));
let vertex_range = 0..VERTICES.len() as u32;
let instance_range = 0..1;
render_pass.draw(vertex_range, instance_range);
if app.keys.down.contains(&Key::Space) {
let file_path = app
.project_path()
.expect("failed to locate project directory")
.join("frames")
.join(format!("{:0}.png", app.elapsed_frames()));
app.main_window().capture_frame(file_path);
}
}
fn vertices_as_bytes(data: &[Vertex]) -> &[u8] {
unsafe { wgpu::bytes::from_slice(data) }
}

0 comments on commit c78d381

Please sign in to comment.