Struct bevy::render::texture::Image

source ·
pub struct Image {
    pub data: Vec<u8>,
    pub texture_descriptor: TextureDescriptor<Option<&'static str>, &'static [TextureFormat]>,
    pub sampler: ImageSampler,
    pub texture_view_descriptor: Option<TextureViewDescriptor<'static>>,
    pub asset_usage: RenderAssetUsages,
}

Fields§

§data: Vec<u8>§texture_descriptor: TextureDescriptor<Option<&'static str>, &'static [TextureFormat]>§sampler: ImageSampler

The ImageSampler to use during rendering.

§texture_view_descriptor: Option<TextureViewDescriptor<'static>>§asset_usage: RenderAssetUsages

Implementations§

source§

impl Image

source

pub fn new( size: Extent3d, dimension: TextureDimension, data: Vec<u8>, format: TextureFormat, asset_usage: RenderAssetUsages ) -> Image

Creates a new image from raw binary data and the corresponding metadata.

§Panics

Panics if the length of the data, volume of the size and the size of the format do not match.

source

pub fn new_fill( size: Extent3d, dimension: TextureDimension, pixel: &[u8], format: TextureFormat, asset_usage: RenderAssetUsages ) -> Image

Creates a new image from raw binary data and the corresponding metadata, by filling the image data with the pixel data repeated multiple times.

§Panics

Panics if the size of the format is not a multiple of the length of the pixel data.

