compressed_image_saver/
compressed_image_saver.rs1use bevy::{
4 camera::Hdr,
5 light::{CascadeShadowConfigBuilder, DirectionalLightShadowMap},
6 mesh::SphereKind,
7 prelude::*,
8};
9use std::{
10 fs,
11 io::{self, Read},
12 path::Path,
13};
14
15fn main() {
16 download_assets().expect("failed to download GroundSand005 textures");
17
18 App::new()
19 .add_plugins(DefaultPlugins.set(AssetPlugin {
20 mode: AssetMode::Processed,
21 ..default()
22 }))
23 .insert_resource(DirectionalLightShadowMap { size: 4096 })
24 .add_systems(Startup, spawn_scene)
25 .add_systems(Update, rotate)
26 .run();
27}
28
29fn spawn_scene(
30 asset_server: Res<AssetServer>,
31 mut meshes: ResMut<Assets<Mesh>>,
32 mut commands: Commands,
33) {
34 let orm = asset_server.load("textures/GroundSand005/GroundSand005_ORM_2K.png");
36 let sphere_material = StandardMaterial {
37 base_color_texture: Some(
38 asset_server.load("textures/GroundSand005/GroundSand005_COL_2K.jpg"),
39 ),
40 perceptual_roughness: 1.0,
41 metallic_roughness_texture: Some(orm.clone()),
42 normal_map_texture: Some(
43 asset_server.load("textures/GroundSand005/GroundSand005_NRM_2K.jpg"),
44 ),
45 occlusion_texture: Some(orm),
46 parallax_mapping_method: ParallaxMappingMethod::Relief { max_steps: 4 },
47 depth_map: Some(asset_server.load("textures/GroundSand005/GroundSand005_DISP_2K.jpg")),
48 ..Default::default()
49 };
50
51 let diffuse_env_map = asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2");
52 let specular_env_map = asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2");
53
54 let floor_mesh = meshes.add(Circle::new(4.0).mesh().resolution(128).build());
55
56 let sphere_mesh = meshes.add(
57 Sphere::new(1.0)
58 .mesh()
59 .kind(SphereKind::Ico { subdivisions: 50 })
60 .build()
61 .with_generated_tangents()
62 .unwrap(),
63 );
64
65 commands.spawn_scene_list(bsn_list! {
66 Mesh3d(floor_mesh)
67 MeshMaterial3d::<StandardMaterial>(asset_value(Color::WHITE))
68 Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2))
69 --
70 Mesh3d(sphere_mesh)
71 MeshMaterial3d::<StandardMaterial>(asset_value(sphere_material))
72 Transform::from_xyz(0.0, 1.0, 0.0)
73 Rotating
74 --
75 DirectionalLight {
76 illuminance: 7300.0,
77 shadow_maps_enabled: true,
78 }
79 Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y)
80 CascadeShadowConfigBuilder {
81 num_cascades: 1,
82 maximum_distance: 20.0,
83 ..default()
84 }.build()
85 --
86 Camera3d
87 Hdr
88 Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y)
89 EnvironmentMapLight {
90 diffuse_map: diffuse_env_map,
91 specular_map: specular_env_map,
92 intensity: 1200.0,
93 }
94 });
95}
96
97#[derive(Component, Default, Clone)]
98struct Rotating;
99
100fn rotate(mut query: Query<&mut Transform, With<Rotating>>, time: Res<Time>) {
101 for mut transform in &mut query {
102 transform.rotate_y(time.delta_secs() * 0.5);
103 }
104}
105
106fn download_assets() -> io::Result<()> {
115 let asset_files = &[
116 "GroundSand005_COL_2K.jpg",
117 "GroundSand005_COL_2K.jpg.meta",
118 "GroundSand005_NRM_2K.jpg",
119 "GroundSand005_NRM_2K.jpg.meta",
120 "GroundSand005_DISP_2K.jpg",
121 "GroundSand005_DISP_2K.jpg.meta",
122 "GroundSand005_ORM_2K.png",
123 "GroundSand005_ORM_2K.png.meta",
124 ];
125
126 let dir = Path::new("assets/textures/GroundSand005");
127 fs::create_dir_all(dir)?;
128
129 for file in asset_files {
130 let dest = dir.join(file);
131 if dest.exists() {
132 continue;
133 }
134
135 let url =
136 format!("https://github.com/bevyengine/bevy_asset_files/raw/main/GroundSand005/{file}");
137 info!("Downloading {url}");
138
139 let mut response = ureq::get(&url)
140 .call()
141 .map_err(|e| io::Error::other(e.to_string()))?;
142 let mut bytes = Vec::new();
143 response.body_mut().as_reader().read_to_end(&mut bytes)?;
144 fs::write(&dest, &bytes)?;
145 }
146
147 Ok(())
148}