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) {
|
||||
float alt00 = alt_at(pos);
|
||||
float alt10 = alt_at(pos + vec2(100, 0));
|
||||
float alt01 = alt_at(pos + vec2(0, 100));
|
||||
float alt10 = alt_at(pos + vec2(32, 0));
|
||||
float alt01 = alt_at(pos + vec2(0, 32));
|
||||
float slope = abs(alt00 - alt10) + abs(alt00 - alt01);
|
||||
|
||||
return normalize(vec3(
|
||||
(alt00 - alt10) / 100,
|
||||
(alt00 - alt01) / 100,
|
||||
100 / (slope + 0.00001) // Avoid NaN
|
||||
(alt00 - alt10) / 32,
|
||||
(alt00 - alt01) / 32,
|
||||
32 / (slope + 0.00001) // Avoid NaN
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ out vec3 f_pos;
|
||||
out float f_light;
|
||||
|
||||
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);
|
||||
|
||||
|
@ -24,6 +24,7 @@ pub mod npc;
|
||||
pub mod path;
|
||||
pub mod ray;
|
||||
pub mod region;
|
||||
pub mod spiral;
|
||||
pub mod state;
|
||||
pub mod sync;
|
||||
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 std::iter::FromIterator;
|
||||
|
||||
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
||||
#[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.
|
||||
pub struct Tri<P: Pipeline> {
|
||||
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 {
|
||||
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,
|
||||
};
|
||||
use client::Client;
|
||||
use common::spiral::Spiral2d;
|
||||
use vek::*;
|
||||
|
||||
pub struct Lod {
|
||||
@ -30,22 +31,25 @@ impl Lod {
|
||||
}
|
||||
|
||||
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 {
|
||||
for y in 0..detail {
|
||||
if Vec2::new(x, y).map(transform).magnitude() <= 1.0 {
|
||||
mesh.push_quad(Quad::new(
|
||||
Vertex::new(Vec2::new(x + 0, y + 0).map(transform)),
|
||||
Vertex::new(Vec2::new(x + 1, y + 0).map(transform)),
|
||||
Vertex::new(Vec2::new(x + 1, y + 1).map(transform)),
|
||||
Vertex::new(Vec2::new(x + 0, y + 1).map(transform)),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mesh
|
||||
Quad::new(
|
||||
Vertex::new(Vec2::new(x + 0, y + 0).map(transform)),
|
||||
Vertex::new(Vec2::new(x + 1, y + 0).map(transform)),
|
||||
Vertex::new(Vec2::new(x + 1, y + 1).map(transform)),
|
||||
Vertex::new(Vec2::new(x + 0, y + 1).map(transform)),
|
||||
)
|
||||
.rotated_by(if (x > detail as i32 / 2) ^ (y > detail as i32 / 2) {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -329,6 +329,13 @@ impl Scene {
|
||||
/// Render the scene using the provided `Renderer`.
|
||||
pub fn render(&mut self, renderer: &mut Renderer, client: &mut Client) {
|
||||
// Render terrain and figures.
|
||||
self.terrain.render(
|
||||
renderer,
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
self.camera.get_focus_pos(),
|
||||
);
|
||||
self.figure_mgr.render(
|
||||
renderer,
|
||||
client,
|
||||
@ -337,13 +344,6 @@ impl Scene {
|
||||
&self.shadows,
|
||||
&self.camera,
|
||||
);
|
||||
self.terrain.render(
|
||||
renderer,
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
self.camera.get_focus_pos(),
|
||||
);
|
||||
self.lod.render(renderer, &self.globals);
|
||||
|
||||
// Render the skybox.
|
||||
|
@ -10,6 +10,7 @@ use client::Client;
|
||||
use common::{
|
||||
assets,
|
||||
figure::Segment,
|
||||
spiral::Spiral2d,
|
||||
terrain::{Block, BlockKind, TerrainChunk},
|
||||
vol::{BaseVol, ReadVol, RectRasterableVol, SampleVol, Vox},
|
||||
volumes::vol_grid_2d::{VolGrid2d, VolGrid2dError},
|
||||
@ -1404,9 +1405,11 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
if *n >= chunks.len() {
|
||||
None
|
||||
} else {
|
||||
*n += 1;
|
||||
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);
|
||||
@ -1443,9 +1446,11 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
if *n >= chunks.len() {
|
||||
None
|
||||
} else {
|
||||
*n += 1;
|
||||
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);
|
||||
@ -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);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user