Examples found in repository?
examples/stress_tests/bevymark.rs (lines 546-556)
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
fn init_textures(textures: &mut Vec<Handle<Image>>, args: &Args, images: &mut Assets<Image>) {
    let mut color_rng = StdRng::seed_from_u64(42);
    while textures.len() < args.material_texture_count {
        let pixel = [color_rng.gen(), color_rng.gen(), color_rng.gen(), 255];
        textures.push(images.add(Image::new_fill(
            Extent3d {
                width: BIRD_TEXTURE_SIZE as u32,
                height: BIRD_TEXTURE_SIZE as u32,
                depth_or_array_layers: 1,
            },
            TextureDimension::D2,
            &pixel,
            TextureFormat::Rgba8UnormSrgb,
            RenderAssetUsages::RENDER_WORLD,
        )));
    }
}
More examples
Hide additional examples
examples/stress_tests/many_cubes.rs (lines 204-214)
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
fn init_textures(args: &Args, images: &mut Assets<Image>) -> Vec<Handle<Image>> {
    let mut color_rng = StdRng::seed_from_u64(42);
    let color_bytes: Vec<u8> = (0..(args.material_texture_count * 4))
        .map(|i| if (i % 4) == 3 { 255 } else { color_rng.gen() })
        .collect();
    color_bytes
        .chunks(4)
        .map(|pixel| {
            images.add(Image::new_fill(
                Extent3d {
                    width: 1,
                    height: 1,
                    depth_or_array_layers: 1,
                },
                TextureDimension::D2,
                pixel,
                TextureFormat::Rgba8UnormSrgb,
                RenderAssetUsages::RENDER_WORLD,
            ))
        })
        .collect()
}
examples/3d/3d_shapes.rs (lines 113-123)
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
fn uv_debug_texture() -> Image {
    const TEXTURE_SIZE: usize = 8;

    let mut palette: [u8; 32] = [
        255, 102, 159, 255, 255, 159, 102, 255, 236, 255, 102, 255, 121, 255, 102, 255, 102, 255,
        198, 255, 102, 198, 255, 255, 121, 102, 255, 255, 236, 102, 255, 255,
    ];

    let mut texture_data = [0; TEXTURE_SIZE * TEXTURE_SIZE * 4];
    for y in 0..TEXTURE_SIZE {
        let offset = TEXTURE_SIZE * y * 4;
        texture_data[offset..(offset + TEXTURE_SIZE * 4)].copy_from_slice(&palette);
        palette.rotate_right(4);
    }

    Image::new_fill(
        Extent3d {
            width: TEXTURE_SIZE as u32,
            height: TEXTURE_SIZE as u32,
            depth_or_array_layers: 1,
        },
        TextureDimension::D2,
        &texture_data,
        TextureFormat::Rgba8UnormSrgb,
        RenderAssetUsages::RENDER_WORLD,
    )
}
examples/shader/compute_shader_game_of_life.rs (lines 43-53)
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
    let mut image = Image::new_fill(
        Extent3d {
            width: SIZE.0,
            height: SIZE.1,
            depth_or_array_layers: 1,
        },
        TextureDimension::D2,
        &[0, 0, 0, 255],
        TextureFormat::Rgba8Unorm,
        RenderAssetUsages::RENDER_WORLD,
    );
    image.texture_descriptor.usage =
        TextureUsages::COPY_DST | TextureUsages::STORAGE_BINDING | TextureUsages::TEXTURE_BINDING;
    let image = images.add(image);

    commands.spawn(SpriteBundle {
        sprite: Sprite {
            custom_size: Some(Vec2::new(SIZE.0 as f32, SIZE.1 as f32)),
            ..default()
        },
        texture: image.clone(),
        ..default()
    });
    commands.spawn(Camera2dBundle::default());

    commands.insert_resource(GameOfLifeImage { texture: image });
}
examples/3d/anti_aliasing.rs (lines 375-385)
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
fn uv_debug_texture() -> Image {
    const TEXTURE_SIZE: usize = 8;

    let mut palette: [u8; 32] = [
        255, 102, 159, 255, 255, 159, 102, 255, 236, 255, 102, 255, 121, 255, 102, 255, 102, 255,
        198, 255, 102, 198, 255, 255, 121, 102, 255, 255, 236, 102, 255, 255,
    ];

    let mut texture_data = [0; TEXTURE_SIZE * TEXTURE_SIZE * 4];
    for y in 0..TEXTURE_SIZE {
        let offset = TEXTURE_SIZE * y * 4;
        texture_data[offset..(offset + TEXTURE_SIZE * 4)].copy_from_slice(&palette);
        palette.rotate_right(4);
    }

    let mut img = Image::new_fill(
        Extent3d {
            width: TEXTURE_SIZE as u32,
            height: TEXTURE_SIZE as u32,
            depth_or_array_layers: 1,
        },
        TextureDimension::D2,
        &texture_data,
        TextureFormat::Rgba8UnormSrgb,
        RenderAssetUsages::RENDER_WORLD,
    );
    img.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor::default());
    img
}
examples/3d/tonemapping.rs (lines 675-685)
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
fn uv_debug_texture() -> Image {
    const TEXTURE_SIZE: usize = 8;

    let mut palette: [u8; 32] = [
        255, 102, 159, 255, 255, 159, 102, 255, 236, 255, 102, 255, 121, 255, 102, 255, 102, 255,
        198, 255, 102, 198, 255, 255, 121, 102, 255, 255, 236, 102, 255, 255,
    ];

    let mut texture_data = [0; TEXTURE_SIZE * TEXTURE_SIZE * 4];
    for y in 0..TEXTURE_SIZE {
        let offset = TEXTURE_SIZE * y * 4;
        texture_data[offset..(offset + TEXTURE_SIZE * 4)].copy_from_slice(&palette);
        palette.rotate_right(4);
    }

    let mut img = Image::new_fill(
        Extent3d {
            width: TEXTURE_SIZE as u32,
            height: TEXTURE_SIZE as u32,
            depth_or_array_layers: 1,
        },
        TextureDimension::D2,
        &texture_data,
        TextureFormat::Rgba8UnormSrgb,
        RenderAssetUsages::RENDER_WORLD,
    );
    img.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor::default());
    img
}
source

pub fn width(&self) -> u32

Returns the width of a 2D image.

Examples found in repository?
examples/3d/skybox.rs (line 155)
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
fn asset_loaded(
    asset_server: Res<AssetServer>,
    mut images: ResMut<Assets<Image>>,
    mut cubemap: ResMut<Cubemap>,
    mut skyboxes: Query<&mut Skybox>,
) {
    if !cubemap.is_loaded && asset_server.load_state(&cubemap.image_handle) == LoadState::Loaded {
        info!("Swapping to {}...", CUBEMAPS[cubemap.index].0);
        let image = images.get_mut(&cubemap.image_handle).unwrap();
        // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture,
        // so they appear as one texture. The following code reconfigures the texture as necessary.
        if image.texture_descriptor.array_layer_count() == 1 {
            image.reinterpret_stacked_2d_as_array(image.height() / image.width());
            image.texture_view_descriptor = Some(TextureViewDescriptor {
                dimension: Some(TextureViewDimension::Cube),
                ..default()
            });
        }

        for mut skybox in &mut skyboxes {
            skybox.image = cubemap.image_handle.clone();
        }

        cubemap.is_loaded = true;
    }
}
source

