fullscreen_material/
fullscreen_material.rs1use bevy::{
9 core_pipeline::fullscreen_material::{FullscreenMaterial, FullscreenMaterialPlugin},
10 prelude::*,
11 render::{extract_component::ExtractComponent, render_resource::ShaderType},
12 shader::ShaderRef,
13};
14
15fn main() {
16 App::new()
17 .add_plugins((
18 DefaultPlugins,
19 FullscreenMaterialPlugin::<FullscreenEffect>::default(),
20 ))
21 .add_systems(Startup, setup)
22 .add_systems(Update, update_intensity)
23 .run();
24}
25
26fn setup(
27 mut commands: Commands,
28 mut meshes: ResMut<Assets<Mesh>>,
29 mut materials: ResMut<Assets<StandardMaterial>>,
30) {
31 commands.spawn((
32 Camera3d::default(),
33 Transform::from_translation(Vec3::new(0.0, 0.0, 5.0)).looking_at(Vec3::default(), Vec3::Y),
34 FullscreenEffect::new(FullscreenEffect::MAX_INTENSITY),
35 ));
36
37 commands.spawn((
38 Mesh3d(meshes.add(Cuboid::default())),
39 MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
40 Transform::default(),
41 ));
42
43 commands.spawn(DirectionalLight {
44 illuminance: 1_000.,
45 ..default()
46 });
47}
48
49fn update_intensity(effects: Query<&mut FullscreenEffect>, time: Res<Time>) {
50 for mut effect in effects {
51 let phase = time.elapsed_secs() * FullscreenEffect::FREQUENCY;
52 let mut intensity = ops::sin(phase);
54
55 intensity = (intensity + 1.0) / 2.0;
57 effect.intensity = intensity * FullscreenEffect::MAX_INTENSITY;
58 }
59}
60
61#[derive(Component, ExtractComponent, Clone, Copy, ShaderType, Default)]
62struct FullscreenEffect {
63 intensity: f32,
64 #[cfg(feature = "webgl2")]
67 _webgl2_padding: Vec3,
68}
69
70impl FullscreenEffect {
71 const FREQUENCY: f32 = 2.0;
72 const MAX_INTENSITY: f32 = 0.015;
73
74 fn new(intensity: f32) -> Self {
75 Self {
76 intensity,
77 ..Default::default()
78 }
79 }
80}
81
82impl FullscreenMaterial for FullscreenEffect {
83 fn fragment_shader() -> ShaderRef {
84 "shaders/fullscreen_effect.wgsl".into()
85 }
86
87 }