Lighting fixes

This commit is contained in:
Joshua Barretto 2019-06-18 12:33:18 +01:00
parent bf5b1cb4ad
commit bc7cee1846
5 changed files with 80 additions and 59 deletions

View File

@ -30,11 +30,11 @@ void main() {
float glob_ambience = 0.0005;
float sun_ambience = 0.8;
float sun_ambience = 0.3;
vec3 sun_dir = normalize(vec3(0.7, 1.3, 2.1));
float sun_diffuse = dot(sun_dir, f_norm);
float sun_diffuse = max(dot(sun_dir, f_norm), 0.0);
float sun_light = sun_ambience + sun_diffuse;
float static_light = glob_ambience + min(sun_light, f_light);

View File

@ -10,10 +10,6 @@ use vek::*;
type FigureVertex = <FigurePipeline as render::Pipeline>::Vertex;
fn create_vertex(origin: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>) -> FigureVertex {
FigureVertex::new(origin, norm, col, 0)
}
impl Meshable for Segment {
type Pipeline = FigurePipeline;
type Supplement = Vec3<f32>;
@ -31,8 +27,9 @@ impl Meshable for Segment {
pos,
offs + pos.map(|e| e as f32),
col,
create_vertex,
|origin, norm, col, light| FigureVertex::new(origin, norm, col * light, 0),
true,
&[[[1.0; 3]; 3]; 3],
);
}
}

View File

@ -51,19 +51,48 @@ impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone> Meshable for
for x in range.min.x + 1..range.max.x - 1 {
for y in range.min.y + 1..range.max.y - 1 {
let mut neighbour_light = [[(1.0f32, 0.0); 3]; 3];
let mut neighbour_light = [[[1.0f32; 3]; 3]; 3];
for z in (range.min.z..range.max.z).rev() {
let pos = Vec3::new(x, y, z);
// Shift lighting
neighbour_light[2] = neighbour_light[1];
neighbour_light[1] = neighbour_light[0];
// Accumulate shade under opaque blocks
for i in 0..3 {
for j in 0..3 {
neighbour_light[0][i][j] = if let Some(opacity) = self
.get(pos + Vec3::new(i as i32 - 1, j as i32 - 1, -1))
.ok()
.and_then(|vox| vox.get_opacity())
{
(neighbour_light[0][i][j] * (1.0 - opacity * 0.2)).max(1.0 - opacity * 1.0)
} else {
(neighbour_light[0][i][j] * 1.035).min(1.0)
};
}
}
// Spread light
neighbour_light[0] = [[neighbour_light[0]
.iter()
.map(|col| col.iter())
.flatten()
.copied()
.fold(0.0, |a, x| a + x) / 9.0; 3]; 3];
// Create mesh polygons
if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) {
let avg_light = neighbour_light
.iter()
.map(|row| row.iter())
.flatten()
.map(|col| col.iter())
.flatten()
.fold(0.0, |a, (x, _)| a + x)
/ 9.0;
.fold(0.0, |a, x| a + x)
/ 27.0;
let light = avg_light;
let col = col.map(|e| e as f32 / 255.0);
@ -77,30 +106,11 @@ impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone> Meshable for
pos,
offs,
col,
|pos, norm, col| TerrainVertex::new(pos, norm, col, light),
|pos, norm, col, light| TerrainVertex::new(pos, norm, col, light),
false,
&neighbour_light,
);
}
// Accumulate shade under opaque blocks
for i in 0..3 {
for j in 0..3 {
let max_opacity = neighbour_light[i][j].1;
neighbour_light[i][j] = if let Some(opacity) = self
.get(pos + Vec3::new(i as i32 - 1, j as i32 - 1, 0))
.ok()
.and_then(|vox| vox.get_opacity())
{
(
(neighbour_light[i][j].0 * (1.0 - max_opacity * 0.3))
.max(1.0 - max_opacity * 0.999),
max_opacity.max(opacity),
)
} else {
((neighbour_light[i][j].0 * 1.02).min(1.0), max_opacity)
};
}
}
}
}
}

View File