pub fn height(&self) -> u32

Returns the height of a 2D image.

Examples found in repository?
examples/3d/skybox.rs (line 155)
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
fn asset_loaded(
    asset_server: Res<AssetServer>,
    mut images: ResMut<Assets<Image>>,
    mut cubemap: ResMut<Cubemap>,
    mut skyboxes: Query<&mut Skybox>,
) {
    if !cubemap.is_loaded && asset_server.load_state(&cubemap.image_handle) == LoadState::Loaded {
        info!("Swapping to {}...", CUBEMAPS[cubemap.index].0);
        let image = images.get_mut(&cubemap.image_handle).unwrap();
        // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture,
        // so they appear as one texture. The following code reconfigures the texture as necessary.
        if image.texture_descriptor.array_layer_count() == 1 {
            image.reinterpret_stacked_2d_as_array(image.height() / image.width());
            image.texture_view_descriptor = Some(TextureViewDescriptor {
                dimension: Some(TextureViewDimension::Cube),
                ..default()
            });
        }

        for mut skybox in &mut skyboxes {
            skybox.image = cubemap.image_handle.clone();
        }

        cubemap.is_loaded = true;
    }
}
source

pub fn aspect_ratio(&self) -> AspectRatio

Returns the aspect ratio (width / height) of a 2D image.

source

pub fn size_f32(&self) -> Vec2

Returns the size of a 2D image as f32.

Examples found in repository?
examples/3d/tonemapping.rs (line 344)
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
fn resize_image(
    image_mesh: Query<(&Handle<StandardMaterial>, &Handle<Mesh>), With<HDRViewer>>,
    materials: Res<Assets<StandardMaterial>>,
    mut meshes: ResMut<Assets<Mesh>>,
    images: Res<Assets<Image>>,
    mut image_events: EventReader<AssetEvent<Image>>,
) {
    for event in image_events.read() {
        let (AssetEvent::Added { id } | AssetEvent::Modified { id }) = event else {
            continue;
        };

        for (mat_h, mesh_h) in &image_mesh {
            let Some(mat) = materials.get(mat_h) else {
                continue;
            };

            let Some(ref base_color_texture) = mat.base_color_texture else {
                continue;
            };

            if *id != base_color_texture.id() {
                continue;
            };

            let Some(image_changed) = images.get(*id) else {
                continue;
            };

            let size = image_changed.size_f32().normalize_or_zero() * 1.4;
            // Resize Mesh
            let quad = Mesh::from(Rectangle::from_size(size));
            meshes.insert(mesh_h, quad);
        }
    }
}
source

pub fn size(&self) -> UVec2

Returns the size of a 2D image.

source

pub fn resize(&mut self, size: Extent3d)

Resizes the image to the new size, by removing information or appending 0 to the data. Does not properly resize the contents of the image, but only its internal data buffer.

Examples found in repository?
examples/2d/pixel_grid_snap.rs (line 121)
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
fn setup_camera(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
    let canvas_size = Extent3d {
        width: RES_WIDTH,
        height: RES_HEIGHT,
        ..default()
    };

    // this Image serves as a canvas representing the low-resolution game screen
    let mut canvas = Image {
        texture_descriptor: TextureDescriptor {
            label: None,
            size: canvas_size,
            dimension: TextureDimension::D2,
            format: TextureFormat::Bgra8UnormSrgb,
            mip_level_count: 1,
            sample_count: 1,
            usage: TextureUsages::TEXTURE_BINDING
                | TextureUsages::COPY_DST
                | TextureUsages::RENDER_ATTACHMENT,
            view_formats: &[],
        },
        ..default()
    };

    // fill image.data with zeroes
    canvas.resize(canvas_size);

    let image_handle = images.add(canvas);

    // this camera renders whatever is on `PIXEL_PERFECT_LAYERS` to the canvas
    commands.spawn((
        Camera2dBundle {
            camera: Camera {
                // render before the "main pass" camera
                order: -1,
                target: RenderTarget::Image(image_handle.clone()),
                ..default()
            },
            ..default()
        },
        InGameCamera,
        PIXEL_PERFECT_LAYERS,
    ));

    // spawn the canvas
    commands.spawn((
        SpriteBundle {
            texture: image_handle,
            ..default()
        },
        Canvas,
        HIGH_RES_LAYERS,
    ));

    // the "outer" camera renders whatever is on `HIGH_RES_LAYERS` to the screen.
    // here, the canvas and one of the sample sprites will be rendered by this camera
    commands.spawn((Camera2dBundle::default(), OuterCamera, HIGH_RES_LAYERS));
}
More examples
Hide additional examples
examples/ui/render_ui_to_texture.rs (line 57)
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
    mut images: ResMut<Assets<Image>>,
) {
    let size = Extent3d {
        width: 512,
        height: 512,
        ..default()
    };

    // This is the texture that will be rendered to.
    let mut image = Image {
        texture_descriptor: TextureDescriptor {
            label: None,
            size,
            dimension: TextureDimension::D2,
            format: TextureFormat::Bgra8UnormSrgb,
            mip_level_count: 1,
            sample_count: 1,
            usage: TextureUsages::TEXTURE_BINDING
                | TextureUsages::COPY_DST
                | TextureUsages::RENDER_ATTACHMENT,
            view_formats: &[],
        },
        ..default()
    };

    // fill image.data with zeroes
    image.resize(size);

    let image_handle = images.add(image);

    // Light
    commands.spawn(DirectionalLightBundle::default());

    let texture_camera = commands
        .spawn(Camera2dBundle {
            camera: Camera {
                // render before the "main pass" camera
                order: -1,
                target: RenderTarget::Image(image_handle.clone()),
                ..default()
            },
            ..default()
        })
        .id();

    commands
        .spawn((
            NodeBundle {
                style: Style {
                    // Cover the whole image
                    width: Val::Percent(100.),
                    height: Val::Percent(100.),
                    flex_direction: FlexDirection::Column,
                    justify_content: JustifyContent::Center,
                    align_items: AlignItems::Center,
                    ..default()
                },
                background_color: Color::GOLD.into(),
                ..default()
            },
            TargetCamera(texture_camera),
        ))
        .with_children(|parent| {
            parent.spawn(TextBundle::from_section(
                "This is a cube",
                TextStyle {
                    font_size: 40.0,
                    color: Color::BLACK,
                    ..default()
                },
            ));
        });

    let cube_size = 4.0;
    let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size));

    // This material has the texture that has been rendered.
    let material_handle = materials.add(StandardMaterial {
        base_color_texture: Some(image_handle),
        reflectance: 0.02,
        unlit: false,

        ..default()
    });

    // Cube with material containing the rendered UI texture.
    commands.spawn((
        PbrBundle {
            mesh: cube_handle,
            material: material_handle,
            transform: Transform::from_xyz(0.0, 0.0, 1.5)
                .with_rotation(Quat::from_rotation_x(-PI / 5.0)),
            ..default()
        },
        Cube,
    ));

    // The main pass camera.
    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });
}
examples/3d/render_to_texture.rs (line 61)
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
    mut images: ResMut<Assets<Image>>,
) {
    let size = Extent3d {
        width: 512,
        height: 512,
        ..default()
    };

    // This is the texture that will be rendered to.
    let mut image = Image {
        texture_descriptor: TextureDescriptor {
            label: None,
            size,
            dimension: TextureDimension::D2,
            format: TextureFormat::Bgra8UnormSrgb,
            mip_level_count: 1,
            sample_count: 1,
            usage: TextureUsages::TEXTURE_BINDING
                | TextureUsages::COPY_DST
                | TextureUsages::RENDER_ATTACHMENT,
            view_formats: &[],
        },
        ..default()
    };

    // fill image.data with zeroes
    image.resize(size);

    let image_handle = images.add(image);

    let cube_handle = meshes.add(Cuboid::new(4.0, 4.0, 4.0));
    let cube_material_handle = materials.add(StandardMaterial {
        base_color: Color::rgb(0.8, 0.7, 0.6),
        reflectance: 0.02,
        unlit: false,
        ..default()
    });

    // This specifies the layer used for the first pass, which will be attached to the first pass camera and cube.
    let first_pass_layer = RenderLayers::layer(1);

    // The cube that will be rendered to the texture.
    commands.spawn((
        PbrBundle {
            mesh: cube_handle,
            material: cube_material_handle,
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)),
            ..default()
        },
        FirstPassCube,
        first_pass_layer,
    ));

    // Light
    // NOTE: we add the light to all layers so it affects both the rendered-to-texture cube, and the cube on which we display the texture
    // Setting the layer to RenderLayers::layer(0) would cause the main view to be lit, but the rendered-to-texture cube to be unlit.
    // Setting the layer to RenderLayers::layer(1) would cause the rendered-to-texture cube to be lit, but the main view to be unlit.
    commands.spawn((
        PointLightBundle {
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)),
            ..default()
        },
        RenderLayers::all(),
    ));

    commands.spawn((
        Camera3dBundle {
            camera: Camera {
                // render before the "main pass" camera
                order: -1,
                target: image_handle.clone().into(),
                clear_color: Color::WHITE.into(),
                ..default()
            },
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 15.0))
                .looking_at(Vec3::ZERO, Vec3::Y),
            ..default()
        },
        first_pass_layer,
    ));

    let cube_size = 4.0;
    let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size));

    // This material has the texture that has been rendered.
    let material_handle = materials.add(StandardMaterial {
        base_color_texture: Some(image_handle),
        reflectance: 0.02,
        unlit: false,
        ..default()
    });

    // Main pass cube, with material containing the rendered first pass texture.
    commands.spawn((
        PbrBundle {
            mesh: cube_handle,
            material: material_handle,
            transform: Transform::from_xyz(0.0, 0.0, 1.5)
                .with_rotation(Quat::from_rotation_x(-PI / 5.0)),
            ..default()
        },
        MainPassCube,
    ));

    // The main pass camera.
    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });
}
source

