mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Higher detail LOD.
This commit is contained in:
parent
add2cfae04
commit
2101113b46
@ -46,7 +46,7 @@ flat out uint f_pos_norm;
|
||||
// out float f_light;
|
||||
// out vec3 light_pos[2];
|
||||
|
||||
const float EXTRA_NEG_Z = /*65536.0*/65536.1;
|
||||
const float EXTRA_NEG_Z = 65536.0/*65536.1*/;
|
||||
|
||||
void main() {
|
||||
f_pos = vec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0x1FFFFu)) - vec3(0, 0, EXTRA_NEG_Z) + model_offs - focus_off.xyz;
|
||||
|
@ -68,4 +68,6 @@
|
||||
/*
|
||||
// When sets, shadow maps are used to cast shadows.
|
||||
#define HAS_SHADOW_MAPS
|
||||
// When set, "full" LOD terrain informatino is available (e.g. terrain colors).
|
||||
#define HAS_LOD_FULL_INFO
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <sky.glsl>
|
||||
#include <srgb.glsl>
|
||||
|
||||
uniform sampler2D t_map;
|
||||
uniform sampler2D t_alt;
|
||||
uniform sampler2D t_horizon;
|
||||
|
||||
const float MIN_SHADOW = 0.33;
|
||||
@ -11,7 +11,7 @@ vec2 pos_to_uv(sampler2D sampler, vec2 pos) {
|
||||
// Want: (pixel + 0.5) / W
|
||||
vec2 texSize = textureSize(sampler, 0);
|
||||
vec2 uv_pos = (focus_off.xy + pos + 16) / (32.0 * texSize);
|
||||
return vec2(uv_pos.x, 1.0 - uv_pos.y);
|
||||
return vec2(uv_pos.x, /*1.0 - */uv_pos.y);
|
||||
}
|
||||
|
||||
vec2 pos_to_tex(vec2 pos) {
|
||||
@ -35,6 +35,7 @@ vec4 cubic(float v) {
|
||||
vec4 textureBicubic(sampler2D sampler, vec2 texCoords) {
|
||||
vec2 texSize = textureSize(sampler, 0);
|
||||
vec2 invTexSize = 1.0 / texSize;
|
||||
/* texCoords.y = texSize.y - texCoords.y; */
|
||||
|
||||
texCoords = texCoords/* * texSize */ - 0.5;
|
||||
|
||||
@ -52,8 +53,8 @@ vec4 textureBicubic(sampler2D sampler, vec2 texCoords) {
|
||||
vec4 offset = c + vec4 (xcubic.yw, ycubic.yw) / s;
|
||||
|
||||
offset *= invTexSize.xxyy;
|
||||
// Correct for map rotaton.
|
||||
offset.zw = 1.0 - offset.zw;
|
||||
/* // Correct for map rotaton.
|
||||
offset.zw = 1.0 - offset.zw; */
|
||||
|
||||
vec4 sample0 = texture(sampler, offset.xz);
|
||||
vec4 sample1 = texture(sampler, offset.yz);
|
||||
@ -73,7 +74,7 @@ vec4 textureBicubic(sampler2D sampler, vec2 texCoords) {
|
||||
}
|
||||
|
||||
float alt_at(vec2 pos) {
|
||||
return (texture/*textureBicubic*/(t_map, pos_to_uv(t_map, pos)).a * (/*1300.0*//*1278.7266845703125*/view_distance.w) + /*140.0*/view_distance.z - focus_off.z);
|
||||
return (/*round*/(texture/*textureBicubic*/(t_alt, pos_to_uv(t_alt, pos)).r * (/*1300.0*//*1278.7266845703125*/view_distance.w)) + /*140.0*/view_distance.z - focus_off.z);
|
||||
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
||||
|
||||
// return 0.0
|
||||
@ -87,7 +88,7 @@ float alt_at_real(vec2 pos) {
|
||||
// #if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||
// return alt_at(pos);
|
||||
// #elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||
return (textureBicubic(t_map, pos_to_tex(pos)).a * (/*1300.0*//*1278.7266845703125*/view_distance.w) + /*140.0*/view_distance.z - focus_off.z);
|
||||
return (/*round*/(textureBicubic(t_alt, pos_to_tex(pos)).r * (/*1300.0*//*1278.7266845703125*/view_distance.w)) + /*140.0*/view_distance.z - focus_off.z);
|
||||
// #endif
|
||||
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
||||
|
||||
@ -201,14 +202,14 @@ vec2 splay(vec2 pos) {
|
||||
const float SQRT_2 = sqrt(2.0) / 2.0;
|
||||
// /const float CBRT_2 = cbrt(2.0) / 2.0;
|
||||
// vec2 splayed = pos * (view_distance.x * SQRT_2 + pow(len * 0.5, 3.0) * (SPLAY_MULT - view_distance.x));
|
||||
vec2 splayed = pos * (view_distance.x * SQRT_2 + pow(len/* * SQRT_2*//* * 0.5*/, 3.0) * (textureSize(t_map, 0) * 32.0 - view_distance.x));
|
||||
vec2 splayed = pos * (view_distance.x * SQRT_2 + pow(len/* * SQRT_2*//* * 0.5*/, 3.0) * (textureSize(t_alt, 0) * 32.0 - view_distance.x));
|
||||
return splayed;
|
||||
|
||||
// Radial: pos.x = r - view_distance.x from focus_pos, pos.y = θ from cam_pos to focus_pos on xy plane.
|
||||
// const float PI_2 = 3.1415926535897932384626433832795;
|
||||
// float squared = pos.x * pos.x;
|
||||
// // // vec2 splayed2 = pos * vec2(squared * (SPLAY_MULT - view_distance.x), PI);
|
||||
// vec2 splayed2 = pos * vec2(squared * (textureSize(t_map, 0).x * 32.0 - view_distance.x), PI);
|
||||
// vec2 splayed2 = pos * vec2(squared * (textureSize(t_alt, 0).x * 32.0 - view_distance.x), PI);
|
||||
// float r = splayed2.x + view_distance.x;
|
||||
// vec2 theta = vec2(cos(splayed2.y), sin(splayed2.y));
|
||||
// return r * theta;
|
||||
@ -273,9 +274,14 @@ vec3 lod_pos(vec2 pos, vec2 focus_pos) {
|
||||
return vec3(hpos, alt_at_real(hpos));
|
||||
}
|
||||
|
||||
#ifdef HAS_LOD_FULL_INFO
|
||||
uniform sampler2D t_map;
|
||||
|
||||
vec3 lod_col(vec2 pos) {
|
||||
//return vec3(0, 0.5, 0);
|
||||
// return /*linear_to_srgb*/vec3(alt_at(pos), textureBicubic(t_map, pos_to_tex(pos)).gb);
|
||||
return /*linear_to_srgb*/(textureBicubic(t_map, pos_to_tex(pos)).rgb)
|
||||
;//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
|
||||
//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
|
||||
}
|
||||
#endif
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||
|
||||
#define HAS_LOD_FULL_INFO
|
||||
|
||||
#include <globals.glsl>
|
||||
#include <sky.glsl>
|
||||
#include <lod.glsl>
|
||||
|
@ -74,15 +74,18 @@ pub struct Client {
|
||||
client_state: ClientState,
|
||||
thread_pool: ThreadPool,
|
||||
pub server_info: ServerInfo,
|
||||
/// Just the "base" layer for LOD; currently includes colors and a 1-byte
|
||||
/// approximation for height. In the future we'll add more layers, like
|
||||
/// shadows, rivers, and probably foliage, cities, roads, and other
|
||||
/// structures.
|
||||
pub lod_base: Arc<DynamicImage>,
|
||||
/// Just the "base" layer for LOD; currently includes colors and nothing
|
||||
/// else. In the future we'll add more layers, like shadows, rivers, and
|
||||
/// probably foliage, cities, roads, and other structures.
|
||||
pub lod_base: Vec<u32>,
|
||||
/// The "height" layer for LOD; currently includes only land altitudes, but
|
||||
/// in the future should also water depth, and probably other
|
||||
/// information as well.
|
||||
pub lod_alt: Vec<u32>,
|
||||
/// The "shadow" layer for LOD. Includes east and west horizon angles and
|
||||
/// an approximate max occluder height, which we use to try to
|
||||
/// approximate soft and volumetric shadows.
|
||||
pub lod_horizon: Arc<DynamicImage>,
|
||||
pub lod_horizon: Vec<u32>,
|
||||
/// A fully rendered map image for use with the map and minimap; note that
|
||||
/// this can be constructed dynamically by combining the layers of world
|
||||
/// map data (e.g. with shadow map data or river data), but at present
|
||||
@ -92,7 +95,7 @@ pub struct Client {
|
||||
/// in chunks), and the third element holds the minimum height for any land
|
||||
/// chunk (i.e. the sea level) in its x coordinate, and the maximum land
|
||||
/// height above this height (i.e. the max height) in its y coordinate.
|
||||
pub world_map: (Arc<DynamicImage>, Vec2<u32>, Vec2<f32>),
|
||||
pub world_map: (Arc<DynamicImage>, Vec2<u16>, Vec2<f32>),
|
||||
pub player_list: HashMap<Uid, PlayerInfo>,
|
||||
pub character_list: CharacterList,
|
||||
pub active_character_id: Option<i32>,
|
||||
@ -144,182 +147,203 @@ impl Client {
|
||||
let mut stream = block_on(participant.open(10, PROMISES_ORDERED | PROMISES_CONSISTENCY))?;
|
||||
|
||||
// Wait for initial sync
|
||||
let (state, entity, server_info, lod_base, lod_horizon, world_map) = block_on(async {
|
||||
loop {
|
||||
match stream.recv().await? {
|
||||
ServerMsg::InitialSync {
|
||||
entity_package,
|
||||
server_info,
|
||||
time_of_day,
|
||||
world_map,
|
||||
} => {
|
||||
// TODO: Display that versions don't match in Voxygen
|
||||
if &server_info.git_hash != *common::util::GIT_HASH {
|
||||
warn!(
|
||||
"Server is running {}[{}], you are running {}[{}], versions might \
|
||||
be incompatible!",
|
||||
server_info.git_hash,
|
||||
server_info.git_date,
|
||||
common::util::GIT_HASH.to_string(),
|
||||
common::util::GIT_DATE.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
debug!("Auth Server: {:?}", server_info.auth_provider);
|
||||
|
||||
// Initialize `State`
|
||||
let mut state = State::default();
|
||||
// Client-only components
|
||||
state
|
||||
.ecs_mut()
|
||||
.register::<comp::Last<comp::CharacterState>>();
|
||||
|
||||
let entity = state.ecs_mut().apply_entity_package(entity_package);
|
||||
*state.ecs_mut().write_resource() = time_of_day;
|
||||
|
||||
let map_size = world_map.dimensions;
|
||||
let max_height = world_map.max_height;
|
||||
let rgba = world_map.rgba;
|
||||
assert_eq!(rgba.len(), (map_size.x * map_size.y) as usize);
|
||||
let [west, east] = world_map.horizons;
|
||||
let scale_angle =
|
||||
|a: u8| (a as Alt / 255.0 * <Alt as FloatConst>::FRAC_PI_2()).tan();
|
||||
let scale_height = |h: u8| h as Alt / 255.0 * max_height as Alt;
|
||||
|
||||
debug!("Preparing image...");
|
||||
let unzip_horizons = |(angles, heights): &(Vec<_>, Vec<_>)| {
|
||||
(
|
||||
angles.iter().copied().map(scale_angle).collect::<Vec<_>>(),
|
||||
heights
|
||||
.iter()
|
||||
.copied()
|
||||
.map(scale_height)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
};
|
||||
let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
|
||||
|
||||
// Redraw map (with shadows this time).
|
||||
let mut world_map = vec![0u32; rgba.len()];
|
||||
let mut map_config = world::sim::MapConfig::default();
|
||||
map_config.lgain = 1.0;
|
||||
map_config.gain = max_height;
|
||||
map_config.horizons = Some(&horizons);
|
||||
// map_config.light_direction = Vec3::new(1.0, -1.0, 0.0);
|
||||
map_config.focus.z = 0.0;
|
||||
let rescale_height = |h: Alt| (h / max_height as Alt) as f32;
|
||||
let bounds_check = |pos: Vec2<i32>| {
|
||||
pos.reduce_partial_min() >= 0
|
||||
&& pos.x < map_size.x as i32
|
||||
&& pos.y < map_size.y as i32
|
||||
};
|
||||
map_config.generate(
|
||||
|pos| {
|
||||
let (rgba, downhill_wpos) = if bounds_check(pos) {
|
||||
let posi =
|
||||
pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
let [r, g, b, a] = rgba[posi].to_le_bytes();
|
||||
// Compute downhill.
|
||||
let downhill = {
|
||||
let mut best = -1;
|
||||
let mut besth = a;
|
||||
// TODO: Fix to work for dynamic WORLD_SIZE (i.e. map_size).
|
||||
for nposi in neighbors(posi) {
|
||||
let nbh = rgba[nposi].to_le_bytes()[3];
|
||||
if nbh < besth {
|
||||
besth = nbh;
|
||||
best = nposi as isize;
|
||||
}
|
||||
}
|
||||
best
|
||||
};
|
||||
let downhill_wpos = if downhill < 0 {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
Vec2::new(
|
||||
(downhill as usize % map_size.x as usize) as i32,
|
||||
(downhill as usize / map_size.x as usize) as i32,
|
||||
) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
)
|
||||
};
|
||||
(Rgba::new(r, g, b, a), downhill_wpos)
|
||||
} else {
|
||||
(Rgba::zero(), None)
|
||||
};
|
||||
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||
let downhill_wpos = downhill_wpos.unwrap_or(
|
||||
wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
let (state, entity, server_info, lod_base, lod_alt, lod_horizon, world_map) = block_on(
|
||||
async {
|
||||
loop {
|
||||
match stream.recv().await? {
|
||||
ServerMsg::InitialSync {
|
||||
entity_package,
|
||||
server_info,
|
||||
time_of_day,
|
||||
world_map,
|
||||
} => {
|
||||
// TODO: Display that versions don't match in Voxygen
|
||||
if &server_info.git_hash != *common::util::GIT_HASH {
|
||||
warn!(
|
||||
"Server is running {}[{}], you are running {}[{}], versions \
|
||||
might be incompatible!",
|
||||
server_info.git_hash,
|
||||
server_info.git_date,
|
||||
common::util::GIT_HASH.to_string(),
|
||||
common::util::GIT_DATE.to_string(),
|
||||
);
|
||||
let alt = rescale_height(scale_height(rgba.a));
|
||||
world::sim::MapSample {
|
||||
rgb: Rgb::from(rgba),
|
||||
alt: alt as Alt,
|
||||
downhill_wpos,
|
||||
connections: None,
|
||||
}
|
||||
},
|
||||
|wpos| {
|
||||
let pos =
|
||||
wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
||||
rescale_height(if bounds_check(pos) {
|
||||
let posi =
|
||||
pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
scale_height(rgba[posi].to_le_bytes()[3])
|
||||
} else {
|
||||
0.0
|
||||
})
|
||||
},
|
||||
|pos, (r, g, b, a)| {
|
||||
world_map[pos.y * map_size.x as usize + pos.x] =
|
||||
u32::from_le_bytes([r, g, b, a]);
|
||||
},
|
||||
);
|
||||
let make_raw = |rgba| -> Result<_, Error> {
|
||||
let mut raw = vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/];
|
||||
LittleEndian::write_u32_into(rgba, &mut raw);
|
||||
Ok(Arc::new(
|
||||
image::DynamicImage::ImageRgba8({
|
||||
}
|
||||
|
||||
debug!("Auth Server: {:?}", server_info.auth_provider);
|
||||
|
||||
// Initialize `State`
|
||||
let mut state = State::default();
|
||||
// Client-only components
|
||||
state
|
||||
.ecs_mut()
|
||||
.register::<comp::Last<comp::CharacterState>>();
|
||||
|
||||
let entity = state.ecs_mut().apply_entity_package(entity_package);
|
||||
*state.ecs_mut().write_resource() = time_of_day;
|
||||
|
||||
let map_size = world_map.dimensions;
|
||||
let max_height = world_map.max_height;
|
||||
let rgba = world_map.rgba;
|
||||
let alt = world_map.alt;
|
||||
let expected_size =
|
||||
(u32::from(map_size.x) * u32::from(map_size.y)) as usize;
|
||||
if rgba.len() != expected_size {
|
||||
return Err(Error::Other(
|
||||
"Server sent a bad world map image".into(),
|
||||
));
|
||||
}
|
||||
if alt.len() != expected_size {
|
||||
return Err(Error::Other("Server sent a bad altitude map.".into()));
|
||||
}
|
||||
let [west, east] = world_map.horizons;
|
||||
let scale_angle =
|
||||
|a: u8| (a as Alt / 255.0 * <Alt as FloatConst>::FRAC_PI_2()).tan();
|
||||
let scale_height = |h: u8| h as Alt / 255.0 * max_height as Alt;
|
||||
let scale_height_big =
|
||||
|h: u32| (h >> 3) as Alt / 8191.0 * max_height as Alt;
|
||||
|
||||
debug!("Preparing image...");
|
||||
let unzip_horizons = |(angles, heights): &(Vec<_>, Vec<_>)| {
|
||||
(
|
||||
angles.iter().copied().map(scale_angle).collect::<Vec<_>>(),
|
||||
heights
|
||||
.iter()
|
||||
.copied()
|
||||
.map(scale_height)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
};
|
||||
let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
|
||||
|
||||
// Redraw map (with shadows this time).
|
||||
let mut world_map = vec![0u32; rgba.len()];
|
||||
let mut map_config = world::sim::MapConfig::default();
|
||||
map_config.lgain = 1.0;
|
||||
map_config.gain = max_height;
|
||||
map_config.horizons = Some(&horizons);
|
||||
// map_config.light_direction = Vec3::new(1.0, -1.0, 0.0);
|
||||
map_config.focus.z = 0.0;
|
||||
let rescale_height = |h: Alt| (h / max_height as Alt) as f32;
|
||||
let bounds_check = |pos: Vec2<i32>| {
|
||||
pos.reduce_partial_min() >= 0
|
||||
&& pos.x < map_size.x as i32
|
||||
&& pos.y < map_size.y as i32
|
||||
};
|
||||
map_config.generate(
|
||||
|pos| {
|
||||
let (rgba, alt, downhill_wpos) = if bounds_check(pos) {
|
||||
let posi =
|
||||
pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
let [r, g, b, a] = rgba[posi].to_le_bytes();
|
||||
let alti = alt[posi];
|
||||
// Compute downhill.
|
||||
let downhill = {
|
||||
let mut best = -1;
|
||||
let mut besth = alti;
|
||||
// TODO: Fix to work for dynamic WORLD_SIZE (i.e.
|
||||
// map_size).
|
||||
for nposi in neighbors(posi) {
|
||||
let nbh = alt[nposi];
|
||||
if nbh < besth {
|
||||
besth = nbh;
|
||||
best = nposi as isize;
|
||||
}
|
||||
}
|
||||
best
|
||||
};
|
||||
let downhill_wpos = if downhill < 0 {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
Vec2::new(
|
||||
(downhill as usize % map_size.x as usize)
|
||||
as i32,
|
||||
(downhill as usize / map_size.x as usize)
|
||||
as i32,
|
||||
) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
)
|
||||
};
|
||||
(Rgba::new(r, g, b, a), alti, downhill_wpos)
|
||||
} else {
|
||||
(Rgba::zero(), 0, None)
|
||||
};
|
||||
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||
let downhill_wpos = downhill_wpos.unwrap_or(
|
||||
wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
);
|
||||
let alt = rescale_height(scale_height_big(alt));
|
||||
world::sim::MapSample {
|
||||
rgb: Rgb::from(rgba),
|
||||
alt: alt as Alt,
|
||||
downhill_wpos,
|
||||
connections: None,
|
||||
}
|
||||
},
|
||||
|wpos| {
|
||||
let pos =
|
||||
wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
||||
rescale_height(if bounds_check(pos) {
|
||||
let posi =
|
||||
pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
scale_height_big(alt[posi])
|
||||
} else {
|
||||
0.0
|
||||
})
|
||||
},
|
||||
|pos, (r, g, b, a)| {
|
||||
world_map[pos.y * map_size.x as usize + pos.x] =
|
||||
u32::from_le_bytes([r, g, b, a]);
|
||||
},
|
||||
);
|
||||
let make_raw = |rgba| -> Result<_, Error> {
|
||||
let mut raw =
|
||||
vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/];
|
||||
LittleEndian::write_u32_into(rgba, &mut raw);
|
||||
Ok(Arc::new(
|
||||
image::DynamicImage::ImageRgba8({
|
||||
// Should not fail if the dimensions are correct.
|
||||
let map =
|
||||
image::ImageBuffer::from_raw(map_size.x, map_size.y, raw);
|
||||
image::ImageBuffer::from_raw(u32::from(map_size.x), u32::from(map_size.y), raw);
|
||||
map.ok_or(Error::Other("Server sent a bad world map image".into()))?
|
||||
})
|
||||
// Flip the image, since Voxygen uses an orientation where rotation from
|
||||
// positive x axis to positive y axis is counterclockwise around the z axis.
|
||||
.flipv(),
|
||||
))
|
||||
};
|
||||
let lod_base = make_raw(&rgba)?;
|
||||
let world_map = make_raw(&world_map)?;
|
||||
let horizons = (west.0, west.1, east.0, east.1)
|
||||
.into_par_iter()
|
||||
.map(|(wa, wh, ea, eh)| u32::from_le_bytes([wa, wh, ea, eh]))
|
||||
.collect::<Vec<_>>();
|
||||
let lod_horizon = make_raw(&horizons)?;
|
||||
// TODO: Get sea_level from server.
|
||||
let map_bounds = Vec2::new(
|
||||
/* map_config.focus.z */ world::CONFIG.sea_level,
|
||||
/* map_config.gain */ max_height,
|
||||
);
|
||||
debug!("Done preparing image...");
|
||||
))
|
||||
};
|
||||
let lod_base = rgba; //make_raw(&rgba)?;
|
||||
let lod_alt = alt; //make_raw(&alt)?;
|
||||
let world_map = make_raw(&world_map)?;
|
||||
let horizons = (west.0, west.1, east.0, east.1)
|
||||
.into_par_iter()
|
||||
.map(|(wa, wh, ea, eh)| u32::from_le_bytes([wa, wh, ea, eh]))
|
||||
.collect::<Vec<_>>();
|
||||
let lod_horizon = horizons; //make_raw(&horizons)?;
|
||||
// TODO: Get sea_level from server.
|
||||
let map_bounds = Vec2::new(
|
||||
/* map_config.focus.z */ world::CONFIG.sea_level,
|
||||
/* map_config.gain */ max_height,
|
||||
);
|
||||
debug!("Done preparing image...");
|
||||
|
||||
break Ok((
|
||||
state,
|
||||
entity,
|
||||
server_info,
|
||||
lod_base,
|
||||
lod_horizon,
|
||||
(world_map, map_size, map_bounds),
|
||||
));
|
||||
},
|
||||
ServerMsg::TooManyPlayers => break Err(Error::TooManyPlayers),
|
||||
err => {
|
||||
warn!("whoops, server mad {:?}, ignoring", err);
|
||||
},
|
||||
break Ok((
|
||||
state,
|
||||
entity,
|
||||
server_info,
|
||||
lod_base,
|
||||
lod_alt,
|
||||
lod_horizon,
|
||||
(world_map, map_size, map_bounds),
|
||||
));
|
||||
},
|
||||
ServerMsg::TooManyPlayers => break Err(Error::TooManyPlayers),
|
||||
err => {
|
||||
warn!("whoops, server mad {:?}, ignoring", err);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
|
||||
stream.send(ClientMsg::Ping)?;
|
||||
|
||||
@ -335,6 +359,7 @@ impl Client {
|
||||
server_info,
|
||||
world_map,
|
||||
lod_base,
|
||||
lod_alt,
|
||||
lod_horizon,
|
||||
player_list: HashMap::new(),
|
||||
character_list: CharacterList::default(),
|
||||
|
@ -65,12 +65,17 @@ pub struct CharacterInfo {
|
||||
/// shadow maps intended for height maps.
|
||||
pub struct WorldMapMsg {
|
||||
/// World map dimensions (width × height)
|
||||
pub dimensions: Vec2<u32>,
|
||||
pub dimensions: Vec2<u16>,
|
||||
/// Max height (used to scale altitudes).
|
||||
pub max_height: f32,
|
||||
/// RGB+A; the alpha channel is currently a proxy for altitude.
|
||||
/// Entries are in the usual chunk order.
|
||||
/// RGB+A; the alpha channel is currently unused, but will be used in the
|
||||
/// future. Entries are in the usual chunk order.
|
||||
pub rgba: Vec<u32>,
|
||||
/// Altitudes: bits 2 to 0 are unused, then bits 15 to 3 are used for
|
||||
/// altitude. The remainder are currently unused, but we have plans to
|
||||
/// use 7 bits for water depth (using an integer f7 encoding), and we
|
||||
/// will find other uses for the remaining 12 bits.
|
||||
pub alt: Vec<u32>,
|
||||
/// Horizon mapping. This is a variant of shadow mapping that is
|
||||
/// specifically designed for height maps; it takes advantage of their
|
||||
/// regular structure (e.g. no holes) to compress all information needed
|
||||
|
@ -508,7 +508,7 @@ impl Hud {
|
||||
// Load world map
|
||||
let world_map = (
|
||||
ui.add_graphic_with_rotations(Graphic::Image(client.world_map.0.clone())),
|
||||
client.world_map.1,
|
||||
client.world_map.1.map(u32::from),
|
||||
);
|
||||
// Load images.
|
||||
let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
|
||||
|
@ -36,8 +36,8 @@ pub use self::{
|
||||
Globals, Light, Shadow,
|
||||
},
|
||||
renderer::{
|
||||
ColLightFmt, ColLightInfo, LodColorFmt, LodTextureFmt, Renderer, ShadowDepthStencilFmt,
|
||||
TgtColorFmt, TgtDepthStencilFmt, WinColorFmt, WinDepthFmt,
|
||||
ColLightFmt, ColLightInfo, LodAltFmt, LodColorFmt, LodTextureFmt, Renderer,
|
||||
ShadowDepthStencilFmt, TgtColorFmt, TgtDepthStencilFmt, WinColorFmt, WinDepthFmt,
|
||||
},
|
||||
texture::Texture,
|
||||
};
|
||||
|
@ -50,7 +50,7 @@ gfx_defines! {
|
||||
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_shadow_maps",
|
||||
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
@ -25,7 +25,7 @@ gfx_defines! {
|
||||
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_shadow_maps",
|
||||
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
@ -23,6 +23,7 @@ gfx_defines! {
|
||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
@ -33,7 +33,7 @@ gfx_defines! {
|
||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
// map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_map",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
@ -58,7 +58,7 @@ gfx_defines! {
|
||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
// map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_map",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
@ -22,7 +22,7 @@ gfx_defines! {
|
||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
@ -62,7 +62,7 @@ gfx_defines! {
|
||||
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_shadow_maps",
|
||||
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
@ -35,7 +35,7 @@ gfx_defines! {
|
||||
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_shadow_maps",
|
||||
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
@ -51,6 +51,9 @@ pub type WinDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources, Wi
|
||||
/// Represents the format of LOD shadows.
|
||||
pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); //[gfx::format::U8Norm; 4];
|
||||
|
||||
/// Represents the format of LOD altitudes.
|
||||
pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm); //[gfx::format::U8Norm; 4];
|
||||
|
||||
/// Represents the format of LOD map colors.
|
||||
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb); //[gfx::format::U8Norm; 4];
|
||||
|
||||
@ -1081,7 +1084,7 @@ impl Renderer {
|
||||
model: &Model<skybox::SkyboxPipeline>,
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<skybox::Locals>,
|
||||
map: &Texture<LodColorFmt>,
|
||||
alt: &Texture<LodAltFmt>,
|
||||
horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
@ -1098,7 +1101,7 @@ impl Renderer {
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||
@ -1117,7 +1120,7 @@ impl Renderer {
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
light_shadows: &Consts<shadow::Locals>,
|
||||
map: &Texture<LodColorFmt>,
|
||||
alt: &Texture<LodAltFmt>,
|
||||
horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
// return;
|
||||
@ -1157,7 +1160,7 @@ impl Renderer {
|
||||
vbuf: model.vbuf.clone(),
|
||||
// abuf: atlas_model.vbuf.clone(),
|
||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||
// col_lights: (map.srv.clone(), map.sampler.clone()),
|
||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
bones: bones.buf.clone(),
|
||||
@ -1167,7 +1170,7 @@ impl Renderer {
|
||||
point_shadow_maps,
|
||||
directed_shadow_maps,
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||
@ -1186,7 +1189,7 @@ impl Renderer {
|
||||
_lights: &Consts<Light>,
|
||||
_shadows: &Consts<Shadow>,
|
||||
_light_shadows: &Consts<shadow::Locals>,
|
||||
_map: &Texture<LodColorFmt>,
|
||||
_alt: &Texture<LodAltFmt>,
|
||||
_horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
return;
|
||||
@ -1226,7 +1229,7 @@ impl Renderer {
|
||||
vbuf: model.vbuf.clone(),
|
||||
// abuf: atlas_model.vbuf.clone(),
|
||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||
// col_lights: (map.srv.clone(), map.sampler.clone()),
|
||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
bones: bones.buf.clone(),
|
||||
@ -1236,7 +1239,7 @@ impl Renderer {
|
||||
point_shadow_maps,
|
||||
directed_shadow_maps,
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (0, 0) */),
|
||||
@ -1255,7 +1258,7 @@ impl Renderer {
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
light_shadows: &Consts<shadow::Locals>,
|
||||
map: &Texture<LodColorFmt>,
|
||||
alt: &Texture<LodAltFmt>,
|
||||
horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
let (point_shadow_maps, directed_shadow_maps) =
|
||||
@ -1294,7 +1297,7 @@ impl Renderer {
|
||||
vbuf: model.vbuf.clone(),
|
||||
// abuf: atlas_model.vbuf.clone(),
|
||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||
// col_lights: (map.srv.clone(), map.sampler.clone()),
|
||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
bones: bones.buf.clone(),
|
||||
@ -1304,7 +1307,7 @@ impl Renderer {
|
||||
point_shadow_maps,
|
||||
directed_shadow_maps,
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||
@ -1325,7 +1328,7 @@ impl Renderer {
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
light_shadows: &Consts<shadow::Locals>,
|
||||
map: &Texture<LodColorFmt>,
|
||||
alt: &Texture<LodAltFmt>,
|
||||
horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
let (point_shadow_maps, directed_shadow_maps) =
|
||||
@ -1362,7 +1365,7 @@ impl Renderer {
|
||||
// since we don't need it for things like shadows.
|
||||
// abuf: atlas_model.vbuf.clone(),
|
||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||
// col_lights: (map.srv.clone(), map.sampler.clone()),
|
||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
lights: lights.buf.clone(),
|
||||
@ -1371,7 +1374,7 @@ impl Renderer {
|
||||
point_shadow_maps,
|
||||
directed_shadow_maps,
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||
@ -1390,7 +1393,7 @@ impl Renderer {
|
||||
locals: &Consts<shadow::Locals>,
|
||||
/* lights: &Consts<Light>,
|
||||
* shadows: &Consts<Shadow>,
|
||||
* map: &Texture<LodColorFmt>,
|
||||
* alt: &Texture<LodAltFmt>,
|
||||
* horizon: &Texture<LodTextureFmt>, */
|
||||
) {
|
||||
if !self.mode.shadow.is_map() {
|
||||
@ -1422,7 +1425,7 @@ impl Renderer {
|
||||
// lights: lights.buf.clone(),
|
||||
// shadows: shadows.buf.clone(),
|
||||
// noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
// map: (map.srv.clone(), map.sampler.clone()),
|
||||
// alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
// horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
|
||||
// Shadow stuff
|
||||
@ -1445,7 +1448,7 @@ impl Renderer {
|
||||
locals: &Consts<shadow::Locals>,
|
||||
/* lights: &Consts<Light>,
|
||||
* shadows: &Consts<Shadow>,
|
||||
* map: &Texture<LodColorFmt>,
|
||||
* alt: &Texture<LodAltFmt>,
|
||||
* horizon: &Texture<LodTextureFmt>, */
|
||||
) {
|
||||
if !self.mode.shadow.is_map() {
|
||||
@ -1477,7 +1480,7 @@ impl Renderer {
|
||||
// lights: lights.buf.clone(),
|
||||
// shadows: shadows.buf.clone(),
|
||||
// noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
// map: (map.srv.clone(), map.sampler.clone()),
|
||||
// alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
// horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
|
||||
// Shadow stuff
|
||||
@ -1501,7 +1504,7 @@ impl Renderer {
|
||||
locals: &Consts<shadow::Locals>,
|
||||
/* lights: &Consts<Light>,
|
||||
* shadows: &Consts<Shadow>,
|
||||
* map: &Texture<LodColorFmt>,
|
||||
* alt: &Texture<LodAltFmt>,
|
||||
* horizon: &Texture<LodTextureFmt>, */
|
||||
) {
|
||||
if !self.mode.shadow.is_map() {
|
||||
@ -1535,7 +1538,7 @@ impl Renderer {
|
||||
// lights: lights.buf.clone(),
|
||||
// shadows: shadows.buf.clone(),
|
||||
// noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
// map: (map.srv.clone(), map.sampler.clone()),
|
||||
// alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
// horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
|
||||
// Shadow stuff
|
||||
@ -1557,7 +1560,7 @@ impl Renderer {
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
light_shadows: &Consts<shadow::Locals>,
|
||||
map: &Texture<LodColorFmt>,
|
||||
alt: &Texture<LodAltFmt>,
|
||||
horizon: &Texture<LodTextureFmt>,
|
||||
waves: &Texture,
|
||||
) {
|
||||
@ -1598,7 +1601,7 @@ impl Renderer {
|
||||
light_shadows: light_shadows.buf.clone(),
|
||||
point_shadow_maps,
|
||||
directed_shadow_maps,
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
waves: (waves.srv.clone(), waves.sampler.clone()),
|
||||
@ -1623,7 +1626,7 @@ impl Renderer {
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
light_shadows: &Consts<shadow::Locals>,
|
||||
map: &Texture<LodColorFmt>,
|
||||
alt: &Texture<LodAltFmt>,
|
||||
horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
let (point_shadow_maps, directed_shadow_maps) =
|
||||
@ -1668,7 +1671,7 @@ impl Renderer {
|
||||
point_shadow_maps,
|
||||
directed_shadow_maps,
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||
@ -1684,6 +1687,7 @@ impl Renderer {
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<lod_terrain::Locals>,
|
||||
map: &Texture<LodColorFmt>,
|
||||
alt: &Texture<LodAltFmt>,
|
||||
horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
@ -1701,6 +1705,7 @@ impl Renderer {
|
||||
globals: globals.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||
|
@ -2013,7 +2013,7 @@ impl FigureMgr {
|
||||
lights,
|
||||
shadows,
|
||||
shadow_mats,
|
||||
&lod.map,
|
||||
&lod.alt,
|
||||
&lod.horizon,
|
||||
);
|
||||
}
|
||||
@ -2077,7 +2077,7 @@ impl FigureMgr {
|
||||
lights,
|
||||
shadows,
|
||||
shadow_mats,
|
||||
&lod.map,
|
||||
&lod.alt,
|
||||
&lod.horizon,
|
||||
);
|
||||
renderer.render_player_shadow(
|
||||
@ -2089,7 +2089,7 @@ impl FigureMgr {
|
||||
lights,
|
||||
shadows,
|
||||
shadow_mats,
|
||||
&lod.map,
|
||||
&lod.alt,
|
||||
&lod.horizon,
|
||||
);
|
||||
}
|
||||
|
@ -1,17 +1,19 @@
|
||||
use crate::{
|
||||
render::{
|
||||
pipelines::lod_terrain::{Locals, Vertex},
|
||||
Consts, FilterMethod, Globals, LodColorFmt, LodTerrainPipeline, LodTextureFmt, Mesh, Model,
|
||||
Quad, Renderer, Texture, WrapMode,
|
||||
Consts, Globals, LodAltFmt, LodColorFmt, LodTerrainPipeline, LodTextureFmt, Mesh, Model,
|
||||
Quad, Renderer, Texture,
|
||||
},
|
||||
settings::Settings,
|
||||
};
|
||||
use client::Client;
|
||||
use common::{spiral::Spiral2d, util::srgba_to_linear};
|
||||
use gfx::texture::SamplerInfo;
|
||||
use vek::*;
|
||||
|
||||
pub struct LodData {
|
||||
pub map: Texture<LodColorFmt>,
|
||||
pub alt: Texture<LodAltFmt>,
|
||||
pub horizon: Texture<LodTextureFmt>,
|
||||
pub tgt_detail: u32,
|
||||
}
|
||||
@ -25,28 +27,54 @@ pub struct Lod {
|
||||
impl LodData {
|
||||
pub fn new(
|
||||
renderer: &mut Renderer,
|
||||
lod_base: &image::DynamicImage,
|
||||
lod_horizon: &image::DynamicImage,
|
||||
map_size: Vec2<u16>,
|
||||
lod_base: &[u32],
|
||||
lod_alt: &[u32],
|
||||
lod_horizon: &[u32],
|
||||
tgt_detail: u32,
|
||||
border_color: gfx::texture::PackedColor,
|
||||
) -> Self {
|
||||
let kind = gfx::texture::Kind::D2(map_size.x, map_size.y, gfx::texture::AaMode::Single);
|
||||
let info = gfx::texture::SamplerInfo::new(
|
||||
gfx::texture::FilterMethod::Bilinear,
|
||||
gfx::texture::WrapMode::Border,
|
||||
);
|
||||
Self {
|
||||
map: renderer
|
||||
.create_texture(
|
||||
lod_base,
|
||||
Some(FilterMethod::Bilinear),
|
||||
Some(WrapMode::Border),
|
||||
Some(border_color),
|
||||
.create_texture_immutable_raw(
|
||||
kind,
|
||||
gfx::texture::Mipmap::Provided,
|
||||
&[gfx::memory::cast_slice(lod_base)],
|
||||
SamplerInfo {
|
||||
border: border_color,
|
||||
..info
|
||||
},
|
||||
)
|
||||
.expect("Failed to generate map texture"),
|
||||
alt: renderer
|
||||
.create_texture_immutable_raw(
|
||||
kind,
|
||||
gfx::texture::Mipmap::Provided,
|
||||
&[gfx::memory::cast_slice(lod_alt)],
|
||||
SamplerInfo {
|
||||
border: [0.0, 0.0, 0.0, 0.0].into(),
|
||||
..info
|
||||
},
|
||||
)
|
||||
.expect("Failed to generate alt texture"),
|
||||
horizon: renderer
|
||||
.create_texture(
|
||||
lod_horizon,
|
||||
Some(FilterMethod::Trilinear),
|
||||
Some(WrapMode::Border),
|
||||
Some([0.0, 1.0, 0.0, 1.0].into()),
|
||||
.create_texture_immutable_raw(
|
||||
kind,
|
||||
gfx::texture::Mipmap::Provided,
|
||||
&[gfx::memory::cast_slice(lod_horizon)],
|
||||
SamplerInfo {
|
||||
// filter: gfx::texture::FilterMethod::Nearest,
|
||||
// filter: gfx::texture::FilterMethod::TriLinear,
|
||||
border: [1.0, 0.0, 1.0, 0.0].into(),
|
||||
..info
|
||||
},
|
||||
)
|
||||
.expect("Failed to generate map texture"),
|
||||
.expect("Failed to generate horizon texture"),
|
||||
tgt_detail,
|
||||
}
|
||||
}
|
||||
@ -60,7 +88,9 @@ impl Lod {
|
||||
locals: renderer.create_consts(&[Locals::default()]).unwrap(),
|
||||
data: LodData::new(
|
||||
renderer,
|
||||
client.world_map.1,
|
||||
&client.lod_base,
|
||||
&client.lod_alt,
|
||||
&client.lod_horizon,
|
||||
settings.graphics.lod_detail.max(100).min(2500),
|
||||
[water_color.r, water_color.g, water_color.b, water_color.a].into(),
|
||||
@ -95,6 +125,7 @@ impl Lod {
|
||||
globals,
|
||||
&self.locals,
|
||||
&self.data.map,
|
||||
&self.data.alt,
|
||||
&self.data.horizon,
|
||||
);
|
||||
}
|
||||
|
@ -1512,7 +1512,7 @@ impl Scene {
|
||||
&self.skybox.model,
|
||||
&self.globals,
|
||||
&self.skybox.locals,
|
||||
&lod.map,
|
||||
&lod.alt,
|
||||
&lod.horizon,
|
||||
);
|
||||
|
||||
|
@ -105,16 +105,19 @@ impl Scene {
|
||||
|
||||
let map_bounds = Vec2::new(-65536.0, 131071.0);
|
||||
let map_border = [0.0, 0.0, 0.0, 0.0];
|
||||
let map_image = image::DynamicImage::ImageRgba8(image::RgbaImage::from_pixel(
|
||||
/* let map_image = image::DynamicImage::ImageRgba8(image::RgbaImage::from_pixel(
|
||||
1,
|
||||
1,
|
||||
image::Rgba([0, 0, 0, 0]),
|
||||
));
|
||||
let horizon_image = image::DynamicImage::ImageRgba8(image::RgbaImage::from_pixel(
|
||||
)); */
|
||||
let map_image = [0];
|
||||
let alt_image = [0];
|
||||
/* let horizon_image = image::DynamicImage::ImageRgba8(image::RgbaImage::from_pixel(
|
||||
1,
|
||||
1,
|
||||
image::Rgba([0, 1, 0, 1]),
|
||||
));
|
||||
)); */
|
||||
let horizon_image = [0x_00_01_00_01];
|
||||
|
||||
let mut camera = Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson);
|
||||
camera.set_focus_pos(Vec3::unit_z() * 1.5);
|
||||
@ -139,7 +142,7 @@ impl Scene {
|
||||
.create_consts(&[PostProcessLocals::default()])
|
||||
.unwrap(),
|
||||
},
|
||||
lod: LodData::new(renderer, &map_image, &horizon_image, 1, map_border.into()),// Lod::new(renderer, client, settings),
|
||||
lod: LodData::new(renderer, Vec2::new(1, 1), &map_image, &alt_image, &horizon_image, 1, map_border.into()),// Lod::new(renderer, client, settings),
|
||||
map_bounds,//: client.world_map.2,
|
||||
|
||||
figure_model_cache: FigureModelCache::new(),
|
||||
@ -333,7 +336,7 @@ impl Scene {
|
||||
&self.skybox.model,
|
||||
&self.globals,
|
||||
&self.skybox.locals,
|
||||
&self.lod.map,
|
||||
&self.lod.alt,
|
||||
&self.lod.horizon,
|
||||
);
|
||||
|
||||
@ -360,7 +363,7 @@ impl Scene {
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
&self.shadow_mats,
|
||||
&self.lod.map,
|
||||
&self.lod.alt,
|
||||
&self.lod.horizon,
|
||||
);
|
||||
}
|
||||
@ -375,7 +378,7 @@ impl Scene {
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
&self.shadow_mats,
|
||||
&self.lod.map,
|
||||
&self.lod.alt,
|
||||
&self.lod.horizon,
|
||||
);
|
||||
}
|
||||
|
@ -3126,7 +3126,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
shadow_mats,
|
||||
/* lights, */
|
||||
/* shadows,
|
||||
* &lod.map,
|
||||
* &lod.alt,
|
||||
* &lod.horizon, */
|
||||
);
|
||||
});
|
||||
@ -3148,7 +3148,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
shadow_mats,
|
||||
/* lights, */
|
||||
/* shadows,
|
||||
* &lod.map,
|
||||
* &lod.alt,
|
||||
* &lod.horizon, */
|
||||
);
|
||||
}
|
||||
@ -3210,7 +3210,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
shadow_mats,
|
||||
// lights,
|
||||
// shadows,
|
||||
// &lod.map,
|
||||
// &lod.alt,
|
||||
// &lod.horizon,
|
||||
);
|
||||
}
|
||||
@ -3229,7 +3229,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
shadow_mats,
|
||||
// lights,
|
||||
// shadows,
|
||||
// &lod.map,
|
||||
// &lod.alt,
|
||||
// &lod.horizon,
|
||||
);
|
||||
}
|
||||
@ -3258,7 +3258,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
lights,
|
||||
shadows,
|
||||
shadow_mats,
|
||||
&lod.map,
|
||||
&lod.alt,
|
||||
&lod.horizon,
|
||||
);
|
||||
}
|
||||
@ -3362,7 +3362,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
lights,
|
||||
shadows,
|
||||
shadow_mats,
|
||||
&lod.map,
|
||||
&lod.alt,
|
||||
&lod.horizon,
|
||||
);
|
||||
}
|
||||
@ -3391,7 +3391,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
lights,
|
||||
shadows,
|
||||
shadow_mats,
|
||||
&lod.map,
|
||||
&lod.alt,
|
||||
&lod.horizon,
|
||||
&self.waves,
|
||||
)
|
||||
|
@ -1382,6 +1382,7 @@ impl WorldSim {
|
||||
.unwrap();
|
||||
|
||||
let mut v = vec![0u32; WORLD_SIZE.x * WORLD_SIZE.y];
|
||||
let mut alts = vec![0u32; WORLD_SIZE.x * WORLD_SIZE.y];
|
||||
// TODO: Parallelize again.
|
||||
let config = MapConfig {
|
||||
gain: self.max_height,
|
||||
@ -1400,15 +1401,18 @@ impl WorldSim {
|
||||
self,
|
||||
pos.map(|e| e as i32) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
);
|
||||
let a = (alt.min(1.0).max(0.0) * 255.0) as u8;
|
||||
let a = 0; //(alt.min(1.0).max(0.0) * 255.0) as u8;
|
||||
|
||||
v[pos.y * WORLD_SIZE.x + pos.x] = u32::from_le_bytes([r, g, b, a]);
|
||||
let posi = pos.y * WORLD_SIZE.x + pos.x;
|
||||
v[posi] = u32::from_le_bytes([r, g, b, a]);
|
||||
alts[posi] = (((alt.min(1.0).max(0.0) * 8191.0) as u32) & 0x1FFF) << 3;
|
||||
},
|
||||
);
|
||||
WorldMapMsg {
|
||||
dimensions: WORLD_SIZE.map(|e| e as u32),
|
||||
dimensions: WORLD_SIZE.map(|e| e as u16),
|
||||
max_height: self.max_height,
|
||||
rgba: v,
|
||||
alt: alts,
|
||||
horizons,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user