Skip to content

Commit

Permalink
Set sampler descriptors for gltf image URI
Browse files Browse the repository at this point in the history
  • Loading branch information
Kanabenki committed Oct 1, 2023
1 parent 857fb9c commit e9ce9ea
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 15 deletions.
34 changes: 25 additions & 9 deletions crates/bevy_gltf/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,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.clone();
})
}
};
Expand Down Expand Up @@ -620,6 +625,7 @@ async fn load_image<'a, 'b>(
supported_compressed_formats: CompressedImageFormats,
) -> Result<ImageOrPath, GltfError> {
let is_srgb = !linear_textures.contains(&gltf_texture.index());
let sampler_descriptor = ImageSampler::Descriptor(texture_sampler(&gltf_texture));
match gltf_texture.source().source() {
gltf::image::Source::View { view, mime_type } => {
let start = view.offset();
Expand All @@ -645,20 +651,23 @@ async fn load_image<'a, 'b>(
if let Ok(data_uri) = DataUri::parse(uri) {
let bytes = data_uri.decode()?;
let image_type = ImageType::MimeType(data_uri.mime_type);
let mut image = Image::from_buffer(
&bytes,
mime_type.map(ImageType::MimeType).unwrap_or(image_type),
supported_compressed_formats,
is_srgb,
)?;
image.sampler_descriptor = sampler_descriptor;
Ok(ImageOrPath::Image {
image: Image::from_buffer(
&bytes,
mime_type.map(ImageType::MimeType).unwrap_or(image_type),
supported_compressed_formats,
is_srgb,
)?,
image,
label: texture_label(&gltf_texture),
})
} else {
let image_path = parent_path.join(uri);
Ok(ImageOrPath::Path {
path: image_path,
is_srgb,
sampler_descriptor,
})
}
}
Expand Down Expand Up @@ -1233,8 +1242,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: ImageSampler,
},
}

struct DataUri<'a> {
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.12.0-dev" }
image = { version = "0.24", default-features = false }

# misc
wgpu = { version = "0.16.0", features=["naga"] }
wgpu = { version = "0.16.0", features = ["naga"] }
wgpu-types = { version = "0.16.0", features = ["trace", "replay"] }
codespan-reporting = "0.11.0"
naga = { version = "0.12.0", features = ["wgsl-in"] }
serde = { version = "1", features = ["derive"] }
Expand Down
23 changes: 21 additions & 2 deletions crates/bevy_render/src/texture/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ pub struct Image {
/// Used in [`Image`], this determines what image sampler to use when rendering. The default setting,
/// [`ImageSampler::Default`], will read the sampler from the [`ImagePlugin`](super::ImagePlugin) at setup.
/// Setting this to [`ImageSampler::Descriptor`] will override the global default descriptor for this [`Image`].
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub enum ImageSampler {
/// Default image sampler, derived from the [`ImagePlugin`](super::ImagePlugin) setup.
#[default]
Default,
/// Custom sampler for this image which will override global default.
Descriptor(wgpu::SamplerDescriptor<'static>),
Descriptor(#[serde(with = "WgpuSamplerDescriptor")] wgpu::SamplerDescriptor<'static>),
}

impl ImageSampler {
Expand Down Expand Up @@ -160,6 +160,25 @@ impl ImageSampler {
}
}

/// Proxy type used to implement [`Serialize`] and [`Deserialize`] for [`ImageSampler`].
#[derive(Serialize, Deserialize)]
#[serde(remote = "wgpu::SamplerDescriptor<'static>")]
struct WgpuSamplerDescriptor {
#[serde(skip)]
label: wgpu::Label<'static>,
address_mode_u: wgpu::AddressMode,
address_mode_v: wgpu::AddressMode,
address_mode_w: wgpu::AddressMode,
mag_filter: wgpu::FilterMode,
min_filter: wgpu::FilterMode,
mipmap_filter: wgpu::FilterMode,
lod_min_clamp: f32,
lod_max_clamp: f32,
compare: Option<wgpu::CompareFunction>,
anisotropy_clamp: u16,
border_color: Option<wgpu::SamplerBorderColor>,
}

/// A rendering resource for the default image sampler which is set during renderer
/// initialization.
///
Expand Down
10 changes: 7 additions & 3 deletions crates/bevy_render/src/texture/image_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
texture::{Image, ImageFormat, ImageType, TextureError},
};

use super::CompressedImageFormats;
use super::{CompressedImageFormats, ImageSampler};
use serde::{Deserialize, Serialize};

/// Loader for images that can be read by the `image` crate.
Expand Down Expand Up @@ -57,13 +57,15 @@ pub enum ImageFormatSetting {
pub struct ImageLoaderSettings {
pub format: ImageFormatSetting,
pub is_srgb: bool,
pub sampler_descriptor: ImageSampler,
}

impl Default for ImageLoaderSettings {
fn default() -> Self {
Self {
format: ImageFormatSetting::default(),
is_srgb: true,
sampler_descriptor: ImageSampler::Default,
}
}
}
Expand All @@ -87,7 +89,7 @@ impl AssetLoader for ImageLoader {
ImageFormatSetting::FromExtension => ImageType::Extension(ext),
ImageFormatSetting::Format(format) => ImageType::Format(format),
};
Ok(Image::from_buffer(
let mut image = Image::from_buffer(
&bytes,
image_type,
self.supported_compressed_formats,
Expand All @@ -96,7 +98,9 @@ impl AssetLoader for ImageLoader {
.map_err(|err| FileTextureError {
error: err,
path: format!("{}", load_context.path().display()),
})?)
})?;
image.sampler_descriptor = settings.sampler_descriptor.clone();
Ok(image)
})
}

Expand Down

0 comments on commit e9ce9ea

Please sign in to comment.