mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'ao-artifact-fix' into 'master'
Fix ambient occlusion artifact See merge request veloren/veloren!89 Former-commit-id: b529f9df722d8b174b0c8e5ce9ef2d32965d7294
This commit is contained in:
commit
3c45d3c996
@ -1,179 +1,183 @@
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
use common::vol::{ReadVol, Vox};
|
use common::vol::{ReadVol, Vox};
|
||||||
|
|
||||||
use crate::render::{
|
use crate::render::{
|
||||||
mesh::{Mesh, Quad},
|
mesh::{Mesh, Quad},
|
||||||
Pipeline,
|
Pipeline,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Given a volume, a position and the cardinal directions, compute each vertex' AO value
|
/// Given a volume, a position and the cardinal directions, compute each vertex' AO value
|
||||||
/// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice
|
/// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice
|
||||||
/// yields each vertex' adjacent positions.
|
/// yields each vertex' adjacent positions.
|
||||||
fn get_ao_quad<V: ReadVol>(vol: &V, pos: Vec3<i32>, dirs: &[Vec3<i32>]) -> Vec4<f32> {
|
fn get_ao_quad<V: ReadVol>(vol: &V, pos: Vec3<i32>, dirs: &[Vec3<i32>]) -> Vec4<f32> {
|
||||||
dirs.windows(2)
|
dirs.windows(2)
|
||||||
.map(|offs| {
|
.map(|offs| {
|
||||||
let (s1, s2) = (
|
let (s1, s2) = (
|
||||||
vol.get(pos + offs[0])
|
vol.get(pos + offs[0])
|
||||||
.map(|v| v.is_empty() as i32)
|
.map(|v| !v.is_empty())
|
||||||
.unwrap_or(1),
|
.unwrap_or(false),
|
||||||
vol.get(pos + offs[1])
|
vol.get(pos + offs[1])
|
||||||
.map(|v| v.is_empty() as i32)
|
.map(|v| !v.is_empty())
|
||||||
.unwrap_or(1),
|
.unwrap_or(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
if s1 == 0 && s2 == 0 {
|
if s1 && s2 {
|
||||||
0
|
0.0
|
||||||
} else {
|
} else {
|
||||||
let corner = vol
|
let corner = vol
|
||||||
.get(pos + offs[0] + offs[1])
|
.get(pos + offs[0] + offs[1])
|
||||||
.map(|v| v.is_empty() as i32)
|
.map(|v| !v.is_empty())
|
||||||
.unwrap_or(1);
|
.unwrap_or(false);
|
||||||
s1 + s2 + corner
|
// Map both 1 and 2 neighbors to 0.5 occlusion
|
||||||
}
|
if s1 || s2 || corner {
|
||||||
})
|
0.5
|
||||||
.map(|i| i as f32 / 3.0)
|
} else {
|
||||||
.collect::<Vec4<f32>>()
|
1.0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Utility function
|
})
|
||||||
fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex>(
|
.collect::<Vec4<f32>>()
|
||||||
origin: Vec3<f32>,
|
}
|
||||||
unit_x: Vec3<f32>,
|
|
||||||
unit_y: Vec3<f32>,
|
// Utility function
|
||||||
norm: Vec3<f32>,
|
fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex>(
|
||||||
col: Rgb<f32>,
|
origin: Vec3<f32>,
|
||||||
ao: Vec4<f32>,
|
unit_x: Vec3<f32>,
|
||||||
vcons: &F,
|
unit_y: Vec3<f32>,
|
||||||
) -> Quad<P> {
|
norm: Vec3<f32>,
|
||||||
let ao_scale = 1.0;
|
col: Rgb<f32>,
|
||||||
let dark = col * (1.0 - ao_scale);
|
ao: Vec4<f32>,
|
||||||
|
vcons: &F,
|
||||||
if ao[0] + ao[2] < ao[1] + ao[3] {
|
) -> Quad<P> {
|
||||||
Quad::new(
|
let ao_scale = 1.0;
|
||||||
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])),
|
let dark = col * (1.0 - ao_scale);
|
||||||
vcons(origin, norm, Rgb::lerp(dark, col, ao[0])),
|
|
||||||
vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])),
|
if ao[0] + ao[2] < ao[1] + ao[3] {
|
||||||
vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])),
|
Quad::new(
|
||||||
)
|
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])),
|
||||||
} else {
|
vcons(origin, norm, Rgb::lerp(dark, col, ao[0])),
|
||||||
Quad::new(
|
vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])),
|
||||||
vcons(origin, norm, Rgb::lerp(dark, col, ao[0])),
|
vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])),
|
||||||
vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])),
|
)
|
||||||
vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])),
|
} else {
|
||||||
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])),
|
Quad::new(
|
||||||
)
|
vcons(origin, norm, Rgb::lerp(dark, col, ao[0])),
|
||||||
}
|
vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])),
|
||||||
}
|
vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])),
|
||||||
|
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])),
|
||||||
pub fn push_vox_verts<
|
)
|
||||||
V: ReadVol,
|
}
|
||||||
P: Pipeline,
|
}
|
||||||
F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex,
|
|
||||||
>(
|
pub fn push_vox_verts<
|
||||||
mesh: &mut Mesh<P>,
|
V: ReadVol,
|
||||||
vol: &V,
|
P: Pipeline,
|
||||||
pos: Vec3<i32>,
|
F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex,
|
||||||
offs: Vec3<f32>,
|
>(
|
||||||
col: Rgb<f32>,
|
mesh: &mut Mesh<P>,
|
||||||
vcons: F,
|
vol: &V,
|
||||||
) {
|
pos: Vec3<i32>,
|
||||||
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
|
offs: Vec3<f32>,
|
||||||
|
col: Rgb<f32>,
|
||||||
// -x
|
vcons: F,
|
||||||
if vol
|
) {
|
||||||
.get(pos - Vec3::unit_x())
|
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
|
||||||
.map(|v| v.is_empty())
|
|
||||||
.unwrap_or(true)
|
// -x
|
||||||
{
|
if vol
|
||||||
mesh.push_quad(create_quad(
|
.get(pos - Vec3::unit_x())
|
||||||
offs,
|
.map(|v| v.is_empty())
|
||||||
Vec3::unit_z(),
|
.unwrap_or(true)
|
||||||
Vec3::unit_y(),
|
{
|
||||||
-Vec3::unit_x(),
|
mesh.push_quad(create_quad(
|
||||||
col,
|
offs,
|
||||||
get_ao_quad(vol, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]),
|
Vec3::unit_z(),
|
||||||
&vcons,
|
Vec3::unit_y(),
|
||||||
));
|
-Vec3::unit_x(),
|
||||||
}
|
col,
|
||||||
// +x
|
get_ao_quad(vol, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]),
|
||||||
if vol
|
&vcons,
|
||||||
.get(pos + Vec3::unit_x())
|
));
|
||||||
.map(|v| v.is_empty())
|
}
|
||||||
.unwrap_or(true)
|
// +x
|
||||||
{
|
if vol
|
||||||
mesh.push_quad(create_quad(
|
.get(pos + Vec3::unit_x())
|
||||||
offs + Vec3::unit_x(),
|
.map(|v| v.is_empty())
|
||||||
Vec3::unit_y(),
|
.unwrap_or(true)
|
||||||
Vec3::unit_z(),
|
{
|
||||||
Vec3::unit_x(),
|
mesh.push_quad(create_quad(
|
||||||
col,
|
offs + Vec3::unit_x(),
|
||||||
get_ao_quad(vol, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]),
|
Vec3::unit_y(),
|
||||||
&vcons,
|
Vec3::unit_z(),
|
||||||
));
|
Vec3::unit_x(),
|
||||||
}
|
col,
|
||||||
// -y
|
get_ao_quad(vol, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]),
|
||||||
if vol
|
&vcons,
|
||||||
.get(pos - Vec3::unit_y())
|
));
|
||||||
.map(|v| v.is_empty())
|
}
|
||||||
.unwrap_or(true)
|
// -y
|
||||||
{
|
if vol
|
||||||
mesh.push_quad(create_quad(
|
.get(pos - Vec3::unit_y())
|
||||||
offs,
|
.map(|v| v.is_empty())
|
||||||
Vec3::unit_x(),
|
.unwrap_or(true)
|
||||||
Vec3::unit_z(),
|
{
|
||||||
-Vec3::unit_y(),
|
mesh.push_quad(create_quad(
|
||||||
col,
|
offs,
|
||||||
get_ao_quad(vol, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]),
|
Vec3::unit_x(),
|
||||||
&vcons,
|
Vec3::unit_z(),
|
||||||
));
|
-Vec3::unit_y(),
|
||||||
}
|
col,
|
||||||
// +y
|
get_ao_quad(vol, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]),
|
||||||
if vol
|
&vcons,
|
||||||
.get(pos + Vec3::unit_y())
|
));
|
||||||
.map(|v| v.is_empty())
|
}
|
||||||
.unwrap_or(true)
|
// +y
|
||||||
{
|
if vol
|
||||||
mesh.push_quad(create_quad(
|
.get(pos + Vec3::unit_y())
|
||||||
offs + Vec3::unit_y(),
|
.map(|v| v.is_empty())
|
||||||
Vec3::unit_z(),
|
.unwrap_or(true)
|
||||||
Vec3::unit_x(),
|
{
|
||||||
Vec3::unit_y(),
|
mesh.push_quad(create_quad(
|
||||||
col,
|
offs + Vec3::unit_y(),
|
||||||
get_ao_quad(vol, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]),
|
Vec3::unit_z(),
|
||||||
&vcons,
|
Vec3::unit_x(),
|
||||||
));
|
Vec3::unit_y(),
|
||||||
}
|
col,
|
||||||
// -z
|
get_ao_quad(vol, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]),
|
||||||
if vol
|
&vcons,
|
||||||
.get(pos - Vec3::unit_z())
|
));
|
||||||
.map(|v| v.is_empty())
|
}
|
||||||
.unwrap_or(true)
|
// -z
|
||||||
{
|
if vol
|
||||||
mesh.push_quad(create_quad(
|
.get(pos - Vec3::unit_z())
|
||||||
offs,
|
.map(|v| v.is_empty())
|
||||||
Vec3::unit_y(),
|
.unwrap_or(true)
|
||||||
Vec3::unit_x(),
|
{
|
||||||
-Vec3::unit_z(),
|
mesh.push_quad(create_quad(
|
||||||
col,
|
offs,
|
||||||
get_ao_quad(vol, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]),
|
Vec3::unit_y(),
|
||||||
&vcons,
|
Vec3::unit_x(),
|
||||||
));
|
-Vec3::unit_z(),
|
||||||
}
|
col,
|
||||||
// +z
|
get_ao_quad(vol, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]),
|
||||||
if vol
|
&vcons,
|
||||||
.get(pos + Vec3::unit_z())
|
));
|
||||||
.map(|v| v.is_empty())
|
}
|
||||||
.unwrap_or(true)
|
// +z
|
||||||
{
|
if vol
|
||||||
mesh.push_quad(create_quad(
|
.get(pos + Vec3::unit_z())
|
||||||
offs + Vec3::unit_z(),
|
.map(|v| v.is_empty())
|
||||||
Vec3::unit_x(),
|
.unwrap_or(true)
|
||||||
Vec3::unit_y(),
|
{
|
||||||
Vec3::unit_z(),
|
mesh.push_quad(create_quad(
|
||||||
col,
|
offs + Vec3::unit_z(),
|
||||||
get_ao_quad(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]),
|
Vec3::unit_x(),
|
||||||
&vcons,
|
Vec3::unit_y(),
|
||||||
));
|
Vec3::unit_z(),
|
||||||
}
|
col,
|
||||||
}
|
get_ao_quad(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]),
|
||||||
|
&vcons,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user