Faster meshing, better AO, colour correction

This commit is contained in:
Joshua Barretto 2019-09-24 10:01:50 +01:00
parent 2bd8967921
commit 3979dddbc1
10 changed files with 131 additions and 117 deletions

View File

@ -28,10 +28,12 @@ uniform u_bones {
out vec4 tgt_color;
void main() {
vec3 diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, diffuse_light, ambient_light);
diffuse_light += light_at(f_pos, f_norm);
vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), diffuse_light, ambient_light);
vec3 light, diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
vec3 point_light = light_at(f_pos, f_norm);
light += point_light;
diffuse_light += point_light;
vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), light, diffuse_light, ambient_light);
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);

View File

@ -37,12 +37,14 @@ void main() {
vec3 norm = warp_normal(f_norm, f_pos, tick.x);
vec3 diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, diffuse_light, ambient_light);
vec3 light, diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
diffuse_light *= f_light;
ambient_light *= f_light;
diffuse_light += light_at(f_pos, f_norm);
vec3 surf_color = illuminate(f_col, diffuse_light, ambient_light);
vec3 point_light = light_at(f_pos, f_norm);
light += point_light;
diffuse_light += point_light;
vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);

View File

@ -10,9 +10,9 @@ uniform u_lights {
#include <srgb.glsl>
vec3 illuminate(vec3 color, vec3 diffuse, vec3 ambience) {
vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) {
float avg_col = (color.r + color.g + color.b) / 3.0;
return ((color - avg_col) * ambience * 5.0 + (diffuse + ambience) * avg_col) * (diffuse + ambience);
return ((color - avg_col) * light + (diffuse + ambience) * avg_col) * (diffuse + ambience);
}
float attenuation_strength(vec3 rpos) {

View File

@ -27,13 +27,13 @@ vec3 get_sun_dir(float time_of_day) {
}
float get_sun_brightness(vec3 sun_dir) {
return max(-sun_dir.z + 0.6, 0.0) * 1.0;
return max(-sun_dir.z + 0.6, 0.0);
}
const float PERSISTENT_AMBIANCE = 0.008;
void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 diffuse_light, out vec3 ambient_light) {
const float SUN_AMBIANCE = 0.2;
void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diffuse_light, out vec3 ambient_light) {
const float SUN_AMBIANCE = 0.1;
vec3 sun_dir = get_sun_dir(time_of_day);
@ -51,7 +51,8 @@ void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 diffuse_light, out v
max(-sun_dir.z, 0)
);
diffuse_light = vec3(max(dot(-norm, sun_dir), 0.0) * sun_color * sun_light);
light = vec3(sun_color * sun_light);
diffuse_light = light * (dot(-norm, sun_dir) * 0.5 + 0.5);
ambient_light = vec3((SUN_AMBIANCE + PERSISTENT_AMBIANCE) * sun_light);
}

View File

@ -16,12 +16,14 @@ const float RENDER_DIST = 112.0;
const float FADE_DIST = 32.0;
void main() {
vec3 diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, diffuse_light, ambient_light);
vec3 light, diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
diffuse_light *= f_light;
ambient_light *= f_light;
diffuse_light += light_at(f_pos, f_norm);
vec3 surf_color = illuminate(f_col, diffuse_light, ambient_light);
vec3 point_light = light_at(f_pos, f_norm);
light += point_light;
diffuse_light += point_light;
vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);

View File

@ -18,12 +18,14 @@ out vec4 tgt_color;
#include <light.glsl>
void main() {
vec3 diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, diffuse_light, ambient_light);
vec3 light, diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
diffuse_light *= f_light;
ambient_light *= f_light;
diffuse_light += light_at(f_pos, f_norm);
vec3 surf_color = illuminate(f_col, diffuse_light, ambient_light);
vec3 point_light = light_at(f_pos, f_norm);
light += point_light;
diffuse_light += point_light;
vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);

View File

