7 releases
0.14.8 | Sep 7, 2024 |
---|---|
0.14.7 | Sep 6, 2024 |
0.14.3 | Aug 24, 2024 |
#201 in Game dev
126 downloads per month
Used in bevy_clay_tiles
50KB
814 lines
Material Overrides Tool for Bevy
This Rust crate provides functionality for loading materials from a .glb
file and additional material configuration data from a separate file. It supports hot-swapping materials in a Bevy scene using two custom components: MaterialOverrideComponent
and MaterialOverrideWhenSceneReadyComponent
.
Features
- Material Loading: Automatically load materials from a specified
.glb
file and apply additional configurations, such as UV scaling and color tinting, from a separate configuration file. - Hot-Swapping: Dynamically swap materials in the scene using the
MaterialOverrideComponent
andMaterialOverrideWhenSceneReadyComponent
. - Flexible Configuration: Customize materials using a configuration file that allows for UV scale adjustments and diffuse color tinting.
Define your materials like this:
Getting Started
1. Installation
To use this crate, add it to your Cargo.toml
:
cargo add bevy_material_tool
2. Usage
Setting Up the Plugin
First, set up the plugin
in your Bevy application:
app.add_plugins(BevyMaterialToolPlugin{
material_types_config_path: "assets/material_overrides/material_types.ron".to_string(),
material_overrides_gltf_path : "material_overrides/doodad_material_overrides.glb".to_string()
} );
Configuring Material Overrides
Material override means that every child of the entity that has a handle will have its handle overridden by the specified material, indexed by string.
The plugin uses either of two components to manage material overrides:
-
MaterialOverrideComponent
: Attach this component to entities that require material replacement immediately.commands.entity(entity) .insert(MaterialOverrideComponent { material_override: "Wall1".to_string(), });
-
MaterialOverrideWhenSceneReadyComponent
: Use this component to defer material overrides until the scene is ready.commands.entity(entity) .insert(MaterialOverrideWhenSceneReadyComponent { material_override: "StoneToon1".to_string(), });
Take care not to add these components until after 'MaterialOverridesLoadingState::Complete' state has been entered. !
Configuring Material Replacements
To use material replacement, you need to load your GLTFs in a special way: First you must load the GLTF into the asset server (not the scene!) and then to attach it to your entity to see it in engine , you would use something like 'AddGltfModelComponent' in gltf_models.rs.
This way, the material_name_map plugin will be able to index every single named material in every GLTF you load into its resource and add a 'MaterialMetadataName' component to each entity with handle loaded this way.
Material replacement means that you specify a HashMap<String,String> (old material name -> new material name) and then every child of the entity will be inspected for a 'MaterialMetadataName' component . If that exists, and if its material name (from blender) matches any of thte 'keys' of the replacement hashmap, then that material will be swapped out for the new material using MaterialOverride.
While MaterialOverride component only lets you make a GLTFs meshes all use a single material, MaterialReplacements component allows you to swap multiple materials for multiple other materials, surgically.
Loading Materials
The materials are loaded from a .glb
file specified in the MaterialOverridesResource
:
3. Configuration File
The material configuration file is a RON (Rusty Object Notation) file that defines the material types and their properties, such as UV scale and color tint.
Example material_types_config.ron
:
(
material_types: {
//these keys are material names used for MaterialOverride.0 or for the values of MaterialReplacement. The values should match your materials in the blender file of the .glb material swatch template that gets extracted by material_overrides.rs.
"Wall1": (
material_name: "Wall1",
uv_scale_factor: 16.0,
diffuse_color_tint: Some(LinearRgba(
red: 1.0,
green: 1.0,
blue: 1.0,
alpha: 1.0,
)),
),
"StoneToon1": (
material_name: "StoneToon1",
uv_scale_factor: 2.0,
),
"StoneToon2": (
material_name: "StoneToon2",
uv_scale_factor: 2.0,
),
"DirtToon1": (
material_name: "DirtToon1",
uv_scale_factor: 2.0,
),
"TiledWall1": (
material_name: "Wall1",
uv_scale_factor: 1.0,
),
},
//this is optional and it makes material replacement more succinct. You can use the component MaterialReplacementApplySetWhenSceneReadyComponent("tree_fir") for example to specify that an entities children should experience material replacement according to the replacement map where the keys of the map are the material names in blender for the asset and the values are your custom material names defined as keys in material_types above.
material_replacement_sets: Some( {
"tree_fir" : {
"bark" : "TreeBark1",
"leaves" : "TreeLeavesFir",
"branches": "Branches1"
},
"tree_suntail" : {
"bark" : "Wood1",
"leaves" : "Leaves3",
"branches": "Branches1"
}
} )
)
4. Advanced Usage
MaterialOverridesLoadingState
The crate defines a state machine to manage material loading and processing:
Init
: Initial state.Extracting
: Extracts materials from the.glb
file.Building
: Builds materials based on the configuration file.Complete
: All materials are loaded and ready.
You can customize or extend these states for more complex material management workflows.
5. Contributing
Contributions are welcome! Please open an issue or submit a pull request on GitHub.
6. License
The code in this project is licensed under the MIT License. Texture/material assets are not included in this license. See the LICENSE file for details.
Dependencies
~24MB
~438K SLoC