mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added correctly generating world paths, sub-voxel shader noise
This commit is contained in:
parent
431b2ae07b
commit
431e199731
@ -1,6 +1,7 @@
|
||||
#version 330 core
|
||||
|
||||
#include <globals.glsl>
|
||||
#include <random.glsl>
|
||||
|
||||
in vec3 f_pos;
|
||||
flat in uint f_pos_norm;
|
||||
@ -46,7 +47,9 @@ void main() {
|
||||
ambient_light *= f_light * ao;
|
||||
diffuse_light *= f_light * ao;
|
||||
diffuse_light += point_light * ao;
|
||||
vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
||||
|
||||
vec3 col = f_col + snoise(vec4(mod(floor(f_pos * 3.0), 100.0) * 10.0, 0)) * 0.02; // Small-scale noise
|
||||
vec3 surf_color = illuminate(srgb_to_linear(col), light, diffuse_light, ambient_light);
|
||||
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
vec4 clouds;
|
||||
|
@ -236,7 +236,7 @@ impl Scene {
|
||||
};
|
||||
|
||||
self.camera.set_focus_pos(
|
||||
player_pos + Vec3::unit_z() * (up + dist * 0.15 - tilt.min(0.0) * dist * 0.75),
|
||||
player_pos + Vec3::unit_z() * (up + dist * 0.15 - tilt.min(0.0) * dist * 0.4),
|
||||
);
|
||||
|
||||
// Tick camera for interpolation.
|
||||
|
@ -29,6 +29,7 @@ pub fn structure_gen<'a>(
|
||||
|| st_sample.alt < st_sample.water_level
|
||||
|| st_sample.spawn_rate < 0.5
|
||||
|| st_sample.water_dist.map(|d| d < 8.0).unwrap_or(false)
|
||||
|| st_sample.path.map(|(d, _)| d < 12.0).unwrap_or(false)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ impl Civs {
|
||||
}
|
||||
}
|
||||
|
||||
for _ in 0..100 {
|
||||
for _ in 0..32 {
|
||||
attempt(5, || {
|
||||
let loc = find_site_loc(&mut ctx, None)?;
|
||||
this.establish_site(&mut ctx.reseed(), loc, |place| Site {
|
||||
@ -498,7 +498,7 @@ fn walk_in_dir(sim: &WorldSim, a: Vec2<i32>, dir: Vec2<i32>) -> Option<f32> {
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
Some((b_alt - a_alt).abs() / 2.5)
|
||||
Some(1.0 + ((b_alt - a_alt).abs() / 2.5).powf(2.0) + water_cost)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1118,18 +1118,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
5.0
|
||||
};
|
||||
|
||||
const PATH_WIDTH: f32 = 5.0;
|
||||
let path_dist_factor = sim
|
||||
.get_nearest_path(wpos)
|
||||
.map(|(dist, _)| dist / PATH_WIDTH)
|
||||
.unwrap_or(1.0)
|
||||
.min(1.0);
|
||||
let ground = Lerp::lerp(
|
||||
sub_surface_color,
|
||||
ground,
|
||||
(path_dist_factor.max(0.8) - 0.8) / 0.2,
|
||||
);
|
||||
let alt = alt - if path_dist_factor < 0.8 { 1.0 } else { 0.0 };
|
||||
let path = sim.get_nearest_path(wpos);
|
||||
|
||||
Some(ColumnSample {
|
||||
alt,
|
||||
@ -1174,6 +1163,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
spawn_rate,
|
||||
stone_col,
|
||||
water_dist,
|
||||
path,
|
||||
|
||||
chunk: sim_chunk,
|
||||
})
|
||||
@ -1207,6 +1197,7 @@ pub struct ColumnSample<'a> {
|
||||
pub spawn_rate: f32,
|
||||
pub stone_col: Rgb<u8>,
|
||||
pub water_dist: Option<f32>,
|
||||
pub path: Option<(f32, Vec2<i32>)>,
|
||||
|
||||
pub chunk: &'a SimChunk,
|
||||
}
|
||||
|
81
world/src/layer/mod.rs
Normal file
81
world/src/layer/mod.rs
Normal file
@ -0,0 +1,81 @@
|
||||
use std::f32;
|
||||
use vek::*;
|
||||
use common::{
|
||||
terrain::{Block, BlockKind},
|
||||
vol::{BaseVol, ReadVol, RectSizedVol, RectVolSize, Vox, WriteVol},
|
||||
};
|
||||
use crate::{
|
||||
column::ColumnSample,
|
||||
util::{RandomField, Sampler},
|
||||
};
|
||||
|
||||
pub fn apply_paths_to<'a>(
|
||||
wpos2d: Vec2<i32>,
|
||||
mut get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
|
||||
vol: &mut (impl BaseVol<Vox = Block> + RectSizedVol + ReadVol + WriteVol),
|
||||
) {
|
||||
for y in 0..vol.size_xy().y as i32 {
|
||||
for x in 0..vol.size_xy().x as i32 {
|
||||
let offs = Vec2::new(x, y);
|
||||
|
||||
let wpos2d = wpos2d + offs;
|
||||
|
||||
// Sample terrain
|
||||
let col_sample = if let Some(col_sample) = get_column(offs) {
|
||||
col_sample
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let surface_z = col_sample.riverless_alt.floor() as i32;
|
||||
|
||||
let noisy_color = |col: Rgb<u8>, factor: u32| {
|
||||
let nz = RandomField::new(0).get(Vec3::new(wpos2d.x, wpos2d.y, surface_z));
|
||||
col.map(|e| {
|
||||
(e as u32 + nz % (factor * 2))
|
||||
.saturating_sub(factor)
|
||||
.min(255) as u8
|
||||
})
|
||||
};
|
||||
|
||||
if let Some((path_dist, path_nearest)) = col_sample.path.filter(|(dist, _)| *dist < 5.0) {
|
||||
let inset = 0;
|
||||
|
||||
// Try to use the column at the centre of the path for sampling to make them
|
||||
// flatter
|
||||
let col = get_column(offs + path_nearest - wpos2d)
|
||||
.unwrap_or(col_sample);
|
||||
let (bridge_offset, depth) = if let Some(water_dist) = col.water_dist {
|
||||
(
|
||||
((water_dist.max(0.0) * 0.2).min(f32::consts::PI).cos() + 1.0) * 5.0,
|
||||
((1.0 - ((water_dist + 2.0) * 0.3).min(0.0).cos().abs())
|
||||
* (col.riverless_alt + 5.0 - col.alt).max(0.0)
|
||||
* 1.75
|
||||
+ 3.0) as i32,
|
||||
)
|
||||
} else {
|
||||
(0.0, 3)
|
||||
};
|
||||
let surface_z = (col.riverless_alt + bridge_offset).floor() as i32;
|
||||
|
||||
for z in inset - depth..inset {
|
||||
vol.set(
|
||||
Vec3::new(offs.x, offs.y, surface_z + z),
|
||||
if bridge_offset >= 2.0 && path_dist >= 3.0 || z < inset - 1 {
|
||||
Block::new(BlockKind::Normal, noisy_color(Rgb::new(80, 80, 100), 8))
|
||||
} else {
|
||||
let path_color = col_sample.sub_surface_color.map(|e| (e * 255.0 * 0.7) as u8);
|
||||
Block::new(BlockKind::Normal, noisy_color(path_color, 8))
|
||||
},
|
||||
);
|
||||
}
|
||||
let head_space = (8 - (path_dist * 0.25).powf(6.0).round() as i32).max(1);
|
||||
for z in inset..inset + head_space {
|
||||
let pos = Vec3::new(offs.x, offs.y, surface_z + z);
|
||||
if vol.get(pos).unwrap().kind() != BlockKind::Water {
|
||||
vol.set(pos, Block::empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ mod column;
|
||||
pub mod config;
|
||||
pub mod sim;
|
||||
pub mod site;
|
||||
pub mod layer;
|
||||
pub mod util;
|
||||
|
||||
// Reexports
|
||||
@ -166,6 +167,9 @@ impl World {
|
||||
.iter()
|
||||
.for_each(|site| site.apply_to(chunk_wpos2d, sample_get, &mut chunk));
|
||||
|
||||
// Apply paths
|
||||
layer::apply_paths_to(chunk_wpos2d, sample_get, &mut chunk);
|
||||
|
||||
let gen_entity_pos = || {
|
||||
let lpos2d = TerrainChunkSize::RECT_SIZE
|
||||
.map(|sz| rand::thread_rng().gen::<u32>().rem_euclid(sz) as i32);
|
||||
|
@ -149,7 +149,7 @@ impl Settlement {
|
||||
|
||||
this.place_farms(&mut ctx);
|
||||
this.place_town(&mut ctx);
|
||||
this.place_paths(ctx.rng);
|
||||
//this.place_paths(ctx.rng);
|
||||
this.place_buildings(&mut ctx);
|
||||
|
||||
this
|
||||
@ -349,6 +349,10 @@ impl Settlement {
|
||||
.tile_at(tile_pos)
|
||||
.map(|t| t.contains(WayKind::Path))
|
||||
.unwrap_or(true)
|
||||
|| ctx.sim
|
||||
.and_then(|sim| sim.get_nearest_path(self.origin + house_pos))
|
||||
.map(|(dist, _)| dist < 28.0)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user