bevyengine/bevy · critical
Too many triangles ({triangle_count}) in an emissive mesh, m
Error message
Too many triangles ({triangle_count}) in an emissive mesh, maximum is 65535. What it means
GpuLightSource::new_emissive_mesh_light (scene/binder.rs:418-424) stores the emissive mesh's triangle count in the u32 `kind` field shifted left by one bit (the low bit is the light-kind tag), leaving only 16 bits for the count. A single emissive mesh with more than 65,535 triangles therefore panics with the actual count in the message.
Source
Thrown at crates/bevy_solari/src/scene/binder.rs:428
base_color: Vec3,
perceptual_roughness: f32,
emissive: Vec3,
metallic: f32,
_padding: Vec3,
reflectance: f32,
}
#[derive(ShaderType)]
struct GpuLightSource {
kind: u32,
id: u32,
}
impl GpuLightSource {
fn new_emissive_mesh_light(instance_id: u32, triangle_count: u32) -> GpuLightSource {
if triangle_count > u16::MAX as u32 {
panic!("Too many triangles ({triangle_count}) in an emissive mesh, maximum is 65535.");
}
Self {
kind: triangle_count << 1,
id: instance_id,
}
}
fn new_directional_light(directional_light_id: u32) -> GpuLightSource {
Self {
kind: 1,
id: directional_light_id,
}
}
}
#[derive(ShaderType, Default)]
struct GpuDirectionalLight {View on GitHub (pinned to 4805ca792c)
Solutions
- Split the emissive mesh so each part has at most 65,535 triangles
- Use a simplified low-poly emissive proxy for the light and keep the detailed mesh non-emissive
- Remove the emissive component from high-poly scenery that should not light the scene
- Decimate the mesh below the limit
Example fix
// before — one 200k-triangle emissive mesh
commands.spawn((
high_poly_mesh,
StandardMaterial { emissive: emissive_color, ..default() },
));
// after — detailed mesh stays non-emissive, low-poly proxy emits the light
commands.spawn((high_poly_mesh, StandardMaterial::default()));
commands.spawn((low_poly_proxy_mesh, StandardMaterial { emissive: emissive_color, ..default() })); Defensive patterns
Strategy: validation
Validate before calling
fn tri_count(mesh: &Mesh) -> usize {
match mesh.indices() {
Some(indices) => indices.len() / 3,
None => mesh.count_vertices() / 3,
}
}
// before assigning an emissive material under Solari:
assert!(
tri_count(&mesh) <= u16::MAX as usize,
"emissive mesh too dense for Solari: {} triangles",
tri_count(&mesh)
); Prevention
- Check triangle counts of imported models before applying emissive materials
- Use low-poly emissive proxies for lighting and keep detailed meshes non-emissive
When it happens
Trigger: Assigning an emissive material to any mesh with >65535 triangles while the Solari renderer processes the scene (indices.len()/3 above u16::MAX).
Common situations: High-poly GLTF imports whose materials are emissive; using emissive materials as decoration on dense scenery meshes; decimated-but-still-large models marked emissive.
Related errors
- Too many light sources in the scene, maximum is 65535.
- Failed to insert attribute. Invalid attribute format for {}.
- The number of vertices exceeds u32::MAX
- `Mesh::ATTRIBUTE_POSITION` vertex attributes should be of ty
- The inner and outer meshes should have the same number of ve
AI-assisted analysis of bevyengine/bevy@4805ca792c (2026-08-20).
Data as JSON: /api/errors/dcf08bcb7f7d8000.
Report an issue: GitHub.