More lights, minimised light and glow map data

This commit is contained in:
Joshua Barretto 2020-11-22 01:25:08 +00:00
parent 6e51967079
commit b539ecf438
6 changed files with 62 additions and 27 deletions

View File

@ -122,7 +122,7 @@ impl SpriteKind {
SpriteKind::Pumpkin => 0.81,
SpriteKind::Cabbage => 0.45,
SpriteKind::Chest => 1.09,
SpriteKind::StreetLamp => 3.0,
SpriteKind::StreetLamp => 2.65,
SpriteKind::Carrot => 0.18,
SpriteKind::Radish => 0.18,
// TODO: Uncomment this when we have a way to open doors

View File

@ -181,7 +181,7 @@ where
0.0
}
};
let get_glow = |vol: &mut V, pos: Vec3<i32>| 0.0;
let get_glow = |_vol: &mut V, _pos: Vec3<i32>| 0.0;
let get_color = |vol: &mut V, pos: Vec3<i32>| {
vol.get(pos)
.ok()
@ -277,7 +277,7 @@ where
0.0
}
};
let get_glow = |vol: &mut V, pos: Vec3<i32>| 0.0;
let get_glow = |_vol: &mut V, _pos: Vec3<i32>| 0.0;
let get_color = |vol: &mut V, pos: Vec3<i32>| {
vol.get(pos)
.ok()

View File

@ -36,7 +36,7 @@ const MAX_LIGHT_DIST: i32 = SUNLIGHT as i32;
fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
is_sunlight: bool,
// When above bounds
default_light: f32,
default_light: u8,
bounds: Aabb<i32>,
vol: &VolGrid2d<V>,
lit_blocks: impl Iterator<Item = (Vec3<i32>, u8)>,
@ -67,8 +67,8 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
.collect::<VecDeque<_>>();
// Start sun rays
if is_sunlight {
for x in 0..outer.size().w {
for y in 0..outer.size().h {
for y in 0..outer.size().h {
for x in 0..outer.size().w {
let z = outer.size().d - 1;
let is_air = vol_cached
.get(outer.min + Vec3::new(x, y, z))
@ -208,16 +208,41 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
}
}
let min_bounds = Aabb {
min: bounds.min - Vec3::unit_z(),
max: bounds.max + Vec3::unit_z(),
};
// Minimise light map to reduce duplication. We can now discard light info
// for blocks outside of the chunk borders.
let mut light_map2 = vec![UNKNOWN; min_bounds.size().product() as usize];
let lm_idx2 = {
let (w, h, _) = min_bounds.clone().size().into_tuple();
move |x, y, z| (z * h * w + x * h + y) as usize
};
for z in 0..min_bounds.size().d {
for y in 0..min_bounds.size().h {
for x in 0..min_bounds.size().w {
let off = min_bounds.min - outer.min;
light_map2[lm_idx2(x, y, z)] = light_map[lm_idx(x + off.x, y + off.y, z + off.z)];
}
}
}
drop(light_map);
move |wpos| {
let pos = wpos - outer.min;
light_map
.get(lm_idx(pos.x, pos.y, pos.z))
.map(|l| if *l != OPAQUE && *l != UNKNOWN {
*l as f32 / SUNLIGHT as f32
} else {
0.0
})
.unwrap_or(default_light)
let pos = wpos - min_bounds.min;
let l = light_map2
.get(lm_idx2(pos.x, pos.y, pos.z))
.copied()
.unwrap_or(default_light);
if l != OPAQUE && l != UNKNOWN {
l as f32 / SUNLIGHT as f32
} else {
0.0
}
}
}
@ -243,7 +268,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + 'static>
fn generate_mesh(
self,
(range, max_texture_size, boi): Self::Supplement,
(range, max_texture_size, _boi): Self::Supplement,
) -> MeshGen<TerrainPipeline, FluidPipeline, Self> {
span!(
_guard,
@ -277,8 +302,8 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + 'static>
}
// Calculate chunk lighting (sunlight defaults to 1.0, glow to 0.0)
let mut light = calc_light(true, 1.0, range, self, core::iter::empty());
let mut glow = calc_light(false, 0.0, range, self, glow_blocks.into_iter());
let light = calc_light(true, SUNLIGHT, range, self, core::iter::empty());
let glow = calc_light(false, 0, range, self, glow_blocks.into_iter());
let mut opaque_limits = None::<Limits>;
let mut fluid_limits = None::<Limits>;

View File

@ -477,7 +477,7 @@ impl ParticleMgr {
cond: |_| true,
},
BlockParticles {
blocks: |boi| &boi.embers,
blocks: |boi| &boi.fires,
range: 2,
rate: 20.0,
lifetime: 0.25,
@ -485,7 +485,7 @@ impl ParticleMgr {
cond: |_| true,
},
BlockParticles {
blocks: |boi| &boi.embers,
blocks: |boi| &boi.smokers,
range: 8,
rate: 3.0,
lifetime: 40.0,

View File

@ -10,7 +10,8 @@ pub struct BlocksOfInterest {
pub leaves: Vec<Vec3<i32>>,
pub grass: Vec<Vec3<i32>>,
pub river: Vec<Vec3<i32>>,
pub embers: Vec<Vec3<i32>>,
pub fires: Vec<Vec3<i32>>,
pub smokers: Vec<Vec3<i32>>,
pub beehives: Vec<Vec3<i32>>,
pub reeds: Vec<Vec3<i32>>,
pub flowers: Vec<Vec3<i32>>,
@ -26,7 +27,8 @@ impl BlocksOfInterest {
let mut leaves = Vec::new();
let mut grass = Vec::new();
let mut river = Vec::new();
let mut embers = Vec::new();
let mut fires = Vec::new();
let mut smokers = Vec::new();
let mut beehives = Vec::new();
let mut reeds = Vec::new();
let mut flowers = Vec::new();
@ -60,7 +62,14 @@ impl BlocksOfInterest {
}
},
_ => match block.get_sprite() {
Some(SpriteKind::Ember) => embers.push(pos),
Some(SpriteKind::Ember) => {
fires.push(pos);
smokers.push(pos);
},
// Offset positions to account for block height.
// TODO: Is this a good idea?
Some(SpriteKind::StreetLamp) => fires.push(pos + Vec3::unit_z() * 3),
Some(SpriteKind::StreetLampTall) => fires.push(pos + Vec3::unit_z() * 4),
Some(SpriteKind::Beehive) => beehives.push(pos),
Some(SpriteKind::Reed) => reeds.push(pos),
Some(SpriteKind::PinkFlower) => flowers.push(pos),
@ -84,7 +93,8 @@ impl BlocksOfInterest {
leaves,
grass,
river,
embers,
fires,
smokers,
beehives,
reeds,
flowers,

View File

@ -634,15 +634,15 @@ impl Settlement {
.rotated_z(f32::consts::PI / 2.0)
.normalized();
let is_lamp = if path_dir.x.abs() > path_dir.y.abs() {
wpos2d.x as f32 % 30.0 / path_dir.dot(Vec2::unit_y()).abs()
wpos2d.x as f32 % 15.0 / path_dir.dot(Vec2::unit_y()).abs()
<= 1.0
} else {
(wpos2d.y as f32 + 10.0) % 30.0
(wpos2d.y as f32 + 10.0) % 15.0
/ path_dir.dot(Vec2::unit_x()).abs()
<= 1.0
};
if (col_sample.path.map(|(dist, _, _, _)| dist > 6.0 && dist < 7.0).unwrap_or(false) && is_lamp) //roll(0, 50) == 0)
|| (roll(0, 2000) == 0 && col_sample.path.map(|(dist, _, _, _)| dist > 20.0).unwrap_or(true))
|| (roll(0, 750) == 0 && col_sample.path.map(|(dist, _, _, _)| dist > 20.0).unwrap_or(true))
{
surface_sprite = Some(SpriteKind::StreetLamp);
}