@ -37,7 +37,7 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
FigureVertex::new(
origin,
norm,
linear_to_srgb(srgb_to_linear(col) * ao * light),
linear_to_srgb(srgb_to_linear(col) * light.min(ao)),
0,
)
},
@ -47,7 +47,7 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
for x in 0..3 {
for y in 0..3 {
for z in 0..3 {
ls[x][y][z] = if self
ls[z][y][x] = if self
.get(pos + Vec3::new(x as i32, y as i32, z as i32) - 1)
.map(|v| v.is_empty())
.unwrap_or(true)

View File

@ -141,108 +141,89 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
for x in range.min.x + 1..range.max.x - 1 {
for y in range.min.y + 1..range.max.y - 1 {
for z in (range.min.z..range.max.z).rev() {
let mut lights = [[[0.0; 3]; 3]; 3];
for i in 0..3 {
for j in 0..3 {
for k in 0..3 {
lights[k][j][i] = light(
Vec3::new(x, y, range.min.z)
+ Vec3::new(i as i32, j as i32, k as i32)
- 1,
);
}
}
}
let get_color = |pos| {
self.get(pos)
.ok()
.filter(|vox| vox.is_opaque())
.and_then(|vox| vox.get_color())
.map(|col| col.map(|e| e as f32 / 255.0))
};
let mut colors = [[[None; 3]; 3]; 3];
for i in 0..3 {
for j in 0..3 {
for k in 0..3 {
colors[k][j][i] = get_color(
Vec3::new(x, y, range.min.z)
+ Vec3::new(i as i32, j as i32, k as i32)
- 1,
);
}
}
}
for z in range.min.z..range.max.z {
let pos = Vec3::new(x, y, z);
let offs = (pos - (range.min + 1) * Vec3::new(1, 1, 0)).map(|e| e as f32);
lights[0] = lights[1];
lights[1] = lights[2];
for i in 0..3 {
for j in 0..3 {
lights[2][j][i] = light(pos + Vec3::new(i as i32, j as i32, 2) - 1);
}
}
colors[0] = colors[1];
colors[1] = colors[2];
for i in 0..3 {
for j in 0..3 {
colors[2][j][i] = get_color(pos + Vec3::new(i as i32, j as i32, 2) - 1);
}
}
let block = self.get(pos).ok();
// Create mesh polygons
if let Some(col) = block
.filter(|vox| vox.is_opaque())
.and_then(|vox| vox.get_color())
{
if block.map(|vox| vox.is_opaque()).unwrap_or(false) {
vol::push_vox_verts(
&mut opaque_mesh,
self,
pos,
offs,
&{
let mut cols = [[[None; 3]; 3]; 3];
for x in 0..3 {
for y in 0..3 {
for z in 0..3 {
cols[x][y][z] = self
.get(
pos + Vec3::new(x as i32, y as i32, z as i32)
- 1,
)
.ok()
.filter(|vox| vox.is_opaque())
.and_then(|vox| vox.get_color())
.map(|col| col.map(|e| e as f32 / 255.0));
}
}
}
cols
},
&colors,
|pos, norm, col, ao, light| {
TerrainVertex::new(pos, norm, col, light * ao)
TerrainVertex::new(pos, norm, col, light.min(ao))
},
false,
&{
let mut ls = [[[0.0; 3]; 3]; 3];
for x in 0..3 {
for y in 0..3 {
for z in 0..3 {
ls[x][y][z] = light(
pos + Vec3::new(x as i32, y as i32, z as i32) - 1,
);
}
}
}
ls
},
&lights,
|vox| !vox.is_opaque(),
|vox| vox.is_opaque(),
);
} else if let Some(col) = block
.filter(|vox| vox.is_fluid())
.and_then(|vox| vox.get_color())
{
let col = col.map(|e| e as f32 / 255.0);
} else if block.map(|vox| vox.is_fluid()).unwrap_or(false) {
vol::push_vox_verts(
&mut fluid_mesh,
self,
pos,
offs,
&{
let mut cols = [[[None; 3]; 3]; 3];
for x in 0..3 {
for y in 0..3 {
for z in 0..3 {
cols[x][y][z] = self
.get(
pos + Vec3::new(x as i32, y as i32, z as i32)
- 1,
)
.ok()
.filter(|vox| vox.is_fluid())
.and_then(|vox| vox.get_color())
.map(|col| col.map(|e| e as f32 / 255.0));
}
}
}
cols
},
&colors,
|pos, norm, col, ao, light| {
FluidVertex::new(pos, norm, col, light * ao, 0.3)
FluidVertex::new(pos, norm, col, light.min(ao), 0.3)
},
false,
&{
let mut ls = [[[0.0; 3]; 3]; 3];
for x in 0..3 {
for y in 0..3 {
for z in 0..3 {
ls[x][y][z] = light(
pos + Vec3::new(x as i32, y as i32, z as i32) - 1,
);
}
}
}
ls
},
&lights,
|vox| vox.is_air(),
|vox| vox.is_opaque(),
);

View File

@ -20,17 +20,42 @@ fn get_ao_quad<V: ReadVol>(
) -> Vec4<(f32, f32)> {
dirs.windows(2)
.map(|offs| {
let (s1, s2) = (
vol.get(pos + shift + offs[0])
.map(&is_opaque)
.unwrap_or(false),
vol.get(pos + shift + offs[1])
.map(&is_opaque)
.unwrap_or(false),
);
let mut darkness = 0.0;
for x in 0..2 {
for y in 0..2 {
let dark_pos = shift + offs[0] * x + offs[1] * y + 1;
darkness += darknesses[dark_pos.x as usize][dark_pos.y as usize]
[dark_pos.z as usize]
darkness += darknesses[dark_pos.z as usize][dark_pos.y as usize]
[dark_pos.x as usize]
/ 4.0;
}
}
(darkness.powf(2.0), 1.0)
(
darkness,
if s1 && s2 {
0.0
} else {
let corner = vol
.get(pos + shift + offs[0] + offs[1])
.map(&is_opaque)
.unwrap_or(false);
// Map both 1 and 2 neighbors to 0.5 occlusion.
if s1 || s2 || corner {
0.5
} else {
1.0
}
},
)
})
.collect::<Vec4<(f32, f32)>>()
}
@ -45,6 +70,7 @@ fn get_col_quad<V: ReadVol>(
) -> Vec4<Rgb<f32>> {
dirs.windows(2)
.map(|offs| {
let primary_col = cols[1][1][1].unwrap_or(Rgb::zero());
let mut color = Rgb::zero();
let mut total = 0.0;
for x in 0..2 {
@ -52,10 +78,14 @@ fn get_col_quad<V: ReadVol>(
for z in 0..2 {
let col_pos = shift * z + offs[0] * x + offs[1] * y + 1;
if let Some(col) =
cols[col_pos.x as usize][col_pos.y as usize][col_pos.z as usize]
cols[col_pos.z as usize][col_pos.y as usize][col_pos.x as usize]
{
color += col;
total += 1.0;
if Vec3::<f32>::from(primary_col).distance_squared(Vec3::from(col))
< 0.25 * 0.25
{
color += col;
total += 1.0;
}
}
}
}
@ -64,13 +94,7 @@ fn get_col_quad<V: ReadVol>(
if total == 0.0 {
Rgb::zero()
} else {
let primary_col = cols[1][1][1].unwrap_or(Rgb::zero());
let blended_col = color / total;
if (primary_col - blended_col).map(|e| e.abs()).average() > 0.15 {
primary_col
} else {
blended_col
}
color / total
}
})
.collect()
@ -89,7 +113,7 @@ fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32, f32) -> P
let darkness = darkness_ao.map(|e| e.0);
let ao = darkness_ao.map(|e| e.1);
let ao_map = ao.map(|e| 0.05 + e.powf(1.6) * 0.95);
let ao_map = ao.map(|e| e); //0.05 + e.powf(1.2) * 0.95);
if ao[0].min(ao[2]) < ao[1].min(ao[3]) {
Quad::new(

View File

@ -230,8 +230,8 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
let snow = Rgb::new(0.8, 0.85, 1.0);
let dirt = Lerp::lerp(
Rgb::new(0.085, 0.075, 0.25),
Rgb::new(0.75, 0.45, 0.1),
Rgb::new(0.075, 0.07, 0.3),
Rgb::new(0.75, 0.55, 0.1),
marble,
);
let tundra = Lerp::lerp(snow, Rgb::new(0.01, 0.3, 0.0), 0.4 + marble * 0.6);