mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Preserved light/glow maps to prevent sprites/entities being lit when they shouldn't be
This commit is contained in:
parent
51d1a2ecff
commit
27e7fd0727
@ -49,6 +49,7 @@ layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 model_mat;
|
||||
vec4 highlight_col;
|
||||
vec4 model_light;
|
||||
ivec4 atlas_offs;
|
||||
vec3 model_pos;
|
||||
// bit 0 - is player
|
||||
@ -159,6 +160,10 @@ void main() {
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
|
||||
// Make voxel shadows block the sun and moon
|
||||
sun_info.block *= model_light.x;
|
||||
moon_info.block *= model_light.x;
|
||||
|
||||
// vec3 light_frac = /*vec3(1.0);*//*vec3(max(dot(f_norm, -sun_dir) * 0.5 + 0.5, 0.0));*/light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
|
||||
// vec3 point_light = light_at(f_pos, f_norm);
|
||||
// vec3 light, diffuse_light, ambient_light;
|
||||
@ -176,6 +181,9 @@ void main() {
|
||||
|
||||
float ao = f_ao * sqrt(f_ao);//0.25 + f_ao * 0.75; ///*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
|
||||
|
||||
float glow = model_light.y;
|
||||
emitted_light += glow;
|
||||
|
||||
reflected_light *= ao;
|
||||
emitted_light *= ao;
|
||||
/* reflected_light *= cloud_shadow(f_pos); */
|
||||
|
@ -27,6 +27,7 @@ layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 model_mat;
|
||||
vec4 highlight_col;
|
||||
vec4 model_light;
|
||||
ivec4 atlas_offs;
|
||||
vec3 model_pos;
|
||||
// bit 0 - is player
|
||||
|
@ -7,6 +7,8 @@
|
||||
struct DirectionalLight {
|
||||
// vec3 dir;
|
||||
float shadow;
|
||||
// Fully blocks all light, including ambience
|
||||
float block;
|
||||
// vec3 color;
|
||||
// float brightness;
|
||||
};
|
||||
@ -135,6 +137,7 @@ vec3 get_moon_color(/*vec3 moon_dir*/) {
|
||||
|
||||
DirectionalLight get_sun_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/, /*vec4 sun_pos*/vec3 f_pos) {
|
||||
float shadow = shade_frac;
|
||||
float block = 1.0;
|
||||
#ifdef HAS_SHADOW_MAPS
|
||||
#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||
if (sun_dir.z < /*0.6*/0.0) {
|
||||
@ -151,15 +154,16 @@ DirectionalLight get_sun_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return DirectionalLight(/*dir, */shadow/*, get_sun_color(dir), get_sun_brightness(dir)*/);
|
||||
return DirectionalLight(/*dir, */shadow, block/*, get_sun_color(dir), get_sun_brightness(dir)*/);
|
||||
}
|
||||
|
||||
DirectionalLight get_moon_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/) {
|
||||
float shadow = shade_frac;
|
||||
float block = 1.0;
|
||||
// #ifdef HAS_SHADOW_MAPS
|
||||
// shadow = min(shade_frac, ShadowCalculationDirected(light_pos, 1u));
|
||||
// #endif
|
||||
return DirectionalLight(/*dir, */shadow/*, get_moon_color(dir), get_moon_brightness(dir)*/);
|
||||
return DirectionalLight(/*dir, */shadow, block/*, get_moon_color(dir), get_moon_brightness(dir)*/);
|
||||
}
|
||||
|
||||
// // Calculates extra emission and reflectance (due to sunlight / moonlight).
|
||||
@ -227,8 +231,8 @@ float get_sun_diffuse2(DirectionalLight sun_info, DirectionalLight moon_info, ve
|
||||
vec3 sun_dir = sun_dir.xyz;
|
||||
vec3 moon_dir = moon_dir.xyz;
|
||||
|
||||
float sun_light = get_sun_brightness(/*sun_dir*/);//sun_info.brightness;;
|
||||
float moon_light = get_moon_brightness(/*moon_dir*/);//moon_info.brightness;
|
||||
float sun_light = get_sun_brightness(/*sun_dir*/) * sun_info.block;//sun_info.brightness;;
|
||||
float moon_light = get_moon_brightness(/*moon_dir*/) * moon_info.block;//moon_info.brightness;
|
||||
|
||||
vec3 sun_color = get_sun_color(/*sun_dir*/) * SUN_COLOR_FACTOR;//sun_info.color * SUN_COLOR_FACTOR;
|
||||
vec3 moon_color = get_moon_color(/*moon_dir*/);//moon_info.color;
|
||||
|
@ -39,6 +39,7 @@ layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 model_mat;
|
||||
vec4 highlight_col;
|
||||
vec4 model_light;
|
||||
ivec4 atlas_offs;
|
||||
vec3 model_pos;
|
||||
// bit 0 - is player
|
||||
|
@ -66,6 +66,13 @@ void main() {
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
|
||||
// This is a bit of a hack. Because we can't find the volumetric lighting of each particle (they don't talk to the
|
||||
// CPU) we need to some how find an approximation of how much the sun is blocked. We do this by fading out the sun
|
||||
// as the particle moves underground. This isn't perfect, but it does at least mean that particles don't look like
|
||||
// they're exposed to the sun when in dungeons
|
||||
const float SUN_FADEOUT_DIST = 20.0;
|
||||
sun_info.block *= clamp((f_pos.z - f_alt) / SUN_FADEOUT_DIST + 1, 0, 1);
|
||||
|
||||
// To account for prior saturation.
|
||||
float max_light = 0.0;
|
||||
max_light += get_sun_diffuse2(sun_info, moon_info, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
|
@ -25,6 +25,7 @@ layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 model_mat;
|
||||
vec4 highlight_col;
|
||||
vec4 model_light;
|
||||
ivec4 atlas_offs;
|
||||
vec3 model_pos;
|
||||
int flags;
|
||||
|
@ -21,6 +21,7 @@ flat in vec3 f_norm;
|
||||
flat in float f_light;
|
||||
// flat in vec3 f_pos_norm;
|
||||
in vec2 f_uv_pos;
|
||||
in vec2 f_inst_light;
|
||||
// flat in uint f_atlas_pos;
|
||||
// in vec3 f_col;
|
||||
// in float f_ao;
|
||||
@ -133,6 +134,10 @@ void main() {
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
|
||||
// Make voxel shadows block the sun and moon
|
||||
sun_info.block = f_inst_light.x;
|
||||
moon_info.block = f_inst_light.x;
|
||||
|
||||
// To account for prior saturation.
|
||||
// float vert_light = pow(f_light, 1.5);
|
||||
// vec3 light_frac = light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
|
||||
@ -169,6 +174,9 @@ void main() {
|
||||
reflected_light += point_light; */
|
||||
|
||||
// float ao = /*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
|
||||
float glow = f_inst_light.y;
|
||||
emitted_light += glow;
|
||||
|
||||
float ao = f_ao;
|
||||
emitted_light *= ao;
|
||||
reflected_light *= ao;
|
||||
|
@ -25,7 +25,7 @@ in vec4 inst_mat0;
|
||||
in vec4 inst_mat1;
|
||||
in vec4 inst_mat2;
|
||||
in vec4 inst_mat3;
|
||||
// in vec3 inst_col;
|
||||
in vec4 inst_light;
|
||||
in float inst_wind_sway;
|
||||
|
||||
struct SpriteLocals {
|
||||
@ -77,6 +77,7 @@ flat out float f_light;
|
||||
// out vec3 f_col;
|
||||
// out float f_ao;
|
||||
out vec2 f_uv_pos;
|
||||
out vec2 f_inst_light;
|
||||
// flat out uint f_atlas_pos;
|
||||
// out vec3 light_pos[2];
|
||||
// out float f_light;
|
||||
@ -117,6 +118,8 @@ void main() {
|
||||
// float inst_wind_sway = wind_sway.w;
|
||||
// vec3 inst_offs = model_offs - focus_off.xyz;
|
||||
|
||||
f_inst_light = inst_light.xy;
|
||||
|
||||
// vec3 sprite_pos = floor(inst_mat3.xyz * SCALE) + inst_offs;
|
||||
|
||||
// f_pos_norm = v_pos;
|
||||
|
@ -261,12 +261,15 @@ void main() {
|
||||
// emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
||||
// reflected_light *= f_light * point_shadow * shade_frac;
|
||||
// max_light *= f_light * point_shadow * shade_frac;
|
||||
emitted_light += pow(f_glow, 5) * 16;
|
||||
reflected_light += pow(f_glow, 5) * 16;
|
||||
emitted_light *= f_light;
|
||||
reflected_light *= f_light;
|
||||
max_light *= f_light;
|
||||
|
||||
// TODO: Apply AO after this
|
||||
float l = pow(f_glow, 6) * 8 + pow(f_glow, 2) * 0.5;
|
||||
emitted_light += l;
|
||||
reflected_light += l;
|
||||
|
||||
max_light += lights_at(f_pos, f_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, f_norm, 1.0, emitted_light, reflected_light);
|
||||
|
||||
// float f_ao = 1.0;
|
||||
|
@ -35,10 +35,12 @@ 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,
|
||||
bounds: Aabb<i32>,
|
||||
vol: &VolGrid2d<V>,
|
||||
lit_blocks: impl Iterator<Item = (Vec3<i32>, u8)>,
|
||||
) -> impl FnMut(Vec3<i32>) -> f32 + '_ {
|
||||
) -> impl Fn(Vec3<i32>) -> f32 + 'static + Send + Sync {
|
||||
span!(_guard, "calc_light");
|
||||
const UNKNOWN: u8 = 255;
|
||||
const OPAQUE: u8 = 254;
|
||||
@ -210,17 +212,25 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
||||
let pos = wpos - outer.min;
|
||||
light_map
|
||||
.get(lm_idx(pos.x, pos.y, pos.z))
|
||||
.filter(|l| **l != OPAQUE && **l != UNKNOWN)
|
||||
.map(|l| *l as f32 / SUNLIGHT as f32)
|
||||
.unwrap_or(0.0)
|
||||
.map(|l| if *l != OPAQUE && *l != UNKNOWN {
|
||||
*l as f32 / SUNLIGHT as f32
|
||||
} else {
|
||||
0.0
|
||||
})
|
||||
.unwrap_or(default_light)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||
impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + 'static>
|
||||
Meshable<TerrainPipeline, FluidPipeline> for &'a VolGrid2d<V>
|
||||
{
|
||||
type Pipeline = TerrainPipeline;
|
||||
type Result = (Aabb<f32>, ColLightInfo);
|
||||
type Result = (
|
||||
Aabb<f32>,
|
||||
ColLightInfo,
|
||||
Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
|
||||
Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
|
||||
);
|
||||
type ShadowPipeline = ShadowPipeline;
|
||||
type Supplement = (Aabb<i32>, Vec2<u16>, &'a BlocksOfInterest);
|
||||
type TranslucentPipeline = FluidPipeline;
|
||||
@ -266,9 +276,9 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate chunk lighting
|
||||
let mut light = calc_light(true, range, self, core::iter::empty());
|
||||
let mut glow = calc_light(false, range, self, glow_blocks.into_iter());
|
||||
// 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 mut opaque_limits = None::<Limits>;
|
||||
let mut fluid_limits = None::<Limits>;
|
||||
@ -433,7 +443,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||
opaque_mesh,
|
||||
fluid_mesh,
|
||||
Mesh::new(),
|
||||
(bounds, (col_lights, col_lights_size)),
|
||||
(bounds, (col_lights, col_lights_size), Box::new(light), Box::new(glow)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ gfx_defines! {
|
||||
constant Locals {
|
||||
model_mat: [[f32; 4]; 4] = "model_mat",
|
||||
highlight_col: [f32; 4] = "highlight_col",
|
||||
model_light: [f32; 4] = "model_light",
|
||||
atlas_offs: [i32; 4] = "atlas_offs",
|
||||
model_pos: [f32; 3] = "model_pos",
|
||||
flags: u32 = "flags",
|
||||
@ -54,19 +55,22 @@ gfx_defines! {
|
||||
impl Locals {
|
||||
pub fn new(
|
||||
model_mat: anim::vek::Mat4<f32>,
|
||||
col: Rgba<f32>,
|
||||
col: Rgb<f32>,
|
||||
pos: anim::vek::Vec3<f32>,
|
||||
atlas_offs: Vec2<i32>,
|
||||
is_player: bool,
|
||||
light: f32,
|
||||
glow: f32,
|
||||
) -> Self {
|
||||
let mut flags = 0;
|
||||
flags |= is_player as u32;
|
||||
|
||||
Self {
|
||||
model_mat: model_mat.into_col_arrays(),
|
||||
highlight_col: col.into_array(),
|
||||
highlight_col: [col.r, col.g, col.b, glow],
|
||||
model_pos: pos.into_array(),
|
||||
atlas_offs: Vec4::from(atlas_offs).into_array(),
|
||||
model_light: [light, glow, 1.0, 1.0],
|
||||
flags,
|
||||
}
|
||||
}
|
||||
@ -76,10 +80,12 @@ impl Default for Locals {
|
||||
fn default() -> Self {
|
||||
Self::new(
|
||||
anim::vek::Mat4::identity(),
|
||||
Rgba::broadcast(1.0),
|
||||
Rgb::broadcast(1.0),
|
||||
anim::vek::Vec3::default(),
|
||||
Vec2::default(),
|
||||
false,
|
||||
1.0,
|
||||
0.0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ gfx_defines! {
|
||||
inst_mat1: [f32; 4] = "inst_mat1",
|
||||
inst_mat2: [f32; 4] = "inst_mat2",
|
||||
inst_mat3: [f32; 4] = "inst_mat3",
|
||||
inst_light: [f32; 4] = "inst_light",
|
||||
inst_wind_sway: f32 = "inst_wind_sway",
|
||||
}
|
||||
|
||||
@ -114,7 +115,7 @@ impl Vertex {
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn new(mat: Mat4<f32>, wind_sway: f32, pos: Vec3<i32>, ori_bits: u8) -> Self {
|
||||
pub fn new(mat: Mat4<f32>, wind_sway: f32, pos: Vec3<i32>, ori_bits: u8, light: f32, glow: f32) -> Self {
|
||||
const EXTRA_NEG_Z: i32 = 32768;
|
||||
|
||||
let mat_arr = mat.into_col_arrays();
|
||||
@ -127,13 +128,14 @@ impl Instance {
|
||||
inst_mat1: mat_arr[1],
|
||||
inst_mat2: mat_arr[2],
|
||||
inst_mat3: mat_arr[3],
|
||||
inst_light: [light, glow, 1.0, 1.0],
|
||||
inst_wind_sway: wind_sway,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Instance {
|
||||
fn default() -> Self { Self::new(Mat4::identity(), 0.0, Vec3::zero(), 0) }
|
||||
fn default() -> Self { Self::new(Mat4::identity(), 0.0, Vec3::zero(), 0, 1.0, 0.0) }
|
||||
}
|
||||
|
||||
impl Default for Locals {
|
||||
|
@ -13,6 +13,7 @@ use crate::{
|
||||
scene::{
|
||||
camera::{Camera, CameraMode, Dependents},
|
||||
math, LodData, SceneData,
|
||||
terrain::Terrain,
|
||||
},
|
||||
};
|
||||
use anim::{
|
||||
@ -455,6 +456,7 @@ impl FigureMgr {
|
||||
// Visible chunk data.
|
||||
visible_psr_bounds: math::Aabr<f32>,
|
||||
camera: &Camera,
|
||||
terrain: Option<&Terrain>,
|
||||
) -> anim::vek::Aabb<f32> {
|
||||
span!(_guard, "maintain", "FigureManager::maintain");
|
||||
let state = scene_data.state;
|
||||
@ -1329,6 +1331,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedSmall(body) => {
|
||||
@ -1439,6 +1442,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedMedium(body) => {
|
||||
@ -1560,6 +1564,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedLow(body) => {
|
||||
@ -1668,6 +1673,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::BirdMedium(body) => {
|
||||
@ -1773,6 +1779,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::FishMedium(body) => {
|
||||
@ -1859,6 +1866,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::Dragon(body) => {
|
||||
@ -1941,6 +1949,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::Theropod(body) => {
|
||||
@ -2025,6 +2034,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::BirdSmall(body) => {
|
||||
@ -2111,6 +2121,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::FishSmall(body) => {
|
||||
@ -2197,6 +2208,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::BipedLarge(body) => {
|
||||
@ -2603,6 +2615,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::Golem(body) => {
|
||||
@ -2707,6 +2720,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::Object(body) => {
|
||||
@ -2740,6 +2754,7 @@ impl FigureMgr {
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
}
|
||||
@ -3393,6 +3408,7 @@ impl<S: Skeleton> FigureState<S> {
|
||||
is_player: bool,
|
||||
_camera: &Camera,
|
||||
buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT],
|
||||
terrain: Option<&Terrain>,
|
||||
) {
|
||||
// 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
|
||||
@ -3429,12 +3445,23 @@ impl<S: Skeleton> FigureState<S> {
|
||||
* anim::vek::Mat4::scaling_3d(anim::vek::Vec3::from(0.8 * scale));
|
||||
|
||||
let atlas_offs = model.allocation.rectangle.min;
|
||||
|
||||
let (light, glow) = terrain
|
||||
.map(|t| {
|
||||
// Sample the location a little above to avoid clipping into terrain
|
||||
let wpos = (Vec3::from(pos.into_array()) + Vec3::unit_z() * 0.5).map(|e: f32| e.floor() as i32);
|
||||
(t.light_at_wpos(wpos), t.glow_at_wpos(wpos))
|
||||
})
|
||||
.unwrap_or((1.0, 0.0));
|
||||
|
||||
let locals = FigureLocals::new(
|
||||
mat,
|
||||
col,
|
||||
col.rgb(),
|
||||
pos,
|
||||
vek::Vec2::new(atlas_offs.x, atlas_offs.y),
|
||||
is_player,
|
||||
light,
|
||||
glow,
|
||||
);
|
||||
renderer.update_consts(&mut self.locals, &[locals]).unwrap();
|
||||
|
||||
|
@ -698,9 +698,13 @@ impl Scene {
|
||||
);
|
||||
|
||||
// Maintain the figures.
|
||||
let _figure_bounds =
|
||||
self.figure_mgr
|
||||
.maintain(renderer, scene_data, visible_psr_bounds, &self.camera);
|
||||
let _figure_bounds = self.figure_mgr.maintain(
|
||||
renderer,
|
||||
scene_data,
|
||||
visible_psr_bounds,
|
||||
&self.camera,
|
||||
Some(&self.terrain),
|
||||
);
|
||||
|
||||
let sun_dir = scene_data.get_sun_dir();
|
||||
let is_daylight = sun_dir.z < 0.0;
|
||||
|
@ -187,6 +187,7 @@ impl Scene {
|
||||
false,
|
||||
&camera,
|
||||
&mut buf,
|
||||
None,
|
||||
);
|
||||
(model, state)
|
||||
}),
|
||||
@ -353,6 +354,7 @@ impl Scene {
|
||||
false,
|
||||
&self.camera,
|
||||
&mut buf,
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,8 @@ pub struct TerrainChunkData {
|
||||
opaque_model: Model<TerrainPipeline>,
|
||||
fluid_model: Option<Model<FluidPipeline>>,
|
||||
col_lights: guillotiere::AllocId,
|
||||
light_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
|
||||
glow_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
|
||||
sprite_instances: HashMap<(SpriteKind, usize), Instances<SpriteInstance>>,
|
||||
locals: Consts<TerrainLocals>,
|
||||
pub blocks_of_interest: BlocksOfInterest,
|
||||
@ -87,6 +89,8 @@ struct MeshWorkerResponse {
|
||||
opaque_mesh: Mesh<TerrainPipeline>,
|
||||
fluid_mesh: Mesh<FluidPipeline>,
|
||||
col_lights_info: ColLightInfo,
|
||||
light_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
|
||||
glow_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
|
||||
sprite_instances: HashMap<(SpriteKind, usize), Vec<SpriteInstance>>,
|
||||
started_tick: u64,
|
||||
blocks_of_interest: BlocksOfInterest,
|
||||
@ -126,7 +130,7 @@ type SpriteSpec = sprite::sprite_kind::PureCases<Option<SpriteConfig<String>>>;
|
||||
/// Function executed by worker threads dedicated to chunk meshing.
|
||||
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
|
||||
|
||||
fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
||||
fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug + 'static>(
|
||||
pos: Vec2<i32>,
|
||||
z_bounds: (f32, f32),
|
||||
started_tick: u64,
|
||||
@ -139,7 +143,7 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
||||
) -> MeshWorkerResponse {
|
||||
span!(_guard, "mesh_worker");
|
||||
let blocks_of_interest = BlocksOfInterest::from_chunk(&chunk);
|
||||
let (opaque_mesh, fluid_mesh, _shadow_mesh, (bounds, col_lights_info)) =
|
||||
let (opaque_mesh, fluid_mesh, _shadow_mesh, (bounds, col_lights_info, light_map, glow_map)) =
|
||||
volume.generate_mesh((range, Vec2::new(max_texture_size, max_texture_size), &blocks_of_interest));
|
||||
MeshWorkerResponse {
|
||||
pos,
|
||||
@ -190,6 +194,8 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
||||
cfg.wind_sway,
|
||||
rel_pos,
|
||||
ori,
|
||||
light_map(wpos),
|
||||
glow_map(wpos),
|
||||
);
|
||||
|
||||
instances.entry(key).or_insert(Vec::new()).push(instance);
|
||||
@ -200,6 +206,8 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
||||
|
||||
instances
|
||||
},
|
||||
light_map,
|
||||
glow_map,
|
||||
blocks_of_interest,
|
||||
started_tick,
|
||||
}
|
||||
@ -213,7 +221,7 @@ struct SpriteData {
|
||||
offset: Vec3<f32>,
|
||||
}
|
||||
|
||||
pub struct Terrain<V: RectRasterableVol> {
|
||||
pub struct Terrain<V: RectRasterableVol = TerrainChunk> {
|
||||
atlas: AtlasAllocator,
|
||||
sprite_config: Arc<SpriteSpec>,
|
||||
chunks: HashMap<Vec2<i32>, TerrainChunkData>,
|
||||
@ -462,6 +470,18 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the light level (sunlight) at the given world position.
|
||||
pub fn light_at_wpos(&self, wpos: Vec3<i32>) -> f32 {
|
||||
let chunk_pos = Vec2::from(wpos).map2(TerrainChunk::RECT_SIZE, |e: i32, sz| e.div_euclid(sz as i32));
|
||||
self.chunks.get(&chunk_pos).map(|c| (c.light_map)(wpos)).unwrap_or(1.0)
|
||||
}
|
||||
|
||||
/// Find the glow level (light from lamps) at the given world position.
|
||||
pub fn glow_at_wpos(&self, wpos: Vec3<i32>) -> f32 {
|
||||
let chunk_pos = Vec2::from(wpos).map2(TerrainChunk::RECT_SIZE, |e: i32, sz| e.div_euclid(sz as i32));
|
||||
self.chunks.get(&chunk_pos).map(|c| (c.glow_map)(wpos)).unwrap_or(0.0)
|
||||
}
|
||||
|
||||
/// Maintain terrain data. To be called once per tick.
|
||||
#[allow(clippy::for_loops_over_fallibles)] // TODO: Pending review in #587
|
||||
#[allow(clippy::len_zero)] // TODO: Pending review in #587
|
||||
@ -732,6 +752,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
None
|
||||
},
|
||||
col_lights: allocation.id,
|
||||
light_map: response.light_map,
|
||||
glow_map: response.glow_map,
|
||||
sprite_instances: response
|
||||
.sprite_instances
|
||||
.into_iter()
|
||||
|
Loading…
Reference in New Issue
Block a user