@@ -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
1617use crate :: geometry:: { BuiltinAttributes , Geometry , layout:: VertexLayout } ;
1718use crate :: graphics;
18- use crate :: render:: material:: UntypedMaterial ;
19+ use crate :: material:: ProcessingMaterial ;
20+ use crate :: render:: material:: { ProcessingExtendedMaterial , UntypedMaterial } ;
1921use processing_core:: config:: { Config , ConfigKey } ;
2022use 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
7374pub 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+
185214pub 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