Skip to content

Instantly share code, notes, and snippets.

@IceSentry
Created October 22, 2025 00:46
Show Gist options
  • Select an option

  • Save IceSentry/376957e38469ea8cb52e0e9a4c3c4bec to your computer and use it in GitHub Desktop.

Select an option

Save IceSentry/376957e38469ea8cb52e0e9a4c3c4bec to your computer and use it in GitHub Desktop.
Fake post processing material using Mesh2d
//! Fake post processing using a Mesh2d
//! This assumes a single camera that is always covering the entire window
use bevy::{
prelude::*,
shader::ShaderRef,
sprite_render::{Material2d, Material2dPlugin},
window::WindowResized,
};
use bevy_render::render_resource::{AsBindGroup, ShaderType};
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
Material2dPlugin::<PostProcessingMaterial>::default(),
))
.add_systems(Startup, setup)
.add_systems(Update, on_resize)
.run();
}
#[derive(Component)]
struct PostProcessingMesh;
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<PostProcessingMaterial>>,
) {
commands.spawn(Camera2d);
commands.spawn((
Mesh2d(meshes.add(Rectangle::new(1280.0, 720.0).mesh())),
MeshMaterial2d(materials.add(PostProcessingMaterial {
color: Vec3::new(0.0, 0.0, 1.0),
})),
PostProcessingMesh,
));
}
// Resize the mesh to always match the size of the screen
fn on_resize(
mut window_resized: MessageReader<WindowResized>,
post_processing_mesh: Single<&Mesh2d, With<PostProcessingMesh>>,
mut meshes: ResMut<Assets<Mesh>>,
) {
let Some(window_resized) = window_resized.read().last() else {
return;
};
let Some(mesh) = meshes.get_mut(post_processing_mesh.id()) else {
return;
};
*mesh = Rectangle::new(window_resized.width, window_resized.height - 10.0)
.mesh()
.build();
}
#[derive(AsBindGroup, Asset, TypePath, Clone, ShaderType)]
struct PostProcessingMaterial {
#[uniform(0)]
color: Vec3,
}
impl Material2d for PostProcessingMaterial {
fn fragment_shader() -> ShaderRef {
"post_processing_material.wgsl".into()
}
}
#import bevy_sprite::mesh2d_vertex_output::VertexOutput
@group(#{MATERIAL_BIND_GROUP}) @binding(0) var<uniform> material_color: vec3<f32>;
@fragment
fn fragment(mesh: VertexOutput) -> @location(0) vec4<f32> {
return vec4(mesh.uv, 0.0, 1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment