mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Limit number of minor lights applied to entities to solve performance problems
This commit is contained in:
parent
0b16baf46a
commit
cda6c031b8
@ -30,6 +30,7 @@ enum FaceKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const SUNLIGHT: u8 = 24;
|
pub const SUNLIGHT: u8 = 24;
|
||||||
|
pub const SUNLIGHT_INV: f32 = 1.0 / SUNLIGHT as f32;
|
||||||
pub const MAX_LIGHT_DIST: i32 = SUNLIGHT as i32;
|
pub const MAX_LIGHT_DIST: i32 = SUNLIGHT as i32;
|
||||||
|
|
||||||
fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
||||||
@ -217,7 +218,7 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
|||||||
.unwrap_or(default_light);
|
.unwrap_or(default_light);
|
||||||
|
|
||||||
if l != OPAQUE && l != UNKNOWN {
|
if l != OPAQUE && l != UNKNOWN {
|
||||||
l as f32 / SUNLIGHT as f32
|
l as f32 * SUNLIGHT_INV
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
}
|
}
|
||||||
|
@ -6411,6 +6411,8 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
// get the rider offset
|
// get the rider offset
|
||||||
skel_body: S::Body,
|
skel_body: S::Body,
|
||||||
) {
|
) {
|
||||||
|
span!(_guard, "update", "FigureState::update");
|
||||||
|
|
||||||
// NOTE: As long as update() always gets called after get_or_create_model(), and
|
// NOTE: As long as update() always gets called after get_or_create_model(), and
|
||||||
// visibility is not set again until after the model is rendered, we
|
// visibility is not set again until after the model is rendered, we
|
||||||
// know we don't pair the character model with invalid model state.
|
// know we don't pair the character model with invalid model state.
|
||||||
@ -6475,6 +6477,11 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
|
|
||||||
let (light, glow) = terrain
|
let (light, glow) = terrain
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
|
span!(
|
||||||
|
_guard,
|
||||||
|
"light_glow",
|
||||||
|
"FigureState::update (fetch light/glow)"
|
||||||
|
);
|
||||||
// Sample the location a little above to avoid clipping into terrain
|
// Sample the location a little above to avoid clipping into terrain
|
||||||
// TODO: Try to make this faster? It might be fine though
|
// TODO: Try to make this faster? It might be fine though
|
||||||
let wpos = Vec3::from(pos.into_array()) + Vec3::unit_z();
|
let wpos = Vec3::from(pos.into_array()) + Vec3::unit_z();
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
mesh::{
|
mesh::{
|
||||||
greedy::{GreedyMesh, SpriteAtlasAllocator},
|
greedy::{GreedyMesh, SpriteAtlasAllocator},
|
||||||
segment::generate_mesh_base_vol_sprite,
|
segment::generate_mesh_base_vol_sprite,
|
||||||
terrain::{generate_mesh, SUNLIGHT},
|
terrain::{generate_mesh, SUNLIGHT_INV},
|
||||||
},
|
},
|
||||||
render::{
|
render::{
|
||||||
pipelines::{self, ColLights},
|
pipelines::{self, ColLights},
|
||||||
@ -775,9 +775,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
let chunk_pos = wpos_chunk + rpos;
|
let chunk_pos = wpos_chunk + rpos;
|
||||||
self.chunks
|
self.chunks
|
||||||
.get(&chunk_pos)
|
.get(&chunk_pos)
|
||||||
.map(|c| c.blocks_of_interest.lights.iter())
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flat_map(|c| c.blocks_of_interest.lights.iter())
|
||||||
.map(move |(lpos, level)| {
|
.map(move |(lpos, level)| {
|
||||||
(
|
(
|
||||||
Vec3::<i32>::from(
|
Vec3::<i32>::from(
|
||||||
@ -791,7 +790,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
(Vec3::broadcast(0.001), 0.0),
|
(Vec3::broadcast(0.001), 0.0),
|
||||||
|(bias, total), (lpos, level)| {
|
|(bias, total), (lpos, level)| {
|
||||||
let rpos = lpos.map(|e| e as f32 + 0.5) - wpos;
|
let rpos = lpos.map(|e| e as f32 + 0.5) - wpos;
|
||||||
let level = (*level as f32 - rpos.magnitude()).max(0.0) / SUNLIGHT as f32;
|
let level = (*level as f32 - rpos.magnitude()).max(0.0) * SUNLIGHT_INV;
|
||||||
(
|
(
|
||||||
bias + rpos.try_normalized().unwrap_or_else(Vec3::zero) * level,
|
bias + rpos.try_normalized().unwrap_or_else(Vec3::zero) * level,
|
||||||
total + level,
|
total + level,
|
||||||
|
@ -71,6 +71,9 @@ impl BlocksOfInterest {
|
|||||||
let mut flowers = Vec::new();
|
let mut flowers = Vec::new();
|
||||||
let mut interactables = Vec::new();
|
let mut interactables = Vec::new();
|
||||||
let mut lights = Vec::new();
|
let mut lights = Vec::new();
|
||||||
|
// Lights that can be omitted at random if we have too many and need to cull
|
||||||
|
// some of them
|
||||||
|
let mut minor_lights = Vec::new();
|
||||||
let mut fire_bowls = Vec::new();
|
let mut fire_bowls = Vec::new();
|
||||||
let mut snow = Vec::new();
|
let mut snow = Vec::new();
|
||||||
let mut cricket1 = Vec::new();
|
let mut cricket1 = Vec::new();
|
||||||
@ -168,10 +171,26 @@ impl BlocksOfInterest {
|
|||||||
interactables.push((pos, Interaction::Collect));
|
interactables.push((pos, Interaction::Collect));
|
||||||
}
|
}
|
||||||
if let Some(glow) = block.get_glow() {
|
if let Some(glow) = block.get_glow() {
|
||||||
lights.push((pos, glow));
|
// Currently, we count filled blocks as 'minor' lights, and sprites as
|
||||||
|
// non-minor.
|
||||||
|
if block.get_sprite().is_none() {
|
||||||
|
minor_lights.push((pos, glow));
|
||||||
|
} else {
|
||||||
|
lights.push((pos, glow));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Come up with a better way to prune many light sources: grouping them
|
||||||
|
// into larger lights with k-means clustering, perhaps?
|
||||||
|
const MAX_MINOR_LIGHTS: usize = 64;
|
||||||
|
let minor_light_count = minor_lights.len();
|
||||||
|
lights.extend(
|
||||||
|
minor_lights
|
||||||
|
.choose_multiple(&mut rng, MAX_MINOR_LIGHTS)
|
||||||
|
.copied(),
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
leaves,
|
leaves,
|
||||||
drip,
|
drip,
|
||||||
|
Loading…
Reference in New Issue
Block a user