Skip to content

Commit

Permalink
dark clouds
Browse files Browse the repository at this point in the history
  • Loading branch information
altunenes committed Mar 30, 2024
1 parent 594fa5e commit c3394e3
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,7 @@ path = "src/pixelflow.rs"
name = "gaborlbrot"
path = "src/gaborlbrot.rs"

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

84 changes: 84 additions & 0 deletions shaders/darkclouds.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const PI: f32 = 3.141592653589793;
struct TimeUniform {
time: f32,
};
@group(1) @binding(0)
var<uniform> u_time: TimeUniform;

fn random(st: vec2<f32>) -> vec2<f32> {
let st_transformed: vec2<f32> = vec2<f32>(
dot(st, vec2<f32>(127.1, 311.7)),
dot(st, vec2<f32>(269.5, 183.3))
);
return -1.0 + 2.0 * fract(sin(st_transformed) * 43758.5453123);
}

fn oscillate(minValue: f32, maxValue: f32, interval: f32, currentTime: f32) -> f32 {
return minValue + (maxValue - minValue) * 0.5 * (sin(2.0 * PI * currentTime / interval) + 1.0);
}

fn noise(st: vec2<f32>) -> f32 {
let i: vec2<f32> = floor(st);
let f: vec2<f32> = fract(st);
let u: vec2<f32> = f * f * ((3.0 - 2.0) * f);
return mix(mix(dot(random(i + vec2<f32>(0.0, 0.0)), f - vec2<f32>(0.0, 0.0)),
dot(random(i + vec2<f32>(1.0, 0.0)), f - vec2<f32>(1.0, 0.0)), u.x),
mix(dot(random(i + vec2<f32>(0.0, 1.0)), f - vec2<f32>(0.0, 1.0)),
dot(random(i + vec2<f32>(1.0, 1.0)), f - vec2<f32>(1.0, 1.0)), u.x), u.y);
}
fn rotate2D(r: f32) -> mat2x2<f32> {
return mat2x2<f32>(cos(r), -sin(r),
sin(r), cos(r));
}
fn sinh(x: f32) -> f32 {
return (exp(x) - exp(-x)) / 2.0;
}
@fragment
fn main(@builtin(position) FragCoord: vec4<f32>) -> @location(0) vec4<f32> {
let iResolution: vec2<f32> = vec2<f32>(640.0, 480.0);
let uv: vec2<f32> = 3.0*(FragCoord.xy - 0.5 * iResolution) / min(iResolution.x, iResolution.y);

var col: vec3<f32> = vec3<f32>(0.0);
let t: f32 = u_time.time;
let oscillationFactors: vec3<f32> = vec3<f32>(oscillate(0.5, 0.51, 15.0, t), oscillate(2.0, 2.51, 15.0, t), oscillate(0.5, 0.51, 15.0, t));

var N: vec2<f32> = vec2<f32>(0.0);
var p: vec2<f32> = uv + t / 20.0;
var S: f32 = oscillationFactors.y;
let m: mat2x2<f32> = rotate2D(oscillationFactors.x);
let branchFactor: f32 = 1.78;

var n: vec2<f32> = vec2<f32>(0.0, 0.0);

for (var j: i32 = 0; j < 45; j = j + 1) {
p *= m;
n *= m;

let q: vec2<f32> = p * S * f32(j) + n + t;
n += branchFactor * cos(q);
N += branchFactor * cos(q) / S * oscillationFactors.z;

S *= 1.4 * sinh(0.9);
}

let colorOffset: vec3<f32> = vec3<f32>(
0.1 * smoothstep(0.4, 1.0, sin(N.x)),
0.5 * smoothstep(1.0, 1.0, sin(N.x)),
0.1 * smoothstep(0.5, 1.0, cos(N.x))
);

let flowColorChange: vec3<f32> = vec3<f32>(
1.5 * cos(1.0 * t + N.x),
0.5 * sin(1.0 * t + N.y),
1.5 * cos(1.0 * t + N.y)
);

let flowIntensity: vec3<f32> = vec3<f32>(
0.1 / length(1.03 * N),
smoothstep(5.5, 25.0, N.x),
smoothstep(5.5, 1.0, N.y)
);
col = (vec3<f32>(0.5, 0.0, 2.1) * colorOffset + flowColorChange + 4.5 * flowIntensity) *
((0.5 * N.x * 0.5 * N.y) + .0015 / length(1.0 * N));
return vec4<f32>(col, 1.0);
}
122 changes: 122 additions & 0 deletions src/darkclouds.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/darkclouds.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;
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 c3394e3

Please sign in to comment.