@ -10,23 +10,33 @@ use crate::render::{
/// Given volume, position, and cardinal directions, compute each vertex's AO value.
/// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice
/// 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>, shift: Vec3<i32>, dirs: &[Vec3<i32>], corners: &[[usize; 3]; 4], darknesses: &[[[f32; 3]; 3]; 3]) -> Vec4<f32> {
dirs.windows(2)
.map(|offs| {
.enumerate()
.map(|(i, offs)| {
let (s1, s2) = (
vol.get(pos + offs[0])
vol.get(pos + shift + offs[0])
.map(|v| !v.is_empty())
.unwrap_or(false),
vol.get(pos + offs[1])
vol.get(pos + shift + offs[1])
.map(|v| !v.is_empty())
.unwrap_or(false),
);
if s1 && s2 {
let darkness = darknesses[corners[i][0]][corners[i][1]][corners[i][2]];
let darkness = darknesses
.iter()
.map(|x| x.iter().map(|y| y.iter()))
.flatten()
.flatten()
.fold(0.0, |a: f32, x| a.max(*x));
darkness * if s1 && s2 {
0.0
} else {
let corner = vol
.get(pos + offs[0] + offs[1])
.get(pos + shift + offs[0] + offs[1])
.map(|v| !v.is_empty())
.unwrap_or(false);
// Map both 1 and 2 neighbors to 0.5 occlusion.
@ -41,7 +51,7 @@ fn get_ao_quad<V: ReadVol>(vol: &V, pos: Vec3<i32>, dirs: &[Vec3<i32>]) -> Vec4<
}
// Utility function
fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex>(
fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32) -> P::Vertex>(
origin: Vec3<f32>,
unit_x: Vec3<f32>,
unit_y: Vec3<f32>,
@ -53,29 +63,31 @@ fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex>(
let ao_scale = 0.95;
let dark = col * (1.0 - ao_scale);
let ao_map = ao.map(|e| 0.15 + e.powf(2.0) * 0.85);
let ao_map = ao;//ao.map(|e| 0.2 + e.powf(1.0) * 0.8);
if ao[0].min(ao[2]) < ao[1].min(ao[3]) {
Quad::new(
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])),
vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])),
vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao_map[1])),
vcons(origin + unit_y, norm, col, ao_map[3]),
vcons(origin, norm, col, ao_map[0]),
vcons(origin + unit_x, norm, col, ao_map[1]),
vcons(
origin + unit_x + unit_y,
norm,
Rgb::lerp(dark, col, ao_map[2]),
col,
ao_map[2],
),
)
} else {
Quad::new(
vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])),
vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao_map[1])),
vcons(origin, norm, col, ao_map[0]),
vcons(origin + unit_x, norm, col, ao_map[1]),
vcons(
origin + unit_x + unit_y,
norm,
Rgb::lerp(dark, col, ao_map[2]),
col,
ao_map[2],
),
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])),
vcons(origin + unit_y, norm, col, ao_map[3]),
)
}
}
@ -83,7 +95,7 @@ fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex>(
pub fn push_vox_verts<
V: ReadVol,
P: Pipeline,
F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex,
F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32) -> P::Vertex,
>(
mesh: &mut Mesh<P>,
vol: &V,
@ -92,6 +104,7 @@ pub fn push_vox_verts<
col: Rgb<f32>,
vcons: F,
error_makes_face: bool,
darknesses: &[[[f32; 3]; 3]; 3],
) {
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
@ -107,7 +120,7 @@ pub fn push_vox_verts<
Vec3::unit_y(),
-Vec3::unit_x(),
col,
get_ao_quad(vol, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]),
get_ao_quad(vol, pos, -Vec3::unit_x(), &[-z, -y, z, y, -z], &[[0; 3]; 4], darknesses),
&vcons,
));
}
@ -123,7 +136,7 @@ pub fn push_vox_verts<
Vec3::unit_z(),
Vec3::unit_x(),
col,
get_ao_quad(vol, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]),
get_ao_quad(vol, pos, Vec3::unit_x(), &[-y, -z, y, z, -y], &[[0; 3]; 4], darknesses),
&vcons,
));
}
@ -139,7 +152,7 @@ pub fn push_vox_verts<
Vec3::unit_z(),
-Vec3::unit_y(),
col,
get_ao_quad(vol, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]),
get_ao_quad(vol, pos, -Vec3::unit_y(), &[-x, -z, x, z, -x], &[[0; 3]; 4], darknesses),
&vcons,
));
}
@ -155,7 +168,7 @@ pub fn push_vox_verts<
Vec3::unit_x(),
Vec3::unit_y(),
col,
get_ao_quad(vol, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]),
get_ao_quad(vol, pos, Vec3::unit_y(), &[-z, -x, z, x, -z], &[[0; 3]; 4], darknesses),
&vcons,
));
}
@ -171,7 +184,7 @@ pub fn push_vox_verts<
Vec3::unit_x(),
-Vec3::unit_z(),
col,
get_ao_quad(vol, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]),
get_ao_quad(vol, pos, -Vec3::unit_z(), &[-y, -x, y, x, -y], &[[0; 3]; 4], darknesses),
&vcons,
));
}
@ -187,7 +200,7 @@ pub fn push_vox_verts<
Vec3::unit_y(),
Vec3::unit_z(),
col,
get_ao_quad(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]),
get_ao_quad(vol, pos, Vec3::unit_z(), &[-x, -y, x, y, -x], &[[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], darknesses),
&vcons,
));
}

View File

@ -39,9 +39,10 @@ impl<'a> Sampler for ColumnGen<'a> {
let forest_kind = sim.get(chunk_pos)?.forest_kind;
let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)?
+ sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32
* chaos.max(0.2)
* 64.0;
+ (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32)
.abs()
.mul(chaos.max(0.2))
.mul(64.0);
let rock = (sim.gen_ctx.small_nz.get(
Vec3::new(wposf.x, wposf.y, alt as f64)
@ -62,8 +63,8 @@ impl<'a> Sampler for ColumnGen<'a> {
.mul(0.5);
// Colours
let cold_grass = Rgb::new(0.0, 0.3, 0.1);
let warm_grass = Rgb::new(0.35, 1.0, 0.05);
let cold_grass = Rgb::new(0.0, 0.3, 0.15);
let warm_grass = Rgb::new(0.2, 0.8, 0.05);
let cold_stone = Rgb::new(0.55, 0.7, 0.75);
let warm_stone = Rgb::new(0.65, 0.65, 0.35);
let beach_sand = Rgb::new(0.93, 0.84, 0.4);