diff --git a/crates/bevy_core_pipeline/src/tonemapping/mod.rs b/crates/bevy_core_pipeline/src/tonemapping/mod.rs index 2af1d48b6eed0..7a093e027261c 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/mod.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/mod.rs @@ -356,10 +356,7 @@ pub fn get_lut_bind_group_layout_entries(bindings: [u32; 2]) -> [BindGroupLayout // allow(dead_code) so it doesn't complain when the tonemapping_luts feature is disabled #[allow(dead_code)] fn setup_tonemapping_lut_image(bytes: &[u8], image_type: ImageType) -> Image { - let mut image = - Image::from_buffer(bytes, image_type, CompressedImageFormats::NONE, false).unwrap(); - - image.sampler_descriptor = bevy_render::texture::ImageSampler::Descriptor(SamplerDescriptor { + let image_sampler = bevy_render::texture::ImageSampler::Descriptor(SamplerDescriptor { label: Some("Tonemapping LUT sampler"), address_mode_u: AddressMode::ClampToEdge, address_mode_v: AddressMode::ClampToEdge, @@ -369,8 +366,14 @@ fn setup_tonemapping_lut_image(bytes: &[u8], image_type: ImageType) -> Image { mipmap_filter: FilterMode::Linear, ..default() }); - - image + Image::from_buffer( + bytes, + image_type, + CompressedImageFormats::NONE, + false, + image_sampler, + ) + .unwrap() } pub fn lut_placeholder() -> Image { diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 65ba1dbf9e5d1..0c5a7f43f5f40 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -22,9 +22,10 @@ use bevy_render::{ }, prelude::SpatialBundle, primitives::Aabb, - render_resource::{AddressMode, Face, FilterMode, PrimitiveTopology, SamplerDescriptor}, + render_resource::{Face, PrimitiveTopology}, texture::{ - CompressedImageFormats, Image, ImageLoaderSettings, ImageSampler, ImageType, TextureError, + CompressedImageFormats, Image, ImageAddressMode, ImageFilterMode, ImageLoaderSettings, + ImageSampler, ImageSamplerDescriptor, ImageType, TextureError, }, }; use bevy_scene::Scene; @@ -256,9 +257,14 @@ async fn load_gltf<'a, 'b, 'c>( ) { let handle = match texture { ImageOrPath::Image { label, image } => load_context.add_labeled_asset(label, image), - ImageOrPath::Path { path, is_srgb } => { + ImageOrPath::Path { + path, + is_srgb, + sampler_descriptor, + } => { load_context.load_with_settings(path, move |settings: &mut ImageLoaderSettings| { settings.is_srgb = is_srgb; + settings.sampler_descriptor = sampler_descriptor; }) } }; @@ -667,18 +673,19 @@ async fn load_image<'a, 'b>( supported_compressed_formats: CompressedImageFormats, ) -> Result { let is_srgb = !linear_textures.contains(&gltf_texture.index()); + let sampler_descriptor = texture_sampler(&gltf_texture); match gltf_texture.source().source() { gltf::image::Source::View { view, mime_type } => { let start = view.offset(); let end = view.offset() + view.length(); let buffer = &buffer_data[view.buffer().index()][start..end]; - let mut image = Image::from_buffer( + let image = Image::from_buffer( buffer, ImageType::MimeType(mime_type), supported_compressed_formats, is_srgb, + ImageSampler::Descriptor(sampler_descriptor.into()), )?; - image.sampler_descriptor = ImageSampler::Descriptor(texture_sampler(&gltf_texture)); Ok(ImageOrPath::Image { image, label: texture_label(&gltf_texture), @@ -698,6 +705,7 @@ async fn load_image<'a, 'b>( mime_type.map(ImageType::MimeType).unwrap_or(image_type), supported_compressed_formats, is_srgb, + ImageSampler::Descriptor(sampler_descriptor.into()), )?, label: texture_label(&gltf_texture), }) @@ -706,6 +714,7 @@ async fn load_image<'a, 'b>( Ok(ImageOrPath::Path { path: image_path, is_srgb, + sampler_descriptor, }) } } @@ -1110,32 +1119,32 @@ fn skin_label(skin: &gltf::Skin) -> String { } /// Extracts the texture sampler data from the glTF texture. -fn texture_sampler<'a>(texture: &gltf::Texture) -> SamplerDescriptor<'a> { +fn texture_sampler(texture: &gltf::Texture) -> ImageSamplerDescriptor { let gltf_sampler = texture.sampler(); - SamplerDescriptor { + ImageSamplerDescriptor { address_mode_u: texture_address_mode(&gltf_sampler.wrap_s()), address_mode_v: texture_address_mode(&gltf_sampler.wrap_t()), mag_filter: gltf_sampler .mag_filter() .map(|mf| match mf { - MagFilter::Nearest => FilterMode::Nearest, - MagFilter::Linear => FilterMode::Linear, + MagFilter::Nearest => ImageFilterMode::Nearest, + MagFilter::Linear => ImageFilterMode::Linear, }) - .unwrap_or(SamplerDescriptor::default().mag_filter), + .unwrap_or(ImageSamplerDescriptor::default().mag_filter), min_filter: gltf_sampler .min_filter() .map(|mf| match mf { MinFilter::Nearest | MinFilter::NearestMipmapNearest - | MinFilter::NearestMipmapLinear => FilterMode::Nearest, + | MinFilter::NearestMipmapLinear => ImageFilterMode::Nearest, MinFilter::Linear | MinFilter::LinearMipmapNearest - | MinFilter::LinearMipmapLinear => FilterMode::Linear, + | MinFilter::LinearMipmapLinear => ImageFilterMode::Linear, }) - .unwrap_or(SamplerDescriptor::default().min_filter), + .unwrap_or(ImageSamplerDescriptor::default().min_filter), mipmap_filter: gltf_sampler .min_filter() @@ -1143,23 +1152,23 @@ fn texture_sampler<'a>(texture: &gltf::Texture) -> SamplerDescriptor<'a> { MinFilter::Nearest | MinFilter::Linear | MinFilter::NearestMipmapNearest - | MinFilter::LinearMipmapNearest => FilterMode::Nearest, + | MinFilter::LinearMipmapNearest => ImageFilterMode::Nearest, MinFilter::NearestMipmapLinear | MinFilter::LinearMipmapLinear => { - FilterMode::Linear + ImageFilterMode::Linear } }) - .unwrap_or(SamplerDescriptor::default().mipmap_filter), + .unwrap_or(ImageSamplerDescriptor::default().mipmap_filter), ..Default::default() } } /// Maps the texture address mode form glTF to wgpu. -fn texture_address_mode(gltf_address_mode: &gltf::texture::WrappingMode) -> AddressMode { +fn texture_address_mode(gltf_address_mode: &gltf::texture::WrappingMode) -> ImageAddressMode { match gltf_address_mode { - WrappingMode::ClampToEdge => AddressMode::ClampToEdge, - WrappingMode::Repeat => AddressMode::Repeat, - WrappingMode::MirroredRepeat => AddressMode::MirrorRepeat, + WrappingMode::ClampToEdge => ImageAddressMode::ClampToEdge, + WrappingMode::Repeat => ImageAddressMode::Repeat, + WrappingMode::MirroredRepeat => ImageAddressMode::MirrorRepeat, } } @@ -1280,8 +1289,15 @@ fn resolve_node_hierarchy( } enum ImageOrPath { - Image { image: Image, label: String }, - Path { path: PathBuf, is_srgb: bool }, + Image { + image: Image, + label: String, + }, + Path { + path: PathBuf, + is_srgb: bool, + sampler_descriptor: ImageSamplerDescriptor, + }, } struct DataUri<'a> { diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index 17c3547728764..5d8f9d0435180 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -554,6 +554,7 @@ impl Image { image_type: ImageType, #[allow(unused_variables)] supported_compressed_formats: CompressedImageFormats, is_srgb: bool, + image_sampler: ImageSampler, ) -> Result { let format = image_type.to_image_format()?; @@ -582,7 +583,9 @@ impl Image { reader.set_format(image_crate_format); reader.no_limits(); let dyn_img = reader.decode()?; - Ok(Self::from_dynamic(dyn_img, is_srgb)) + let mut img = Self::from_dynamic(dyn_img, is_srgb); + img.sampler_descriptor = image_sampler; + Ok(img) } } } diff --git a/crates/bevy_render/src/texture/image_loader.rs b/crates/bevy_render/src/texture/image_loader.rs index 8f8a283289481..130fc9ee4a31e 100644 --- a/crates/bevy_render/src/texture/image_loader.rs +++ b/crates/bevy_render/src/texture/image_loader.rs @@ -7,7 +7,7 @@ use crate::{ texture::{Image, ImageFormat, ImageType, TextureError}, }; -use super::CompressedImageFormats; +use super::{CompressedImageFormats, ImageSampler, ImageSamplerDescriptor}; use serde::{Deserialize, Serialize}; /// Loader for images that can be read by the `image` crate. @@ -56,6 +56,7 @@ pub enum ImageFormatSetting { pub struct ImageLoaderSettings { pub format: ImageFormatSetting, pub is_srgb: bool, + pub sampler_descriptor: ImageSamplerDescriptor, } impl Default for ImageLoaderSettings { @@ -63,6 +64,7 @@ impl Default for ImageLoaderSettings { Self { format: ImageFormatSetting::default(), is_srgb: true, + sampler_descriptor: ImageSamplerDescriptor::default(), } } } @@ -101,6 +103,7 @@ impl AssetLoader for ImageLoader { image_type, self.supported_compressed_formats, settings.is_srgb, + ImageSampler::Descriptor(settings.sampler_descriptor.into()), ) .map_err(|err| FileTextureError { error: err,