Path: blob/main/crates/bevy_gltf/src/loader/extensions/khr_materials_specular.rs
6598 views
use bevy_asset::LoadContext;12use gltf::{Document, Material};34use serde_json::Value;56#[cfg(feature = "pbr_specular_textures")]7use {8crate::loader::gltf_ext::material::parse_material_extension_texture, bevy_asset::Handle,9bevy_image::Image, bevy_pbr::UvChannel,10};1112/// Parsed data from the `KHR_materials_specular` extension.13///14/// We currently don't parse `specularFactor` and `specularTexture`, since15/// they're incompatible with Filament.16///17/// Note that the map is a *specular map*, not a *reflectance map*. In Bevy and18/// Filament terms, the reflectance values in the specular map range from [0.0,19/// 0.5], rather than [0.0, 1.0]. This is an unfortunate20/// `KHR_materials_specular` specification requirement that stems from the fact21/// that glTF is specified in terms of a specular strength model, not the22/// reflectance model that Filament and Bevy use. A workaround, which is noted23/// in the [`StandardMaterial`](bevy_pbr::StandardMaterial) documentation, is to set the reflectance value24/// to 2.0, which spreads the specular map range from [0.0, 1.0] as normal.25///26/// See the specification:27/// <https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md>28#[derive(Default)]29pub(crate) struct SpecularExtension {30pub(crate) specular_factor: Option<f64>,31#[cfg(feature = "pbr_specular_textures")]32pub(crate) specular_channel: UvChannel,33#[cfg(feature = "pbr_specular_textures")]34pub(crate) specular_texture: Option<Handle<Image>>,35pub(crate) specular_color_factor: Option<[f64; 3]>,36#[cfg(feature = "pbr_specular_textures")]37pub(crate) specular_color_channel: UvChannel,38#[cfg(feature = "pbr_specular_textures")]39pub(crate) specular_color_texture: Option<Handle<Image>>,40}4142impl SpecularExtension {43pub(crate) fn parse(44_load_context: &mut LoadContext,45_document: &Document,46material: &Material,47) -> Option<Self> {48let extension = material49.extensions()?50.get("KHR_materials_specular")?51.as_object()?;5253#[cfg(feature = "pbr_specular_textures")]54let (_specular_channel, _specular_texture) = parse_material_extension_texture(55material,56_load_context,57_document,58extension,59"specularTexture",60"specular",61);6263#[cfg(feature = "pbr_specular_textures")]64let (_specular_color_channel, _specular_color_texture) = parse_material_extension_texture(65material,66_load_context,67_document,68extension,69"specularColorTexture",70"specular color",71);7273Some(SpecularExtension {74specular_factor: extension.get("specularFactor").and_then(Value::as_f64),75#[cfg(feature = "pbr_specular_textures")]76specular_channel: _specular_channel,77#[cfg(feature = "pbr_specular_textures")]78specular_texture: _specular_texture,79specular_color_factor: extension80.get("specularColorFactor")81.and_then(Value::as_array)82.and_then(|json_array| {83if json_array.len() < 3 {84None85} else {86Some([87json_array[0].as_f64()?,88json_array[1].as_f64()?,89json_array[2].as_f64()?,90])91}92}),93#[cfg(feature = "pbr_specular_textures")]94specular_color_channel: _specular_color_channel,95#[cfg(feature = "pbr_specular_textures")]96specular_color_texture: _specular_color_texture,97})98}99}100101102