diff --git a/assets/shaders/default.wgsl b/assets/shaders/default.wgsl index c736dcd..96009de 100644 --- a/assets/shaders/default.wgsl +++ b/assets/shaders/default.wgsl @@ -1,30 +1,18 @@ -// Simple UV gradient shader (vertex + fragment) +#import bevy_sprite::mesh2d_vertex_output::VertexOutput -struct VertexInput { - @location(0) position: vec3, - @location(1) uv: vec2, -} - -struct VertexOutput { - @builtin(position) clip_position: vec4, - @location(0) uv: vec2, -} - -@vertex -fn vertex(in: VertexInput) -> VertexOutput { - var out: VertexOutput; - // assume incoming positions are in clip-space (vec3 with z, or model-transformed) - out.clip_position = vec4(in.position, 1.0); - out.uv = in.uv; - return out; -} +@group(2) @binding(0) var u_time: f32; +@group(2) @binding(1) var u_resolution: vec2; @fragment -fn fragment(in: VertexOutput) -> @location(0) vec4 { +fn fragment(mesh: VertexOutput) -> @location(0) vec4 { // very simple vertical gradient between two colors let bottom = vec3(1.0, 0.8, 0.2); // warm let top = vec3(0.2, 0.6, 1.0); // cool - let color = mix(bottom, top, in.uv.y); + // use time to subtly shift the gradient + let t = u_time; + let shift = 0.2 * sin(t); + + let color = mix(bottom, top, mesh.uv.y + shift); return vec4(color, 1.0); } diff --git a/src/main.rs b/src/main.rs index db2dae4..8d9cfa4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ fn main() { .add_systems( Update, ( + update_material_time, resize_fullscreen_quad, exit_app.run_if(input_just_pressed(KeyCode::Escape)), toggle_fullscreen.run_if(input_just_pressed(KeyCode::F11)), @@ -31,24 +32,30 @@ fn main() { /// set up a simple 2D-screen-like surface fn setup( - mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, mut primary_window: Single<&mut Window, With>, + mut commands: Commands, ) { primary_window.decorations = false; commands.spawn(Camera2d); // quad that fills the whole window - let size = Vec2::new( + let screen_size = Vec2::new( primary_window.resolution.width(), primary_window.resolution.height(), ); + // create material with initial time = 0.0 + let material_handle = materials.add(CustomMaterial { + time: 0.0, + resolution: screen_size, + }); + commands.spawn(( Mesh2d(meshes.add(Rectangle::default())), - MeshMaterial2d(materials.add(CustomMaterial {})), - Transform::from_scale(Vec3::new(size.x, size.y, 1.0)), + MeshMaterial2d(material_handle), + Transform::from_scale(Vec3::new(screen_size.x, screen_size.y, 1.0)), FullscreenQuad, )); } @@ -83,7 +90,19 @@ fn toggle_fullscreen(mut primary_window: Single<&mut Window, With // This is the struct that will be passed to your shader #[derive(Asset, TypePath, AsBindGroup, Clone)] -struct CustomMaterial {} +struct CustomMaterial { + #[uniform(0)] + time: f32, + #[uniform(1)] + resolution: Vec2, +} + +fn update_material_time(mut materials: ResMut>, time: Res