mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Faster meshing, better AO, colour correction
This commit is contained in:
parent
2bd8967921
commit
3979dddbc1
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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(),
|
||||
);
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user