Static light improvements, fixed lighting update bug

This commit is contained in:
Joshua Barretto 2021-03-04 12:57:29 +00:00
parent 120cb86c0d
commit a229d65932
2 changed files with 16 additions and 4 deletions

View File

@ -26,7 +26,7 @@ impl<V: RectRasterableVol> VolGrid2d<V> {
#[inline(always)]
pub fn chunk_key<P: Into<Vec2<i32>>>(pos: P) -> Vec2<i32> {
pos.into()
.map2(V::RECT_SIZE, |e, sz: u32| e >> (sz - 1).count_ones())
.map2(V::RECT_SIZE, |e, sz: u32| e.div_euclid(sz as i32))
}
#[inline(always)]

View File

@ -630,13 +630,25 @@ impl<V: RectRasterableVol> Terrain<V> {
// be meshed
span!(guard, "Add chunks with modified blocks to mesh todo list");
// TODO: would be useful if modified blocks were grouped by chunk
for pos in scene_data
for (&pos, &block) in scene_data
.state
.terrain_changes()
.modified_blocks
.iter()
.map(|(p, _)| *p)
{
// TODO: Be cleverer about this to avoid remeshing all neighbours. There are a few things that can create
// an 'effect at a distance'. These are as follows:
// - A glowing block is added or removed, thereby causing a lighting recalculation proportional to its glow
// radius.
// - An opaque block that was blocking sunlight from entering a cavity is removed (or added) thereby
// changing the way that sunlight propagates into the cavity.
//
// We can and should be cleverer about this, but it's non-trivial. For now, just conservatively assume that
// the lighting in all neighbouring chunks is invalidated. Thankfully, this doesn't need to happen often
// because block modification is unusual in Veloren.
// let block_effect_radius = block.get_glow().unwrap_or(0).max(1);
let block_effect_radius = crate::mesh::terrain::MAX_LIGHT_DIST;
// Handle block changes on chunk borders
// Remesh all neighbours because we have complex lighting now
// TODO: if lighting is on the server this can be updated to only remesh when
@ -644,7 +656,7 @@ impl<V: RectRasterableVol> Terrain<V> {
// change was on the border
for x in -1..2 {
for y in -1..2 {
let neighbour_pos = pos + Vec3::new(x, y, 0);
let neighbour_pos = pos + Vec3::new(x, y, 0) * block_effect_radius;
let neighbour_chunk_pos = scene_data.state.terrain().pos_key(neighbour_pos);
// Only remesh if this chunk has all its neighbors