mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
WIP -- lighting changes and soft shadows.
This commit is contained in:
parent
9cd2b3fb0d
commit
8414987e58
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4908,6 +4908,7 @@ dependencies = [
|
||||
"log 0.4.8",
|
||||
"num 0.2.1",
|
||||
"num_cpus",
|
||||
"rayon",
|
||||
"specs",
|
||||
"uvth",
|
||||
"vek 0.10.0",
|
||||
|
@ -29,21 +29,25 @@ out vec4 tgt_color;
|
||||
|
||||
void main() {
|
||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||
vec3 view_dir = normalize(-vec3(vert_pos4) / vert_pos4.w);
|
||||
|
||||
vec3 surf_color = /*srgb_to_linear*/(model_col.rgb * f_col);
|
||||
|
||||
vec3 k_a = surf_color;
|
||||
vec3 k_d = 0.5 * surf_color;
|
||||
vec3 k_s = 0.5 * surf_color;
|
||||
vec3 k_a = vec3(0.5);
|
||||
vec3 k_d = vec3(0.5);
|
||||
vec3 k_s = vec3(0.5);
|
||||
float alpha = 2.0;
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
vec3 light_frac = light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), 2.0);
|
||||
// vec3 point_light = light_at(f_pos, f_norm);
|
||||
// vec3 light, diffuse_light, ambient_light;
|
||||
get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, k_a * point_shadow, k_d * point_shadow, k_s * point_shadow, alpha, emitted_light, reflected_light);
|
||||
get_sun_diffuse(f_norm, time_of_day.x, view_dir, k_a * (0.5 * point_shadow + 0.5 * light_frac), k_d * point_shadow, k_s * point_shadow, alpha, emitted_light, reflected_light);
|
||||
|
||||
lights_at(f_pos, f_norm, cam_to_frag, k_a * point_shadow, k_d * point_shadow, k_s * point_shadow, alpha, emitted_light, reflected_light);
|
||||
lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
// get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, surf_color * f_light * point_shadow, 0.5 * surf_color * f_light * point_shadow, 0.5 * surf_color * f_light * point_shadow, 2.0, emitted_light, reflected_light);
|
||||
|
||||
// get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0);
|
||||
@ -54,7 +58,7 @@ void main() {
|
||||
// diffuse_light += point_light;
|
||||
// reflected_light += point_light;
|
||||
// vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), light, diffuse_light, ambient_light);
|
||||
surf_color = illuminate(emitted_light, reflected_light);
|
||||
surf_color = illuminate(surf_color * emitted_light, surf_color * reflected_light);
|
||||
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
vec4 clouds;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#version 330 core
|
||||
|
||||
// https://www.shadertoy.com/view/XdsyWf
|
||||
|
||||
#include <globals.glsl>
|
||||
#include <random.glsl>
|
||||
|
||||
@ -66,6 +68,8 @@ void main() {
|
||||
vec3 f_norm = normals[norm_axis + norm_dir];
|
||||
|
||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||
vec3 view_dir = normalize(-vec3(vert_pos4) / vert_pos4.w);
|
||||
float frag_dist = length(f_pos - cam_pos.xyz);
|
||||
|
||||
vec3 b_norm;
|
||||
@ -95,22 +99,31 @@ void main() {
|
||||
|
||||
|
||||
vec4 _clouds;
|
||||
vec3 reflect_ray_dir = reflect(cam_to_frag, norm);
|
||||
vec3 reflect_ray_dir = reflect(cam_to_frag/*-view_dir*/, norm);
|
||||
/* vec4 reflect_ray_dir4 = view_mat * vec4(reflect_ray_dir, 1.0);
|
||||
reflect_ray_dir = normalize(vec3(reflect_ray_dir4) / reflect_ray_dir4.w); */
|
||||
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
vec3 reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.25, false, _clouds) * f_light;
|
||||
vec3 surf_color = /*srgb_to_linear*/(vec3(0.2, 0.5, 1.0));
|
||||
|
||||
vec3 k_a = surf_color;
|
||||
vec3 k_d = vec3(1.0);
|
||||
vec3 k_s = reflect_color;
|
||||
vec3 k_a = vec3(1.0);
|
||||
vec3 k_d = surf_color;
|
||||
vec3 k_s = 2.0 * reflect_color;
|
||||
float alpha = 0.255;
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
// vec3 light, diffuse_light, ambient_light;
|
||||
float point_shadow = shadow_at(f_pos,f_norm);
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
// 0 = 100% reflection, 1 = translucent water
|
||||
float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag), 0.5);
|
||||
get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, k_a * f_light * point_shadow, vec3(0.0), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
||||
lights_at(f_pos, f_norm, cam_to_frag, k_a * f_light * point_shadow, k_d * f_light * point_shadow, k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
||||
float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag/*-view_dir*/), -cam_to_frag/*view_dir*/), 0.5);
|
||||
vec3 diffuse_light_point = vec3(0.0);
|
||||
get_sun_diffuse(norm, time_of_day.x, view_dir, k_a * f_light * point_shadow, vec3(0.0), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
||||
lights_at(f_pos, norm, view_dir, k_a, vec3(1.0), vec3(0.0), alpha, emitted_light, diffuse_light_point);
|
||||
vec3 dump_light = vec3(0.0);
|
||||
vec3 specular_light_point = vec3(0.0);
|
||||
lights_at(f_pos, norm, view_dir, vec3(0.0), vec3(0.0), vec3(1.0), alpha, dump_light, specular_light_point);
|
||||
float reflected_light_point = diffuse_light_point.r + f_light * point_shadow;
|
||||
reflected_light += k_d * (diffuse_light_point + f_light * point_shadow) + k_s * specular_light_point;
|
||||
// get_sun_diffuse(norm, time_of_day.x, light, diffuse_light, ambient_light, 0.0);
|
||||
// diffuse_light *= f_light * point_shadow;
|
||||
// ambient_light *= f_light * point_shadow;
|
||||
@ -119,7 +132,7 @@ void main() {
|
||||
// diffuse_light += point_light;
|
||||
// reflected_light += point_light;
|
||||
// vec3 surf_color = srgb_to_linear(vec3(0.2, 0.5, 1.0)) * light * diffuse_light * ambient_light;
|
||||
surf_color = illuminate(emitted_light, reflected_light);
|
||||
surf_color = illuminate(surf_color * emitted_light, reflected_light);
|
||||
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
vec4 clouds;
|
||||
@ -133,11 +146,12 @@ void main() {
|
||||
// vec3 reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.25, false, _clouds) * f_light;
|
||||
// Tint
|
||||
// reflect_color = mix(reflect_color, surf_color, 0.6);
|
||||
|
||||
|
||||
// vec4 color = mix(vec4(reflect_color * 2.0, 1.0), vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*/(f_light * point_shadow + point_light) * 0.25)), passthrough);
|
||||
vec4 color = vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*/(/*f_light * point_shadow + point_light*/reflected_light) * 0.25));
|
||||
// vec4 color = surf_color;
|
||||
// vec4 color = mix(vec4(reflect_color * 2.0, 1.0), vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*/(/*f_light * point_shadow*/f_light * point_shadow + reflected_light_point/* + point_light*//*reflected_light*/) * 0.25)), passthrough);
|
||||
// vec4 color = mix(vec4(surf_color, 1.0), vec4(surf_color, 0.0), passthrough);
|
||||
//vec4 color = vec4(surf_color, 1.0);
|
||||
vec4 color = vec4(surf_color, mix(1.0, 1.0 / (1.0 + 0.25 * /*diffuse_light*/(/*f_light * point_shadow*/reflected_light_point)), passthrough));
|
||||
|
||||
tgt_color = color; // mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
||||
tgt_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
||||
}
|
||||
|
@ -1,6 +1,19 @@
|
||||
#include <random.glsl>
|
||||
#include <sky.glsl>
|
||||
|
||||
uniform sampler2D t_map;
|
||||
uniform sampler2D t_horizon;
|
||||
|
||||
vec3 linear_to_srgb(vec3 col) {
|
||||
vec3 s1 = vec3(sqrt(col.r), sqrt(col.g), sqrt(col.b));
|
||||
vec3 s2 = vec3(sqrt(s1.r), sqrt(s1.g), sqrt(s1.b));
|
||||
vec3 s3 = vec3(sqrt(s2.r), sqrt(s2.g), sqrt(s2.b));
|
||||
return vec3(
|
||||
mix(11.500726 * col.r, (0.585122381 * s1.r + 0.783140355 * s2.r - 0.368262736 * s3.r), clamp((col.r - 0.0060) * 10000.0, 0.0, 1.0)),
|
||||
mix(11.500726 * col.g, (0.585122381 * s1.g + 0.783140355 * s2.g - 0.368262736 * s3.g), clamp((col.g - 0.0060) * 10000.0, 0.0, 1.0)),
|
||||
mix(11.500726 * col.b, (0.585122381 * s1.b + 0.783140355 * s2.b - 0.368262736 * s3.b), clamp((col.b - 0.0060) * 10000.0, 0.0, 1.0))
|
||||
);
|
||||
}
|
||||
|
||||
vec2 pos_to_uv(vec2 pos) {
|
||||
vec2 uv_pos = (pos + 16) / 32768.0;
|
||||
@ -52,7 +65,7 @@ vec4 textureBicubic(sampler2D sampler, vec2 texCoords) {
|
||||
}
|
||||
|
||||
float alt_at(vec2 pos) {
|
||||
return texture(t_map, pos_to_uv(pos)).a * (1300.0) + 140.0;
|
||||
return texture/*textureBicubic*/(t_map, pos_to_uv(pos)).a * (1300.0) + 140.0;
|
||||
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
||||
|
||||
return 0.0
|
||||
@ -61,6 +74,79 @@ float alt_at(vec2 pos) {
|
||||
+ texture(t_noise, pos * 0.003).x * 30.0;
|
||||
}
|
||||
|
||||
float horizon_at(vec3 pos, /*float time_of_day*/vec3 light_dir) {
|
||||
// vec3 sun_dir = get_sun_dir(time_of_day);
|
||||
const float PI_2 = 3.1415926535897932384626433832795 / 2.0;
|
||||
const float MIN_LIGHT = 0.115;
|
||||
/*
|
||||
|
||||
let shade_frac = horizon_map
|
||||
.and_then(|(angles, heights)| {
|
||||
chunk_idx
|
||||
.and_then(|chunk_idx| angles.get(chunk_idx))
|
||||
.map(|&e| (e as f64, heights))
|
||||
})
|
||||
.and_then(|(e, heights)| {
|
||||
chunk_idx
|
||||
.and_then(|chunk_idx| heights.get(chunk_idx))
|
||||
.map(|&f| (e, f as f64))
|
||||
})
|
||||
.map(|(angle, height)| {
|
||||
let w = 0.1;
|
||||
if angle != 0.0 && light_direction.x != 0.0 {
|
||||
let deltax = height / angle;
|
||||
let lighty = (light_direction.y / light_direction.x * deltax).abs();
|
||||
let deltay = lighty - height;
|
||||
let s = (deltay / deltax / w).min(1.0).max(0.0);
|
||||
// Smoothstep
|
||||
s * s * (3.0 - 2.0 * s)
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
})
|
||||
.unwrap_or(1.0);
|
||||
*/
|
||||
float alt = alt_at(pos.xy);
|
||||
vec4 f_horizons = textureBicubic(t_horizon, pos_to_uv(pos.xy));
|
||||
f_horizons.xyz = linear_to_srgb(f_horizons.xyz);
|
||||
vec2 f_horizon;
|
||||
if (light_dir.z >= 0) {
|
||||
return MIN_LIGHT;
|
||||
}
|
||||
if (light_dir.x >= 0) {
|
||||
f_horizon = f_horizons.rg;
|
||||
} else {
|
||||
f_horizon = f_horizons.ba;
|
||||
}
|
||||
float angle = tan(f_horizon.x * PI_2);
|
||||
float height = f_horizon.y * /*1300.0*/1278.7266845703125 + 140.0;
|
||||
const float w = 0.1;
|
||||
float deltah = height - alt;
|
||||
if (deltah < 0.0001 || angle < 0.0001 || abs(light_dir.x) < 0.0001) {
|
||||
return 1.0;
|
||||
} else {
|
||||
float lighta = abs(light_dir.z / light_dir.x);
|
||||
float deltax = deltah / angle;
|
||||
float lighty = lighta * deltax;
|
||||
float deltay = lighty - (deltah + max(pos.z - alt, 0.0));
|
||||
float s = max(min(max(deltay, 0.0) / deltax / w, 1.0), 0.0);
|
||||
return max(/*0.2 + 0.8 * */(s * s * (3.0 - 2.0 * s)), MIN_LIGHT);
|
||||
/* if (lighta >= angle) {
|
||||
return 1.0;
|
||||
} else {
|
||||
return MIN_LIGHT;
|
||||
} */
|
||||
// float deltah = height - alt;
|
||||
// float deltah = max(height - alt, 0.0);
|
||||
// float lighty = abs(sun_dir.z / sun_dir.x * deltax);
|
||||
// float lighty = abs(sun_dir.z / sun_dir.x * deltax);
|
||||
// float deltay = lighty - /*pos.z*//*deltah*/(deltah + max(pos.z - alt, 0.0))/*deltah*/;
|
||||
// float s = max(min(max(deltay, 0.0) / deltax / w, 1.0), 0.0);
|
||||
// Smoothstep
|
||||
return max(/*0.2 + 0.8 * */(s * s * (3.0 - 2.0 * s)), MIN_LIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
vec2 splay(vec2 pos) {
|
||||
return pos * pow(length(pos) * 0.5, 3.0);
|
||||
}
|
||||
@ -96,6 +182,6 @@ vec3 lod_pos(vec2 v_pos, vec2 focus_pos) {
|
||||
|
||||
vec3 lod_col(vec2 pos) {
|
||||
//return vec3(0, 0.5, 0);
|
||||
return textureBicubic(t_map, pos_to_uv(pos)).rgb;
|
||||
return linear_to_srgb(textureBicubic(t_map, pos_to_uv(pos)).rgb);
|
||||
//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ vec3 get_moon_dir(float time_of_day) {
|
||||
return normalize(-vec3(sin(moon_angle_rad), 0.0, cos(moon_angle_rad) - 0.5));
|
||||
}
|
||||
|
||||
const float PERSISTENT_AMBIANCE = 0.025; // 0.1;
|
||||
const float PERSISTENT_AMBIANCE = 0.1; // 0.025; // 0.1;
|
||||
|
||||
float get_sun_brightness(vec3 sun_dir) {
|
||||
return max(-sun_dir.z + 0.6, 0.0) * 0.9;
|
||||
@ -95,13 +95,13 @@ void get_sun_diffuse(vec3 norm, float time_of_day, vec3 dir, vec3 k_a, vec3 k_d,
|
||||
|
||||
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
||||
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
||||
float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
||||
float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-norm, sun_dir)) * mix(0.0, 1.0, abs(sun_dir.z) * 10000.0) * 10000.0), 0.0, 0.5);
|
||||
|
||||
emitted_light = k_a * (ambient_sides + vec3(SUN_AMBIANCE * sun_light + moon_light)) + PERSISTENT_AMBIANCE;
|
||||
// TODO: Add shadows.
|
||||
reflected_light =
|
||||
sun_chroma * light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha) +
|
||||
moon_chroma * 0.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha);
|
||||
moon_chroma * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha);
|
||||
|
||||
/* light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
||||
diffuse_light =
|
||||
|
@ -11,9 +11,9 @@ vec3 srgb_to_linear(vec3 srgb) {
|
||||
//
|
||||
// Note: norm, dir, light_dir must all be normalizd.
|
||||
vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3 k_s, float alpha) {
|
||||
float ndotL = max(dot(-norm, light_dir), 0.0);
|
||||
if (ndotL > 0.0) {
|
||||
vec3 H = normalize(-light_dir + dir);
|
||||
float ndotL = max(dot(norm, -light_dir), 0.0);
|
||||
if (ndotL > 0.0/* && dot(s_norm, -light_dir) > 0.0*/) {
|
||||
vec3 H = normalize(light_dir + dir);
|
||||
// (k_d * (L ⋅ N) + k_s * (R ⋅ V)^α)
|
||||
return k_d * ndotL + k_s * pow(max(dot(norm, H), 0.0), alpha * 4.0);
|
||||
}
|
||||
|
@ -17,23 +17,76 @@ void main() {
|
||||
vec3 f_col = lod_col(f_pos.xy);
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||
vec3 view_dir = normalize(-vec3(vert_pos4) / vert_pos4.w);
|
||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
|
||||
// Note: because voxels, we reduce the normal for reflections to just its z component, dpendng on distance to camera.
|
||||
// Idea: the closer we are to facing top-down, the more the norm should tend towards up-z.
|
||||
vec3 l_norm = vec3(0.0, 0.0, 1.0);
|
||||
// vec3 l_norm = normalize(vec3(f_norm.x / max(abs(f_norm.x), 0.001), f_norm.y / max(abs(f_norm.y), 0.001), f_norm.z / max(abs(f_norm.z), 0.001)));
|
||||
// vec3 l_factor = 1.0 / (1.0 + max(abs(/*f_pos - cam_pos.xyz*//*-vec3(vert_pos4) / vert_pos4.w*/vec3(f_pos.xy, 0.0) - vec3(/*cam_pos*/focus_pos.xy, cam_to_frag)) - vec3(view_distance.x, view_distance.x, 0.0), 0.0) / vec3(32.0 * 2.0, 32.0 * 2.0, 1.0));
|
||||
// l_factor.z =
|
||||
// vec4 focus_pos4 = view_mat * vec4(focus_pos.xyz, 1.0);
|
||||
// vec3 focus_dir = normalize(-vec3(focus_pos4) / focus_pos4.w);
|
||||
float l_factor = 1.0 - pow(clamp(0.5 + 0.5 * dot(/*-view_dir*/-cam_to_frag, l_norm), 0.0, 1.0), 2.0);//1.0 / (1.0 + 0.5 * pow(max(distance(/*focus_pos.xy*/vec3(focus_pos.xy, /*vert_pos4.z / vert_pos4.w*/f_pos.z), vec3(f_pos.xy, f_pos.z))/* - view_distance.x*/ - 32.0, 0.0) / (32.0 * 1.0), /*0.5*/1.0));
|
||||
l_factor = 1.0;
|
||||
l_norm = normalize(mix(l_norm, f_norm, l_factor));
|
||||
/* l_norm = normalize(vec3(
|
||||
mix(l_norm.x, f_norm.x, clamp(pow(f_norm.x * 0.5, 64), 0, 1)),
|
||||
mix(-1.0, 1.0, clamp(pow(f_norm.y * 0.5, 64), 0, 1)),
|
||||
mix(-1.0, 1.0, clamp(pow(f_norm.z * 0.5, 64), 0, 1))
|
||||
)); */
|
||||
// f_norm = mix(l_norm, f_norm, min(1.0 / max(cam_to_frag, 0.001), 1.0));
|
||||
/* vec3 l_norm = normalize(vec3(
|
||||
mix(-1.0, 1.0, clamp(pow(f_norm.x * 0.5, 64), 0, 1)),
|
||||
mix(-1.0, 1.0, clamp(pow(f_norm.y * 0.5, 64), 0, 1)),
|
||||
mix(-1.0, 1.0, clamp(pow(f_norm.z * 0.5, 64), 0, 1))
|
||||
)); */
|
||||
|
||||
// Use f_norm here for better shadows.
|
||||
vec3 light_frac = light_reflection_factor(l_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), 4.0);
|
||||
|
||||
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||
vec3 moon_dir = get_moon_dir(time_of_day.x);
|
||||
// float sun_light = get_sun_brightness(sun_dir);
|
||||
// float moon_light = get_moon_brightness(moon_dir);
|
||||
float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
||||
float moon_shade_frac = horizon_at(f_pos, moon_dir);
|
||||
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
||||
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
||||
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
||||
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
||||
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
||||
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
||||
float shade_frac = sun_shade_frac + moon_shade_frac;
|
||||
// float brightness_denominator = (ambient_sides + vec3(SUN_AMBIANCE * sun_light + moon_light);
|
||||
|
||||
// vec3 light, diffuse_light, ambient_light;
|
||||
get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, f_col, 0.5 * f_col, 0.5 * vec3(1.0), 2.0, emitted_light, reflected_light);
|
||||
// get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, (0.25 * shade_frac + 0.25 * light_frac) * f_col, 0.5 * shade_frac * f_col, 0.5 * shade_frac * /*vec3(1.0)*/f_col, 2.0, emitted_light, reflected_light);
|
||||
get_sun_diffuse(l_norm, time_of_day.x, view_dir, 1.0 * (0.5 * light_frac + vec3(0.5 * shade_frac)), vec3(shade_frac * 0.5), /*0.5 * shade_frac * *//*vec3(1.0)*//*f_col*/vec3(shade_frac * 0.5), 4.0, emitted_light, reflected_light);
|
||||
|
||||
// emitted_light += 0.5 * vec3(SUN_AMBIANCE * sun_shade_frac * sun_light + moon_shade_frac * moon_light) * f_col * (ambient_sides + 1.0);
|
||||
|
||||
// Ambient lighting attempt: vertical light.
|
||||
// reflected_light += /*0.0125*/0.15 * 0.25 * _col * light_reflection_factor(f_norm, cam_to_frag, vec3(0, 0, -1.0), 0.5 * f_col, 0.5 * f_col, 2.0);
|
||||
// emitted_light += /*0.0125*/0.25 * f_col * ;
|
||||
// vec3 light, diffuse_light, ambient_light;
|
||||
// get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0);
|
||||
// vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
|
||||
vec3 surf_color = illuminate(emitted_light, reflected_light);
|
||||
vec3 surf_color = /*illuminate(emitted_light, reflected_light)*/illuminate(f_col * emitted_light, f_col * reflected_light);
|
||||
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
|
||||
vec4 clouds;
|
||||
vec3 fog_color = get_sky_color(cam_to_frag, time_of_day.x, cam_pos.xyz, f_pos, 1.0, true, clouds);
|
||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||
// vec3 color = surf_color;
|
||||
|
||||
float mist_factor = max(1 - (f_pos.z + (texture(t_noise, f_pos.xy * 0.0005 + time_of_day.x * 0.0003).x - 0.5) * 128.0) / 400.0, 0.0);
|
||||
// float mist_factor = max(1 - (f_pos.z + (texture(t_noise, f_pos.xy * 0.0005 + time_of_day.x * 0.0003).x - 0.5) * 128.0) / 400.0, 0.0);
|
||||
//float mist_factor = f_norm.z * 2.0;
|
||||
color = mix(color, vec3(1.0) * /*diffuse_light*/reflected_light, clamp(mist_factor * 0.00005 * distance(f_pos.xy, focus_pos.xy), 0, 0.3));
|
||||
// color = mix(color, vec3(1.0) * /*diffuse_light*/reflected_light, clamp(mist_factor * 0.00005 * distance(f_pos.xy, focus_pos.xy), 0, 0.3));
|
||||
// color = surf_color;
|
||||
|
||||
tgt_color = vec4(color, 1.0);
|
||||
}
|
||||
|
@ -17,16 +17,19 @@ const float FADE_DIST = 32.0;
|
||||
|
||||
void main() {
|
||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||
vec3 view_dir = normalize(-vec3(vert_pos4) / vert_pos4.w);
|
||||
vec3 surf_color = /*srgb_to_linear*/(f_col);
|
||||
|
||||
vec3 k_a = surf_color;
|
||||
vec3 k_d = 0.5 * surf_color;
|
||||
vec3 k_s = 0.5 * surf_color;
|
||||
vec3 k_a = vec3(1.0);
|
||||
vec3 k_d = vec3(0.5);
|
||||
vec3 k_s = vec3(0.5);
|
||||
float alpha = 2.0;
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
vec3 light_frac = light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), 2.0);
|
||||
|
||||
// vec3 light, diffuse_light, ambient_light;
|
||||
// vec3 emitted_light, reflected_light;
|
||||
@ -34,7 +37,7 @@ void main() {
|
||||
// vec3 point_light = light_at(f_pos, f_norm);
|
||||
// vec3 surf_color = srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
||||
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, k_a * f_light * point_shadow, k_d * f_light * point_shadow, k_s * f_light * point_shadow, 2.0, emitted_light, reflected_light);
|
||||
get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, k_a * (0.5 * f_light * point_shadow + 0.5 * light_frac), k_d * f_light * point_shadow, k_s * f_light * point_shadow, 2.0, emitted_light, reflected_light);
|
||||
// get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0);
|
||||
// float point_shadow = shadow_at(f_pos, f_norm);
|
||||
// diffuse_light *= f_light * point_shadow;
|
||||
@ -42,8 +45,8 @@ void main() {
|
||||
// light += point_light;
|
||||
// diffuse_light += point_light;
|
||||
// reflected_light += point_light;
|
||||
lights_at(f_pos, f_norm, cam_to_frag, k_a * f_light * point_shadow, k_d * f_light * point_shadow, k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
||||
surf_color = illuminate(emitted_light, reflected_light);
|
||||
lights_at(f_pos, f_norm, cam_to_frag, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
surf_color = illuminate(surf_color * emitted_light, surf_color * reflected_light);
|
||||
// vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
|
||||
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
|
@ -11,6 +11,7 @@ out vec4 tgt_color;
|
||||
|
||||
#include <sky.glsl>
|
||||
#include <light.glsl>
|
||||
#include <lod.glsl>
|
||||
|
||||
void main() {
|
||||
// First 3 normals are negative, next 3 are positive
|
||||
@ -24,19 +25,36 @@ void main() {
|
||||
vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
||||
|
||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||
vec3 view_dir = normalize(-vec3(vert_pos4) / vert_pos4.w);
|
||||
|
||||
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||
vec3 moon_dir = get_moon_dir(time_of_day.x);
|
||||
// float sun_light = get_sun_brightness(sun_dir);
|
||||
// float moon_light = get_moon_brightness(moon_dir);
|
||||
float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
||||
float moon_shade_frac = horizon_at(f_pos, moon_dir);
|
||||
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
||||
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
||||
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
||||
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
||||
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
||||
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
||||
float shade_frac = sun_shade_frac + moon_shade_frac;
|
||||
|
||||
vec3 surf_color = /*srgb_to_linear*/(f_col);
|
||||
vec3 k_a = 0.5 * surf_color;
|
||||
vec3 k_d = 0.5 * surf_color;
|
||||
vec3 k_s = 0.5 * surf_color;
|
||||
vec3 k_a = vec3(1.0);
|
||||
vec3 k_d = vec3(0.5);
|
||||
vec3 k_s = vec3(0.5);
|
||||
float alpha = 2.0;
|
||||
|
||||
vec3 emitted_light, reflected_light;
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
vec3 light_frac = light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), 2.0);
|
||||
|
||||
get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, k_a * f_light * point_shadow, k_d * f_light * point_shadow, k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
||||
get_sun_diffuse(f_norm, time_of_day.x, view_dir, k_a * f_light * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), k_d * f_light * point_shadow * shade_frac, k_s * f_light * point_shadow * shade_frac, alpha, emitted_light, reflected_light);
|
||||
|
||||
lights_at(f_pos, f_norm, cam_to_frag, k_a * f_light * point_shadow, k_d * f_light * point_shadow, k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
||||
lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
|
||||
// float point_shadow = shadow_at(f_pos, f_norm);
|
||||
// vec3 point_light = light_at(f_pos, f_norm);
|
||||
@ -56,13 +74,13 @@ void main() {
|
||||
// light_reflection_factorplight_reflection_factor
|
||||
|
||||
// vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
||||
surf_color = illuminate(emitted_light, reflected_light);
|
||||
surf_color = illuminate(f_col * emitted_light, f_col * reflected_light);
|
||||
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
vec4 clouds;
|
||||
vec3 fog_color = get_sky_color(cam_to_frag, time_of_day.x, cam_pos.xyz, f_pos, 1.0, true, clouds);
|
||||
vec3 color = surf_color;
|
||||
// vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||
// vec3 color = surf_color;
|
||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||
|
||||
tgt_color = vec4(color, 1.0);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ image = "0.22.3"
|
||||
num = "0.2.0"
|
||||
num_cpus = "1.10.1"
|
||||
log = "0.4.8"
|
||||
rayon = "^1.3.0"
|
||||
specs = "0.15.1"
|
||||
vek = { version = "0.10.0", features = ["serde"] }
|
||||
hashbrown = { version = "0.6.2", features = ["rayon", "serde", "nightly"] }
|
||||
|
@ -34,6 +34,7 @@ use hashbrown::HashMap;
|
||||
use image::DynamicImage;
|
||||
use log::{error, warn};
|
||||
use num::traits::FloatConst;
|
||||
use rayon::prelude::*;
|
||||
use std::{
|
||||
net::SocketAddr,
|
||||
sync::Arc,
|
||||
@ -72,6 +73,10 @@ pub struct Client {
|
||||
/// shadows, rivers, and probably foliage, cities, roads, and other
|
||||
/// structures.
|
||||
pub lod_base: Arc<DynamicImage>,
|
||||
/// The "shadow" layer for LOD. Includes east and west horizon angles and
|
||||
/// an approximate max occluder height, which we use to try to
|
||||
/// approximate soft and volumetric shadows.
|
||||
pub lod_horizon: Arc<DynamicImage>,
|
||||
/// A fully rendered map image for use with the map and minimap; note that
|
||||
/// this can be constructed dynamically by combining the layers of world
|
||||
/// map data (e.g. with shadow map data or river data), but at present
|
||||
@ -103,131 +108,137 @@ impl Client {
|
||||
let mut postbox = PostBox::to(addr)?;
|
||||
|
||||
// Wait for initial sync
|
||||
let (state, entity, server_info, lod_base, world_map) = match postbox.next_message()? {
|
||||
ServerMsg::InitialSync {
|
||||
entity_package,
|
||||
server_info,
|
||||
time_of_day,
|
||||
world_map,
|
||||
} => {
|
||||
// TODO: Display that versions don't match in Voxygen
|
||||
if server_info.git_hash != common::util::GIT_HASH.to_string() {
|
||||
log::warn!(
|
||||
"Server is running {}[{}], you are running {}[{}], versions might be \
|
||||
incompatible!",
|
||||
server_info.git_hash,
|
||||
server_info.git_date,
|
||||
common::util::GIT_HASH.to_string(),
|
||||
common::util::GIT_DATE.to_string(),
|
||||
);
|
||||
}
|
||||
let (state, entity, server_info, lod_base, lod_horizon, world_map) =
|
||||
match postbox.next_message()? {
|
||||
ServerMsg::InitialSync {
|
||||
entity_package,
|
||||
server_info,
|
||||
time_of_day,
|
||||
world_map,
|
||||
} => {
|
||||
// TODO: Display that versions don't match in Voxygen
|
||||
if server_info.git_hash != common::util::GIT_HASH.to_string() {
|
||||
log::warn!(
|
||||
"Server is running {}[{}], you are running {}[{}], versions might be \
|
||||
incompatible!",
|
||||
server_info.git_hash,
|
||||
server_info.git_date,
|
||||
common::util::GIT_HASH.to_string(),
|
||||
common::util::GIT_DATE.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
log::debug!("Auth Server: {:?}", server_info.auth_provider);
|
||||
log::debug!("Auth Server: {:?}", server_info.auth_provider);
|
||||
|
||||
// Initialize `State`
|
||||
let mut state = State::default();
|
||||
// Client-only components
|
||||
state
|
||||
.ecs_mut()
|
||||
.register::<comp::Last<comp::CharacterState>>();
|
||||
// Initialize `State`
|
||||
let mut state = State::default();
|
||||
// Client-only components
|
||||
state
|
||||
.ecs_mut()
|
||||
.register::<comp::Last<comp::CharacterState>>();
|
||||
|
||||
let entity = state.ecs_mut().apply_entity_package(entity_package);
|
||||
*state.ecs_mut().write_resource() = time_of_day;
|
||||
let entity = state.ecs_mut().apply_entity_package(entity_package);
|
||||
*state.ecs_mut().write_resource() = time_of_day;
|
||||
|
||||
let map_size = world_map.dimensions;
|
||||
let max_height = world_map.max_height;
|
||||
let rgba = world_map.rgba;
|
||||
assert_eq!(rgba.len(), (map_size.x * map_size.y) as usize);
|
||||
let [west, east] = world_map.horizons;
|
||||
let scale_angle =
|
||||
|a: u8| (a as Alt / 255.0 * <Alt as FloatConst>::FRAC_PI_2()).tan();
|
||||
let scale_height = |h: u8| h as Alt / 255.0 * max_height as Alt;
|
||||
let map_size = world_map.dimensions;
|
||||
let max_height = world_map.max_height;
|
||||
let rgba = world_map.rgba;
|
||||
assert_eq!(rgba.len(), (map_size.x * map_size.y) as usize);
|
||||
let [west, east] = world_map.horizons;
|
||||
let scale_angle =
|
||||
|a: u8| (a as Alt / 255.0 * <Alt as FloatConst>::FRAC_PI_2()).tan();
|
||||
let scale_height = |h: u8| h as Alt / 255.0 * max_height as Alt;
|
||||
|
||||
log::debug!("Preparing image...");
|
||||
let unzip_horizons = |(angles, heights): (Vec<_>, Vec<_>)| {
|
||||
(
|
||||
angles.into_iter().map(scale_angle).collect::<Vec<_>>(),
|
||||
heights.into_iter().map(scale_height).collect::<Vec<_>>(),
|
||||
)
|
||||
};
|
||||
let horizons = [unzip_horizons(west), unzip_horizons(east)];
|
||||
log::debug!("Preparing image...");
|
||||
let unzip_horizons = |(angles, heights): &(Vec<_>, Vec<_>)| {
|
||||
(
|
||||
angles.iter().copied().map(scale_angle).collect::<Vec<_>>(),
|
||||
heights
|
||||
.iter()
|
||||
.copied()
|
||||
.map(scale_height)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
};
|
||||
let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
|
||||
|
||||
// Redraw map (with shadows this time).
|
||||
let mut world_map = vec![0u32; rgba.len()];
|
||||
let mut map_config = world::sim::MapConfig::default();
|
||||
map_config.lgain = 1.0;
|
||||
map_config.gain = max_height;
|
||||
map_config.horizons = Some(&horizons);
|
||||
map_config.focus.z = 0.0;
|
||||
let rescale_height = |h: Alt| (h / max_height as Alt) as f32;
|
||||
let bounds_check = |pos: Vec2<i32>| {
|
||||
pos.reduce_partial_min() >= 0
|
||||
&& pos.x < map_size.x as i32
|
||||
&& pos.y < map_size.y as i32
|
||||
};
|
||||
map_config.generate(
|
||||
|pos| {
|
||||
let (rgba, downhill_wpos) = if bounds_check(pos) {
|
||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
let [r, g, b, a] = rgba[posi].to_le_bytes();
|
||||
// Compute downhill.
|
||||
let downhill = {
|
||||
let mut best = -1;
|
||||
let mut besth = a;
|
||||
// TODO: Fix to work for dynamic WORLD_SIZE (i.e. map_size).
|
||||
for nposi in neighbors(posi) {
|
||||
let nbh = rgba[nposi].to_le_bytes()[3];
|
||||
if nbh < besth {
|
||||
besth = nbh;
|
||||
best = nposi as isize;
|
||||
// Redraw map (with shadows this time).
|
||||
let mut world_map = vec![0u32; rgba.len()];
|
||||
let mut map_config = world::sim::MapConfig::default();
|
||||
map_config.lgain = 1.0;
|
||||
map_config.gain = max_height;
|
||||
map_config.horizons = Some(&horizons);
|
||||
// map_config.light_direction = Vec3::new(1.0, -1.0, 0.0);
|
||||
map_config.focus.z = 0.0;
|
||||
let rescale_height = |h: Alt| (h / max_height as Alt) as f32;
|
||||
let bounds_check = |pos: Vec2<i32>| {
|
||||
pos.reduce_partial_min() >= 0
|
||||
&& pos.x < map_size.x as i32
|
||||
&& pos.y < map_size.y as i32
|
||||
};
|
||||
map_config.generate(
|
||||
|pos| {
|
||||
let (rgba, downhill_wpos) = if bounds_check(pos) {
|
||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
let [r, g, b, a] = rgba[posi].to_le_bytes();
|
||||
// Compute downhill.
|
||||
let downhill = {
|
||||
let mut best = -1;
|
||||
let mut besth = a;
|
||||
// TODO: Fix to work for dynamic WORLD_SIZE (i.e. map_size).
|
||||
for nposi in neighbors(posi) {
|
||||
let nbh = rgba[nposi].to_le_bytes()[3];
|
||||
if nbh < besth {
|
||||
besth = nbh;
|
||||
best = nposi as isize;
|
||||
}
|
||||
}
|
||||
}
|
||||
best
|
||||
};
|
||||
let downhill_wpos = if downhill < 0 {
|
||||
None
|
||||
best
|
||||
};
|
||||
let downhill_wpos = if downhill < 0 {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
Vec2::new(
|
||||
(downhill as usize % map_size.x as usize) as i32,
|
||||
(downhill as usize / map_size.x as usize) as i32,
|
||||
) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
)
|
||||
};
|
||||
(Rgba::new(r, g, b, a), downhill_wpos)
|
||||
} else {
|
||||
Some(
|
||||
Vec2::new(
|
||||
(downhill as usize % map_size.x as usize) as i32,
|
||||
(downhill as usize / map_size.x as usize) as i32,
|
||||
) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
)
|
||||
(Rgba::zero(), None)
|
||||
};
|
||||
(Rgba::new(r, g, b, a), downhill_wpos)
|
||||
} else {
|
||||
(Rgba::zero(), None)
|
||||
};
|
||||
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||
let downhill_wpos = downhill_wpos
|
||||
.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
|
||||
let alt = rescale_height(scale_height(rgba.a));
|
||||
world::sim::MapSample {
|
||||
rgb: Rgb::from(rgba),
|
||||
alt: alt as Alt,
|
||||
downhill_wpos,
|
||||
connections: None,
|
||||
}
|
||||
},
|
||||
|wpos| {
|
||||
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
||||
rescale_height(if bounds_check(pos) {
|
||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
scale_height(rgba[posi].to_le_bytes()[3])
|
||||
} else {
|
||||
0.0
|
||||
})
|
||||
},
|
||||
|pos, (r, g, b, a)| {
|
||||
world_map[pos.y * map_size.x as usize + pos.x] =
|
||||
u32::from_le_bytes([r, g, b, a]);
|
||||
},
|
||||
);
|
||||
let make_raw = |rgba| -> Result<_, Error> {
|
||||
let mut raw = vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/];
|
||||
LittleEndian::write_u32_into(rgba, &mut raw);
|
||||
Ok(Arc::new(
|
||||
image::DynamicImage::ImageRgba8({
|
||||
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||
let downhill_wpos = downhill_wpos
|
||||
.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
|
||||
let alt = rescale_height(scale_height(rgba.a));
|
||||
world::sim::MapSample {
|
||||
rgb: Rgb::from(rgba),
|
||||
alt: alt as Alt,
|
||||
downhill_wpos,
|
||||
connections: None,
|
||||
}
|
||||
},
|
||||
|wpos| {
|
||||
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
||||
rescale_height(if bounds_check(pos) {
|
||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
scale_height(rgba[posi].to_le_bytes()[3])
|
||||
} else {
|
||||
0.0
|
||||
})
|
||||
},
|
||||
|pos, (r, g, b, a)| {
|
||||
world_map[pos.y * map_size.x as usize + pos.x] =
|
||||
u32::from_le_bytes([r, g, b, a]);
|
||||
},
|
||||
);
|
||||
let make_raw = |rgba| -> Result<_, Error> {
|
||||
let mut raw = vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/];
|
||||
LittleEndian::write_u32_into(rgba, &mut raw);
|
||||
Ok(Arc::new(
|
||||
image::DynamicImage::ImageRgba8({
|
||||
// Should not fail if the dimensions are correct.
|
||||
let map =
|
||||
image::ImageBuffer::from_raw(map_size.x, map_size.y, raw);
|
||||
@ -236,17 +247,29 @@ impl Client {
|
||||
// Flip the image, since Voxygen uses an orientation where rotation from
|
||||
// positive x axis to positive y axis is counterclockwise around the z axis.
|
||||
.flipv(),
|
||||
))
|
||||
};
|
||||
let lod_base = make_raw(&rgba)?;
|
||||
let world_map = make_raw(&world_map)?;
|
||||
log::debug!("Done preparing image...");
|
||||
))
|
||||
};
|
||||
let lod_base = make_raw(&rgba)?;
|
||||
let world_map = make_raw(&world_map)?;
|
||||
let horizons = (west.0, west.1, east.0, east.1)
|
||||
.into_par_iter()
|
||||
.map(|(wa, wh, ea, eh)| u32::from_le_bytes([wa, wh, ea, eh]))
|
||||
.collect::<Vec<_>>();
|
||||
let lod_horizon = make_raw(&horizons)?;
|
||||
log::debug!("Done preparing image...");
|
||||
|
||||
(state, entity, server_info, lod_base, (world_map, map_size))
|
||||
},
|
||||
ServerMsg::TooManyPlayers => return Err(Error::TooManyPlayers),
|
||||
_ => return Err(Error::ServerWentMad),
|
||||
};
|
||||
(
|
||||
state,
|
||||
entity,
|
||||
server_info,
|
||||
lod_base,
|
||||
lod_horizon,
|
||||
(world_map, map_size),
|
||||
)
|
||||
},
|
||||
ServerMsg::TooManyPlayers => return Err(Error::TooManyPlayers),
|
||||
_ => return Err(Error::ServerWentMad),
|
||||
};
|
||||
|
||||
postbox.send_message(ClientMsg::Ping);
|
||||
|
||||
@ -262,6 +285,7 @@ impl Client {
|
||||
server_info,
|
||||
world_map,
|
||||
lod_base,
|
||||
lod_horizon,
|
||||
player_list: HashMap::new(),
|
||||
|
||||
postbox,
|
||||
|
@ -23,6 +23,7 @@ gfx_defines! {
|
||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
|
@ -28,6 +28,9 @@ gfx_defines! {
|
||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
|
@ -557,6 +557,8 @@ impl Renderer {
|
||||
locals: &Consts<terrain::Locals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
map: &Texture, /* <(gfx::format::R8, gfx::format::Unorm)> */
|
||||
horizon: &Texture, /* <(gfx::format::R8, gfx::format::Unorm)> */
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
@ -574,6 +576,8 @@ impl Renderer {
|
||||
lights: lights.buf.clone(),
|
||||
shadows: shadows.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
},
|
||||
@ -654,6 +658,7 @@ impl Renderer {
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<lod_terrain::Locals>,
|
||||
map: &Texture,
|
||||
horizon: &Texture,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
@ -670,6 +675,7 @@ impl Renderer {
|
||||
globals: globals.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
map: (map.srv.clone(), map.sampler.clone()),
|
||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
},
|
||||
|
@ -12,7 +12,8 @@ use vek::*;
|
||||
pub struct Lod {
|
||||
model: Option<(u32, Model<LodTerrainPipeline>)>,
|
||||
locals: Consts<Locals>,
|
||||
map: Texture,
|
||||
pub map: Texture,
|
||||
pub horizon: Texture,
|
||||
tgt_detail: u32,
|
||||
}
|
||||
|
||||
@ -24,6 +25,9 @@ impl Lod {
|
||||
map: renderer
|
||||
.create_texture(&client.lod_base, Some(FilterMethod::Trilinear), None)
|
||||
.expect("Failed to generate map texture"),
|
||||
horizon: renderer
|
||||
.create_texture(&client.lod_horizon, Some(FilterMethod::Trilinear), None)
|
||||
.expect("Failed to generate horizon texture"),
|
||||
tgt_detail: settings.graphics.lod_detail.max(100).min(2500),
|
||||
}
|
||||
}
|
||||
@ -48,7 +52,7 @@ impl Lod {
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer, globals: &Consts<Globals>) {
|
||||
if let Some((_, model)) = self.model.as_ref() {
|
||||
renderer.render_lod_terrain(&model, globals, &self.locals, &self.map);
|
||||
renderer.render_lod_terrain(&model, globals, &self.locals, &self.map, &self.horizon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -395,6 +395,7 @@ impl Scene {
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
&self.lod,
|
||||
self.camera.get_focus_pos(),
|
||||
);
|
||||
self.figure_mgr.render(
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::SceneData;
|
||||
use super::{Lod, SceneData};
|
||||
use common::{
|
||||
assets,
|
||||
figure::Segment,
|
||||
@ -1393,6 +1393,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
globals: &Consts<Globals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
lod: &Lod,
|
||||
focus_pos: Vec3<f32>,
|
||||
) {
|
||||
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
|
||||
@ -1415,6 +1416,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
&chunk.locals,
|
||||
lights,
|
||||
shadows,
|
||||
&lod.map,
|
||||
&lod.horizon,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ impl<'a> BlockGen<'a> {
|
||||
.as_ref()
|
||||
}
|
||||
|
||||
fn get_cliff_height(
|
||||
pub fn get_cliff_height(
|
||||
column_gen: &ColumnGen<'a>,
|
||||
cache: &mut SmallCache<Option<ColumnSample<'a>>>,
|
||||
wpos: Vec2<f32>,
|
||||
|
@ -1316,6 +1316,42 @@ impl WorldSim {
|
||||
|angle: Alt| (angle.atan() * <Alt as FloatConst>::FRAC_2_PI() * 255.0).floor() as u8;
|
||||
let scale_height =
|
||||
|height: Alt| (height as Alt * 255.0 / self.max_height as Alt).floor() as u8;
|
||||
|
||||
let samples_data = {
|
||||
let column_sample = ColumnGen::new(self);
|
||||
(0..WORLD_SIZE.product())
|
||||
.into_par_iter()
|
||||
.map_init(
|
||||
|| Box::new(BlockGen::new(ColumnGen::new(self))),
|
||||
|block_gen, posi| {
|
||||
let wpos = uniform_idx_as_vec2(posi);
|
||||
let mut sample = column_sample.get(
|
||||
uniform_idx_as_vec2(posi) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
)?;
|
||||
// let zcache = block_gen.get_z_cache();
|
||||
let alt = sample.alt;
|
||||
sample.alt = alt.max(BlockGen::get_cliff_height(
|
||||
&mut block_gen.column_gen,
|
||||
&mut block_gen.column_cache,
|
||||
wpos.map(|e| e as f32),
|
||||
&sample.close_cliffs,
|
||||
sample.cliff_hill,
|
||||
32.0,
|
||||
));
|
||||
sample.basement += sample.alt - alt;
|
||||
|
||||
Some(sample)
|
||||
},
|
||||
)
|
||||
/* .map(|posi| {
|
||||
let mut sample = column_sample.get(
|
||||
uniform_idx_as_vec2(posi) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
);
|
||||
}) */
|
||||
.collect::<Vec<_>>()
|
||||
.into_boxed_slice()
|
||||
};
|
||||
|
||||
let horizons = get_horizon_map(
|
||||
map_config.lgain,
|
||||
Aabr {
|
||||
@ -1325,27 +1361,18 @@ impl WorldSim {
|
||||
CONFIG.sea_level as Alt,
|
||||
(CONFIG.sea_level + self.max_height) as Alt,
|
||||
|posi| {
|
||||
let chunk = &self.chunks[posi];
|
||||
chunk.alt.max(chunk.water_alt) as Alt
|
||||
/* let chunk = &self.chunks[posi];
|
||||
chunk.alt.max(chunk.water_alt) as Alt */
|
||||
let sample = samples_data[posi].as_ref();
|
||||
sample
|
||||
.map(|s| s.alt.max(s.water_level))
|
||||
.unwrap_or(CONFIG.sea_level) as Alt
|
||||
},
|
||||
|a| scale_angle(a),
|
||||
|h| scale_height(h),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let samples_data = {
|
||||
let column_sample = ColumnGen::new(self);
|
||||
(0..WORLD_SIZE.product())
|
||||
.into_par_iter()
|
||||
.map(|posi| {
|
||||
column_sample.get(
|
||||
uniform_idx_as_vec2(posi) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into_boxed_slice()
|
||||
};
|
||||
|
||||
let mut v = vec![0u32; WORLD_SIZE.x * WORLD_SIZE.y];
|
||||
// TODO: Parallelize again.
|
||||
let config = MapConfig {
|
||||
|
Loading…
Reference in New Issue
Block a user