-
Hello bevy community, I wish to render a few Items that have a color changing frame-by-frame (color animations). For this, I spawn components in my setup system: fn init(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) {
let led_mat = materials.add(StandardMaterial {
base_color: Color::rgba_linear(1.0, 1.0, 1.0, 0.95),
emissive: if rng.gen() {
Color::rgb_linear(rng.gen(), rng.gen(), rng.gen()) * 10.0
} else {
Color::BLACK
},
alpha_mode: AlphaMode::Add,
..default()
});
commands.spawn((
PbrBundle {
mesh: led_mesh.clone(),
material: { led_mat_handle.clone() },
transform: Transform::from_translation(Vec3::new(
x as f32, y as f32, z as f32,
))
.with_scale(Vec3::new(0.2, 0.2, 0.2)),
..Default::default()
},
AnimationState {
progress: 0.0, // Initialize the animation progress
y: y,
},
LED { index: (x, y, z) },
));
} To change the color of the LED, I use an update system: fn animate_system(
time: Res<Time>,
mut commands: Commands,
mut materials: ResMut<Assets<StandardMaterial>>,
mut query: Query<(
&mut Transform,
&mut AnimationState,
&mut Handle<StandardMaterial>,
)>,
) {
let sinewave = 1.0 + (time.elapsed_seconds_wrapped() * 2.0 * PI * 1.0 / 4.0).sin();
for (mut transform, mut animation_state, mut material_handle) in query.iter_mut() {
// Update the animation state
animation_state.progress += time.delta_seconds();
// Apply the animation to the transform
// This is a placeholder for your actual animation logic
transform.translation.y =
animation_state.y as f32 + animation_state.progress.mul(1.0).sin();
let _material = materials.get_mut(material_handle.clone()).unwrap();
material.emissive = Color::rgb(sinewave, sinewave, sinewave).into();
}
} My framerate drops from 200 fps to 16 and below, as soon as the update system is added. I traced this back to the materials.get_mut call (I guess it crosses threads?). Am I doing this the wrong way and is there an intended way to do what I want to achieve correctly? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Apart form the fps degredation, I also notice that my memory use jumps frm 160MB to 260MB according to task manager. Might this actually be a bug and linked to #2439? Tracy show that a lot of time (160ms) is spent in pevy_pbr::materials::prepare_materials() |
Beta Was this translation helpful? Give feedback.
-
So I found a solution that worked for me: Create an Image with as many pixels as entities there shall be. Create one material with the image's handle used as the emissive or base-color texture. UV map the mesh of every single entity to one pixel in the image. |
Beta Was this translation helpful? Give feedback.
So I found a solution that worked for me:
Create an Image with as many pixels as entities there shall be. Create one material with the image's handle used as the emissive or base-color texture. UV map the mesh of every single entity to one pixel in the image.
In the update method I write new data into the image-data array. For this change to be applied, the Material must be updated. So to access the image, the most straight-forward way is to get_mut() the Material and use the relevant texture-member. The get_mut() triggers a material update (only one, not 4096 as in my original approach).