This commit is contained in:
Matthew Deville 2026-09-28 23:50:36 +02:00
parent f9cb9f8235
commit 44c40dcf50
4 changed files with 103 additions and 1 deletions

49
assets/shaders/sky.wgsl Normal file
View file

@ -0,0 +1,49 @@
#import bevy_sprite::mesh2d_vertex_output::VertexOutput
#import bevy_sprite::mesh2d_view_bindings::globals
fn hash(p: vec2<f32>) -> f32 {
return fract(sin(dot(p, vec2<f32>(127.1, 311.7))) * 43758.5453);
}
fn noise(p: vec2<f32>) -> f32 {
let i = floor(p);
let f = fract(p);
let u = f * f * (3.0 - 2.0 * f);
return mix(
mix(hash(i), hash(i + vec2<f32>(1.0, 0.0)), u.x),
mix(hash(i + vec2<f32>(0.0, 1.0)), hash(i + vec2<f32>(1.0, 1.0)), u.x),
u.y,
);
}
fn fbm(p: vec2<f32>) -> f32 {
var value = 0.0;
var amplitude = 0.5;
var q = p;
for (var i = 0; i < 5; i++) {
value += amplitude * noise(q);
q *= 2.0;
amplitude *= 0.5;
}
return value;
}
@fragment
fn fragment(mesh: VertexOutput) -> @location(0) vec4<f32> {
let t = globals.time;
// uv.y is 0 at the top of the quad
let height = 1.0 - mesh.uv.y;
let horizon = vec3<f32>(0.98, 0.85, 0.72);
let zenith = vec3<f32>(0.45, 0.68, 0.92);
var color = mix(horizon, zenith, smoothstep(0.0, 1.0, height));
// Two layers of slowly drifting clouds
let p = mesh.world_position.xy / 300.0;
let clouds = fbm(p + vec2<f32>(t * 0.03, 0.0)) * 0.6
+ fbm(p * 2.0 + vec2<f32>(t * 0.05, t * 0.01)) * 0.4;
let cover = smoothstep(0.45, 0.75, clouds);
color = mix(color, vec3<f32>(1.0), cover * 0.8);
return vec4<f32>(color, 1.0);
}

View file

@ -51,7 +51,7 @@ fn setup(
Vec2::new(-3.0, 3.0), Vec2::new(-3.0, 3.0),
Vec2::new(-3.0, -3.0), Vec2::new(-3.0, -3.0),
))), ))),
material: MeshMaterial2d(materials.add(Color::WHITE)), material: MeshMaterial2d(materials.add(Color::BLACK)),
}; };
spawn_boids( spawn_boids(
&mut commands, &mut commands,

View file

@ -1,6 +1,7 @@
mod boids; mod boids;
mod config; mod config;
mod pointer; mod pointer;
mod sky;
mod spatial_grid; mod spatial_grid;
mod ui; mod ui;
@ -22,6 +23,7 @@ fn main() {
.add_plugins(( .add_plugins((
config::ConfigPlugin, config::ConfigPlugin,
pointer::PointerPlugin, pointer::PointerPlugin,
sky::SkyPlugin,
boids::BoidsPlugin, boids::BoidsPlugin,
ui::ConfigUiPlugin, ui::ConfigUiPlugin,
)) ))

51
src/sky.rs Normal file
View file

@ -0,0 +1,51 @@
use bevy::{
prelude::*,
render::render_resource::AsBindGroup,
shader::ShaderRef,
sprite_render::{Material2d, Material2dPlugin},
window::PrimaryWindow,
};
pub struct SkyPlugin;
impl Plugin for SkyPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(Material2dPlugin::<SkyMaterial>::default())
.add_systems(Startup, setup_sky)
.add_systems(Update, fit_sky_to_window);
}
}
/// Animated sky, driven by the global shader time.
#[derive(Asset, TypePath, AsBindGroup, Clone)]
struct SkyMaterial {}
impl Material2d for SkyMaterial {
fn fragment_shader() -> ShaderRef {
"shaders/sky.wgsl".into()
}
}
#[derive(Component)]
struct Sky;
fn setup_sky(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<SkyMaterial>>,
) {
commands.spawn((
Sky,
Mesh2d(meshes.add(Rectangle::new(1.0, 1.0))),
MeshMaterial2d(materials.add(SkyMaterial {})),
// Behind the boids
Transform::from_xyz(0.0, 0.0, -10.0),
));
}
fn fit_sky_to_window(
window: Single<&Window, (With<PrimaryWindow>, Changed<Window>)>,
mut sky: Single<&mut Transform, With<Sky>>,
) {
sky.scale = window.size().extend(1.0);
}