pub fn reinterpret_size(&mut self, new_size: Extent3d)

Changes the size, asserting that the total number of data elements (pixels) remains the same.

§Panics

Panics if the new_size does not have the same volume as to old one.

source

pub fn reinterpret_stacked_2d_as_array(&mut self, layers: u32)

Takes a 2D image containing vertically stacked images of the same size, and reinterprets it as a 2D array texture, where each of the stacked images becomes one layer of the array. This is primarily for use with the texture2DArray shader uniform type.

§Panics

Panics if the texture is not 2D, has more than one layers or is not evenly dividable into the layers.

Examples found in repository?
examples/3d/skybox.rs (line 155)
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
fn asset_loaded(
    asset_server: Res<AssetServer>,
    mut images: ResMut<Assets<Image>>,
    mut cubemap: ResMut<Cubemap>,
    mut skyboxes: Query<&mut Skybox>,
) {
    if !cubemap.is_loaded && asset_server.load_state(&cubemap.image_handle) == LoadState::Loaded {
        info!("Swapping to {}...", CUBEMAPS[cubemap.index].0);
        let image = images.get_mut(&cubemap.image_handle).unwrap();
        // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture,
        // so they appear as one texture. The following code reconfigures the texture as necessary.
        if image.texture_descriptor.array_layer_count() == 1 {
            image.reinterpret_stacked_2d_as_array(image.height() / image.width());
            image.texture_view_descriptor = Some(TextureViewDescriptor {
                dimension: Some(TextureViewDimension::Cube),
                ..default()
            });
        }

        for mut skybox in &mut skyboxes {
            skybox.image = cubemap.image_handle.clone();
        }

        cubemap.is_loaded = true;
    }
}
More examples
Hide additional examples
examples/shader/array_texture.rs (line 66)
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
fn create_array_texture(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut loading_texture: ResMut<LoadingTexture>,
    mut images: ResMut<Assets<Image>>,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ArrayTextureMaterial>>,
) {
    if loading_texture.is_loaded
        || asset_server.load_state(loading_texture.handle.clone()) != LoadState::Loaded
    {
        return;
    }
    loading_texture.is_loaded = true;
    let image = images.get_mut(&loading_texture.handle).unwrap();

    // Create a new array texture asset from the loaded texture.
    let array_layers = 4;
    image.reinterpret_stacked_2d_as_array(array_layers);

    // Spawn some cubes using the array texture
    let mesh_handle = meshes.add(Cuboid::default());
    let material_handle = materials.add(ArrayTextureMaterial {
        array_texture: loading_texture.handle.clone(),
    });
    for x in -5..=5 {
        commands.spawn(MaterialMeshBundle {
            mesh: mesh_handle.clone(),
            material: material_handle.clone(),
            transform: Transform::from_xyz(x as f32 + 0.5, 0.0, 0.0),
            ..Default::default()
        });
    }
}
source

