mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'imbris/mesh-speed' into 'master'
Speed up terrain meshing ~20% See merge request veloren/veloren!625
This commit is contained in:
commit
c18fe8042b
@ -27,8 +27,7 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
||||
if let Some(col) = vox.get_color() {
|
||||
vol::push_vox_verts(
|
||||
&mut mesh,
|
||||
self,
|
||||
pos,
|
||||
faces_to_make(self, pos, true, |vox| vox.is_empty()),
|
||||
offs + pos.map(|e| e as f32),
|
||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
||||
|origin, norm, col, ao, light| {
|
||||
@ -39,7 +38,6 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
||||
0,
|
||||
)
|
||||
},
|
||||
true,
|
||||
&{
|
||||
let mut ls = [[[0.0; 3]; 3]; 3];
|
||||
for x in 0..3 {
|
||||
@ -59,7 +57,6 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
||||
}
|
||||
ls
|
||||
},
|
||||
|vox| vox.is_empty(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -83,8 +80,7 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
||||
if let Some(col) = vox.get_color() {
|
||||
vol::push_vox_verts(
|
||||
&mut mesh,
|
||||
self,
|
||||
pos,
|
||||
faces_to_make(self, pos, true, |vox| vox.is_empty()),
|
||||
offs + pos.map(|e| e as f32),
|
||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
||||
|origin, norm, col, ao, light| {
|
||||
@ -94,9 +90,7 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
||||
linear_to_srgb(srgb_to_linear(col) * ao * light),
|
||||
)
|
||||
},
|
||||
true,
|
||||
&[[[1.0; 3]; 3]; 3],
|
||||
|vox| vox.is_empty(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -104,3 +98,27 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
||||
(mesh, Mesh::new())
|
||||
}
|
||||
}
|
||||
|
||||
/// Use the 6 voxels/blocks surrounding the one at the specified position
|
||||
/// to detemine which faces should be drawn
|
||||
fn faces_to_make<V: ReadVol>(
|
||||
seg: &V,
|
||||
pos: Vec3<i32>,
|
||||
error_makes_face: bool,
|
||||
should_add: impl Fn(&V::Vox) -> bool,
|
||||
) -> [bool; 6] {
|
||||
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
|
||||
let make_face = |offset| {
|
||||
seg.get(pos + offset)
|
||||
.map(|v| should_add(v))
|
||||
.unwrap_or(error_makes_face)
|
||||
};
|
||||
[
|
||||
make_face(-x),
|
||||
make_face(x),
|
||||
make_face(-y),
|
||||
make_face(y),
|
||||
make_face(-z),
|
||||
make_face(z),
|
||||
]
|
||||
}
|
||||
|
@ -180,19 +180,21 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
.unwrap_or(Rgba::zero())
|
||||
};
|
||||
|
||||
let mut blocks = [[[None; 3]; 3]; 3];
|
||||
let mut colors = [[[Rgba::zero(); 3]; 3]; 3];
|
||||
for i in 0..3 {
|
||||
for j in 0..3 {
|
||||
for k in 0..3 {
|
||||
colors[k][j][i] = get_color(
|
||||
vol_cached
|
||||
.get(
|
||||
Vec3::new(x, y, range.min.z)
|
||||
+ Vec3::new(i as i32, j as i32, k as i32)
|
||||
- 1,
|
||||
)
|
||||
.ok(),
|
||||
);
|
||||
let block = vol_cached
|
||||
.get(
|
||||
Vec3::new(x, y, range.min.z)
|
||||
+ Vec3::new(i as i32, j as i32, k as i32)
|
||||
- 1,
|
||||
)
|
||||
.ok()
|
||||
.copied();
|
||||
colors[k][j][i] = get_color(block.as_ref());
|
||||
blocks[k][j][i] = block;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,6 +205,8 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
|
||||
lights[0] = lights[1];
|
||||
lights[1] = lights[2];
|
||||
blocks[0] = blocks[1];
|
||||
blocks[1] = blocks[2];
|
||||
colors[0] = colors[1];
|
||||
colors[1] = colors[2];
|
||||
|
||||
@ -213,44 +217,39 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
}
|
||||
for i in 0..3 {
|
||||
for j in 0..3 {
|
||||
colors[2][j][i] = get_color(
|
||||
vol_cached
|
||||
.get(pos + Vec3::new(i as i32, j as i32, 2) - 1)
|
||||
.ok(),
|
||||
);
|
||||
let block = vol_cached
|
||||
.get(pos + Vec3::new(i as i32, j as i32, 2) - 1)
|
||||
.ok()
|
||||
.copied();
|
||||
colors[2][j][i] = get_color(block.as_ref());
|
||||
blocks[2][j][i] = block;
|
||||
}
|
||||
}
|
||||
|
||||
let block = vol_cached.get(pos).ok();
|
||||
let block = blocks[1][1][1];
|
||||
|
||||
// Create mesh polygons
|
||||
if block.map(|vox| vox.is_opaque()).unwrap_or(false) {
|
||||
vol::push_vox_verts(
|
||||
&mut opaque_mesh,
|
||||
self,
|
||||
pos,
|
||||
faces_to_make(&blocks, false, |vox| !vox.is_opaque()),
|
||||
offs,
|
||||
&colors, //&[[[colors[1][1][1]; 3]; 3]; 3],
|
||||
|pos, norm, col, ao, light| {
|
||||
TerrainVertex::new(pos, norm, col, light.min(ao))
|
||||
},
|
||||
false,
|
||||
&lights,
|
||||
|vox| !vox.is_opaque(),
|
||||
);
|
||||
} else if block.map(|vox| vox.is_fluid()).unwrap_or(false) {
|
||||
vol::push_vox_verts(
|
||||
&mut fluid_mesh,
|
||||
self,
|
||||
pos,
|
||||
faces_to_make(&blocks, false, |vox| vox.is_air()),
|
||||
offs,
|
||||
&colors,
|
||||
|pos, norm, col, _ao, light| {
|
||||
FluidVertex::new(pos, norm, col, light, 0.3)
|
||||
},
|
||||
false,
|
||||
&lights,
|
||||
|vox| vox.is_air(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -261,6 +260,28 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
}
|
||||
}
|
||||
|
||||
/// Use the 6 voxels/blocks surrounding the center
|
||||
/// to detemine which faces should be drawn
|
||||
/// Unlike the one in segments.rs this uses a provided array of blocks instead
|
||||
/// of retrieving from a volume
|
||||
/// blocks[z][y][x]
|
||||
fn faces_to_make(
|
||||
blocks: &[[[Option<Block>; 3]; 3]; 3],
|
||||
error_makes_face: bool,
|
||||
should_add: impl Fn(Block) -> bool,
|
||||
) -> [bool; 6] {
|
||||
// Faces to draw
|
||||
let make_face = |opt_v: Option<Block>| opt_v.map(|v| should_add(v)).unwrap_or(error_makes_face);
|
||||
[
|
||||
make_face(blocks[1][1][0]),
|
||||
make_face(blocks[1][1][2]),
|
||||
make_face(blocks[1][0][1]),
|
||||
make_face(blocks[1][2][1]),
|
||||
make_face(blocks[0][1][1]),
|
||||
make_face(blocks[2][1][1]),
|
||||
]
|
||||
}
|
||||
|
||||
/*
|
||||
impl<V: BaseVol<Vox = Block> + ReadVol + Debug> Meshable for VolGrid3d<V> {
|
||||
type Pipeline = TerrainPipeline;
|
||||
|
@ -1,7 +1,5 @@
|
||||
use vek::*;
|
||||
|
||||
use common::vol::ReadVol;
|
||||
|
||||
use crate::render::{
|
||||
mesh::{Mesh, Quad},
|
||||
Pipeline,
|
||||
@ -151,25 +149,18 @@ fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32, f32) -> P
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
||||
pub fn push_vox_verts<P: Pipeline>(
|
||||
mesh: &mut Mesh<P>,
|
||||
vol: &V,
|
||||
pos: Vec3<i32>,
|
||||
faces: [bool; 6],
|
||||
offs: Vec3<f32>,
|
||||
cols: &[[[Rgba<u8>; 3]; 3]; 3],
|
||||
vcons: impl Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32, f32) -> P::Vertex,
|
||||
error_makes_face: bool,
|
||||
darknesses: &[[[f32; 3]; 3]; 3],
|
||||
should_add: impl Fn(&V::Vox) -> bool,
|
||||
) {
|
||||
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
|
||||
|
||||
// -x
|
||||
if vol
|
||||
.get(pos - Vec3::unit_x())
|
||||
.map(|v| should_add(v))
|
||||
.unwrap_or(error_makes_face)
|
||||
{
|
||||
if faces[0] {
|
||||
mesh.push_quad(create_quad(
|
||||
offs,
|
||||
Vec3::unit_z(),
|
||||
@ -181,11 +172,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
||||
));
|
||||
}
|
||||
// +x
|
||||
if vol
|
||||
.get(pos + Vec3::unit_x())
|
||||
.map(|v| should_add(v))
|
||||
.unwrap_or(error_makes_face)
|
||||
{
|
||||
if faces[1] {
|
||||
mesh.push_quad(create_quad(
|
||||
offs + Vec3::unit_x(),
|
||||
Vec3::unit_y(),
|
||||
@ -197,11 +184,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
||||
));
|
||||
}
|
||||
// -y
|
||||
if vol
|
||||
.get(pos - Vec3::unit_y())
|
||||
.map(|v| should_add(v))
|
||||
.unwrap_or(error_makes_face)
|
||||
{
|
||||
if faces[2] {
|
||||
mesh.push_quad(create_quad(
|
||||
offs,
|
||||
Vec3::unit_x(),
|
||||
@ -213,11 +196,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
||||
));
|
||||
}
|
||||
// +y
|
||||
if vol
|
||||
.get(pos + Vec3::unit_y())
|
||||
.map(|v| should_add(v))
|
||||
.unwrap_or(error_makes_face)
|
||||
{
|
||||
if faces[3] {
|
||||
mesh.push_quad(create_quad(
|
||||
offs + Vec3::unit_y(),
|
||||
Vec3::unit_z(),
|
||||
@ -229,11 +208,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
||||
));
|
||||
}
|
||||
// -z
|
||||
if vol
|
||||
.get(pos - Vec3::unit_z())
|
||||
.map(|v| should_add(v))
|
||||
.unwrap_or(error_makes_face)
|
||||
{
|
||||
if faces[4] {
|
||||
mesh.push_quad(create_quad(
|
||||
offs,
|
||||
Vec3::unit_y(),
|
||||
@ -245,11 +220,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
||||
));
|
||||
}
|
||||
// +z
|
||||
if vol
|
||||
.get(pos + Vec3::unit_z())
|
||||
.map(|v| should_add(v))
|
||||
.unwrap_or(error_makes_face)
|
||||
{
|
||||
if faces[5] {
|
||||
mesh.push_quad(create_quad(
|
||||
offs + Vec3::unit_z(),
|
||||
Vec3::unit_x(),
|
||||
|
Loading…
Reference in New Issue
Block a user