mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Applied good ideas from experimental branch
This commit is contained in:
parent
58587b6854
commit
be775c9484
@ -38,14 +38,14 @@ vec3 lod_pos(vec2 v_pos) {
|
|||||||
|
|
||||||
vec3 lod_norm(vec2 pos) {
|
vec3 lod_norm(vec2 pos) {
|
||||||
float alt00 = alt_at(pos);
|
float alt00 = alt_at(pos);
|
||||||
float alt10 = alt_at(pos + vec2(100, 0));
|
float alt10 = alt_at(pos + vec2(32, 0));
|
||||||
float alt01 = alt_at(pos + vec2(0, 100));
|
float alt01 = alt_at(pos + vec2(0, 32));
|
||||||
float slope = abs(alt00 - alt10) + abs(alt00 - alt01);
|
float slope = abs(alt00 - alt10) + abs(alt00 - alt01);
|
||||||
|
|
||||||
return normalize(vec3(
|
return normalize(vec3(
|
||||||
(alt00 - alt10) / 100,
|
(alt00 - alt10) / 32,
|
||||||
(alt00 - alt01) / 100,
|
(alt00 - alt01) / 32,
|
||||||
100 / (slope + 0.00001) // Avoid NaN
|
32 / (slope + 0.00001) // Avoid NaN
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ out vec3 f_pos;
|
|||||||
out float f_light;
|
out float f_light;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
f_pos = lod_pos(v_pos + vec2(0, -v_pos.x * 0.5));
|
f_pos = lod_pos(v_pos);
|
||||||
|
|
||||||
f_pos.z -= 1.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0);
|
f_pos.z -= 1.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0);
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ pub mod npc;
|
|||||||
pub mod path;
|
pub mod path;
|
||||||
pub mod ray;
|
pub mod ray;
|
||||||
pub mod region;
|
pub mod region;
|
||||||
|
pub mod spiral;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod sys;
|
pub mod sys;
|
||||||
|
35
common/src/spiral.rs
Normal file
35
common/src/spiral.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use vek::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Spiral2d {
|
||||||
|
layer: i32,
|
||||||
|
i: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Spiral2d {
|
||||||
|
pub fn new() -> Self { Self { layer: 0, i: 0 } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for Spiral2d {
|
||||||
|
type Item = Vec2<i32>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let layer_size = (self.layer * 8 + 4 * self.layer.min(1) - 4).max(1);
|
||||||
|
if self.i >= layer_size {
|
||||||
|
self.layer += 1;
|
||||||
|
self.i = 0;
|
||||||
|
}
|
||||||
|
let layer_size = (self.layer * 8 + 4 * self.layer.min(1) - 4).max(1);
|
||||||
|
|
||||||
|
let pos = Vec2::new(
|
||||||
|
-self.layer + (self.i - (layer_size / 4) * 0).max(0).min(self.layer * 2)
|
||||||
|
- (self.i - (layer_size / 4) * 2).max(0).min(self.layer * 2),
|
||||||
|
-self.layer + (self.i - (layer_size / 4) * 1).max(0).min(self.layer * 2)
|
||||||
|
- (self.i - (layer_size / 4) * 3).max(0).min(self.layer * 2),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.i += 1;
|
||||||
|
|
||||||
|
Some(pos)
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
use super::Pipeline;
|
use super::Pipeline;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -57,6 +58,24 @@ impl<P: Pipeline> Mesh<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<P: Pipeline> FromIterator<Tri<P>> for Mesh<P> {
|
||||||
|
fn from_iter<I: IntoIterator<Item = Tri<P>>>(tris: I) -> Self {
|
||||||
|
tris.into_iter().fold(Self::new(), |mut this, tri| {
|
||||||
|
this.push_tri(tri);
|
||||||
|
this
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: Pipeline> FromIterator<Quad<P>> for Mesh<P> {
|
||||||
|
fn from_iter<I: IntoIterator<Item = Quad<P>>>(quads: I) -> Self {
|
||||||
|
quads.into_iter().fold(Self::new(), |mut this, quad| {
|
||||||
|
this.push_quad(quad);
|
||||||
|
this
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents a triangle stored on the CPU.
|
/// Represents a triangle stored on the CPU.
|
||||||
pub struct Tri<P: Pipeline> {
|
pub struct Tri<P: Pipeline> {
|
||||||
a: P::Vertex,
|
a: P::Vertex,
|
||||||
@ -80,4 +99,18 @@ impl<P: Pipeline> Quad<P> {
|
|||||||
pub fn new(a: P::Vertex, b: P::Vertex, c: P::Vertex, d: P::Vertex) -> Self {
|
pub fn new(a: P::Vertex, b: P::Vertex, c: P::Vertex, d: P::Vertex) -> Self {
|
||||||
Self { a, b, c, d }
|
Self { a, b, c, d }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rotated_by(self, n: usize) -> Self
|
||||||
|
where
|
||||||
|
P::Vertex: Clone,
|
||||||
|
{
|
||||||
|
let verts = [self.a, self.b, self.c, self.d];
|
||||||
|
|
||||||
|
Self {
|
||||||
|
a: verts[(0 + n) % 4].clone(),
|
||||||
|
b: verts[(1 + n) % 4].clone(),
|
||||||
|
c: verts[(2 + n) % 4].clone(),
|
||||||
|
d: verts[(3 + n) % 4].clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use crate::render::{
|
|||||||
Consts, FilterMethod, Globals, LodTerrainPipeline, Mesh, Model, Quad, Renderer, Texture,
|
Consts, FilterMethod, Globals, LodTerrainPipeline, Mesh, Model, Quad, Renderer, Texture,
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
|
use common::spiral::Spiral2d;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub struct Lod {
|
pub struct Lod {
|
||||||
@ -30,22 +31,25 @@ impl Lod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_lod_terrain_mesh(detail: usize) -> Mesh<LodTerrainPipeline> {
|
fn create_lod_terrain_mesh(detail: usize) -> Mesh<LodTerrainPipeline> {
|
||||||
let transform = |x| (2.0 * x as f32) / detail as f32 - 1.0;
|
Spiral2d::new()
|
||||||
|
.take(detail * detail)
|
||||||
|
.map(|pos| {
|
||||||
|
let x = pos.x + detail as i32 / 2;
|
||||||
|
let y = pos.y + detail as i32 / 2;
|
||||||
|
|
||||||
let mut mesh = Mesh::new();
|
let transform = |x| (2.0 * x as f32) / detail as f32 - 1.0;
|
||||||
|
|
||||||
for x in 0..detail {
|
Quad::new(
|
||||||
for y in 0..detail {
|
Vertex::new(Vec2::new(x + 0, y + 0).map(transform)),
|
||||||
if Vec2::new(x, y).map(transform).magnitude() <= 1.0 {
|
Vertex::new(Vec2::new(x + 1, y + 0).map(transform)),
|
||||||
mesh.push_quad(Quad::new(
|
Vertex::new(Vec2::new(x + 1, y + 1).map(transform)),
|
||||||
Vertex::new(Vec2::new(x + 0, y + 0).map(transform)),
|
Vertex::new(Vec2::new(x + 0, y + 1).map(transform)),
|
||||||
Vertex::new(Vec2::new(x + 1, y + 0).map(transform)),
|
)
|
||||||
Vertex::new(Vec2::new(x + 1, y + 1).map(transform)),
|
.rotated_by(if (x > detail as i32 / 2) ^ (y > detail as i32 / 2) {
|
||||||
Vertex::new(Vec2::new(x + 0, y + 1).map(transform)),
|
0
|
||||||
));
|
} else {
|
||||||
}
|
1
|
||||||
}
|
})
|
||||||
}
|
})
|
||||||
|
.collect()
|
||||||
mesh
|
|
||||||
}
|
}
|
||||||
|
@ -329,6 +329,13 @@ impl Scene {
|
|||||||
/// Render the scene using the provided `Renderer`.
|
/// Render the scene using the provided `Renderer`.
|
||||||
pub fn render(&mut self, renderer: &mut Renderer, client: &mut Client) {
|
pub fn render(&mut self, renderer: &mut Renderer, client: &mut Client) {
|
||||||
// Render terrain and figures.
|
// Render terrain and figures.
|
||||||
|
self.terrain.render(
|
||||||
|
renderer,
|
||||||
|
&self.globals,
|
||||||
|
&self.lights,
|
||||||
|
&self.shadows,
|
||||||
|
self.camera.get_focus_pos(),
|
||||||
|
);
|
||||||
self.figure_mgr.render(
|
self.figure_mgr.render(
|
||||||
renderer,
|
renderer,
|
||||||
client,
|
client,
|
||||||
@ -337,13 +344,6 @@ impl Scene {
|
|||||||
&self.shadows,
|
&self.shadows,
|
||||||
&self.camera,
|
&self.camera,
|
||||||
);
|
);
|
||||||
self.terrain.render(
|
|
||||||
renderer,
|
|
||||||
&self.globals,
|
|
||||||
&self.lights,
|
|
||||||
&self.shadows,
|
|
||||||
self.camera.get_focus_pos(),
|
|
||||||
);
|
|
||||||
self.lod.render(renderer, &self.globals);
|
self.lod.render(renderer, &self.globals);
|
||||||
|
|
||||||
// Render the skybox.
|
// Render the skybox.
|
||||||
|
@ -10,6 +10,7 @@ use client::Client;
|
|||||||
use common::{
|
use common::{
|
||||||
assets,
|
assets,
|
||||||
figure::Segment,
|
figure::Segment,
|
||||||
|
spiral::Spiral2d,
|
||||||
terrain::{Block, BlockKind, TerrainChunk},
|
terrain::{Block, BlockKind, TerrainChunk},
|
||||||
vol::{BaseVol, ReadVol, RectRasterableVol, SampleVol, Vox},
|
vol::{BaseVol, ReadVol, RectRasterableVol, SampleVol, Vox},
|
||||||
volumes::vol_grid_2d::{VolGrid2d, VolGrid2dError},
|
volumes::vol_grid_2d::{VolGrid2d, VolGrid2dError},
|
||||||
@ -1404,9 +1405,11 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
if *n >= chunks.len() {
|
if *n >= chunks.len() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
*n += 1;
|
|
||||||
let pos = focus_chunk + rpos;
|
let pos = focus_chunk + rpos;
|
||||||
Some(chunks.get(&pos).map(|c| (pos, c)))
|
Some(chunks.get(&pos).map(|c| {
|
||||||
|
*n += 1;
|
||||||
|
(pos, c)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x);
|
.filter_map(|x| x);
|
||||||
@ -1443,9 +1446,11 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
if *n >= chunks.len() {
|
if *n >= chunks.len() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
*n += 1;
|
|
||||||
let pos = focus_chunk + rpos;
|
let pos = focus_chunk + rpos;
|
||||||
Some(chunks.get(&pos).map(|c| (pos, c)))
|
Some(chunks.get(&pos).map(|c| {
|
||||||
|
*n += 1;
|
||||||
|
(pos, c)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x);
|
.filter_map(|x| x);
|
||||||
@ -1488,37 +1493,3 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Spiral2d {
|
|
||||||
layer: i32,
|
|
||||||
i: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Spiral2d {
|
|
||||||
pub fn new() -> Self { Self { layer: 0, i: 0 } }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for Spiral2d {
|
|
||||||
type Item = Vec2<i32>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let layer_size = (self.layer * 8 + 4 * self.layer.min(1) - 4).max(1);
|
|
||||||
if self.i >= layer_size {
|
|
||||||
self.layer += 1;
|
|
||||||
self.i = 0;
|
|
||||||
}
|
|
||||||
let layer_size = (self.layer * 8 + 4 * self.layer.min(1) - 4).max(1);
|
|
||||||
|
|
||||||
let pos = Vec2::new(
|
|
||||||
-self.layer + (self.i - (layer_size / 4) * 0).max(0).min(self.layer * 2)
|
|
||||||
- (self.i - (layer_size / 4) * 2).max(0).min(self.layer * 2),
|
|
||||||
-self.layer + (self.i - (layer_size / 4) * 1).max(0).min(self.layer * 2)
|
|
||||||
- (self.i - (layer_size / 4) * 3).max(0).min(self.layer * 2),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.i += 1;
|
|
||||||
|
|
||||||
Some(pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -291,7 +291,7 @@ impl MapConfig {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let rgba = (rgb.0, rgb.1, rgb.2, (255.0 * alt) as u8);
|
let rgba = (rgb.0, rgb.1, rgb.2, (255.0 * alt.max(water_alt)) as u8);
|
||||||
|
|
||||||
write_pixel(Vec2::new(i, j), rgba);
|
write_pixel(Vec2::new(i, j), rgba);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user