Skip to content

Animated Materials: Major memory leak #18882

Open
@DissolveDZ

Description

@DissolveDZ

Bevy version

0.16-rc-5

[Optional] Relevant system information

RTX 3080
wayland

Adapter Info

`AdapterInfo { name: "NVIDIA GeForce RTX 3080", vendor: 4318, device: 8710, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "570.133.07", backend: Vulkan }`

What you did

Describe how you arrived at the problem. If you can, consider providing a code snippet or link.

In my game I needed to have my materials update based on some state.
I have many entities in my game (100) which had this component and I noticed my fps absolutely suffering.
After some profiling (renderdoc, nsight) I found out that it's most likely a VRAM leak (or something similar since the capture size gets ridiculously big) and the color changing isn't actually what's causing this problem, it's just calling the following method on many components:
material.get_mut(handle)
I also compiled with release as my target

Additional information

First your fps will be fine but then drop rapidly, more noticeable on a high refresh rate monitor.

Image

How to reproduce

Get the newest bevy-rc (0.16-rc5) and add bevy_dev_tools to have the fps counter
Take the animated mat example and increase the entity spawn count to something like 20 * 20
You can even delete the mutating code, it's just the call to get_mut(id)

//! Shows how to animate material properties

use bevy::dev_tools::fps_overlay::FpsOverlayPlugin;
use bevy::prelude::*;

fn main() {
   App::new()
       .add_plugins(DefaultPlugins)
       .add_plugins(FpsOverlayPlugin::default())
       .add_systems(Startup, setup)
       .add_systems(Update, animate_materials)
       .run();
}

fn setup(
   mut commands: Commands,
   asset_server: Res<AssetServer>,
   mut meshes: ResMut<Assets<Mesh>>,
   mut materials: ResMut<Assets<StandardMaterial>>,
) {
   commands.spawn((
       Camera3d::default(),
       Transform::from_xyz(3.0, 1.0, 3.0).looking_at(Vec3::new(0.0, -0.5, 0.0), Vec3::Y),
       EnvironmentMapLight {
           diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
           specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
           intensity: 2_000.0,
           ..default()
       },
   ));

   let cube = meshes.add(Cuboid::new(0.5, 0.5, 0.5));

   const GOLDEN_ANGLE: f32 = 137.507_77;

   let mut hsla = Hsla::hsl(0.0, 1.0, 0.5);
   for x in -1..20 {
       for z in -1..20 {
           commands.spawn((
               Mesh3d(cube.clone()),
               MeshMaterial3d(materials.add(Color::from(hsla))),
               Transform::from_translation(Vec3::new(x as f32, 0.0, z as f32)),
           ));
           hsla = hsla.rotate_hue(GOLDEN_ANGLE);
       }
   }
}

fn animate_materials(
   material_handles: Query<&MeshMaterial3d<StandardMaterial>>,
   time: Res<Time>,
   mut materials: ResMut<Assets<StandardMaterial>>,
) {
   for material_handle in material_handles.iter() {
       if let Some(material) = materials.get_mut(material_handle) {
           if let Color::Hsla(ref mut hsla) = material.base_color {
               *hsla = hsla.rotate_hue(time.delta_secs() * 100.0);
           }
       }
   }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behaviorS-Needs-InvestigationThis issue requires detective work to figure out what's going wrong

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions