Added glow

This commit is contained in:
Joshua Barretto 2020-11-21 03:05:09 +00:00
parent 3bcffe1bf7
commit 51d1a2ecff
12 changed files with 157 additions and 77 deletions

View File

@ -82,13 +82,8 @@ void main() {
// vec3 f_col = f_col_light.rgb;
// float f_ao = f_col_light.a;
// vec2 f_uv_pos = f_uv_pos + atlas_offs.xy;
vec4 f_col_light = texelFetch(t_col_light, ivec2(f_uv_pos)/* + uv_delta*//* - f_norm * 0.00001*/, 0);
// vec4 f_col_light = texelFetch(t_col_light, ivec2(int(f_uv_pos.x), int(f_uv_pos.y)/* + uv_delta*//* - f_norm * 0.00001*/), 0);
vec3 f_col = /*linear_to_srgb*//*srgb_to_linear*/(f_col_light.rgb);
// vec3 f_col = vec3(1.0);
// vec2 texSize = textureSize(t_col_light, 0);
float f_ao = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
float f_ao, f_glow;
vec3 f_col = greedy_extract_col_light_glow(t_col_light, f_uv_pos, f_ao, f_glow);
// float /*f_light*/f_ao = textureProj(t_col_light, vec3(f_uv_pos, texSize)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
// vec3 my_chunk_pos = (vec3((uvec3(f_pos_norm) >> uvec3(0, 9, 18)) & uvec3(0x1FFu)) - 256.0) / 2.0;

View File

@ -617,3 +617,22 @@ vec3 compute_attenuation_point(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_a
// return 1.0;
//}
//#endif
vec3 greedy_extract_col_light_glow(sampler2D t_col_light, vec2 f_uv_pos, out float f_light, out float f_glow) {
uvec4 f_col_light = uvec4(texelFetch(t_col_light, ivec2(f_uv_pos), 0) * 255);
vec3 f_col = vec3(
float(((f_col_light.r >> 4u) & 0xEu) | (((f_col_light.b >> 4u) & 0xFu) << 4u)),
float(f_col_light.a),
float(((f_col_light.g >> 4u) & 0xEu) | (((f_col_light.b >> 0u) & 0xFu) << 4u))
) / 255.0;
vec2 light_00 = vec2(uvec2(f_col_light.rg) & uvec2(0x1Fu));
vec2 light_10 = vec2(uvec2(texelFetch(t_col_light, ivec2(f_uv_pos) + ivec2(1, 0), 0).rg * 255.0) & uvec2(0x1Fu));
vec2 light_01 = vec2(uvec2(texelFetch(t_col_light, ivec2(f_uv_pos) + ivec2(0, 1), 0).rg * 255.0) & uvec2(0x1Fu));
vec2 light_11 = vec2(uvec2(texelFetch(t_col_light, ivec2(f_uv_pos) + ivec2(1, 1), 0).rg * 255.0) & uvec2(0x1Fu));
vec2 light_0 = mix(light_00, light_01, fract(f_uv_pos.y));
vec2 light_1 = mix(light_10, light_11, fract(f_uv_pos.y));
vec2 light = mix(light_0, light_1, fract(f_uv_pos.x));
f_light = light.x / 31.0;
f_glow = light.y / 31.0;
return srgb_to_linear(f_col);
}

View File

@ -61,17 +61,8 @@ void main() {
// vec3 dv = dFdy(f_pos);
// vec3 f_norm = normalize(cross(du, dv));
// vec4 f_col_light = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)/* + uv_delta*//* - f_norm * 0.00001*/);
// vec4 f_col_light = textureGrad(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0), vec2(0.5), vec2(0.5));
vec4 f_col_light = texelFetch(t_col_light, ivec2(f_uv_pos)/* + uv_delta*//* - f_norm * 0.00001*/, 0);
vec3 f_col = /*linear_to_srgb*//*srgb_to_linear*/(f_col_light.rgb);
// vec3 f_col = vec3(1.0);
// vec2 texSize = textureSize(t_col_light, 0);
// float f_ao = f_col_light.a;
// float f_ao = f_col_light.a + length(vec2(dFdx(f_col_light.a), dFdy(f_col_light.a)));
float f_ao = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
// float f_ao = 1.0;
// float /*f_light*/f_ao = textureProj(t_col_light, vec3(f_uv_pos, texSize)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
float f_ao, f_glow;
vec3 f_col = greedy_extract_col_light_glow(t_col_light, f_uv_pos, f_ao, f_glow);
// vec3 my_chunk_pos = f_pos_norm;
// tgt_color = vec4(hash(floor(vec4(my_chunk_pos.x, 0, 0, 0))), hash(floor(vec4(0, my_chunk_pos.y, 0, 1))), hash(floor(vec4(0, 0, my_chunk_pos.z, 2))), 1.0);

View File

@ -81,12 +81,9 @@ void main() {
vec2 f_uv_pos = f_uv_pos + atlas_offs.xy;
// vec4 f_col_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0)));//(f_uv_pos/* + 0.5*/) / texSize);
// float f_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0))).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
vec4 f_col_light = texelFetch(t_col_light, ivec2(f_uv_pos)/* + uv_delta*//* - f_norm * 0.00001*/, 0);
// float f_light = f_col_light.a;
// vec4 f_col_light = texelFetch(t_col_light, ivec2(int(f_uv_pos.x), int(f_uv_pos.y)/* + uv_delta*//* - f_norm * 0.00001*/), 0);
vec3 f_col = /*linear_to_srgb*//*srgb_to_linear*/(f_col_light.rgb);
// vec3 f_col = vec3(1.0);
float f_light = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
float f_light, f_glow;
vec3 f_col = greedy_extract_col_light_glow(t_col_light, f_uv_pos, f_light, f_glow);
//float f_light = (uint(texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)).r * 255.0) & 0x1Fu) / 31.0;
// vec2 texSize = textureSize(t_col_light, 0);
// float f_light = texture(t_col_light, f_uv_pos/* + vec2(atlas_offs.xy)*/).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
// float f_light = textureProj(t_col_light, vec3(f_uv_pos/* + vec2(atlas_offs.xy)*/, texSize.x)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
@ -264,6 +261,8 @@ 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;

View File

@ -167,13 +167,11 @@ impl Block {
#[inline]
pub fn get_glow(&self) -> Option<u8> {
// TODO: When we have proper volumetric lighting
// match self.get_sprite()? {
// SpriteKind::StreetLamp | SpriteKind::StreetLampTall => Some(20),
// SpriteKind::Velorite | SpriteKind::VeloriteFrag => Some(10),
// _ => None,
// }
None
match self.get_sprite()? {
SpriteKind::StreetLamp | SpriteKind::StreetLampTall => Some(20),
SpriteKind::Velorite | SpriteKind::VeloriteFrag => Some(3),
_ => None,
}
}
#[inline]

View File

@ -11,7 +11,7 @@ type TodoRect = (
Vec3<i32>,
);
pub struct GreedyConfig<D, FL, FC, FO, FS, FP> {
pub struct GreedyConfig<D, FL, FG, FC, FO, FS, FP> {
pub data: D,
/// The minimum position to mesh, in the coordinate system used
/// for queries against the volume.
@ -36,6 +36,9 @@ pub struct GreedyConfig<D, FL, FC, FO, FS, FP> {
/// Given a position, return the lighting information for the voxel at that
/// position.
pub get_light: FL,
/// Given a position, return the glow information for the voxel at that
/// position (i.e: additional non-sun light).
pub get_glow: FG,
/// Given a position, return the color information for the voxel at that
/// position.
pub get_color: FC,
@ -140,11 +143,12 @@ impl<'a> GreedyMesh<'a> {
/// Returns an estimate of the bounds of the current meshed model.
///
/// For more information on the config parameter, see [GreedyConfig].
pub fn push<M: PartialEq, D: 'a, FL, FC, FO, FS, FP>(
pub fn push<M: PartialEq, D: 'a, FL, FG, FC, FO, FS, FP>(
&mut self,
config: GreedyConfig<D, FL, FC, FO, FS, FP>,
config: GreedyConfig<D, FL, FG, FC, FO, FS, FP>,
) where
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
FG: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
FC: for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
FO: for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
@ -173,7 +177,7 @@ impl<'a> GreedyMesh<'a> {
span!(_guard, "finalize", "GreedyMesh::finalize");
let cur_size = self.col_lights_size;
let col_lights = vec![
TerrainVertex::make_col_light(254, Rgb::broadcast(254));
TerrainVertex::make_col_light(254, 0, Rgb::broadcast(254));
usize::from(cur_size.x) * usize::from(cur_size.y)
];
let mut col_lights_info = (col_lights, cur_size);
@ -186,7 +190,7 @@ impl<'a> GreedyMesh<'a> {
pub fn max_size(&self) -> guillotiere::Size { self.max_size }
}
fn greedy_mesh<'a, M: PartialEq, D: 'a, FL, FC, FO, FS, FP>(
fn greedy_mesh<'a, M: PartialEq, D: 'a, FL, FG, FC, FO, FS, FP>(
atlas: &mut guillotiere::SimpleAtlasAllocator,
col_lights_size: &mut Vec2<u16>,
max_size: guillotiere::Size,
@ -196,14 +200,16 @@ fn greedy_mesh<'a, M: PartialEq, D: 'a, FL, FC, FO, FS, FP>(
greedy_size,
greedy_size_cross,
get_light,
get_glow,
get_color,
get_opacity,
mut should_draw,
mut push_quad,
}: GreedyConfig<D, FL, FC, FO, FS, FP>,
}: GreedyConfig<D, FL, FG, FC, FO, FS, FP>,
) -> Box<SuspendedMesh<'a>>
where
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
FG: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
FC: for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
FO: for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
@ -356,6 +362,7 @@ where
todo_rects,
draw_delta,
get_light,
get_glow,
get_color,
get_opacity,
TerrainVertex::make_col_light,
@ -511,9 +518,10 @@ fn draw_col_lights<D>(
todo_rects: Vec<TodoRect>,
draw_delta: Vec3<i32>,
mut get_light: impl FnMut(&mut D, Vec3<i32>) -> f32,
mut get_glow: impl FnMut(&mut D, Vec3<i32>) -> f32,
mut get_color: impl FnMut(&mut D, Vec3<i32>) -> Rgb<u8>,
mut get_opacity: impl FnMut(&mut D, Vec3<i32>) -> bool,
mut make_col_light: impl FnMut(u8, Rgb<u8>) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType,
mut make_col_light: impl FnMut(u8, u8, Rgb<u8>) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType,
) {
todo_rects.into_iter().for_each(|(pos, uv, rect, delta)| {
// NOTE: Conversions are safe because width, height, and offset must be
@ -579,8 +587,9 @@ fn draw_col_lights<D>(
}
) / 4.0;
let col = get_color(data, pos);
let light = (darkness * 255.0) as u8;
*col_light = make_col_light(light, col);
let light = (darkness * 31.5) as u8;
let glow = (get_glow(data, light_pos) * 31.5) as u8;
*col_light = make_col_light(light, glow, col);
});
});
});

View File

@ -77,6 +77,7 @@ where
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()
@ -100,6 +101,7 @@ where
greedy_size,
greedy_size_cross,
get_light,
get_glow,
get_color,
get_opacity,
should_draw,
@ -179,6 +181,7 @@ where
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()
@ -201,6 +204,7 @@ where
greedy_size,
greedy_size_cross,
get_light,
get_glow,
get_color,
get_opacity,
should_draw,
@ -273,6 +277,7 @@ where
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()
@ -295,6 +300,7 @@ where
greedy_size,
greedy_size_cross,
get_light,
get_glow,
get_color,
get_opacity,
should_draw,

View File

@ -4,6 +4,7 @@ use crate::{
MeshGen, Meshable,
},
render::{self, ColLightInfo, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
scene::terrain::BlocksOfInterest,
};
use common::{
span,
@ -30,9 +31,10 @@ enum FaceKind {
}
const SUNLIGHT: u8 = 24;
const _MAX_LIGHT_DIST: i32 = SUNLIGHT as i32;
const MAX_LIGHT_DIST: i32 = SUNLIGHT as i32;
fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
is_sunlight: bool,
bounds: Aabb<i32>,
vol: &VolGrid2d<V>,
lit_blocks: impl Iterator<Item = (Vec3<i32>, u8)>,
@ -57,32 +59,34 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
let mut prop_que = lit_blocks
.map(|(pos, light)| {
let rpos = pos - outer.min;
light_map[lm_idx(rpos.x, rpos.y, rpos.z)] = light;
light_map[lm_idx(rpos.x, rpos.y, rpos.z)] = light.min(SUNLIGHT); // Brightest light
(rpos.x as u8, rpos.y as u8, rpos.z as u16)
})
.collect::<VecDeque<_>>();
// Start sun rays
for x in 0..outer.size().w {
for y in 0..outer.size().h {
let z = outer.size().d - 1;
let is_air = vol_cached
.get(outer.min + Vec3::new(x, y, z))
.ok()
.map_or(false, |b| b.is_air());
light_map[lm_idx(x, y, z)] = if is_air {
if vol_cached
.get(outer.min + Vec3::new(x, y, z - 1))
if is_sunlight {
for x in 0..outer.size().w {
for y in 0..outer.size().h {
let z = outer.size().d - 1;
let is_air = vol_cached
.get(outer.min + Vec3::new(x, y, z))
.ok()
.map_or(false, |b| b.is_air())
{
light_map[lm_idx(x, y, z - 1)] = SUNLIGHT;
prop_que.push_back((x as u8, y as u8, z as u16));
}
SUNLIGHT
} else {
OPAQUE
};
.map_or(false, |b| b.is_air());
light_map[lm_idx(x, y, z)] = if is_air {
if vol_cached
.get(outer.min + Vec3::new(x, y, z - 1))
.ok()
.map_or(false, |b| b.is_air())
{
light_map[lm_idx(x, y, z - 1)] = SUNLIGHT;
prop_que.push_back((x as u8, y as u8, z as u16));
}
SUNLIGHT
} else {
OPAQUE
};
}
}
}
@ -123,7 +127,7 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
let light = light_map[lm_idx(pos.x, pos.y, pos.z)];
// If ray propagate downwards at full strength
if light == SUNLIGHT {
if is_sunlight && light == SUNLIGHT {
// Down is special cased and we know up is a ray
// Special cased ray propagation
let pos = Vec3::new(pos.x, pos.y, pos.z - 1);
@ -218,7 +222,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
type Pipeline = TerrainPipeline;
type Result = (Aabb<f32>, ColLightInfo);
type ShadowPipeline = ShadowPipeline;
type Supplement = (Aabb<i32>, Vec2<u16>);
type Supplement = (Aabb<i32>, Vec2<u16>, &'a BlocksOfInterest);
type TranslucentPipeline = FluidPipeline;
#[allow(clippy::collapsible_if)]
@ -229,21 +233,42 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
fn generate_mesh(
self,
(range, max_texture_size): Self::Supplement,
(range, max_texture_size, boi): Self::Supplement,
) -> MeshGen<TerrainPipeline, FluidPipeline, Self> {
span!(
_guard,
"generate_mesh",
"<&VolGrid2d as Meshable<_, _>>::generate_mesh"
);
// Find blocks that should glow
// FIXME: Replace with real lit blocks when we actually have blocks that glow.
let lit_blocks = core::iter::empty();
// TODO: Search neighbouring chunks too!
// let glow_blocks = boi.lights
// .iter()
// .map(|(pos, glow)| (*pos + range.min.xy(), *glow));
/* DefaultVolIterator::new(self, range.min - MAX_LIGHT_DIST, range.max + MAX_LIGHT_DIST)
.filter_map(|(pos, block)| block.get_glow().map(|glow| (pos, glow))); */
let mut glow_blocks = Vec::new();
// TODO: This expensive, use BlocksOfInterest instead
let mut volume = self.cached();
for x in -MAX_LIGHT_DIST..range.size().w + MAX_LIGHT_DIST {
for y in -MAX_LIGHT_DIST..range.size().h + MAX_LIGHT_DIST {
for z in -1..range.size().d + 1 {
let wpos = range.min + Vec3::new(x, y, z);
volume
.get(wpos)
.ok()
.and_then(|b| b.get_glow())
.map(|glow| glow_blocks.push((wpos, glow)));
}
}
}
// Calculate chunk lighting
let mut light = calc_light(range, self, lit_blocks);
let mut light = calc_light(true, range, self, core::iter::empty());
let mut glow = calc_light(false, range, self, glow_blocks.into_iter());
let mut opaque_limits = None::<Limits>;
let mut fluid_limits = None::<Limits>;
@ -265,8 +290,9 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
for x in 0..range.size().w {
for y in 0..range.size().h {
for z in -1..range.size().d + 1 {
let wpos = range.min + Vec3::new(x, y, z);
let block = volume
.get(range.min + Vec3::new(x, y, z))
.get(wpos)
.map(|b| *b)
// TODO: Replace with None or some other more reasonable value,
// since it's not clear this will work properly with liquid.
@ -342,6 +368,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
let draw_delta = Vec3::new(1, 1, z_start);
let get_light = |_: &mut (), pos: Vec3<i32>| light(pos + range.min);
let get_glow = |_: &mut (), pos: Vec3<i32>| glow(pos + range.min);
let get_color =
|_: &mut (), pos: Vec3<i32>| flat_get(pos).get_color().unwrap_or(Rgb::zero());
let get_opacity = |_: &mut (), pos: Vec3<i32>| !flat_get(pos).is_opaque();
@ -365,6 +392,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
greedy_size,
greedy_size_cross,
get_light,
get_glow,
get_color,
get_opacity,
should_draw,

View File

@ -99,11 +99,34 @@ impl Vertex {
}
pub fn make_col_light(
// 0 to 31
light: u8,
// 0 to 31
glow: u8,
col: Rgb<u8>,
) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType
{
[col.r, col.g, col.b, light]
//[col.r, col.g, col.b, light]
// It would be nice for this to be cleaner, but we want to squeeze 5 fields into 4.
// We can do this because both `light` and `glow` go from 0 to 31, meaning that they
// can both fit into 5 bits. If we steal a bit from red and blue each (not green,
// human eyes are more sensitive to changes in green) then we get just enough to
// expand the nibbles of the alpha field enough to fit both `light` and `glow`.
//
// However, we now have a problem. In the shader code with use hardware filtering to
// get at the `light` and `glow` attributes (but not colour, that remains constant
// across a block). How to we resolve this if we're twiddling bits? The answer is to
// very carefully manipulate the bit pattern such that the fields we want to filter
// (`light` and `glow`) always sit as the lower bits of the fields. Then, we can do
// some modulation magic to extract them from the filtering unharmed and use
// unfiltered texture access (i.e: `texelFetch`) to access the colours, plus a little
// bit-fiddling.
[
((col.r & 0b1110) << 4) | light.min(31),
((col.b & 0b1110) << 4) | glow.min(31),
(col.r & 0b11110000) | (col.b >> 4),
col.g, // Green is lucky, it remains unscathed
]
}
}

View File

@ -67,7 +67,7 @@ pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm);
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
/// Represents the format of greedy meshed color-light textures.
pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
/// A handle to a shadow depth target.
pub type ShadowDepthStencilView =
@ -994,13 +994,18 @@ impl Renderer {
}
/// Update a texture with the provided offset, size, and data.
pub fn update_texture(
pub fn update_texture<T: gfx::format::Formatted>(
&mut self,
texture: &Texture,
texture: &Texture<T>,
offset: [u16; 2],
size: [u16; 2],
data: &[[u8; 4]],
) -> Result<(), RenderError> {
data: &[<<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType],
) -> Result<(), RenderError>
where
<T as gfx::format::Formatted>::Surface: gfx::format::TextureSurface,
<T as gfx::format::Formatted>::Channel: gfx::format::TextureChannel,
<<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
{
texture.update(&mut self.encoder, offset, size, data)
}

View File

@ -138,8 +138,9 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
sprite_config: &SpriteSpec,
) -> MeshWorkerResponse {
span!(_guard, "mesh_worker");
let blocks_of_interest = BlocksOfInterest::from_chunk(&chunk);
let (opaque_mesh, fluid_mesh, _shadow_mesh, (bounds, col_lights_info)) =
volume.generate_mesh((range, Vec2::new(max_texture_size, max_texture_size)));
volume.generate_mesh((range, Vec2::new(max_texture_size, max_texture_size), &blocks_of_interest));
MeshWorkerResponse {
pos,
z_bounds: (bounds.min.z, bounds.max.z),
@ -199,7 +200,7 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
instances
},
blocks_of_interest: BlocksOfInterest::from_chunk(&chunk),
blocks_of_interest,
started_tick,
}
}

View File

@ -17,6 +17,7 @@ pub struct BlocksOfInterest {
// Note: these are only needed for chunks within the iteraction range so this is a potential
// area for optimization
pub interactables: Vec<Vec3<i32>>,
pub lights: Vec<(Vec3<i32>, u8)>,
}
impl BlocksOfInterest {
@ -30,6 +31,7 @@ impl BlocksOfInterest {
let mut reeds = Vec::new();
let mut flowers = Vec::new();
let mut interactables = Vec::new();
let mut lights = Vec::new();
chunk
.vol_iter(
@ -73,6 +75,9 @@ impl BlocksOfInterest {
if block.is_collectible() {
interactables.push(pos);
}
if let Some(glow) = block.get_glow() {
lights.push((pos, glow));
}
});
Self {
@ -84,6 +89,7 @@ impl BlocksOfInterest {
reeds,
flowers,
interactables,
lights,
}
}
}