order_independent_transparency/
order_independent_transparency.rs1use bevy::{
7 camera::visibility::RenderLayers,
8 color::palettes::css::{BLUE, GREEN, RED},
9 core_pipeline::oit::OrderIndependentTransparencySettings,
10 prelude::*,
11};
12
13fn main() {
14 App::new()
15 .add_plugins(DefaultPlugins)
16 .add_systems(Startup, setup)
17 .add_systems(Update, (toggle_oit, cycle_scenes))
18 .run();
19}
20
21fn setup(
23 mut commands: Commands,
24 mut meshes: ResMut<Assets<Mesh>>,
25 mut materials: ResMut<Assets<StandardMaterial>>,
26) {
27 commands.spawn((
29 Camera3d::default(),
30 Transform::from_xyz(0.0, 0.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
31 OrderIndependentTransparencySettings::default(),
33 RenderLayers::layer(1),
34 Msaa::Off,
36 ));
37
38 commands.spawn((
40 PointLight {
41 shadows_enabled: false,
42 ..default()
43 },
44 Transform::from_xyz(4.0, 8.0, 4.0),
45 RenderLayers::layer(1),
46 ));
47
48 commands.spawn((
50 Text::default(),
51 Node {
52 position_type: PositionType::Absolute,
53 top: px(12),
54 left: px(12),
55 ..default()
56 },
57 RenderLayers::layer(1),
58 children![
59 TextSpan::new("Press T to toggle OIT\n"),
60 TextSpan::new("OIT Enabled"),
61 TextSpan::new("\nPress C to cycle test scenes"),
62 ],
63 ));
64
65 spawn_spheres(&mut commands, &mut meshes, &mut materials);
67}
68
69fn toggle_oit(
70 mut commands: Commands,
71 text: Single<Entity, With<Text>>,
72 keyboard_input: Res<ButtonInput<KeyCode>>,
73 q: Single<(Entity, Has<OrderIndependentTransparencySettings>), With<Camera3d>>,
74 mut text_writer: TextUiWriter,
75) {
76 if keyboard_input.just_pressed(KeyCode::KeyT) {
77 let (e, has_oit) = *q;
78 *text_writer.text(*text, 2) = if has_oit {
79 commands
81 .entity(e)
82 .remove::<OrderIndependentTransparencySettings>();
83 "OIT disabled".to_string()
84 } else {
85 commands
88 .entity(e)
89 .insert(OrderIndependentTransparencySettings::default());
90 "OIT enabled".to_string()
91 };
92 }
93}
94
95fn cycle_scenes(
96 mut commands: Commands,
97 keyboard_input: Res<ButtonInput<KeyCode>>,
98 mut meshes: ResMut<Assets<Mesh>>,
99 mut materials: ResMut<Assets<StandardMaterial>>,
100 q: Query<Entity, With<Mesh3d>>,
101 mut scene_id: Local<usize>,
102) {
103 if keyboard_input.just_pressed(KeyCode::KeyC) {
104 for e in &q {
106 commands.entity(e).despawn();
107 }
108 *scene_id = (*scene_id + 1) % 2;
110 match *scene_id {
112 0 => spawn_spheres(&mut commands, &mut meshes, &mut materials),
113 1 => spawn_occlusion_test(&mut commands, &mut meshes, &mut materials),
114 _ => unreachable!(),
115 }
116 }
117}
118
119fn spawn_spheres(
123 commands: &mut Commands,
124 meshes: &mut Assets<Mesh>,
125 materials: &mut Assets<StandardMaterial>,
126) {
127 let pos_a = Vec3::new(-1.0, 0.75, 0.0);
128 let pos_b = Vec3::new(0.0, -0.75, 0.0);
129 let pos_c = Vec3::new(1.0, 0.75, 0.0);
130
131 let offset = Vec3::new(0.0, 0.0, 0.0);
132
133 let sphere_handle = meshes.add(Sphere::new(2.0).mesh());
134
135 let alpha = 0.25;
136
137 let render_layers = RenderLayers::layer(1);
138
139 commands.spawn((
140 Mesh3d(sphere_handle.clone()),
141 MeshMaterial3d(materials.add(StandardMaterial {
142 base_color: RED.with_alpha(alpha).into(),
143 alpha_mode: AlphaMode::Blend,
144 ..default()
145 })),
146 Transform::from_translation(pos_a + offset),
147 render_layers.clone(),
148 ));
149 commands.spawn((
150 Mesh3d(sphere_handle.clone()),
151 MeshMaterial3d(materials.add(StandardMaterial {
152 base_color: GREEN.with_alpha(alpha).into(),
153 alpha_mode: AlphaMode::Blend,
154 ..default()
155 })),
156 Transform::from_translation(pos_b + offset),
157 render_layers.clone(),
158 ));
159 commands.spawn((
160 Mesh3d(sphere_handle.clone()),
161 MeshMaterial3d(materials.add(StandardMaterial {
162 base_color: BLUE.with_alpha(alpha).into(),
163 alpha_mode: AlphaMode::Blend,
164 ..default()
165 })),
166 Transform::from_translation(pos_c + offset),
167 render_layers.clone(),
168 ));
169}
170
171fn spawn_occlusion_test(
175 commands: &mut Commands,
176 meshes: &mut Assets<Mesh>,
177 materials: &mut Assets<StandardMaterial>,
178) {
179 let sphere_handle = meshes.add(Sphere::new(1.0).mesh());
180 let cube_handle = meshes.add(Cuboid::from_size(Vec3::ONE).mesh());
181 let cube_material = materials.add(Color::srgb(0.8, 0.7, 0.6));
182
183 let render_layers = RenderLayers::layer(1);
184
185 let x = -2.5;
187 commands.spawn((
188 Mesh3d(cube_handle.clone()),
189 MeshMaterial3d(cube_material.clone()),
190 Transform::from_xyz(x, 0.0, 2.0),
191 render_layers.clone(),
192 ));
193 commands.spawn((
194 Mesh3d(sphere_handle.clone()),
195 MeshMaterial3d(materials.add(StandardMaterial {
196 base_color: RED.with_alpha(0.5).into(),
197 alpha_mode: AlphaMode::Blend,
198 ..default()
199 })),
200 Transform::from_xyz(x, 0., 0.),
201 render_layers.clone(),
202 ));
203
204 commands.spawn((
206 Mesh3d(cube_handle.clone()),
207 MeshMaterial3d(cube_material.clone()),
208 Transform::from_xyz(x, 0.0, 1.0),
209 render_layers.clone(),
210 ));
211 commands.spawn((
212 Mesh3d(sphere_handle.clone()),
213 MeshMaterial3d(materials.add(StandardMaterial {
214 base_color: RED.with_alpha(0.5).into(),
215 alpha_mode: AlphaMode::Blend,
216 ..default()
217 })),
218 Transform::from_xyz(0., 0., 0.),
219 render_layers.clone(),
220 ));
221
222 let x = 2.5;
224 commands.spawn((
225 Mesh3d(cube_handle.clone()),
226 MeshMaterial3d(cube_material.clone()),
227 Transform::from_xyz(x, 0.0, -2.0),
228 render_layers.clone(),
229 ));
230 commands.spawn((
231 Mesh3d(sphere_handle.clone()),
232 MeshMaterial3d(materials.add(StandardMaterial {
233 base_color: RED.with_alpha(0.5).into(),
234 alpha_mode: AlphaMode::Blend,
235 ..default()
236 })),
237 Transform::from_xyz(x, 0., 0.),
238 render_layers.clone(),
239 ));
240}