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 {
|
uniform u_locals {
|
||||||
mat4 model_mat;
|
mat4 model_mat;
|
||||||
vec4 highlight_col;
|
vec4 highlight_col;
|
||||||
|
vec4 model_light;
|
||||||
ivec4 atlas_offs;
|
ivec4 atlas_offs;
|
||||||
vec3 model_pos;
|
vec3 model_pos;
|
||||||
// bit 0 - is player
|
// bit 0 - is player
|
||||||
@ -159,6 +160,10 @@ void main() {
|
|||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
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 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 point_light = light_at(f_pos, f_norm);
|
||||||
// vec3 light, diffuse_light, ambient_light;
|
// 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 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;
|
reflected_light *= ao;
|
||||||
emitted_light *= ao;
|
emitted_light *= ao;
|
||||||
/* reflected_light *= cloud_shadow(f_pos); */
|
/* reflected_light *= cloud_shadow(f_pos); */
|
||||||
|
@ -27,6 +27,7 @@ layout (std140)
|
|||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
mat4 model_mat;
|
mat4 model_mat;
|
||||||
vec4 highlight_col;
|
vec4 highlight_col;
|
||||||
|
vec4 model_light;
|
||||||
ivec4 atlas_offs;
|
ivec4 atlas_offs;
|
||||||
vec3 model_pos;
|
vec3 model_pos;
|
||||||
// bit 0 - is player
|
// bit 0 - is player
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
struct DirectionalLight {
|
struct DirectionalLight {
|
||||||
// vec3 dir;
|
// vec3 dir;
|
||||||
float shadow;
|
float shadow;
|
||||||
|
// Fully blocks all light, including ambience
|
||||||
|
float block;
|
||||||
// vec3 color;
|
// vec3 color;
|
||||||
// float brightness;
|
// 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) {
|
DirectionalLight get_sun_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/, /*vec4 sun_pos*/vec3 f_pos) {
|
||||||
float shadow = shade_frac;
|
float shadow = shade_frac;
|
||||||
|
float block = 1.0;
|
||||||
#ifdef HAS_SHADOW_MAPS
|
#ifdef HAS_SHADOW_MAPS
|
||||||
#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
if (sun_dir.z < /*0.6*/0.0) {
|
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
|
||||||
#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]*/) {
|
DirectionalLight get_moon_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/) {
|
||||||
float shadow = shade_frac;
|
float shadow = shade_frac;
|
||||||
|
float block = 1.0;
|
||||||
// #ifdef HAS_SHADOW_MAPS
|
// #ifdef HAS_SHADOW_MAPS
|
||||||
// shadow = min(shade_frac, ShadowCalculationDirected(light_pos, 1u));
|
// shadow = min(shade_frac, ShadowCalculationDirected(light_pos, 1u));
|
||||||
// #endif
|
// #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).
|
// // 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 sun_dir = sun_dir.xyz;
|
||||||
vec3 moon_dir = moon_dir.xyz;
|
vec3 moon_dir = moon_dir.xyz;
|
||||||
|
|
||||||
float sun_light = get_sun_brightness(/*sun_dir*/);//sun_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.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 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;
|
vec3 moon_color = get_moon_color(/*moon_dir*/);//moon_info.color;
|
||||||
|
@ -39,6 +39,7 @@ layout (std140)
|
|||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
mat4 model_mat;
|
mat4 model_mat;
|
||||||
vec4 highlight_col;
|
vec4 highlight_col;
|
||||||
|
vec4 model_light;
|
||||||
ivec4 atlas_offs;
|
ivec4 atlas_offs;
|
||||||
vec3 model_pos;
|
vec3 model_pos;
|
||||||
// bit 0 - is player
|
// bit 0 - is player
|
||||||
|
@ -66,6 +66,13 @@ void main() {
|
|||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
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.
|
// To account for prior saturation.
|
||||||
float max_light = 0.0;
|
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);
|
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 {
|
uniform u_locals {
|
||||||
mat4 model_mat;
|
mat4 model_mat;
|
||||||
vec4 highlight_col;
|
vec4 highlight_col;
|
||||||
|
vec4 model_light;
|
||||||
ivec4 atlas_offs;
|
ivec4 atlas_offs;
|
||||||
vec3 model_pos;
|
vec3 model_pos;
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -21,6 +21,7 @@ flat in vec3 f_norm;
|
|||||||
flat in float f_light;
|
flat in float f_light;
|
||||||
// flat in vec3 f_pos_norm;
|
// flat in vec3 f_pos_norm;
|
||||||
in vec2 f_uv_pos;
|
in vec2 f_uv_pos;
|
||||||
|
in vec2 f_inst_light;
|
||||||
// flat in uint f_atlas_pos;
|
// flat in uint f_atlas_pos;
|
||||||
// in vec3 f_col;
|
// in vec3 f_col;
|
||||||
// in float f_ao;
|
// in float f_ao;
|
||||||
@ -133,6 +134,10 @@ void main() {
|
|||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
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.
|
// To account for prior saturation.
|
||||||
// float vert_light = pow(f_light, 1.5);
|
// 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);
|
// 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; */
|
reflected_light += point_light; */
|
||||||
|
|
||||||
// float ao = /*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
|
// 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;
|
float ao = f_ao;
|
||||||
emitted_light *= ao;
|
emitted_light *= ao;
|
||||||
reflected_light *= ao;
|
reflected_light *= ao;
|
||||||
|
@ -25,7 +25,7 @@ in vec4 inst_mat0;
|
|||||||
in vec4 inst_mat1;
|
in vec4 inst_mat1;
|
||||||
in vec4 inst_mat2;
|
in vec4 inst_mat2;
|
||||||
in vec4 inst_mat3;
|
in vec4 inst_mat3;
|
||||||
// in vec3 inst_col;
|
in vec4 inst_light;
|
||||||
in float inst_wind_sway;
|
in float inst_wind_sway;
|
||||||
|
|
||||||
struct SpriteLocals {
|
struct SpriteLocals {
|
||||||
@ -77,6 +77,7 @@ flat out float f_light;
|
|||||||
// out vec3 f_col;
|
// out vec3 f_col;
|
||||||
// out float f_ao;
|
// out float f_ao;
|
||||||
out vec2 f_uv_pos;
|
out vec2 f_uv_pos;
|
||||||
|
out vec2 f_inst_light;
|
||||||
// flat out uint f_atlas_pos;
|
// flat out uint f_atlas_pos;
|
||||||
// out vec3 light_pos[2];
|
// out vec3 light_pos[2];
|
||||||
// out float f_light;
|
// out float f_light;
|
||||||
@ -117,6 +118,8 @@ void main() {
|
|||||||
// float inst_wind_sway = wind_sway.w;
|
// float inst_wind_sway = wind_sway.w;
|
||||||
// vec3 inst_offs = model_offs - focus_off.xyz;
|
// vec3 inst_offs = model_offs - focus_off.xyz;
|
||||||
|
|
||||||
|
f_inst_light = inst_light.xy;
|
||||||
|
|
||||||
// vec3 sprite_pos = floor(inst_mat3.xyz * SCALE) + inst_offs;
|
// vec3 sprite_pos = floor(inst_mat3.xyz * SCALE) + inst_offs;
|
||||||
|
|
||||||
// f_pos_norm = v_pos;
|
// f_pos_norm = v_pos;
|
||||||
|
@ -261,12 +261,15 @@ void main() {
|
|||||||
// emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
// emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
||||||
// reflected_light *= f_light * point_shadow * shade_frac;
|
// reflected_light *= f_light * point_shadow * shade_frac;
|
||||||
// max_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;
|
emitted_light *= f_light;
|
||||||
reflected_light *= f_light;
|
reflected_light *= f_light;
|
||||||
max_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);
|
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;
|
// 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>(
|
fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
||||||
is_sunlight: bool,
|
is_sunlight: bool,
|
||||||
|
// When above bounds
|
||||||
|
default_light: f32,
|
||||||
bounds: Aabb<i32>,
|
bounds: Aabb<i32>,
|
||||||
vol: &VolGrid2d<V>,
|
vol: &VolGrid2d<V>,
|
||||||
lit_blocks: impl Iterator<Item = (Vec3<i32>, u8)>,
|
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");
|
span!(_guard, "calc_light");
|
||||||
const UNKNOWN: u8 = 255;
|
const UNKNOWN: u8 = 255;
|
||||||
const OPAQUE: u8 = 254;
|
const OPAQUE: u8 = 254;
|
||||||
@ -210,17 +212,25 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
|||||||
let pos = wpos - outer.min;
|
let pos = wpos - outer.min;
|
||||||
light_map
|
light_map
|
||||||
.get(lm_idx(pos.x, pos.y, pos.z))
|
.get(lm_idx(pos.x, pos.y, pos.z))
|
||||||
.filter(|l| **l != OPAQUE && **l != UNKNOWN)
|
.map(|l| if *l != OPAQUE && *l != UNKNOWN {
|
||||||
.map(|l| *l as f32 / SUNLIGHT as f32)
|
*l as f32 / SUNLIGHT as f32
|
||||||
.unwrap_or(0.0)
|
} 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>
|
Meshable<TerrainPipeline, FluidPipeline> for &'a VolGrid2d<V>
|
||||||
{
|
{
|
||||||
type Pipeline = TerrainPipeline;
|
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 ShadowPipeline = ShadowPipeline;
|
||||||
type Supplement = (Aabb<i32>, Vec2<u16>, &'a BlocksOfInterest);
|
type Supplement = (Aabb<i32>, Vec2<u16>, &'a BlocksOfInterest);
|
||||||
type TranslucentPipeline = FluidPipeline;
|
type TranslucentPipeline = FluidPipeline;
|
||||||
@ -266,9 +276,9 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate chunk lighting
|
// Calculate chunk lighting (sunlight defaults to 1.0, glow to 0.0)
|
||||||
let mut light = calc_light(true, range, self, core::iter::empty());
|
let mut light = calc_light(true, 1.0, range, self, core::iter::empty());
|
||||||
let mut glow = calc_light(false, range, self, glow_blocks.into_iter());
|
let mut glow = calc_light(false, 0.0, range, self, glow_blocks.into_iter());
|
||||||
|
|
||||||
let mut opaque_limits = None::<Limits>;
|
let mut opaque_limits = None::<Limits>;
|
||||||
let mut fluid_limits = None::<Limits>;
|
let mut fluid_limits = None::<Limits>;
|
||||||
@ -433,7 +443,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
opaque_mesh,
|
opaque_mesh,
|
||||||
fluid_mesh,
|
fluid_mesh,
|
||||||
Mesh::new(),
|
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 {
|
constant Locals {
|
||||||
model_mat: [[f32; 4]; 4] = "model_mat",
|
model_mat: [[f32; 4]; 4] = "model_mat",
|
||||||
highlight_col: [f32; 4] = "highlight_col",
|
highlight_col: [f32; 4] = "highlight_col",
|
||||||
|
model_light: [f32; 4] = "model_light",
|
||||||
atlas_offs: [i32; 4] = "atlas_offs",
|
atlas_offs: [i32; 4] = "atlas_offs",
|
||||||
model_pos: [f32; 3] = "model_pos",
|
model_pos: [f32; 3] = "model_pos",
|
||||||
flags: u32 = "flags",
|
flags: u32 = "flags",
|
||||||
@ -54,19 +55,22 @@ gfx_defines! {
|
|||||||
impl Locals {
|
impl Locals {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
model_mat: anim::vek::Mat4<f32>,
|
model_mat: anim::vek::Mat4<f32>,
|
||||||
col: Rgba<f32>,
|
col: Rgb<f32>,
|
||||||
pos: anim::vek::Vec3<f32>,
|
pos: anim::vek::Vec3<f32>,
|
||||||
atlas_offs: Vec2<i32>,
|
atlas_offs: Vec2<i32>,
|
||||||
is_player: bool,
|
is_player: bool,
|
||||||
|
light: f32,
|
||||||
|
glow: f32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut flags = 0;
|
let mut flags = 0;
|
||||||
flags |= is_player as u32;
|
flags |= is_player as u32;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
model_mat: model_mat.into_col_arrays(),
|
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(),
|
model_pos: pos.into_array(),
|
||||||
atlas_offs: Vec4::from(atlas_offs).into_array(),
|
atlas_offs: Vec4::from(atlas_offs).into_array(),
|
||||||
|
model_light: [light, glow, 1.0, 1.0],
|
||||||
flags,
|
flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,10 +80,12 @@ impl Default for Locals {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
anim::vek::Mat4::identity(),
|
anim::vek::Mat4::identity(),
|
||||||
Rgba::broadcast(1.0),
|
Rgb::broadcast(1.0),
|
||||||
anim::vek::Vec3::default(),
|
anim::vek::Vec3::default(),
|
||||||
Vec2::default(),
|
Vec2::default(),
|
||||||
false,
|
false,
|
||||||
|
1.0,
|
||||||
|
0.0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ gfx_defines! {
|
|||||||
inst_mat1: [f32; 4] = "inst_mat1",
|
inst_mat1: [f32; 4] = "inst_mat1",
|
||||||
inst_mat2: [f32; 4] = "inst_mat2",
|
inst_mat2: [f32; 4] = "inst_mat2",
|
||||||
inst_mat3: [f32; 4] = "inst_mat3",
|
inst_mat3: [f32; 4] = "inst_mat3",
|
||||||
|
inst_light: [f32; 4] = "inst_light",
|
||||||
inst_wind_sway: f32 = "inst_wind_sway",
|
inst_wind_sway: f32 = "inst_wind_sway",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ impl Vertex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
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;
|
const EXTRA_NEG_Z: i32 = 32768;
|
||||||
|
|
||||||
let mat_arr = mat.into_col_arrays();
|
let mat_arr = mat.into_col_arrays();
|
||||||
@ -127,13 +128,14 @@ impl Instance {
|
|||||||
inst_mat1: mat_arr[1],
|
inst_mat1: mat_arr[1],
|
||||||
inst_mat2: mat_arr[2],
|
inst_mat2: mat_arr[2],
|
||||||
inst_mat3: mat_arr[3],
|
inst_mat3: mat_arr[3],
|
||||||
|
inst_light: [light, glow, 1.0, 1.0],
|
||||||
inst_wind_sway: wind_sway,
|
inst_wind_sway: wind_sway,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Instance {
|
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 {
|
impl Default for Locals {
|
||||||
|
@ -13,6 +13,7 @@ use crate::{
|
|||||||
scene::{
|
scene::{
|
||||||
camera::{Camera, CameraMode, Dependents},
|
camera::{Camera, CameraMode, Dependents},
|
||||||
math, LodData, SceneData,
|
math, LodData, SceneData,
|
||||||
|
terrain::Terrain,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use anim::{
|
use anim::{
|
||||||
@ -455,6 +456,7 @@ impl FigureMgr {
|
|||||||
// Visible chunk data.
|
// Visible chunk data.
|
||||||
visible_psr_bounds: math::Aabr<f32>,
|
visible_psr_bounds: math::Aabr<f32>,
|
||||||
camera: &Camera,
|
camera: &Camera,
|
||||||
|
terrain: Option<&Terrain>,
|
||||||
) -> anim::vek::Aabb<f32> {
|
) -> anim::vek::Aabb<f32> {
|
||||||
span!(_guard, "maintain", "FigureManager::maintain");
|
span!(_guard, "maintain", "FigureManager::maintain");
|
||||||
let state = scene_data.state;
|
let state = scene_data.state;
|
||||||
@ -1329,6 +1331,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::QuadrupedSmall(body) => {
|
Body::QuadrupedSmall(body) => {
|
||||||
@ -1439,6 +1442,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::QuadrupedMedium(body) => {
|
Body::QuadrupedMedium(body) => {
|
||||||
@ -1560,6 +1564,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::QuadrupedLow(body) => {
|
Body::QuadrupedLow(body) => {
|
||||||
@ -1668,6 +1673,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::BirdMedium(body) => {
|
Body::BirdMedium(body) => {
|
||||||
@ -1773,6 +1779,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::FishMedium(body) => {
|
Body::FishMedium(body) => {
|
||||||
@ -1859,6 +1866,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::Dragon(body) => {
|
Body::Dragon(body) => {
|
||||||
@ -1941,6 +1949,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::Theropod(body) => {
|
Body::Theropod(body) => {
|
||||||
@ -2025,6 +2034,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::BirdSmall(body) => {
|
Body::BirdSmall(body) => {
|
||||||
@ -2111,6 +2121,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::FishSmall(body) => {
|
Body::FishSmall(body) => {
|
||||||
@ -2197,6 +2208,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::BipedLarge(body) => {
|
Body::BipedLarge(body) => {
|
||||||
@ -2603,6 +2615,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::Golem(body) => {
|
Body::Golem(body) => {
|
||||||
@ -2707,6 +2720,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::Object(body) => {
|
Body::Object(body) => {
|
||||||
@ -2740,6 +2754,7 @@ impl FigureMgr {
|
|||||||
is_player,
|
is_player,
|
||||||
camera,
|
camera,
|
||||||
&mut update_buf,
|
&mut update_buf,
|
||||||
|
terrain,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -3393,6 +3408,7 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
is_player: bool,
|
is_player: bool,
|
||||||
_camera: &Camera,
|
_camera: &Camera,
|
||||||
buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT],
|
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
|
// 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
|
||||||
@ -3429,12 +3445,23 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
* anim::vek::Mat4::scaling_3d(anim::vek::Vec3::from(0.8 * scale));
|
* anim::vek::Mat4::scaling_3d(anim::vek::Vec3::from(0.8 * scale));
|
||||||
|
|
||||||
let atlas_offs = model.allocation.rectangle.min;
|
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(
|
let locals = FigureLocals::new(
|
||||||
mat,
|
mat,
|
||||||
col,
|
col.rgb(),
|
||||||
pos,
|
pos,
|
||||||
vek::Vec2::new(atlas_offs.x, atlas_offs.y),
|
vek::Vec2::new(atlas_offs.x, atlas_offs.y),
|
||||||
is_player,
|
is_player,
|
||||||
|
light,
|
||||||
|
glow,
|
||||||
);
|
);
|
||||||
renderer.update_consts(&mut self.locals, &[locals]).unwrap();
|
renderer.update_consts(&mut self.locals, &[locals]).unwrap();
|
||||||
|
|
||||||
|
@ -698,9 +698,13 @@ impl Scene {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Maintain the figures.
|
// Maintain the figures.
|
||||||
let _figure_bounds =
|
let _figure_bounds = self.figure_mgr.maintain(
|
||||||
self.figure_mgr
|
renderer,
|
||||||
.maintain(renderer, scene_data, visible_psr_bounds, &self.camera);
|
scene_data,
|
||||||
|
visible_psr_bounds,
|
||||||
|
&self.camera,
|
||||||
|
Some(&self.terrain),
|
||||||
|
);
|
||||||
|
|
||||||
let sun_dir = scene_data.get_sun_dir();
|
let sun_dir = scene_data.get_sun_dir();
|
||||||
let is_daylight = sun_dir.z < 0.0;
|
let is_daylight = sun_dir.z < 0.0;
|
||||||
|
@ -187,6 +187,7 @@ impl Scene {
|
|||||||
false,
|
false,
|
||||||
&camera,
|
&camera,
|
||||||
&mut buf,
|
&mut buf,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
(model, state)
|
(model, state)
|
||||||
}),
|
}),
|
||||||
@ -353,6 +354,7 @@ impl Scene {
|
|||||||
false,
|
false,
|
||||||
&self.camera,
|
&self.camera,
|
||||||
&mut buf,
|
&mut buf,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,8 @@ pub struct TerrainChunkData {
|
|||||||
opaque_model: Model<TerrainPipeline>,
|
opaque_model: Model<TerrainPipeline>,
|
||||||
fluid_model: Option<Model<FluidPipeline>>,
|
fluid_model: Option<Model<FluidPipeline>>,
|
||||||
col_lights: guillotiere::AllocId,
|
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>>,
|
sprite_instances: HashMap<(SpriteKind, usize), Instances<SpriteInstance>>,
|
||||||
locals: Consts<TerrainLocals>,
|
locals: Consts<TerrainLocals>,
|
||||||
pub blocks_of_interest: BlocksOfInterest,
|
pub blocks_of_interest: BlocksOfInterest,
|
||||||
@ -87,6 +89,8 @@ struct MeshWorkerResponse {
|
|||||||
opaque_mesh: Mesh<TerrainPipeline>,
|
opaque_mesh: Mesh<TerrainPipeline>,
|
||||||
fluid_mesh: Mesh<FluidPipeline>,
|
fluid_mesh: Mesh<FluidPipeline>,
|
||||||
col_lights_info: ColLightInfo,
|
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>>,
|
sprite_instances: HashMap<(SpriteKind, usize), Vec<SpriteInstance>>,
|
||||||
started_tick: u64,
|
started_tick: u64,
|
||||||
blocks_of_interest: BlocksOfInterest,
|
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.
|
/// Function executed by worker threads dedicated to chunk meshing.
|
||||||
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
|
#[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>,
|
pos: Vec2<i32>,
|
||||||
z_bounds: (f32, f32),
|
z_bounds: (f32, f32),
|
||||||
started_tick: u64,
|
started_tick: u64,
|
||||||
@ -139,7 +143,7 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
|||||||
) -> MeshWorkerResponse {
|
) -> MeshWorkerResponse {
|
||||||
span!(_guard, "mesh_worker");
|
span!(_guard, "mesh_worker");
|
||||||
let blocks_of_interest = BlocksOfInterest::from_chunk(&chunk);
|
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));
|
volume.generate_mesh((range, Vec2::new(max_texture_size, max_texture_size), &blocks_of_interest));
|
||||||
MeshWorkerResponse {
|
MeshWorkerResponse {
|
||||||
pos,
|
pos,
|
||||||
@ -190,6 +194,8 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
|||||||
cfg.wind_sway,
|
cfg.wind_sway,
|
||||||
rel_pos,
|
rel_pos,
|
||||||
ori,
|
ori,
|
||||||
|
light_map(wpos),
|
||||||
|
glow_map(wpos),
|
||||||
);
|
);
|
||||||
|
|
||||||
instances.entry(key).or_insert(Vec::new()).push(instance);
|
instances.entry(key).or_insert(Vec::new()).push(instance);
|
||||||
@ -200,6 +206,8 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
|||||||
|
|
||||||
instances
|
instances
|
||||||
},
|
},
|
||||||
|
light_map,
|
||||||
|
glow_map,
|
||||||
blocks_of_interest,
|
blocks_of_interest,
|
||||||
started_tick,
|
started_tick,
|
||||||
}
|
}
|
||||||
@ -213,7 +221,7 @@ struct SpriteData {
|
|||||||
offset: Vec3<f32>,
|
offset: Vec3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Terrain<V: RectRasterableVol> {
|
pub struct Terrain<V: RectRasterableVol = TerrainChunk> {
|
||||||
atlas: AtlasAllocator,
|
atlas: AtlasAllocator,
|
||||||
sprite_config: Arc<SpriteSpec>,
|
sprite_config: Arc<SpriteSpec>,
|
||||||
chunks: HashMap<Vec2<i32>, TerrainChunkData>,
|
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.
|
/// Maintain terrain data. To be called once per tick.
|
||||||
#[allow(clippy::for_loops_over_fallibles)] // TODO: Pending review in #587
|
#[allow(clippy::for_loops_over_fallibles)] // TODO: Pending review in #587
|
||||||
#[allow(clippy::len_zero)] // TODO: Pending review in #587
|
#[allow(clippy::len_zero)] // TODO: Pending review in #587
|
||||||
@ -732,6 +752,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
col_lights: allocation.id,
|
col_lights: allocation.id,
|
||||||
|
light_map: response.light_map,
|
||||||
|
glow_map: response.glow_map,
|
||||||
sprite_instances: response
|
sprite_instances: response
|
||||||
.sprite_instances
|
.sprite_instances
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
Loading…
Reference in New Issue
Block a user