This commit is contained in:
Matthew Deville 2025-08-31 12:48:46 +02:00
parent b037f9150b
commit 965aa40858
2 changed files with 33 additions and 26 deletions

View file

@ -1,30 +1,18 @@
// Simple UV gradient shader (vertex + fragment) #import bevy_sprite::mesh2d_vertex_output::VertexOutput
struct VertexInput { @group(2) @binding(0) var<uniform> u_time: f32;
@location(0) position: vec3<f32>, @group(2) @binding(1) var<uniform> u_resolution: vec2<f32>;
@location(1) uv: vec2<f32>,
}
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) uv: vec2<f32>,
}
@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<f32>(in.position, 1.0);
out.uv = in.uv;
return out;
}
@fragment @fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> { fn fragment(mesh: VertexOutput) -> @location(0) vec4<f32> {
// very simple vertical gradient between two colors // very simple vertical gradient between two colors
let bottom = vec3<f32>(1.0, 0.8, 0.2); // warm let bottom = vec3<f32>(1.0, 0.8, 0.2); // warm
let top = vec3<f32>(0.2, 0.6, 1.0); // cool let top = vec3<f32>(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<f32>(color, 1.0); return vec4<f32>(color, 1.0);
} }

View file

@ -21,6 +21,7 @@ fn main() {
.add_systems( .add_systems(
Update, Update,
( (
update_material_time,
resize_fullscreen_quad, resize_fullscreen_quad,
exit_app.run_if(input_just_pressed(KeyCode::Escape)), exit_app.run_if(input_just_pressed(KeyCode::Escape)),
toggle_fullscreen.run_if(input_just_pressed(KeyCode::F11)), toggle_fullscreen.run_if(input_just_pressed(KeyCode::F11)),
@ -31,24 +32,30 @@ fn main() {
/// set up a simple 2D-screen-like surface /// set up a simple 2D-screen-like surface
fn setup( fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<CustomMaterial>>, mut materials: ResMut<Assets<CustomMaterial>>,
mut primary_window: Single<&mut Window, With<PrimaryWindow>>, mut primary_window: Single<&mut Window, With<PrimaryWindow>>,
mut commands: Commands,
) { ) {
primary_window.decorations = false; primary_window.decorations = false;
commands.spawn(Camera2d); commands.spawn(Camera2d);
// quad that fills the whole window // quad that fills the whole window
let size = Vec2::new( let screen_size = Vec2::new(
primary_window.resolution.width(), primary_window.resolution.width(),
primary_window.resolution.height(), 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(( commands.spawn((
Mesh2d(meshes.add(Rectangle::default())), Mesh2d(meshes.add(Rectangle::default())),
MeshMaterial2d(materials.add(CustomMaterial {})), MeshMaterial2d(material_handle),
Transform::from_scale(Vec3::new(size.x, size.y, 1.0)), Transform::from_scale(Vec3::new(screen_size.x, screen_size.y, 1.0)),
FullscreenQuad, FullscreenQuad,
)); ));
} }
@ -83,7 +90,19 @@ fn toggle_fullscreen(mut primary_window: Single<&mut Window, With<PrimaryWindow>
// This is the struct that will be passed to your shader // This is the struct that will be passed to your shader
#[derive(Asset, TypePath, AsBindGroup, Clone)] #[derive(Asset, TypePath, AsBindGroup, Clone)]
struct CustomMaterial {} struct CustomMaterial {
#[uniform(0)]
time: f32,
#[uniform(1)]
resolution: Vec2,
}
fn update_material_time(mut materials: ResMut<Assets<CustomMaterial>>, time: Res<Time>) {
let t = time.elapsed_secs();
for (_handle, material) in materials.iter_mut() {
material.time = t;
}
}
/// The Material2d trait is very configurable, but comes with sensible defaults for all methods. /// The Material2d trait is very configurable, but comes with sensible defaults for all methods.
/// You only need to implement functions for features that need non-default behavior. See the Material2d api docs for details! /// You only need to implement functions for features that need non-default behavior. See the Material2d api docs for details!