From a45d42c07af52cc19187fa656a33c2b6439638e8 Mon Sep 17 00:00:00 2001 From: xfy Date: Fri, 10 Jul 2026 10:20:38 +0800 Subject: [PATCH] feat: full-screen quad + BlackHoleMaterial pipeline --- assets/shaders/black_hole.wgsl | 11 +++++++++++ src/main.rs | 7 ++----- src/render/material.rs | 17 +++++++++++++++++ src/render/mod.rs | 4 ++++ src/render/plugin.rs | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 assets/shaders/black_hole.wgsl create mode 100644 src/render/material.rs create mode 100644 src/render/mod.rs create mode 100644 src/render/plugin.rs diff --git a/assets/shaders/black_hole.wgsl b/assets/shaders/black_hole.wgsl new file mode 100644 index 0000000..b2897ea --- /dev/null +++ b/assets/shaders/black_hole.wgsl @@ -0,0 +1,11 @@ +#import bevy_sprite::mesh2d_vertex_output::VertexOutput + +@group(#{MATERIAL_BIND_GROUP}) @binding(0) var time: f32; + +@fragment +fn fragment(in: VertexOutput) -> @location(0) vec4 { + // Gradient from time, just to prove the uniform flows. + let t = (sin(time) + 1.0) * 0.5; + let col = mix(vec3(0.02, 0.02, 0.05), vec3(0.08, 0.04, 0.12), t); + return vec4(col, 1.0); +} diff --git a/src/main.rs b/src/main.rs index c22d663..0f7cd96 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use bevy::window::WindowPlugin; #[cfg(target_arch = "wasm32")] mod web; +mod render; fn main() { // On web, abort startup if WebGPU isn't available and show a message. @@ -24,10 +25,6 @@ fn main() { }), ..default() })) - .add_systems(Startup, setup) + .add_plugins(render::BlackHolePlugin) .run(); } - -fn setup(mut commands: Commands) { - commands.spawn(Camera2d); -} diff --git a/src/render/material.rs b/src/render/material.rs new file mode 100644 index 0000000..40b5d88 --- /dev/null +++ b/src/render/material.rs @@ -0,0 +1,17 @@ +use bevy::prelude::*; +use bevy::reflect::TypePath; +use bevy::render::render_resource::AsBindGroup; +use bevy::shader::ShaderRef; +use bevy::sprite_render::Material2d; + +#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] +pub struct BlackHoleMaterial { + #[uniform(0)] + pub time: f32, +} + +impl Material2d for BlackHoleMaterial { + fn fragment_shader() -> ShaderRef { + "shaders/black_hole.wgsl".into() + } +} diff --git a/src/render/mod.rs b/src/render/mod.rs new file mode 100644 index 0000000..d6739ef --- /dev/null +++ b/src/render/mod.rs @@ -0,0 +1,4 @@ +pub mod plugin; +pub mod material; + +pub use plugin::BlackHolePlugin; diff --git a/src/render/plugin.rs b/src/render/plugin.rs new file mode 100644 index 0000000..44b1a27 --- /dev/null +++ b/src/render/plugin.rs @@ -0,0 +1,33 @@ +use bevy::prelude::*; +use bevy::sprite_render::Material2dPlugin; + +use super::material::BlackHoleMaterial; + +pub struct BlackHolePlugin; + +impl Plugin for BlackHolePlugin { + fn build(&self, app: &mut App) { + app.add_plugins(Material2dPlugin::::default()) + .add_systems(Startup, spawn_fullscreen_quad) + .add_systems(Update, update_time); + } +} + +fn spawn_fullscreen_quad( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + commands.spawn(Camera2d); + commands.spawn(( + Mesh2d(meshes.add(Rectangle::new(2.0, 2.0))), + MeshMaterial2d(materials.add(BlackHoleMaterial { time: 0.0 })), + Transform::default(), + )); +} + +fn update_time(time: Res