mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Use world map as LoD source
This commit is contained in:
parent
dbf650f504
commit
2400786c13
@ -1,6 +1,15 @@
|
||||
#include <random.glsl>
|
||||
|
||||
uniform sampler2D t_map;
|
||||
|
||||
vec2 pos_to_uv(vec2 pos) {
|
||||
vec2 uv_pos = pos / 32768.0;
|
||||
return vec2(uv_pos.x, 1.0 - uv_pos.y);
|
||||
}
|
||||
|
||||
float alt_at(vec2 pos) {
|
||||
return texture(t_map, pos_to_uv(pos)).a * (1500.0);
|
||||
|
||||
return 0.0
|
||||
+ pow(texture(t_noise, pos * 0.00005).x * 1.4, 3.0) * 1000.0
|
||||
+ texture(t_noise, pos * 0.001).x * 100.0
|
||||
@ -11,9 +20,19 @@ vec2 splay(vec2 pos, float e) {
|
||||
return pos * pow(length(pos), e);
|
||||
}
|
||||
|
||||
float splay_scale(vec2 pos, float e) {
|
||||
return distance(splay(pos, e), splay(pos + 0.001, e)) * 500000.0;
|
||||
}
|
||||
|
||||
vec3 lod_pos(vec2 v_pos) {
|
||||
vec2 hpos = focus_pos.xy + splay(v_pos, 5.0) * 1000000.0;
|
||||
return vec3(hpos, alt_at(hpos));
|
||||
float splay = splay_scale(v_pos, 5.0);
|
||||
return vec3(hpos, (
|
||||
alt_at(hpos + vec2(-1, 1) * splay) +
|
||||
alt_at(hpos + vec2(1, 1) * splay) +
|
||||
alt_at(hpos + vec2(1, -1) * splay) +
|
||||
alt_at(hpos + vec2(-1, -1) * splay)
|
||||
) / 4.0);
|
||||
}
|
||||
|
||||
vec3 lod_norm(vec2 pos) {
|
||||
@ -25,11 +44,13 @@ vec3 lod_norm(vec2 pos) {
|
||||
return normalize(vec3(
|
||||
(alt00 - alt10) / 100,
|
||||
(alt00 - alt01) / 100,
|
||||
100 / slope
|
||||
100 / (slope + 0.00001) // Avoid NaN
|
||||
));
|
||||
}
|
||||
|
||||
vec3 lod_col(vec2 pos) {
|
||||
return texture(t_map, pos_to_uv(pos)).rgb;
|
||||
|
||||
vec3 warmth = mix(
|
||||
vec3(0.05, 0.4, 0.1),
|
||||
vec3(0.5, 0.4, 0.0),
|
||||
|
@ -15,9 +15,9 @@ out vec3 f_pos;
|
||||
out float f_light;
|
||||
|
||||
void main() {
|
||||
f_pos = lod_pos(v_pos);
|
||||
f_pos = lod_pos(v_pos + vec2(0, -v_pos.x * 0.5));
|
||||
|
||||
f_pos.z -= 25.0 / pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0);
|
||||
f_pos.z -= 5.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.9), 20.0);
|
||||
|
||||
f_light = 1.0;
|
||||
|
||||
|
@ -21,7 +21,7 @@ void main() {
|
||||
f_pos = vec3((uvec3(v_pos_norm) >> uvec3(0, 8, 16)) & uvec3(0xFFu, 0xFFu, 0x1FFFu)) + model_offs;
|
||||
|
||||
f_pos.z *= min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0);
|
||||
f_pos.z -= 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0);
|
||||
f_pos.z -= 5.0 * pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.9), 20.0);
|
||||
|
||||
f_col = vec3((uvec3(v_col_light) >> uvec3(8, 16, 24)) & uvec3(0xFFu)) / 255.0;
|
||||
|
||||
|
@ -18,20 +18,21 @@ impl From<gfx::PipelineStateError<String>> for RenderError {
|
||||
|
||||
impl From<gfx::PipelineStateError<&str>> for RenderError {
|
||||
fn from(err: gfx::PipelineStateError<&str>) -> Self {
|
||||
// This is horrid. We do it to get rid of the `&str`'s lifetime bound by turning it into a `String`.
|
||||
// This is horrid. We do it to get rid of the `&str`'s lifetime bound by turning
|
||||
// it into a `String`.
|
||||
match err {
|
||||
gfx::PipelineStateError::DescriptorInit(err) => {
|
||||
gfx::PipelineStateError::DescriptorInit(match err {
|
||||
gfx::pso::InitError::VertexImport(s, x) => {
|
||||
gfx::pso::InitError::VertexImport(s.to_string(), x)
|
||||
}
|
||||
},
|
||||
gfx::pso::InitError::ConstantBuffer(s, x) => {
|
||||
gfx::pso::InitError::ConstantBuffer(
|
||||
s.to_string(),
|
||||
x.map(|x| match x {
|
||||
gfx::pso::ElementError::NotFound(s) => {
|
||||
gfx::pso::ElementError::NotFound(s.to_string())
|
||||
}
|
||||
},
|
||||
gfx::pso::ElementError::Offset {
|
||||
name,
|
||||
shader_offset,
|
||||
@ -52,24 +53,24 @@ impl From<gfx::PipelineStateError<&str>> for RenderError {
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
},
|
||||
gfx::pso::InitError::GlobalConstant(s, x) => {
|
||||
gfx::pso::InitError::GlobalConstant(s.to_string(), x)
|
||||
}
|
||||
},
|
||||
gfx::pso::InitError::ResourceView(s, x) => {
|
||||
gfx::pso::InitError::ResourceView(s.to_string(), x)
|
||||
}
|
||||
},
|
||||
gfx::pso::InitError::UnorderedView(s, x) => {
|
||||
gfx::pso::InitError::UnorderedView(s.to_string(), x)
|
||||
}
|
||||
},
|
||||
gfx::pso::InitError::Sampler(s, x) => {
|
||||
gfx::pso::InitError::Sampler(s.to_string(), x)
|
||||
}
|
||||
},
|
||||
gfx::pso::InitError::PixelExport(s, x) => {
|
||||
gfx::pso::InitError::PixelExport(s.to_string(), x)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
gfx::PipelineStateError::Program(p) => gfx::PipelineStateError::Program(p),
|
||||
gfx::PipelineStateError::DeviceCreate(c) => gfx::PipelineStateError::DeviceCreate(c),
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ pub use self::{
|
||||
renderer::{Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt},
|
||||
texture::Texture,
|
||||
};
|
||||
pub use gfx::texture::{FilterMethod, WrapMode};
|
||||
|
||||
#[cfg(feature = "gl")]
|
||||
use gfx_device_gl as gfx_backend;
|
||||
|
@ -3,14 +3,8 @@ use super::{
|
||||
Globals,
|
||||
};
|
||||
use gfx::{
|
||||
self,
|
||||
gfx_constant_struct_meta,
|
||||
// Macros
|
||||
gfx_defines,
|
||||
gfx_impl_struct_meta,
|
||||
gfx_pipeline,
|
||||
gfx_pipeline_inner,
|
||||
gfx_vertex_struct_meta,
|
||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
@ -28,6 +22,7 @@ gfx_defines! {
|
||||
|
||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
@ -45,9 +40,7 @@ impl Vertex {
|
||||
}
|
||||
|
||||
impl Locals {
|
||||
pub fn default() -> Self {
|
||||
Self { nul: [0.0; 4] }
|
||||
}
|
||||
pub fn default() -> Self { Self { nul: [0.0; 4] } }
|
||||
}
|
||||
|
||||
pub struct LodTerrainPipeline;
|
||||
|
@ -9,7 +9,7 @@ use super::{
|
||||
Shadow,
|
||||
},
|
||||
texture::Texture,
|
||||
AaMode, CloudMode, FluidMode, Pipeline, RenderError,
|
||||
AaMode, CloudMode, FilterMethod, FluidMode, Pipeline, RenderError, WrapMode,
|
||||
};
|
||||
use common::assets::{self, watch::ReloadIndicator};
|
||||
use gfx::{
|
||||
@ -419,8 +419,8 @@ impl Renderer {
|
||||
pub fn create_texture(
|
||||
&mut self,
|
||||
image: &image::DynamicImage,
|
||||
filter_method: Option<gfx::texture::FilterMethod>,
|
||||
wrap_mode: Option<gfx::texture::WrapMode>,
|
||||
filter_method: Option<FilterMethod>,
|
||||
wrap_mode: Option<WrapMode>,
|
||||
) -> Result<Texture, RenderError> {
|
||||
Texture::new(&mut self.factory, image, filter_method, wrap_mode)
|
||||
}
|
||||
@ -646,12 +646,14 @@ impl Renderer {
|
||||
);
|
||||
}
|
||||
|
||||
/// Queue the rendering of the provided LoD terrain model in the upcoming frame.
|
||||
/// Queue the rendering of the provided LoD terrain model in the upcoming
|
||||
/// frame.
|
||||
pub fn render_lod_terrain(
|
||||
&mut self,
|
||||
model: &Model<lod_terrain::LodTerrainPipeline>,
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<lod_terrain::Locals>,
|
||||
map: &Texture,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
@ -667,6 +669,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()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
},
|
||||
|
@ -1,26 +1,31 @@
|
||||
use crate::render::{
|
||||
pipelines::lod_terrain::{Locals, Vertex},
|
||||
Consts, Globals, LodTerrainPipeline, Mesh, Model, Quad, Renderer,
|
||||
Consts, FilterMethod, Globals, LodTerrainPipeline, Mesh, Model, Quad, Renderer, Texture,
|
||||
};
|
||||
use client::Client;
|
||||
use vek::*;
|
||||
|
||||
pub struct Lod {
|
||||
model: Model<LodTerrainPipeline>,
|
||||
locals: Consts<Locals>,
|
||||
map: Texture,
|
||||
}
|
||||
|
||||
impl Lod {
|
||||
pub fn new(renderer: &mut Renderer) -> Self {
|
||||
pub fn new(renderer: &mut Renderer, client: &Client) -> Self {
|
||||
Self {
|
||||
model: renderer
|
||||
.create_model(&create_lod_terrain_mesh(175))
|
||||
.create_model(&create_lod_terrain_mesh(300)) //175
|
||||
.unwrap(),
|
||||
locals: renderer.create_consts(&[Locals::default()]).unwrap(),
|
||||
map: renderer
|
||||
.create_texture(&client.world_map.0, Some(FilterMethod::Bilinear), None)
|
||||
.expect("Failed to generate map texture"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer, globals: &Consts<Globals>) {
|
||||
renderer.render_lod_terrain(&self.model, globals, &self.locals);
|
||||
renderer.render_lod_terrain(&self.model, globals, &self.locals, &self.map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@ pub mod terrain;
|
||||
use self::{
|
||||
camera::{Camera, CameraMode},
|
||||
figure::FigureMgr,
|
||||
music::MusicMgr,
|
||||
lod::Lod,
|
||||
music::MusicMgr,
|
||||
terrain::Terrain,
|
||||
};
|
||||
use crate::{
|
||||
@ -67,7 +67,7 @@ pub struct Scene {
|
||||
|
||||
impl Scene {
|
||||
/// Create a new `Scene` with default parameters.
|
||||
pub fn new(renderer: &mut Renderer) -> Self {
|
||||
pub fn new(renderer: &mut Renderer, client: &Client) -> Self {
|
||||
let resolution = renderer.get_resolution().map(|e| e as f32);
|
||||
|
||||
Self {
|
||||
@ -91,7 +91,7 @@ impl Scene {
|
||||
.unwrap(),
|
||||
},
|
||||
terrain: Terrain::new(renderer),
|
||||
lod: Lod::new(renderer),
|
||||
lod: Lod::new(renderer, client),
|
||||
loaded_distance: 0.0,
|
||||
select_pos: None,
|
||||
|
||||
|
@ -1240,7 +1240,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// a sample of the terrain that includes both the chunk we want and
|
||||
// its neighbours.
|
||||
let volume = match client.state().terrain().sample(aabr) {
|
||||
Ok(sample) => sample, // TODO: Ensure that all of the chunk's neighbours still exist to avoid buggy shadow borders
|
||||
Ok(sample) => sample, /* TODO: Ensure that all of the chunk's neighbours still
|
||||
* exist to avoid buggy shadow borders */
|
||||
// Either this chunk or its neighbours doesn't yet exist, so we keep it in the
|
||||
// queue to be processed at a later date when we have its neighbours.
|
||||
Err(VolGrid2dError::NoSuchChunk) => return,
|
||||
|
@ -39,7 +39,7 @@ impl SessionState {
|
||||
pub fn new(global_state: &mut GlobalState, client: Rc<RefCell<Client>>) -> Self {
|
||||
// Create a scene for this session. The scene handles visible elements of the
|
||||
// game world.
|
||||
let mut scene = Scene::new(global_state.window.renderer_mut());
|
||||
let mut scene = Scene::new(global_state.window.renderer_mut(), &*client.borrow());
|
||||
scene
|
||||
.camera_mut()
|
||||
.set_fov_deg(global_state.settings.graphics.fov);
|
||||
|
@ -242,7 +242,7 @@ impl MapConfig {
|
||||
let water_color_factor = 2.0;
|
||||
let g_water = 32.0 * water_color_factor;
|
||||
let b_water = 64.0 * water_color_factor;
|
||||
let rgba = match (river_kind, (is_water, true_alt >= true_sea_level)) {
|
||||
let rgb = match (river_kind, (is_water, true_alt >= true_sea_level)) {
|
||||
(_, (false, _)) | (None, (_, true)) => {
|
||||
let (r, g, b) = (
|
||||
(if is_shaded { alt } else { alt }
|
||||
@ -270,20 +270,17 @@ impl MapConfig {
|
||||
(r * light * 255.0) as u8,
|
||||
(g * light * 255.0) as u8,
|
||||
(b * light * 255.0) as u8,
|
||||
255,
|
||||
)
|
||||
},
|
||||
(Some(RiverKind::Ocean), _) => (
|
||||
0,
|
||||
((g_water - water_depth * g_water) * 1.0) as u8,
|
||||
((b_water - water_depth * b_water) * 1.0) as u8,
|
||||
255,
|
||||
),
|
||||
(Some(RiverKind::River { .. }), _) => (
|
||||
0,
|
||||
g_water as u8 + (alt * (127.0 - g_water)) as u8,
|
||||
b_water as u8 + (alt * (255.0 - b_water)) as u8,
|
||||
255,
|
||||
),
|
||||
(None, _) | (Some(RiverKind::Lake { .. }), _) => (
|
||||
0,
|
||||
@ -291,10 +288,11 @@ impl MapConfig {
|
||||
as u8,
|
||||
(((b_water + water_alt * (255.0 - b_water)) + (-water_depth * b_water))
|
||||
* 1.0) as u8,
|
||||
255,
|
||||
),
|
||||
};
|
||||
|
||||
let rgba = (rgb.0, rgb.1, rgb.2, (255.0 * alt) as u8);
|
||||
|
||||
write_pixel(Vec2::new(i, j), rgba);
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user