Skip to content

Commit 5a4ba97

Browse files
committed
gltf loading ocnverts GltfMaterial into StandardMaterial
1 parent c11b4a8 commit 5a4ba97

1 file changed

Lines changed: 56 additions & 27 deletions

File tree

  • crates/processing_render/src

crates/processing_render/src/gltf.rs

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ use bevy::{
88
},
99
camera::visibility::RenderLayers,
1010
ecs::system::RunSystemOnce,
11-
gltf::{Gltf, GltfMeshName},
11+
gltf::{Gltf, GltfMaterial, GltfMeshName},
12+
pbr::ExtendedMaterial,
1213
prelude::*,
1314
world_serialization::WorldInstanceSpawner,
1415
};
1516

1617
use crate::geometry::{BuiltinAttributes, Geometry, layout::VertexLayout};
1718
use crate::graphics;
18-
use crate::render::material::UntypedMaterial;
19+
use crate::material::ProcessingMaterial;
20+
use crate::render::material::{ProcessingExtendedMaterial, UntypedMaterial};
1921
use processing_core::config::{Config, ConfigKey};
2022
use processing_core::error::{ProcessingError, Result};
2123

@@ -67,7 +69,6 @@ pub struct GltfHandle {
6769
handle: Handle<Gltf>,
6870
instance_id: bevy::world_serialization::InstanceId,
6971
graphics_entity: Entity,
70-
base_path: String,
7172
}
7273

7374
pub fn load(
@@ -76,10 +77,10 @@ pub fn load(
7677
) -> Result<Entity> {
7778
let config = world.resource::<Config>().clone();
7879
let base_path = match path.find('#') {
79-
Some(idx) => path[..idx].to_string(),
80-
None => path.clone(),
80+
Some(idx) => &path[..idx],
81+
None => path.as_str(),
8182
};
82-
let asset_path = resolve_asset_path(&config, &base_path);
83+
let asset_path = resolve_asset_path(&config, base_path);
8384
let handle: Handle<Gltf> = world.get_asset_server().load(asset_path);
8485
block_on_load(world, |w| w.get_asset_server().load_state(&handle))?;
8586

@@ -122,7 +123,6 @@ pub fn load(
122123
handle,
123124
instance_id,
124125
graphics_entity,
125-
base_path,
126126
})
127127
.id();
128128
Ok(entity)
@@ -182,40 +182,69 @@ pub fn geometry(
182182
Ok(entity)
183183
}
184184

185+
/// Translate a bevy [`GltfMaterial`] into the [`StandardMaterial`] base of a
186+
/// [`ProcessingExtendedMaterial`]. `GltfMaterial` mirrors `StandardMaterial`'s
187+
/// fields, so we copy across the ones that drive shading and let the rest fall
188+
/// back to defaults.
189+
fn gltf_material_to_standard(m: &GltfMaterial) -> StandardMaterial {
190+
StandardMaterial {
191+
base_color: m.base_color,
192+
base_color_channel: m.base_color_channel.clone(),
193+
base_color_texture: m.base_color_texture.clone(),
194+
emissive: m.emissive,
195+
emissive_channel: m.emissive_channel.clone(),
196+
emissive_texture: m.emissive_texture.clone(),
197+
perceptual_roughness: m.perceptual_roughness,
198+
metallic: m.metallic,
199+
metallic_roughness_channel: m.metallic_roughness_channel.clone(),
200+
metallic_roughness_texture: m.metallic_roughness_texture.clone(),
201+
normal_map_channel: m.normal_map_channel.clone(),
202+
normal_map_texture: m.normal_map_texture.clone(),
203+
occlusion_channel: m.occlusion_channel.clone(),
204+
occlusion_texture: m.occlusion_texture.clone(),
205+
double_sided: m.double_sided,
206+
cull_mode: m.cull_mode,
207+
unlit: m.unlit,
208+
alpha_mode: m.alpha_mode,
209+
uv_transform: m.uv_transform,
210+
..default()
211+
}
212+
}
213+
185214
pub fn material(
186215
In((gltf_entity, name)): In<(Entity, String)>,
187216
world: &mut World,
188217
) -> Result<Entity> {
189-
let handle = world
218+
let gltf_handle = world
190219
.get::<GltfHandle>(gltf_entity)
191-
.ok_or(ProcessingError::InvalidEntity)?;
192-
let gltf_handle = handle.handle.clone();
193-
let base_path = handle.base_path.clone();
220+
.ok_or(ProcessingError::InvalidEntity)?
221+
.handle
222+
.clone();
194223

195-
let material_index = {
224+
let standard = {
196225
let gltf_assets = world.resource::<Assets<Gltf>>();
197226
let gltf = gltf_assets
198227
.get(&gltf_handle)
199228
.ok_or_else(|| ProcessingError::GltfLoadError("GLTF asset not found".into()))?;
200-
let named_handle = gltf.named_materials.get(name.as_str()).ok_or_else(|| {
229+
let mat_handle = gltf.named_materials.get(name.as_str()).ok_or_else(|| {
201230
ProcessingError::GltfLoadError(format!("Material '{}' not found in GLTF", name))
202231
})?;
203-
gltf.materials
204-
.iter()
205-
.position(|h| h.id() == named_handle.id())
206-
.ok_or_else(|| {
207-
ProcessingError::GltfLoadError(format!(
208-
"Material '{}' not found in materials list",
209-
name
210-
))
211-
})?
232+
233+
let gltf_materials = world.resource::<Assets<GltfMaterial>>();
234+
let gltf_material = gltf_materials.get(mat_handle).ok_or_else(|| {
235+
ProcessingError::GltfLoadError(format!("Material '{}' asset not loaded", name))
236+
})?;
237+
gltf_material_to_standard(gltf_material)
212238
};
213239

214-
let config = world.resource::<Config>().clone();
215-
let std_path = format!("{}#Material{}/std", base_path, material_index);
216-
let asset_path = resolve_asset_path(&config, &std_path);
217-
let handle: Handle<StandardMaterial> = world.get_asset_server().load(asset_path);
218-
block_on_load(world, |w| w.get_asset_server().load_state(&handle))?;
240+
// wrap in the extended material the processing renderer's pipeline expects, so
241+
// the draw systems attach a `MeshMaterial3d` and `material_set` can mutate it
242+
let handle = world
243+
.resource_mut::<Assets<ProcessingExtendedMaterial>>()
244+
.add(ExtendedMaterial {
245+
base: standard,
246+
extension: ProcessingMaterial { blend_state: None },
247+
});
219248
let entity = world.spawn(UntypedMaterial(handle.untyped())).id();
220249
Ok(entity)
221250
}

0 commit comments

Comments
 (0)