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() {
|
if let Some(col) = vox.get_color() {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut mesh,
|
&mut mesh,
|
||||||
self,
|
faces_to_make(self, pos, true, |vox| vox.is_empty()),
|
||||||
pos,
|
|
||||||
offs + pos.map(|e| e as f32),
|
offs + pos.map(|e| e as f32),
|
||||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
||||||
|origin, norm, col, ao, light| {
|
|origin, norm, col, ao, light| {
|
||||||
@ -39,7 +38,6 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
|||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
true,
|
|
||||||
&{
|
&{
|
||||||
let mut ls = [[[0.0; 3]; 3]; 3];
|
let mut ls = [[[0.0; 3]; 3]; 3];
|
||||||
for x in 0..3 {
|
for x in 0..3 {
|
||||||
@ -59,7 +57,6 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
|||||||
}
|
}
|
||||||
ls
|
ls
|
||||||
},
|
},
|
||||||
|vox| vox.is_empty(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,8 +80,7 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
|||||||
if let Some(col) = vox.get_color() {
|
if let Some(col) = vox.get_color() {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut mesh,
|
&mut mesh,
|
||||||
self,
|
faces_to_make(self, pos, true, |vox| vox.is_empty()),
|
||||||
pos,
|
|
||||||
offs + pos.map(|e| e as f32),
|
offs + pos.map(|e| e as f32),
|
||||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
||||||
|origin, norm, col, ao, light| {
|
|origin, norm, col, ao, light| {
|
||||||
@ -94,9 +90,7 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
|||||||
linear_to_srgb(srgb_to_linear(col) * ao * light),
|
linear_to_srgb(srgb_to_linear(col) * ao * light),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
true,
|
|
||||||
&[[[1.0; 3]; 3]; 3],
|
&[[[1.0; 3]; 3]; 3],
|
||||||
|vox| vox.is_empty(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,3 +98,27 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
|||||||
(mesh, Mesh::new())
|
(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())
|
.unwrap_or(Rgba::zero())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut blocks = [[[None; 3]; 3]; 3];
|
||||||
let mut colors = [[[Rgba::zero(); 3]; 3]; 3];
|
let mut colors = [[[Rgba::zero(); 3]; 3]; 3];
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
for j in 0..3 {
|
for j in 0..3 {
|
||||||
for k in 0..3 {
|
for k in 0..3 {
|
||||||
colors[k][j][i] = get_color(
|
let block = vol_cached
|
||||||
vol_cached
|
.get(
|
||||||
.get(
|
Vec3::new(x, y, range.min.z)
|
||||||
Vec3::new(x, y, range.min.z)
|
+ Vec3::new(i as i32, j as i32, k as i32)
|
||||||
+ Vec3::new(i as i32, j as i32, k as i32)
|
- 1,
|
||||||
- 1,
|
)
|
||||||
)
|
.ok()
|
||||||
.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[0] = lights[1];
|
||||||
lights[1] = lights[2];
|
lights[1] = lights[2];
|
||||||
|
blocks[0] = blocks[1];
|
||||||
|
blocks[1] = blocks[2];
|
||||||
colors[0] = colors[1];
|
colors[0] = colors[1];
|
||||||
colors[1] = colors[2];
|
colors[1] = colors[2];
|
||||||
|
|
||||||
@ -213,44 +217,39 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
|||||||
}
|
}
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
for j in 0..3 {
|
for j in 0..3 {
|
||||||
colors[2][j][i] = get_color(
|
let block = vol_cached
|
||||||
vol_cached
|
.get(pos + Vec3::new(i as i32, j as i32, 2) - 1)
|
||||||
.get(pos + Vec3::new(i as i32, j as i32, 2) - 1)
|
.ok()
|
||||||
.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
|
// Create mesh polygons
|
||||||
if block.map(|vox| vox.is_opaque()).unwrap_or(false) {
|
if block.map(|vox| vox.is_opaque()).unwrap_or(false) {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut opaque_mesh,
|
&mut opaque_mesh,
|
||||||
self,
|
faces_to_make(&blocks, false, |vox| !vox.is_opaque()),
|
||||||
pos,
|
|
||||||
offs,
|
offs,
|
||||||
&colors, //&[[[colors[1][1][1]; 3]; 3]; 3],
|
&colors, //&[[[colors[1][1][1]; 3]; 3]; 3],
|
||||||
|pos, norm, col, ao, light| {
|
|pos, norm, col, ao, light| {
|
||||||
TerrainVertex::new(pos, norm, col, light.min(ao))
|
TerrainVertex::new(pos, norm, col, light.min(ao))
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
&lights,
|
&lights,
|
||||||
|vox| !vox.is_opaque(),
|
|
||||||
);
|
);
|
||||||
} else if block.map(|vox| vox.is_fluid()).unwrap_or(false) {
|
} else if block.map(|vox| vox.is_fluid()).unwrap_or(false) {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut fluid_mesh,
|
&mut fluid_mesh,
|
||||||
self,
|
faces_to_make(&blocks, false, |vox| vox.is_air()),
|
||||||
pos,
|
|
||||||
offs,
|
offs,
|
||||||
&colors,
|
&colors,
|
||||||
|pos, norm, col, _ao, light| {
|
|pos, norm, col, _ao, light| {
|
||||||
FluidVertex::new(pos, norm, col, light, 0.3)
|
FluidVertex::new(pos, norm, col, light, 0.3)
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
&lights,
|
&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> {
|
impl<V: BaseVol<Vox = Block> + ReadVol + Debug> Meshable for VolGrid3d<V> {
|
||||||
type Pipeline = TerrainPipeline;
|
type Pipeline = TerrainPipeline;
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
use common::vol::ReadVol;
|
|
||||||
|
|
||||||
use crate::render::{
|
use crate::render::{
|
||||||
mesh::{Mesh, Quad},
|
mesh::{Mesh, Quad},
|
||||||
Pipeline,
|
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>,
|
mesh: &mut Mesh<P>,
|
||||||
vol: &V,
|
faces: [bool; 6],
|
||||||
pos: Vec3<i32>,
|
|
||||||
offs: Vec3<f32>,
|
offs: Vec3<f32>,
|
||||||
cols: &[[[Rgba<u8>; 3]; 3]; 3],
|
cols: &[[[Rgba<u8>; 3]; 3]; 3],
|
||||||
vcons: impl Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32, f32) -> P::Vertex,
|
vcons: impl Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32, f32) -> P::Vertex,
|
||||||
error_makes_face: bool,
|
|
||||||
darknesses: &[[[f32; 3]; 3]; 3],
|
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());
|
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
|
||||||
|
|
||||||
// -x
|
// -x
|
||||||
if vol
|
if faces[0] {
|
||||||
.get(pos - Vec3::unit_x())
|
|
||||||
.map(|v| should_add(v))
|
|
||||||
.unwrap_or(error_makes_face)
|
|
||||||
{
|
|
||||||
mesh.push_quad(create_quad(
|
mesh.push_quad(create_quad(
|
||||||
offs,
|
offs,
|
||||||
Vec3::unit_z(),
|
Vec3::unit_z(),
|
||||||
@ -181,11 +172,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// +x
|
// +x
|
||||||
if vol
|
if faces[1] {
|
||||||
.get(pos + Vec3::unit_x())
|
|
||||||
.map(|v| should_add(v))
|
|
||||||
.unwrap_or(error_makes_face)
|
|
||||||
{
|
|
||||||
mesh.push_quad(create_quad(
|
mesh.push_quad(create_quad(
|
||||||
offs + Vec3::unit_x(),
|
offs + Vec3::unit_x(),
|
||||||
Vec3::unit_y(),
|
Vec3::unit_y(),
|
||||||
@ -197,11 +184,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// -y
|
// -y
|
||||||
if vol
|
if faces[2] {
|
||||||
.get(pos - Vec3::unit_y())
|
|
||||||
.map(|v| should_add(v))
|
|
||||||
.unwrap_or(error_makes_face)
|
|
||||||
{
|
|
||||||
mesh.push_quad(create_quad(
|
mesh.push_quad(create_quad(
|
||||||
offs,
|
offs,
|
||||||
Vec3::unit_x(),
|
Vec3::unit_x(),
|
||||||
@ -213,11 +196,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// +y
|
// +y
|
||||||
if vol
|
if faces[3] {
|
||||||
.get(pos + Vec3::unit_y())
|
|
||||||
.map(|v| should_add(v))
|
|
||||||
.unwrap_or(error_makes_face)
|
|
||||||
{
|
|
||||||
mesh.push_quad(create_quad(
|
mesh.push_quad(create_quad(
|
||||||
offs + Vec3::unit_y(),
|
offs + Vec3::unit_y(),
|
||||||
Vec3::unit_z(),
|
Vec3::unit_z(),
|
||||||
@ -229,11 +208,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// -z
|
// -z
|
||||||
if vol
|
if faces[4] {
|
||||||
.get(pos - Vec3::unit_z())
|
|
||||||
.map(|v| should_add(v))
|
|
||||||
.unwrap_or(error_makes_face)
|
|
||||||
{
|
|
||||||
mesh.push_quad(create_quad(
|
mesh.push_quad(create_quad(
|
||||||
offs,
|
offs,
|
||||||
Vec3::unit_y(),
|
Vec3::unit_y(),
|
||||||
@ -245,11 +220,7 @@ pub fn push_vox_verts<V: ReadVol, P: Pipeline>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// +z
|
// +z
|
||||||
if vol
|
if faces[5] {
|
||||||
.get(pos + Vec3::unit_z())
|
|
||||||
.map(|v| should_add(v))
|
|
||||||
.unwrap_or(error_makes_face)
|
|
||||||
{
|
|
||||||
mesh.push_quad(create_quad(
|
mesh.push_quad(create_quad(
|
||||||
offs + Vec3::unit_z(),
|
offs + Vec3::unit_z(),
|
||||||
Vec3::unit_x(),
|
Vec3::unit_x(),
|
||||||
|
Loading…
Reference in New Issue
Block a user