bevyengine / bevyengine/bevy

Entities with multiple materials only render a single material

Open
#20,092 7 comments 2 reactions 0 assignees View on GitHub
A-Rendering C-Bug C-Feature C-Usability
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## Bevy version

0.16.1

## What you did

I migrated my game from 0.14 to 0.16, and in this process noticed some materials were no longer rendering.
Previously I spawned entities with at minimum a cell shaded material and a material to add an outline (using vertex extrusion)

## What went wrong

Entities with multiple materials only render one of these materials. The material selected appears to always be the same, but this might be affected by system ordering. No warning is given when this happens.

## Additional information

There are alternative solutions, which could be used as a permanent workaround too, but the usability of these would be worse.

### Creating a render pipeline for extra materials

Users could create a render pipeline for materials they want to apply in addition to other materials. However, creating pipelines is a lot more involved than adding an extra `MeshMaterial3d`.

### Spawning child entities with different materials

For the most part this works fine, but is a fair bit clunkier, for example it makes adding and removing the materials much more involved. Additionally this adds extra culling and transform propagation work. This approach also becomes significantly less practical when animated meshes are involved, as simply copying the mesh with another material does not create a usable outcome.

This is the workaround I took for now, besides the performance and skinned mesh concerns it's mostly usable:
```diff
commands.entity(entity).insert((
HasModel,
children![
(
- Mesh3d(meshes.add(Capsule3d::new(0.25, 1.1))),
+ Mesh3d(capsule.clone()),
MeshMaterial3d(materials.add(CellShadedMaterial::new(
&mut images,
get_team_color(team.copied().unwrap_or_default()),
(0.15, 0.5, 0.1),
))),
- MeshMaterial3d(outline.clone()),
+ ),
+ (Mesh3d(capsule.clone()), MeshMaterial3d(outline.clone()),),
+ (
+ Mesh3d(capsule.clone()),
MeshMaterial3d(charge_mats.add(ManaChargeMaterial::new(&loader, 0.))),
),
....
)
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the Bevy 0.16.1 case with one entity carrying multiple MeshMaterial3d components, then compare it with the child-entity workaround described in the issue. Done means multiple materials render reliably on the same entity without requiring duplicated meshes or child entities.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
computer-graphics, game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.