pub fn convert(&self, new_format: TextureFormat) -> Option<Image>

Convert a texture from a format to another. Only a few formats are supported as input and output:

  • TextureFormat::R8Unorm
  • TextureFormat::Rg8Unorm
  • TextureFormat::Rgba8UnormSrgb

To get Image as a image::DynamicImage see: Image::try_into_dynamic.

source

pub fn from_buffer( buffer: &[u8], image_type: ImageType<'_>, supported_compressed_formats: CompressedImageFormats, is_srgb: bool, image_sampler: ImageSampler, asset_usage: RenderAssetUsages ) -> Result<Image, TextureError>

Load a bytes buffer in a Image, according to type image_type, using the image crate

source

pub fn is_compressed(&self) -> bool

Whether the texture format is compressed or uncompressed

source§

impl Image

source

pub fn from_dynamic( dyn_img: DynamicImage, is_srgb: bool, asset_usage: RenderAssetUsages ) -> Image

Converts a DynamicImage to an Image.

source

pub fn try_into_dynamic(self) -> Result<DynamicImage, IntoDynamicImageError>

Convert a Image to a DynamicImage. Useful for editing image data. Not all TextureFormat are covered, therefore it will return an error if the format is unsupported. Supported formats are:

  • TextureFormat::R8Unorm
  • TextureFormat::Rg8Unorm
  • TextureFormat::Rgba8UnormSrgb
  • TextureFormat::Bgra8UnormSrgb

To convert Image to a different format see: Image::convert.

Trait Implementations§

source§

impl Clone for Image

source§

fn clone(&self) -> Image

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Image

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Image

source§

fn default() -> Image

default is a 1x1x1 all ‘1.0’ texture

source§

impl FromReflect for Image
where Image: Any + Send + Sync,

source§

fn from_reflect(reflect: &(dyn Reflect + 'static)) -> Option<Image>

Constructs a concrete instance of Self from a reflected value.
source§

fn take_from_reflect( reflect: Box<dyn Reflect> ) -> Result<Self, Box<dyn Reflect>>

Attempts to downcast the given value to Self using, constructing the value using from_reflect if that fails. Read more
source§

impl GetTypeRegistration for Image
where Image: Any + Send + Sync,

source§

impl Reflect for Image
where Image: Any + Send + Sync,

source§

fn get_represented_type_info(&self) -> Option<&'static TypeInfo>

Returns the TypeInfo of the type represented by this value. Read more
source§

fn into_any(self: Box<Image>) -> Box<dyn Any>

Returns the value as a Box<dyn Any>.
source§

fn as_any(&self) -> &(dyn Any + 'static)

Returns the value as a &dyn Any.
source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Returns the value as a &mut dyn Any.
source§

fn into_reflect(self: Box<Image>) -> Box<dyn Reflect>

Casts this type to a boxed reflected value.
source§

fn as_reflect(&self) -> &(dyn Reflect + 'static)

Casts this type to a reflected value.
source§

fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)

Casts this type to a mutable reflected value.
source§

fn clone_value(&self) -> Box<dyn Reflect>

Clones the value as a Reflect trait object. Read more
source§

fn apply(&mut self, value: &(dyn Reflect + 'static))

Applies a reflected value to this value. Read more
source§

fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>

Performs a type-checked assignment of a reflected value to this value. Read more
source§

fn reflect_kind(&self) -> ReflectKind

Returns a zero-sized enumeration of “kinds” of type. Read more
source§

fn reflect_ref(&self) -> ReflectRef<'_>

Returns an immutable enumeration of “kinds” of type. Read more
source§

fn reflect_mut(&mut self) -> ReflectMut<'_>

Returns a mutable enumeration of “kinds” of type. Read more
source§

fn reflect_owned(self: Box<Image>) -> ReflectOwned

Returns an owned enumeration of “kinds” of type. Read more
source§

fn reflect_hash(&self) -> Option<u64>

Returns a hash of the value (which includes the type). Read more
source§

fn reflect_partial_eq(&self, _value: &(dyn Reflect + 'static)) -> Option<bool>

Returns a “partial equality” comparison result. Read more
source§

fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Debug formatter for the value. Read more
source§

fn serializable(&self) -> Option<Serializable<'_>>

Returns a serializable version of the value. Read more
source§

fn is_dynamic(&self) -> bool

Indicates whether or not this type is a dynamic type. Read more
source§

impl RenderAsset for Image

source§

fn prepare_asset( self, _: &mut <<Image as RenderAsset>::Param as SystemParam>::Item<'_, '_> ) -> Result<<Image as RenderAsset>::PreparedAsset, PrepareAssetError<Image>>

Converts the extracted image into a GpuImage.

§

type PreparedAsset = GpuImage

The GPU-representation of the asset.
§

type Param = (Res<'static, RenderDevice>, Res<'static, RenderQueue>, Res<'static, DefaultImageSampler>)

Specifies all ECS data required by RenderAsset::prepare_asset. Read more
source§

fn asset_usage(&self) -> RenderAssetUsages

Whether or not to unload the asset after extracting it to the render world.
source§

impl TypePath for Image
where Image: Any + Send + Sync,

source§

fn type_path() -> &'static str

Returns the fully qualified path of the underlying type. Read more
source§

fn short_type_path() -> &'static str

Returns a short, pretty-print enabled path to the type. Read more
source§

fn type_ident() -> Option<&'static str>

Returns the name of the type, or None if it is anonymous. Read more
source§

fn crate_name() -> Option<&'static str>

Returns the name of the crate the type is in, or None if it is anonymous. Read more
source§

fn module_path() -> Option<&'static str>

Returns the path to the module the type is in, or None if it is anonymous. Read more
source§

impl Typed for Image
where Image: Any + Send + Sync,

source§

fn type_info() -> &'static TypeInfo

Returns the compile-time info for the underlying type.
source§

impl VisitAssetDependencies for Image

source§

fn visit_dependencies(&self, visit: &mut impl FnMut(UntypedAssetId))

source§

impl Asset for Image

Auto Trait Implementations§

§

impl Freeze for Image

§

impl RefUnwindSafe for Image

§

impl Send for Image

§

impl Sync for Image

§

impl Unpin for Image

§

impl UnwindSafe for Image

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<Image>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
source§

impl<A> AssetContainer for A
where A: Asset,

source§

fn insert(self: Box<A>, id: UntypedAssetId, world: &mut World)

source§

fn asset_type_name(&self) -> &'static str

source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Downcast for T
where T: Any,

source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
source§

impl<T> DynamicTypePath for T
where T: TypePath,

source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<S> FromSample<S> for S

source§

fn from_sample_(s: S) -> S

source§

impl<T> FromWorld for T
where T: Default,

source§

fn from_world(_world: &mut World) -> T

Creates Self using data from the given World.
source§

impl<T> GetPath for T
where T: Reflect + ?Sized,

source§

fn reflect_path<'p>( &self, path: impl ReflectPath<'p> ) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>>

Returns a reference to the value specified by path. Read more
source§

fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p> ) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>

Returns a mutable reference to the value specified by path. Read more
source§

fn path<'p, T>( &self, path: impl ReflectPath<'p> ) -> Result<&T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed reference to the value specified by path. Read more
source§

fn path_mut<'p, T>( &mut self, path: impl ReflectPath<'p> ) -> Result<&mut T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed mutable reference to the value specified by path. Read more
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<A> RenderAssetDependency for A
where A: RenderAsset,

source§

fn register_system( render_app: &mut App, system: NodeConfigs<Box<dyn System<Out = (), In = ()>>> )

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

source§

fn to_sample_(self) -> U

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

source§

impl<T> Settings for T
where T: 'static + Send + Sync,

source§

impl<T> WasmNotSend for T
where T: Send,

source§

impl<T> WasmNotSendSync for T

source§

impl<T> WasmNotSync for T
where T: Sync,