mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved rendering performance with smarter meshing order
This commit is contained in:
parent
db5311189d
commit
a9adebcab3
@ -219,9 +219,6 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
|||||||
&self,
|
&self,
|
||||||
range: Self::Supplement,
|
range: Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
||||||
let mut opaque_mesh = Mesh::new();
|
|
||||||
let mut fluid_mesh = Mesh::new();
|
|
||||||
|
|
||||||
let mut light = calc_light(range, self);
|
let mut light = calc_light(range, self);
|
||||||
|
|
||||||
let mut lowest_opaque = range.size().d;
|
let mut lowest_opaque = range.size().d;
|
||||||
@ -300,6 +297,12 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
|||||||
highest_opaque
|
highest_opaque
|
||||||
}
|
}
|
||||||
.min(range.size().d - 1);
|
.min(range.size().d - 1);
|
||||||
|
|
||||||
|
// We use multiple meshes and then combine them later such that we can group similar z
|
||||||
|
// levels together (better rendering performance)
|
||||||
|
let mut opaque_meshes = vec![Mesh::new(); ((z_end + 1 - z_start).clamped(1, 60) as usize / 10).max(1)];
|
||||||
|
let mut fluid_mesh = Mesh::new();
|
||||||
|
|
||||||
for x in 1..range.size().w - 1 {
|
for x in 1..range.size().w - 1 {
|
||||||
for y in 1..range.size().w - 1 {
|
for y in 1..range.size().w - 1 {
|
||||||
let mut lights = [[[None; 3]; 3]; 3];
|
let mut lights = [[[None; 3]; 3]; 3];
|
||||||
@ -376,10 +379,12 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
|||||||
[[[get_color(blocks[1][1][1].as_ref(), false); 3]; 3]; 3]
|
[[[get_color(blocks[1][1][1].as_ref(), false); 3]; 3]; 3]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let opaque_mesh_index = ((z - z_start) * opaque_meshes.len() as i32 / (z_end + 1 - z_start).max(1)) as usize;
|
||||||
|
let selected_opaque_mesh = &mut opaque_meshes[opaque_mesh_index];
|
||||||
// Create mesh polygons
|
// Create mesh polygons
|
||||||
if block.map_or(false, |vox| vox.is_opaque()) {
|
if block.map_or(false, |vox| vox.is_opaque()) {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut opaque_mesh,
|
selected_opaque_mesh,
|
||||||
faces_to_make(&blocks, false, |vox| !vox.is_opaque()),
|
faces_to_make(&blocks, false, |vox| !vox.is_opaque()),
|
||||||
offs,
|
offs,
|
||||||
&colors,
|
&colors,
|
||||||
@ -414,6 +419,18 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let opaque_mesh = opaque_meshes
|
||||||
|
.into_iter()
|
||||||
|
.rev()
|
||||||
|
.fold(Mesh::new(), |mut opaque_mesh, m: Mesh<Self::Pipeline>| {
|
||||||
|
m.verts().chunks_exact(3).rev().for_each(|vs| {
|
||||||
|
opaque_mesh.push(vs[0]);
|
||||||
|
opaque_mesh.push(vs[1]);
|
||||||
|
opaque_mesh.push(vs[2]);
|
||||||
|
});
|
||||||
|
opaque_mesh
|
||||||
|
});
|
||||||
|
|
||||||
(opaque_mesh, fluid_mesh)
|
(opaque_mesh, fluid_mesh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
use super::Pipeline;
|
use super::Pipeline;
|
||||||
|
|
||||||
/// 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)]
|
|
||||||
pub struct Mesh<P: Pipeline> {
|
pub struct Mesh<P: Pipeline> {
|
||||||
verts: Vec<P::Vertex>,
|
verts: Vec<P::Vertex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<P: Pipeline> Clone for Mesh<P> where P::Vertex: Clone {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self { verts: self.verts.clone() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Mesh<P> {
|
impl<P: Pipeline> Mesh<P> {
|
||||||
/// Create a new `Mesh`.
|
/// Create a new `Mesh`.
|
||||||
pub fn new() -> Self { Self { verts: vec![] } }
|
pub fn new() -> Self { Self { verts: vec![] } }
|
||||||
@ -55,6 +60,23 @@ impl<P: Pipeline> Mesh<P> {
|
|||||||
self.verts.push(f(vert.clone()));
|
self.verts.push(f(vert.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn verts(&self) -> &[P::Vertex] {
|
||||||
|
&self.verts
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> std::slice::Iter<P::Vertex> {
|
||||||
|
self.verts.iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: Pipeline> IntoIterator for Mesh<P> {
|
||||||
|
type Item = P::Vertex;
|
||||||
|
type IntoIter = std::vec::IntoIter<P::Vertex>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.verts.into_iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a triangle stored on the CPU.
|
/// Represents a triangle stored on the CPU.
|
||||||
|
Loading…
Reference in New Issue
Block a user