Function default

Source
pub fn default<T>() -> T
where T: Default,
Expand description

An ergonomic abbreviation for Default::default() to make initializing structs easier.

This is especially helpful when combined with “struct update syntax”.

use bevy_utils::default;

#[derive(Default)]
struct Foo {
  a: usize,
  b: usize,
  c: usize,
}

// Normally you would initialize a struct with defaults using "struct update syntax"
// combined with `Default::default()`. This example sets `Foo::bar` to 10 and the remaining
// values to their defaults.
let foo = Foo {
  a: 10,
  ..Default::default()
};

// But now you can do this, which is equivalent:
let foo = Foo {
  a: 10,
  ..default()
};
Examples found in repository?
examples/3d/color_grading.rs (line 74)
73    fn default() -> Self {
74        Self::Global(default())
75    }
76}
77
78/// Buttons consist of three parts: the button itself, a label child, and a
79/// value child. This specifies one of the three entities.
80#[derive(Clone, Copy, PartialEq, Component)]
81enum ColorGradingOptionWidgetType {
82    /// The parent button.
83    Button,
84    /// The label of the button.
85    Label,
86    /// The numerical value that the button displays.
87    Value,
88}
89
90#[derive(Clone, Copy, Component)]
91struct ColorGradingOptionWidget {
92    widget_type: ColorGradingOptionWidgetType,
93    option: SelectedColorGradingOption,
94}
95
96/// A marker component for the help text at the top left of the screen.
97#[derive(Clone, Copy, Component)]
98struct HelpText;
99
100fn main() {
101    App::new()
102        .add_plugins(DefaultPlugins)
103        .init_resource::<SelectedColorGradingOption>()
104        .add_systems(Startup, setup)
105        .add_systems(
106            Update,
107            (
108                handle_button_presses,
109                adjust_color_grading_option,
110                update_ui_state,
111            )
112                .chain(),
113        )
114        .run();
115}
116
117fn setup(
118    mut commands: Commands,
119    currently_selected_option: Res<SelectedColorGradingOption>,
120    asset_server: Res<AssetServer>,
121) {
122    // Create the scene.
123    add_basic_scene(&mut commands, &asset_server);
124
125    // Create the root UI element.
126    let font = asset_server.load(FONT_PATH);
127    let color_grading = ColorGrading::default();
128    add_buttons(&mut commands, &font, &color_grading);
129
130    // Spawn help text.
131    add_help_text(&mut commands, &font, &currently_selected_option);
132
133    // Spawn the camera.
134    add_camera(&mut commands, &asset_server, color_grading);
135}
136
137/// Adds all the buttons on the bottom of the scene.
138fn add_buttons(commands: &mut Commands, font: &Handle<Font>, color_grading: &ColorGrading) {
139    // Spawn the parent node that contains all the buttons.
140    commands
141        .spawn(Node {
142            flex_direction: FlexDirection::Column,
143            position_type: PositionType::Absolute,
144            row_gap: Val::Px(6.0),
145            left: Val::Px(12.0),
146            bottom: Val::Px(12.0),
147            ..default()
148        })
149        .with_children(|parent| {
150            // Create the first row, which contains the global controls.
151            add_buttons_for_global_controls(parent, color_grading, font);
152
153            // Create the rows for individual controls.
154            for section in [
155                SelectedColorGradingSection::Highlights,
156                SelectedColorGradingSection::Midtones,
157                SelectedColorGradingSection::Shadows,
158            ] {
159                add_buttons_for_section(parent, section, color_grading, font);
160            }
161        });
162}
163
164/// Adds the buttons for the global controls (those that control the scene as a
165/// whole as opposed to shadows, midtones, or highlights).
166fn add_buttons_for_global_controls(
167    parent: &mut ChildSpawnerCommands,
168    color_grading: &ColorGrading,
169    font: &Handle<Font>,
170) {
171    // Add the parent node for the row.
172    parent.spawn(Node::default()).with_children(|parent| {
173        // Add some placeholder text to fill this column.
174        parent.spawn(Node {
175            width: Val::Px(125.0),
176            ..default()
177        });
178
179        // Add each global color grading option button.
180        for option in [
181            SelectedGlobalColorGradingOption::Exposure,
182            SelectedGlobalColorGradingOption::Temperature,
183            SelectedGlobalColorGradingOption::Tint,
184            SelectedGlobalColorGradingOption::Hue,
185        ] {
186            add_button_for_value(
187                parent,
188                SelectedColorGradingOption::Global(option),
189                color_grading,
190                font,
191            );
192        }
193    });
194}
195
196/// Adds the buttons that control color grading for individual sections
197/// (highlights, midtones, shadows).
198fn add_buttons_for_section(
199    parent: &mut ChildSpawnerCommands,
200    section: SelectedColorGradingSection,
201    color_grading: &ColorGrading,
202    font: &Handle<Font>,
203) {
204    // Spawn the row container.
205    parent
206        .spawn(Node {
207            align_items: AlignItems::Center,
208            ..default()
209        })
210        .with_children(|parent| {
211            // Spawn the label ("Highlights", etc.)
212            add_text(parent, &section.to_string(), font, Color::WHITE).insert(Node {
213                width: Val::Px(125.0),
214                ..default()
215            });
216
217            // Spawn the buttons.
218            for option in [
219                SelectedSectionColorGradingOption::Saturation,
220                SelectedSectionColorGradingOption::Contrast,
221                SelectedSectionColorGradingOption::Gamma,
222                SelectedSectionColorGradingOption::Gain,
223                SelectedSectionColorGradingOption::Lift,
224            ] {
225                add_button_for_value(
226                    parent,
227                    SelectedColorGradingOption::Section(section, option),
228                    color_grading,
229                    font,
230                );
231            }
232        });
233}
234
235/// Adds a button that controls one of the color grading values.
236fn add_button_for_value(
237    parent: &mut ChildSpawnerCommands,
238    option: SelectedColorGradingOption,
239    color_grading: &ColorGrading,
240    font: &Handle<Font>,
241) {
242    // Add the button node.
243    parent
244        .spawn((
245            Button,
246            Node {
247                border: UiRect::all(Val::Px(1.0)),
248                width: Val::Px(200.0),
249                justify_content: JustifyContent::Center,
250                align_items: AlignItems::Center,
251                padding: UiRect::axes(Val::Px(12.0), Val::Px(6.0)),
252                margin: UiRect::right(Val::Px(12.0)),
253                ..default()
254            },
255            BorderColor(Color::WHITE),
256            BorderRadius::MAX,
257            BackgroundColor(Color::BLACK),
258        ))
259        .insert(ColorGradingOptionWidget {
260            widget_type: ColorGradingOptionWidgetType::Button,
261            option,
262        })
263        .with_children(|parent| {
264            // Add the button label.
265            let label = match option {
266                SelectedColorGradingOption::Global(option) => option.to_string(),
267                SelectedColorGradingOption::Section(_, option) => option.to_string(),
268            };
269            add_text(parent, &label, font, Color::WHITE).insert(ColorGradingOptionWidget {
270                widget_type: ColorGradingOptionWidgetType::Label,
271                option,
272            });
273
274            // Add a spacer.
275            parent.spawn(Node {
276                flex_grow: 1.0,
277                ..default()
278            });
279
280            // Add the value text.
281            add_text(
282                parent,
283                &format!("{:.3}", option.get(color_grading)),
284                font,
285                Color::WHITE,
286            )
287            .insert(ColorGradingOptionWidget {
288                widget_type: ColorGradingOptionWidgetType::Value,
289                option,
290            });
291        });
292}
293
294/// Creates the help text at the top of the screen.
295fn add_help_text(
296    commands: &mut Commands,
297    font: &Handle<Font>,
298    currently_selected_option: &SelectedColorGradingOption,
299) {
300    commands.spawn((
301        Text::new(create_help_text(currently_selected_option)),
302        TextFont {
303            font: font.clone(),
304            ..default()
305        },
306        Node {
307            position_type: PositionType::Absolute,
308            left: Val::Px(12.0),
309            top: Val::Px(12.0),
310            ..default()
311        },
312        HelpText,
313    ));
314}
315
316/// Adds some text to the scene.
317fn add_text<'a>(
318    parent: &'a mut ChildSpawnerCommands,
319    label: &str,
320    font: &Handle<Font>,
321    color: Color,
322) -> EntityCommands<'a> {
323    parent.spawn((
324        Text::new(label),
325        TextFont {
326            font: font.clone(),
327            font_size: 15.0,
328            ..default()
329        },
330        TextColor(color),
331    ))
332}
333
334fn add_camera(commands: &mut Commands, asset_server: &AssetServer, color_grading: ColorGrading) {
335    commands.spawn((
336        Camera3d::default(),
337        Camera {
338            hdr: true,
339            ..default()
340        },
341        Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
342        color_grading,
343        DistanceFog {
344            color: Color::srgb_u8(43, 44, 47),
345            falloff: FogFalloff::Linear {
346                start: 1.0,
347                end: 8.0,
348            },
349            ..default()
350        },
351        EnvironmentMapLight {
352            diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
353            specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
354            intensity: 2000.0,
355            ..default()
356        },
357    ));
358}
359
360fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
361    // Spawn the main scene.
362    commands.spawn(SceneRoot(asset_server.load(
363        GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
364    )));
365
366    // Spawn the flight helmet.
367    commands.spawn((
368        SceneRoot(
369            asset_server
370                .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
371        ),
372        Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
373    ));
374
375    // Spawn the light.
376    commands.spawn((
377        DirectionalLight {
378            illuminance: 15000.0,
379            shadows_enabled: true,
380            ..default()
381        },
382        Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
383        CascadeShadowConfigBuilder {
384            maximum_distance: 3.0,
385            first_cascade_far_bound: 0.9,
386            ..default()
387        }
388        .build(),
389    ));
390}
More examples
Hide additional examples
examples/3d/pcss.rs (line 66)
64    fn default() -> Self {
65        Self {
66            light_type: default(),
67            shadow_filter: default(),
68            soft_shadows: true,
69        }
70    }
71}
72
73/// The type of light presently in the scene: directional, point, or spot.
74#[derive(Clone, Copy, Default, PartialEq)]
75enum LightType {
76    /// A directional light, with a cascaded shadow map.
77    #[default]
78    Directional,
79    /// A point light, with a cube shadow map.
80    Point,
81    /// A spot light, with a cube shadow map.
82    Spot,
83}
84
85/// The type of shadow filter.
86///
87/// Generally, `Gaussian` is preferred when temporal antialiasing isn't in use,
88/// while `Temporal` is preferred when TAA is in use. In this example, this
89/// setting also turns TAA on and off.
90#[derive(Clone, Copy, Default, PartialEq)]
91enum ShadowFilter {
92    /// The non-temporal Gaussian filter (Castano '13 for directional lights, an
93    /// analogous alternative for point and spot lights).
94    #[default]
95    NonTemporal,
96    /// The temporal Gaussian filter (Jimenez '14 for directional lights, an
97    /// analogous alternative for point and spot lights).
98    Temporal,
99}
100
101/// Each example setting that can be toggled in the UI.
102#[derive(Clone, Copy, PartialEq)]
103enum AppSetting {
104    /// The type of light presently in the scene: directional, point, or spot.
105    LightType(LightType),
106    /// The type of shadow filter.
107    ShadowFilter(ShadowFilter),
108    /// Whether PCSS is enabled or disabled.
109    SoftShadows(bool),
110}
111
112/// The example application entry point.
113fn main() {
114    App::new()
115        .init_resource::<AppStatus>()
116        .add_plugins(DefaultPlugins.set(WindowPlugin {
117            primary_window: Some(Window {
118                title: "Bevy Percentage Closer Soft Shadows Example".into(),
119                ..default()
120            }),
121            ..default()
122        }))
123        .add_plugins(TemporalAntiAliasPlugin)
124        .add_event::<WidgetClickEvent<AppSetting>>()
125        .add_systems(Startup, setup)
126        .add_systems(Update, widgets::handle_ui_interactions::<AppSetting>)
127        .add_systems(
128            Update,
129            update_radio_buttons.after(widgets::handle_ui_interactions::<AppSetting>),
130        )
131        .add_systems(
132            Update,
133            (
134                handle_light_type_change,
135                handle_shadow_filter_change,
136                handle_pcss_toggle,
137            )
138                .after(widgets::handle_ui_interactions::<AppSetting>),
139        )
140        .run();
141}
142
143/// Creates all the objects in the scene.
144fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_status: Res<AppStatus>) {
145    spawn_camera(&mut commands, &asset_server);
146    spawn_light(&mut commands, &app_status);
147    spawn_gltf_scene(&mut commands, &asset_server);
148    spawn_buttons(&mut commands);
149}
150
151/// Spawns the camera, with the initial shadow filtering method.
152fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
153    commands
154        .spawn((
155            Camera3d::default(),
156            Transform::from_xyz(-12.912 * 0.7, 4.466 * 0.7, -10.624 * 0.7).with_rotation(
157                Quat::from_euler(EulerRot::YXZ, -134.76 / 180.0 * PI, -0.175, 0.0),
158            ),
159        ))
160        .insert(ShadowFilteringMethod::Gaussian)
161        // `TemporalJitter` is needed for TAA. Note that it does nothing without
162        // `TemporalAntiAliasSettings`.
163        .insert(TemporalJitter::default())
164        // We want MSAA off for TAA to work properly.
165        .insert(Msaa::Off)
166        // The depth prepass is needed for TAA.
167        .insert(DepthPrepass)
168        // The motion vector prepass is needed for TAA.
169        .insert(MotionVectorPrepass)
170        // Add a nice skybox.
171        .insert(Skybox {
172            image: asset_server.load("environment_maps/sky_skybox.ktx2"),
173            brightness: 500.0,
174            rotation: Quat::IDENTITY,
175        });
176}
177
178/// Spawns the initial light.
179fn spawn_light(commands: &mut Commands, app_status: &AppStatus) {
180    // Because this light can become a directional light, point light, or spot
181    // light depending on the settings, we add the union of the components
182    // necessary for this light to behave as all three of those.
183    commands
184        .spawn((
185            create_directional_light(app_status),
186            Transform::from_rotation(Quat::from_array([
187                0.6539259,
188                -0.34646285,
189                0.36505926,
190                -0.5648683,
191            ]))
192            .with_translation(vec3(57.693, 34.334, -6.422)),
193        ))
194        // These two are needed for point lights.
195        .insert(CubemapVisibleEntities::default())
196        .insert(CubemapFrusta::default())
197        // These two are needed for spot lights.
198        .insert(VisibleMeshEntities::default())
199        .insert(Frustum::default());
200}
201
202/// Loads and spawns the glTF palm tree scene.
203fn spawn_gltf_scene(commands: &mut Commands, asset_server: &AssetServer) {
204    commands.spawn(SceneRoot(
205        asset_server.load("models/PalmTree/PalmTree.gltf#Scene0"),
206    ));
207}
208
209/// Spawns all the buttons at the bottom of the screen.
210fn spawn_buttons(commands: &mut Commands) {
211    commands
212        .spawn(widgets::main_ui_node())
213        .with_children(|parent| {
214            widgets::spawn_option_buttons(
215                parent,
216                "Light Type",
217                &[
218                    (AppSetting::LightType(LightType::Directional), "Directional"),
219                    (AppSetting::LightType(LightType::Point), "Point"),
220                    (AppSetting::LightType(LightType::Spot), "Spot"),
221                ],
222            );
223            widgets::spawn_option_buttons(
224                parent,
225                "Shadow Filter",
226                &[
227                    (AppSetting::ShadowFilter(ShadowFilter::Temporal), "Temporal"),
228                    (
229                        AppSetting::ShadowFilter(ShadowFilter::NonTemporal),
230                        "Non-Temporal",
231                    ),
232                ],
233            );
234            widgets::spawn_option_buttons(
235                parent,
236                "Soft Shadows",
237                &[
238                    (AppSetting::SoftShadows(true), "On"),
239                    (AppSetting::SoftShadows(false), "Off"),
240                ],
241            );
242        });
243}
244
245/// Updates the style of the radio buttons that enable and disable soft shadows
246/// to reflect whether PCSS is enabled.
247fn update_radio_buttons(
248    mut widgets: Query<
249        (
250            Entity,
251            Option<&mut BackgroundColor>,
252            Has<Text>,
253            &WidgetClickSender<AppSetting>,
254        ),
255        Or<(With<RadioButton>, With<RadioButtonText>)>,
256    >,
257    app_status: Res<AppStatus>,
258    mut writer: TextUiWriter,
259) {
260    for (entity, image, has_text, sender) in widgets.iter_mut() {
261        let selected = match **sender {
262            AppSetting::LightType(light_type) => light_type == app_status.light_type,
263            AppSetting::ShadowFilter(shadow_filter) => shadow_filter == app_status.shadow_filter,
264            AppSetting::SoftShadows(soft_shadows) => soft_shadows == app_status.soft_shadows,
265        };
266
267        if let Some(mut bg_color) = image {
268            widgets::update_ui_radio_button(&mut bg_color, selected);
269        }
270        if has_text {
271            widgets::update_ui_radio_button_text(entity, &mut writer, selected);
272        }
273    }
274}
275
276/// Handles requests from the user to change the type of light.
277fn handle_light_type_change(
278    mut commands: Commands,
279    mut lights: Query<Entity, Or<(With<DirectionalLight>, With<PointLight>, With<SpotLight>)>>,
280    mut events: EventReader<WidgetClickEvent<AppSetting>>,
281    mut app_status: ResMut<AppStatus>,
282) {
283    for event in events.read() {
284        let AppSetting::LightType(light_type) = **event else {
285            continue;
286        };
287        app_status.light_type = light_type;
288
289        for light in lights.iter_mut() {
290            let mut light_commands = commands.entity(light);
291            light_commands
292                .remove::<DirectionalLight>()
293                .remove::<PointLight>()
294                .remove::<SpotLight>();
295            match light_type {
296                LightType::Point => {
297                    light_commands.insert(create_point_light(&app_status));
298                }
299                LightType::Spot => {
300                    light_commands.insert(create_spot_light(&app_status));
301                }
302                LightType::Directional => {
303                    light_commands.insert(create_directional_light(&app_status));
304                }
305            }
306        }
307    }
308}
309
310/// Handles requests from the user to change the shadow filter method.
311///
312/// This system is also responsible for enabling and disabling TAA as
313/// appropriate.
314fn handle_shadow_filter_change(
315    mut commands: Commands,
316    mut cameras: Query<(Entity, &mut ShadowFilteringMethod)>,
317    mut events: EventReader<WidgetClickEvent<AppSetting>>,
318    mut app_status: ResMut<AppStatus>,
319) {
320    for event in events.read() {
321        let AppSetting::ShadowFilter(shadow_filter) = **event else {
322            continue;
323        };
324        app_status.shadow_filter = shadow_filter;
325
326        for (camera, mut shadow_filtering_method) in cameras.iter_mut() {
327            match shadow_filter {
328                ShadowFilter::NonTemporal => {
329                    *shadow_filtering_method = ShadowFilteringMethod::Gaussian;
330                    commands.entity(camera).remove::<TemporalAntiAliasing>();
331                }
332                ShadowFilter::Temporal => {
333                    *shadow_filtering_method = ShadowFilteringMethod::Temporal;
334                    commands
335                        .entity(camera)
336                        .insert(TemporalAntiAliasing::default());
337                }
338            }
339        }
340    }
341}
342
343/// Handles requests from the user to toggle soft shadows on and off.
344fn handle_pcss_toggle(
345    mut lights: Query<AnyOf<(&mut DirectionalLight, &mut PointLight, &mut SpotLight)>>,
346    mut events: EventReader<WidgetClickEvent<AppSetting>>,
347    mut app_status: ResMut<AppStatus>,
348) {
349    for event in events.read() {
350        let AppSetting::SoftShadows(value) = **event else {
351            continue;
352        };
353        app_status.soft_shadows = value;
354
355        // Recreating the lights is the simplest way to toggle soft shadows.
356        for (directional_light, point_light, spot_light) in lights.iter_mut() {
357            if let Some(mut directional_light) = directional_light {
358                *directional_light = create_directional_light(&app_status);
359            }
360            if let Some(mut point_light) = point_light {
361                *point_light = create_point_light(&app_status);
362            }
363            if let Some(mut spot_light) = spot_light {
364                *spot_light = create_spot_light(&app_status);
365            }
366        }
367    }
368}
369
370/// Creates the [`DirectionalLight`] component with the appropriate settings.
371fn create_directional_light(app_status: &AppStatus) -> DirectionalLight {
372    DirectionalLight {
373        shadows_enabled: true,
374        soft_shadow_size: if app_status.soft_shadows {
375            Some(LIGHT_RADIUS)
376        } else {
377            None
378        },
379        shadow_depth_bias: DIRECTIONAL_SHADOW_DEPTH_BIAS,
380        ..default()
381    }
382}
383
384/// Creates the [`PointLight`] component with the appropriate settings.
385fn create_point_light(app_status: &AppStatus) -> PointLight {
386    PointLight {
387        intensity: POINT_LIGHT_INTENSITY,
388        range: POINT_LIGHT_RANGE,
389        shadows_enabled: true,
390        radius: LIGHT_RADIUS,
391        soft_shadows_enabled: app_status.soft_shadows,
392        shadow_depth_bias: POINT_SHADOW_DEPTH_BIAS,
393        shadow_map_near_z: SHADOW_MAP_NEAR_Z,
394        ..default()
395    }
396}
397
398/// Creates the [`SpotLight`] component with the appropriate settings.
399fn create_spot_light(app_status: &AppStatus) -> SpotLight {
400    SpotLight {
401        intensity: POINT_LIGHT_INTENSITY,
402        range: POINT_LIGHT_RANGE,
403        radius: LIGHT_RADIUS,
404        shadows_enabled: true,
405        soft_shadows_enabled: app_status.soft_shadows,
406        shadow_depth_bias: DIRECTIONAL_SHADOW_DEPTH_BIAS,
407        shadow_map_near_z: SHADOW_MAP_NEAR_Z,
408        ..default()
409    }
410}
tests/3d/no_prepass.rs (line 9)
5fn main() {
6    App::new()
7        .add_plugins(DefaultPlugins.set(PbrPlugin {
8            prepass_enabled: false,
9            ..default()
10        }))
11        .run();
12}
examples/app/log_layers.rs (line 44)
39fn main() {
40    App::new()
41        .add_plugins(DefaultPlugins.set(bevy::log::LogPlugin {
42            custom_layer,
43
44            ..default()
45        }))
46        .add_systems(Update, log_system)
47        .run();
48}
examples/3d/spherical_area_lights.rs (line 9)
5fn main() {
6    App::new()
7        .insert_resource(AmbientLight {
8            brightness: 60.0,
9            ..default()
10        })
11        .add_plugins(DefaultPlugins)
12        .add_systems(Startup, setup)
13        .run();
14}
15
16fn setup(
17    mut commands: Commands,
18    mut meshes: ResMut<Assets<Mesh>>,
19    mut materials: ResMut<Assets<StandardMaterial>>,
20) {
21    // camera
22    commands.spawn((
23        Camera3d::default(),
24        Transform::from_xyz(0.2, 1.5, 2.5).looking_at(Vec3::ZERO, Vec3::Y),
25    ));
26
27    // plane
28    commands.spawn((
29        Mesh3d(meshes.add(Plane3d::default().mesh().size(100.0, 100.0))),
30        MeshMaterial3d(materials.add(StandardMaterial {
31            base_color: Color::srgb(0.2, 0.2, 0.2),
32            perceptual_roughness: 0.08,
33            ..default()
34        })),
35    ));
36
37    const COUNT: usize = 6;
38    let position_range = -2.0..2.0;
39    let radius_range = 0.0..0.4;
40    let pos_len = position_range.end - position_range.start;
41    let radius_len = radius_range.end - radius_range.start;
42    let mesh = meshes.add(Sphere::new(1.0).mesh().uv(120, 64));
43
44    for i in 0..COUNT {
45        let percent = i as f32 / COUNT as f32;
46        let radius = radius_range.start + percent * radius_len;
47
48        // sphere light
49        commands
50            .spawn((
51                Mesh3d(mesh.clone()),
52                MeshMaterial3d(materials.add(StandardMaterial {
53                    base_color: Color::srgb(0.5, 0.5, 1.0),
54                    unlit: true,
55                    ..default()
56                })),
57                Transform::from_xyz(position_range.start + percent * pos_len, 0.3, 0.0)
58                    .with_scale(Vec3::splat(radius)),
59            ))
60            .with_child(PointLight {
61                radius,
62                color: Color::srgb(0.2, 0.2, 1.0),
63                ..default()
64            });
65    }
66}
examples/asset/asset_decompression.rs (line 111)
106fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
107    commands.spawn(Camera2d);
108
109    commands.spawn(Compressed::<Image> {
110        compressed: asset_server.load("data/compressed_image.png.gz"),
111        ..default()
112    });
113}