More LOD fixes.

This commit is contained in:
Joshua Yanovski 2020-04-26 21:01:23 +02:00
parent 8116b21c2e
commit cc39e5734e
16 changed files with 164 additions and 55 deletions

View File

@ -83,7 +83,7 @@ void main() {
lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, 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 ao = pow(f_ao, 0.5) * 0.85 + 0.15; float ao = /*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
reflected_light *= ao; reflected_light *= ao;
emitted_light *= ao; emitted_light *= ao;

View File

@ -70,6 +70,8 @@ void main() {
// vec3 emitted_light, reflected_light; // vec3 emitted_light, reflected_light;
// vec3 light, diffuse_light, ambient_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);
// Squared to account for prior saturation.
float f_light = pow(f_light, 1.5);
// float vert_light = f_light; // float vert_light = f_light;
// vec3 light_frac = /*vec3(1.0);*/light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha); // vec3 light_frac = /*vec3(1.0);*/light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);

View File

@ -107,6 +107,8 @@ void main() {
/* vec4 reflect_ray_dir4 = view_mat * vec4(reflect_ray_dir, 1.0); /* vec4 reflect_ray_dir4 = view_mat * vec4(reflect_ray_dir, 1.0);
reflect_ray_dir = normalize(vec3(reflect_ray_dir4) / reflect_ray_dir4.w); */ reflect_ray_dir = normalize(vec3(reflect_ray_dir4) / reflect_ray_dir4.w); */
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); // vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
// Squared to account for prior saturation.
float f_light = pow(f_light, 1.5);
vec3 reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.25, false, _clouds) * f_light; vec3 reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.25, false, _clouds) * f_light;
/*const */vec3 water_color = srgb_to_linear(vec3(0.2, 0.5, 1.0)); /*const */vec3 water_color = srgb_to_linear(vec3(0.2, 0.5, 1.0));

View File

@ -70,7 +70,8 @@ float shadow_at(vec3 wpos, vec3 wnorm) {
shadow = min(shadow, shade); shadow = min(shadow, shade);
} }
return min(shadow, 1.0); // NOTE: Squared to compenate for prior saturation.
return min(shadow * shadow, 1.0);
} }
// Returns computed maximum intensity. // Returns computed maximum intensity.
@ -78,7 +79,7 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 k_a, vec3 k_d, vec
// shadow = 0.0; // shadow = 0.0;
vec3 ambient_light = vec3(0.0); vec3 ambient_light = vec3(0.0);
const float LIGHT_AMBIENCE = 0.025; const float LIGHT_AMBIENCE = 0.5;
for (uint i = 0u; i < light_shadow_count.x; i ++) { for (uint i = 0u; i < light_shadow_count.x; i ++) {
@ -97,7 +98,10 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 k_a, vec3 k_d, vec
float strength = 1.0 / distance_2; float strength = 1.0 / distance_2;
// Multiply the vec3 only once // Multiply the vec3 only once
vec3 color = /*srgb_to_linear*/(L.light_col.rgb) * (13.0 * strength * L.light_col.a * L.light_col.a/* * L.light_col.a*/); const float PI = 3.1415926535897932384626433832795;
const float PI_2 = 2 * PI;
float square_factor = /*2.0 * PI_2 * */2.0 * L.light_col.a;
vec3 color = /*srgb_to_linear*/L.light_col.rgb;
// // Only access the array once // // Only access the array once
// Shadow S = shadows[i]; // Shadow S = shadows[i];
@ -117,18 +121,21 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 k_a, vec3 k_d, vec
// Compute reflectance. // Compute reflectance.
vec3 light_dir = -difference / sqrt(distance_2); // normalize(-difference); vec3 light_dir = -difference / sqrt(distance_2); // normalize(-difference);
// light_dir = faceforward(light_dir, wnorm, light_dir); // light_dir = faceforward(light_dir, wnorm, light_dir);
reflected_light += color * (strength == 0.0 ? vec3(1.0) : light_reflection_factor(wnorm, cam_to_frag, light_dir, k_d, k_s, alpha)); bool is_direct = dot(-light_dir, wnorm) > 0.0;
// reflected_light += color * (distance_2 == 0.0 ? vec3(1.0) : light_reflection_factor(wnorm, cam_to_frag, light_dir, k_d, k_s, alpha));
vec3 direct_light = color * strength * square_factor * light_reflection_factor(wnorm, cam_to_frag, is_direct ? light_dir : -light_dir, k_d, k_s, alpha);
reflected_light += is_direct ? direct_light * square_factor : vec3(0.0);
ambient_light += is_direct ? vec3(0.0) : direct_light * LIGHT_AMBIENCE;
// light += color * (max(0, max(dot(normalize(difference), wnorm), 0.15)) + LIGHT_AMBIENCE); // light += color * (max(0, max(dot(normalize(difference), wnorm), 0.15)) + LIGHT_AMBIENCE);
// Compute emiittance. // Compute emiittance.
// float ambient_sides = clamp(mix(0.15, 0.0, abs(dot(wnorm, light_dir)) * 10000.0), 0.0, 0.15); // float ambient_sides = clamp(mix(0.15, 0.0, abs(dot(wnorm, light_dir)) * 10000.0), 0.0, 0.15);
float ambient_sides = 0.0;// max(dot(wnorm, light_dir) - 0.15, 0.15); // float ambient_sides = 0.0;// max(dot(wnorm, light_dir) - 0.15, 0.15);
// float ambient_sides = 0.0; // // float ambient_sides = 0.0;
ambient_light += color * (ambient_sides + LIGHT_AMBIENCE); // ambient_light += color * (ambient_sides + LIGHT_AMBIENCE);
} }
// shadow = shadow_at(wpos, wnorm); // shadow = shadow_at(wpos, wnorm);
// float shadow = shadow_at(wpos, wnorm); // float shadow = shadow_at(wpos, wnorm);
// emitted_light += k_a * ambient_light/* * shadow*/;// min(shadow, 1.0); emitted_light += k_a * ambient_light/* * shadow*/;// min(shadow, 1.0);
return 1.0;//ambient_light; return 1.0;//ambient_light;
} }

View File

@ -188,21 +188,33 @@ float horizon_at(vec3 pos, /*float time_of_day*/vec3 light_dir) {
} }
vec2 splay(vec2 pos) { vec2 splay(vec2 pos) {
return pos * pow(length(pos) * 0.5, 3.0); const float SPLAY_MULT = 1048576.0;
return pos * pow(length(pos) * 0.5, 3.0) * SPLAY_MULT;
} }
vec3 lod_norm(vec2 pos) { vec3 lod_norm(vec2 f_pos/*vec3 pos*/, vec4 square) {
const float SAMPLE_W = 32; // const float SAMPLE_W = 32;
float altx0 = alt_at(pos + vec2(-1.0, 0) * SAMPLE_W); // vec2 f_pos = pos.xy;
float altx1 = alt_at(pos + vec2(1.0, 0) * SAMPLE_W); // float altx0 = alt_at_real(f_pos + vec2(-1.0, 0) * SAMPLE_W);
float alty0 = alt_at(pos + vec2(0, -1.0) * SAMPLE_W); // float altx1 = alt_at_real(f_pos + vec2(1.0, 0) * SAMPLE_W);
float alty1 = alt_at(pos + vec2(0, 1.0) * SAMPLE_W); // float alty0 = alt_at_real(f_pos + vec2(0, -1.0) * SAMPLE_W);
// float alty1 = alt_at_real(f_pos + vec2(0, 1.0) * SAMPLE_W);
float altx0 = alt_at(vec2(square.x, f_pos.y));
float altx1 = alt_at(vec2(square.z, f_pos.y));
float alty0 = alt_at(vec2(f_pos.x, square.y));
float alty1 = alt_at(vec2(f_pos.x, square.w));
float slope = abs(altx1 - altx0) + abs(alty0 - alty1); float slope = abs(altx1 - altx0) + abs(alty0 - alty1);
vec3 norm = normalize(cross( // vec3 norm = normalize(cross(
vec3(2.0 * SAMPLE_W, 0.0, altx1 - altx0), // vec3(/*2.0 * SAMPLE_W*/square.z - square.x, 0.0, altx1 - altx0),
vec3(0.0, 2.0 * SAMPLE_W, alty1 - alty0) // vec3(0.0, /*2.0 * SAMPLE_W*/square.w - square.y, alty1 - alty0)
// ));
vec3 norm = normalize(vec3(
(altx0 - altx1) / (square.z - square.x),
(alty0 - alty1) / (square.w - square.y),
1.0
//(abs(square.w - square.y) + abs(square.z - square.x)) / (slope + 0.00001) // Avoid NaN
)); ));
/* vec3 norm = normalize(vec3( /* vec3 norm = normalize(vec3(
(altx0 - altx1) / (2.0 * SAMPLE_W), (altx0 - altx1) / (2.0 * SAMPLE_W),
@ -210,15 +222,22 @@ vec3 lod_norm(vec2 pos) {
(2.0 * SAMPLE_W) / (slope + 0.00001) // Avoid NaN (2.0 * SAMPLE_W) / (slope + 0.00001) // Avoid NaN
)); */ )); */
return faceforward(norm, vec3(0.0, 0.0, -1.0), norm); return faceforward(norm, vec3(0.0, 0.0, -1.0)/*pos - cam_pos.xyz*/, norm);
} }
vec3 lod_pos(vec2 v_pos, vec2 focus_pos) { vec3 lod_norm(vec2 f_pos/*vec3 pos*/) {
vec2 hpos = focus_pos.xy + splay(v_pos) * 1000000.0; const float SAMPLE_W = 32;
return lod_norm(f_pos, vec4(f_pos - vec2(SAMPLE_W), f_pos + vec2(SAMPLE_W)));
}
vec3 lod_pos(vec2 pos, vec2 focus_pos) {
// Remove spiking by "pushing" vertices towards local optima // Remove spiking by "pushing" vertices towards local optima
vec2 hpos = focus_pos + splay(pos);
vec2 nhpos = hpos; vec2 nhpos = hpos;
for (int i = 0; i < 3; i ++) { for (int i = 0; i < 3; i ++) {
// vec4 square = focus_pos.xy + vec4(splay(pos - vec2(1.0, 1.0), splay(pos + vec2(1.0, 1.0))));
nhpos -= lod_norm(hpos).xy * 15.0; nhpos -= lod_norm(hpos).xy * 15.0;
} }
hpos = hpos + normalize(nhpos - hpos + 0.001) * min(length(nhpos - hpos), 32); hpos = hpos + normalize(nhpos - hpos + 0.001) * min(length(nhpos - hpos), 32);

View File

@ -122,7 +122,7 @@ void get_sun_diffuse(vec3 norm, float time_of_day, vec3 dir, vec3 k_a, vec3 k_d,
// Returns computed maximum intensity. // Returns computed maximum intensity.
float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) { float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) {
const float SUN_AMBIANCE = 0.23 / 1.8;// 0.1 / 3.0; const float SUN_AMBIANCE = 0.23 / 3.0;/* / 1.8*/;// 0.1 / 3.0;
const float MOON_AMBIANCE = 0.23;//0.1; const float MOON_AMBIANCE = 0.23;//0.1;
float sun_light = get_sun_brightness(sun_dir); float sun_light = get_sun_brightness(sun_dir);
@ -221,7 +221,7 @@ float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 k_
vec3 R_t_r = R_d + R_r; vec3 R_t_r = R_d + R_r;
// vec3 half_vec = normalize(-norm + dir); // vec3 half_vec = normalize(-norm + dir);
vec3 light_frac = R_t_b * (sun_chroma * SUN_AMBIANCE + moon_chroma * MOON_AMBIANCE) * light_reflection_factor(norm, norm, /*-norm*/-norm, /*k_d*/k_d * (1.0 - k_s), /*k_s*/vec3(0.0), alpha); vec3 light_frac = R_t_b * (sun_chroma * SUN_AMBIANCE + moon_chroma * MOON_AMBIANCE) * light_reflection_factor(norm, /*norm*/dir, /*-norm*/-dir, /*k_d*/k_d * (1.0 - k_s), /*k_s*/vec3(0.0), alpha);
// vec3 light_frac = /*vec3(1.0)*//*H_d * */ // vec3 light_frac = /*vec3(1.0)*//*H_d * */
// SUN_AMBIANCE * /*sun_light*/sun_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_sun) * 0.5), vec3(k_s * (1.0 - cos_sun) * 0.5), alpha) + // SUN_AMBIANCE * /*sun_light*/sun_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_sun) * 0.5), vec3(k_s * (1.0 - cos_sun) * 0.5), alpha) +
// MOON_AMBIANCE * /*sun_light*/moon_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_moon) * 0.5), vec3(k_s * (1.0 - cos_moon) * 0.5), alpha); // MOON_AMBIANCE * /*sun_light*/moon_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_moon) * 0.5), vec3(k_s * (1.0 - cos_moon) * 0.5), alpha);
@ -265,7 +265,7 @@ float is_star_at(vec3 dir) {
vec3 pos = (floor(dir * star_scale) - 0.5) / star_scale; vec3 pos = (floor(dir * star_scale) - 0.5) / star_scale;
// Noisy offsets // Noisy offsets
pos += (3.0 / star_scale) * rand_perm_3(pos); pos += (3.0 / star_scale) * /*rand_perm_3*/hash(vec4(pos, 1.0));
// Find distance to fragment // Find distance to fragment
float dist = length(normalize(pos) - dir); float dist = length(normalize(pos) - dir);

View File

@ -5,20 +5,38 @@
#include <lod.glsl> #include <lod.glsl>
in vec3 f_pos; in vec3 f_pos;
// in vec3 f_norm; in vec3 f_norm;
// in vec4 f_shadow; // in vec4 f_shadow;
// in vec4 f_square;
out vec4 tgt_color; out vec4 tgt_color;
#include <sky.glsl> #include <sky.glsl>
void main() { void main() {
vec3 f_norm = lod_norm(f_pos.xy); // vec3 f_pos = lod_pos(f_pos.xy);
vec3 f_col = lod_col(f_pos.xy); vec3 f_col = lod_col(f_pos.xy);
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0); // vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/); // vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
float my_alt = /*f_pos.z;*/alt_at_real(f_pos.xy);
// vec3 f_pos = vec3(f_pos.xy, max(my_alt, f_pos.z));
/* gl_Position =
proj_mat *
view_mat *
vec4(f_pos, 1);
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0); */
vec3 my_pos = vec3(f_pos.xy, my_alt);
vec3 my_norm = lod_norm(f_pos.xy/*, f_square*/);
float which_norm = dot(my_norm, normalize(cam_pos.xyz - my_pos));
// which_norm = 0.5 + which_norm * 0.5;
which_norm = pow(max(0.0, which_norm), /*0.03125*/1 / 8.0);// * 0.5;
// which_norm = mix(0.0, 1.0, which_norm > 0.0);
vec3 f_norm = mix(faceforward(f_norm, cam_pos.xyz - f_pos, -f_norm), my_norm, which_norm);
vec3 f_pos = mix(f_pos, my_pos, which_norm);
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
vec3 view_dir = -cam_to_frag; vec3 view_dir = -cam_to_frag;
// vec3 view_dir = normalize(f_pos - cam_pos.xyz); // vec3 view_dir = normalize(f_pos - cam_pos.xyz);
@ -53,11 +71,13 @@ void main() {
vec3 moon_dir = get_moon_dir(time_of_day.x); vec3 moon_dir = get_moon_dir(time_of_day.x);
// float sun_light = get_sun_brightness(sun_dir); // float sun_light = get_sun_brightness(sun_dir);
// float moon_light = get_moon_brightness(moon_dir); // float moon_light = get_moon_brightness(moon_dir);
float my_alt = f_pos.z;//alt_at(f_pos.xy); // float my_alt = f_pos.z;//alt_at_real(f_pos.xy);
// vec3 f_norm = my_norm;
vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy)); vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
// float my_alt = alt_at(f_pos.xy); // float my_alt = alt_at(f_pos.xy);
float sun_shade_frac = horizon_at2(f_shadow, my_alt, f_pos, sun_dir); float shadow_alt = /*f_pos.z;*/alt_at(f_pos.xy);
float moon_shade_frac = horizon_at2(f_shadow, my_alt, f_pos, moon_dir); float sun_shade_frac = horizon_at2(f_shadow, shadow_alt, f_pos, sun_dir);
float moon_shade_frac = horizon_at2(f_shadow, shadow_alt, f_pos, moon_dir);
// float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir); // float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir);
// float moon_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, moon_dir); // float moon_shade_frac = horizon_at(/*f_shadow, f_pos.z, */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). // Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).

View File

@ -12,12 +12,19 @@ uniform u_locals {
}; };
out vec3 f_pos; out vec3 f_pos;
// out vec3 f_norm; out vec3 f_norm;
// out vec4 f_square;
// out vec4 f_shadow; // out vec4 f_shadow;
// out float f_light; // out float f_light;
void main() { void main() {
// Find distances between vertices.
f_pos = lod_pos(v_pos, focus_pos.xy); f_pos = lod_pos(v_pos, focus_pos.xy);
vec2 dims = vec2(1.0 / view_distance.y);
vec4 f_square = focus_pos.xyxy + vec4(splay(v_pos - dims), splay(v_pos + dims));
f_norm = lod_norm(f_pos.xy, f_square);
// f_pos = lod_pos(focus_pos.xy + splay(v_pos) * /*1000000.0*/(1 << 20), square);
// f_norm = lod_norm(f_pos.xy); // f_norm = lod_norm(f_pos.xy);
@ -25,9 +32,9 @@ void main() {
//f_pos.z -= 1.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0); //f_pos.z -= 1.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0);
//f_pos.z -= 100.0 * pow(1.0 + 0.01 / view_distance.x, -pow(distance(focus_pos.xy, f_pos.xy), 2.0)); // f_pos.z -= 100.0 * pow(1.0 + 0.01 / view_distance.x, -pow(distance(focus_pos.xy, f_pos.xy), 2.0));
// f_pos.z = mix(-f_pos.z, f_pos.z, view_distance.x <= distance(focus_pos.xy, f_pos.xy) + 32.0); // f_pos.z = mix(-f_pos.z, f_pos.z, view_distance.x <= distance(focus_pos.xy, f_pos.xy) + 32.0);
f_pos.z -= max(view_distance.x - distance(focus_pos.xy, f_pos.xy), 0.0) * 65536; f_pos.z -= max(view_distance.x - distance(focus_pos.xy, f_pos.xy), 0.0) * (1.0 + max(0.0, f_pos.z - focus_pos.z));
// f_light = 1.0; // f_light = 1.0;

View File

@ -56,7 +56,8 @@ void main() {
vec3 emitted_light, reflected_light; vec3 emitted_light, reflected_light;
float point_shadow = shadow_at(f_pos, f_norm); float point_shadow = shadow_at(f_pos, f_norm);
float vert_light = f_light; // To account for prior saturation.
float vert_light = pow(f_light, 1.5);
// vec3 light_frac = light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha); // vec3 light_frac = light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
/* light_frac += light_reflection_factor(f_norm, view_dir, vec3(1.0, 0, 0.0), vec3(1.0), vec3(1.0), 2.0); /* light_frac += light_reflection_factor(f_norm, view_dir, vec3(1.0, 0, 0.0), vec3(1.0), vec3(1.0), 2.0);
light_frac += light_reflection_factor(f_norm, view_dir, vec3(-1.0, 0, 0.0), vec3(1.0), vec3(1.0), 2.0); light_frac += light_reflection_factor(f_norm, view_dir, vec3(-1.0, 0, 0.0), vec3(1.0), vec3(1.0), 2.0);
@ -85,7 +86,7 @@ void main() {
emitted_light += point_light; emitted_light += point_light;
reflected_light += point_light; */ reflected_light += point_light; */
float ao = pow(f_ao, 0.5) * 0.85 + 0.15; float ao = /*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
emitted_light *= ao; emitted_light *= ao;
reflected_light *= ao; reflected_light *= ao;

View File

@ -68,6 +68,8 @@ void main() {
float max_light = 0.0; float max_light = 0.0;
vec3 emitted_light, reflected_light; vec3 emitted_light, reflected_light;
// To account for prior saturation
float f_light = pow(f_light, 1.5);
float point_shadow = shadow_at(f_pos, f_norm); float point_shadow = shadow_at(f_pos, f_norm);
max_light += get_sun_diffuse2(f_norm, /*time_of_day.x, */sun_dir, moon_dir, view_dir, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, emitted_light, reflected_light); max_light += get_sun_diffuse2(f_norm, /*time_of_day.x, */sun_dir, moon_dir, view_dir, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, emitted_light, reflected_light);
@ -76,7 +78,7 @@ void main() {
max_light += lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light); max_light += lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
float ao = pow(f_ao, 0.5) * 0.9 + 0.1; float ao = /*pow(f_ao, 0.5)*/f_ao * 0.9 + 0.1;
emitted_light *= ao; emitted_light *= ao;
reflected_light *= ao; reflected_light *= ao;
/* vec3 point_light = light_at(f_pos, f_norm); /* vec3 point_light = light_at(f_pos, f_norm);

View File

@ -93,13 +93,20 @@ pub fn hsv_to_rgb(hsv: Vec3<f32>) -> Rgb<f32> {
Rgb::new(r + m, g + m, b + m) Rgb::new(r + m, g + m, b + m)
} }
/// Convert linear rgb to CIEXYZ
#[inline(always)]
pub fn rgb_to_xyz(rgb: Rgb<f32>) -> Vec3<f32> {
// XYZ
Mat3::new(
0.4124, 0.3576, 0.1805, 0.2126, 0.7152, 0.0722, 0.0193, 0.1192, 0.9504,
) * Vec3::from(rgb)
}
/// Convert linear rgb to CIExyY /// Convert linear rgb to CIExyY
#[inline(always)] #[inline(always)]
pub fn rgb_to_xyy(rgb: Rgb<f32>) -> Vec3<f32> { pub fn rgb_to_xyy(rgb: Rgb<f32>) -> Vec3<f32> {
// XYZ // XYZ
let xyz = Mat3::new( let xyz = rgb_to_xyz(rgb);
0.4124, 0.3576, 0.1805, 0.2126, 0.7152, 0.0722, 0.0193, 0.1192, 0.9504,
) * Vec3::from(rgb);
let sum = xyz.sum(); let sum = xyz.sum();
Vec3::new(xyz.x / sum, xyz.y / sum, xyz.y) Vec3::new(xyz.x / sum, xyz.y / sum, xyz.y)

View File

@ -23,7 +23,8 @@ gfx_defines! {
/// NOTE: max_intensity is computed as the ratio between the brightest and least bright /// NOTE: max_intensity is computed as the ratio between the brightest and least bright
/// intensities among all lights in the scene. /// intensities among all lights in the scene.
// hdr_ratio: [f32; 4] = "max_intensity", // hdr_ratio: [f32; 4] = "max_intensity",
/// NOTE: view_distance.x is the horizontal view distance, view_distance.z is the /// NOTE: view_distance.x is the horizontal view distance, view_distance.y is the LOD
/// detail, view_distance.z is the
/// minimum height over any land chunk (i.e. the sea level), and view_distance.w is the /// minimum height over any land chunk (i.e. the sea level), and view_distance.w is the
/// maximum height over this minimum height. /// maximum height over this minimum height.
/// ///
@ -58,6 +59,7 @@ impl Globals {
cam_pos: Vec3<f32>, cam_pos: Vec3<f32>,
focus_pos: Vec3<f32>, focus_pos: Vec3<f32>,
view_distance: f32, view_distance: f32,
tgt_detail: f32,
map_bounds: Vec2<f32>, map_bounds: Vec2<f32>,
time_of_day: f64, time_of_day: f64,
tick: f64, tick: f64,
@ -76,7 +78,7 @@ impl Globals {
all_mat: arr_to_mat((proj_mat * view_mat).into_col_array()), all_mat: arr_to_mat((proj_mat * view_mat).into_col_array()),
cam_pos: Vec4::from(cam_pos).into_array(), cam_pos: Vec4::from(cam_pos).into_array(),
focus_pos: Vec4::from(focus_pos).into_array(), focus_pos: Vec4::from(focus_pos).into_array(),
view_distance: [view_distance, 0.0, map_bounds.x, map_bounds.y], view_distance: [view_distance, tgt_detail, map_bounds.x, map_bounds.y],
time_of_day: [time_of_day as f32; 4], time_of_day: [time_of_day as f32; 4],
tick: [tick as f32; 4], tick: [tick as f32; 4],
screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(), screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(),
@ -101,6 +103,7 @@ impl Default for Globals {
Vec3::zero(), Vec3::zero(),
Vec3::zero(), Vec3::zero(),
0.0, 0.0,
100.0,
Vec2::new(140.0, 2048.0), Vec2::new(140.0, 2048.0),
0.0, 0.0,
0.0, 0.0,

View File

@ -15,7 +15,7 @@ pub struct Lod {
locals: Consts<Locals>, locals: Consts<Locals>,
pub map: Texture<LodColorFmt>, pub map: Texture<LodColorFmt>,
pub horizon: Texture<LodTextureFmt>, pub horizon: Texture<LodTextureFmt>,
tgt_detail: u32, pub tgt_detail: u32,
} }
impl Lod { impl Lod {

View File

@ -351,6 +351,7 @@ impl Scene {
cam_pos, cam_pos,
self.camera.get_focus_pos(), self.camera.get_focus_pos(),
self.loaded_distance, self.loaded_distance,
self.lod.tgt_detail as f32,
self.map_bounds, self.map_bounds,
scene_data.state.get_time_of_day(), scene_data.state.get_time_of_day(),
scene_data.state.get_time(), scene_data.state.get_time(),

View File

@ -180,6 +180,7 @@ impl Scene {
cam_pos, cam_pos,
} = self.camera.dependents(); } = self.camera.dependents();
const VD: f32 = 115.0; // View Distance const VD: f32 = 115.0; // View Distance
const LOD: f32 = 100.0; // LOD detail
// const MAP_BOUNDS: Vec2<f32> = Vec2::new(140.0, 2048.0); // const MAP_BOUNDS: Vec2<f32> = Vec2::new(140.0, 2048.0);
const TIME: f64 = 43200.0; // 12 hours*3600 seconds const TIME: f64 = 43200.0; // 12 hours*3600 seconds
if let Err(err) = renderer.update_consts(&mut self.globals, &[Globals::new( if let Err(err) = renderer.update_consts(&mut self.globals, &[Globals::new(
@ -188,6 +189,7 @@ impl Scene {
cam_pos, cam_pos,
self.camera.get_focus_pos(), self.camera.get_focus_pos(),
VD, VD,
LOD,
self.map_bounds, //MAP_BOUNDS, self.map_bounds, //MAP_BOUNDS,
TIME, TIME,
scene_data.time, scene_data.time,

View File

@ -7,6 +7,7 @@ use crate::{
}; };
use common::{ use common::{
terrain::{structure::StructureBlock, Block, BlockKind, Structure}, terrain::{structure::StructureBlock, Block, BlockKind, Structure},
util::{linear_to_srgb, srgb_to_linear},
vol::{ReadVol, Vox}, vol::{ReadVol, Vox},
}; };
use std::ops::{Add, Div, Mul, Neg}; use std::ops::{Add, Div, Mul, Neg};
@ -563,20 +564,45 @@ pub fn block_from_structure(
let lerp = ((field.get(Vec3::from(structure_pos)).rem_euclid(256)) as f32 / 255.0) * 0.85 let lerp = ((field.get(Vec3::from(structure_pos)).rem_euclid(256)) as f32 / 255.0) * 0.85
+ ((field.get(pos + std::i32::MAX / 2).rem_euclid(256)) as f32 / 255.0) * 0.15; + ((field.get(pos + std::i32::MAX / 2).rem_euclid(256)) as f32 / 255.0) * 0.15;
let saturate_leaves = |col: Rgb<f32>| {
// /*saturate_srgb(col / 255.0, 0.65)*/
let rgb = srgb_to_linear(col / 255.0);
/* let mut xyy = rgb_to_xyy(rgb);
xyy.x *= xyy.x;
xyy.y *= xyy.y;
linear_to_srgb(xyy_to_rgb(xyy).map(|e| e.min(1.0).max(0.0))).map(|e| e * 255.0) */
/* let xyz = rgb_to_xyz(rgb);
let col_adjusted = if xyz.y == 0.0 {
Rgb::zero()
} else {
rgb / xyz.y
};
let col = col_adjusted * col_adjusted * xyz.y;
linear_to_srgb(col).map(|e| e * 255.0) */
/* let mut hsv = rgb_to_hsv(rgb);
hsv.y *= hsv.y;
linear_to_srgb(hsv_to_rgb(hsv).map(|e| e.min(1.0).max(0.0))).map(|e| e * 255.0) */
linear_to_srgb(rgb * rgb).map(|e| e * 255.0)
};
match sblock { match sblock {
StructureBlock::None => None, StructureBlock::None => None,
StructureBlock::TemperateLeaves => Some(Block::new( StructureBlock::TemperateLeaves => Some(Block::new(
BlockKind::Leaves, BlockKind::Leaves,
Lerp::lerp( Lerp::lerp(
Rgb::new(0.0, 132.0, 94.0), saturate_leaves(Rgb::new(0.0, 132.0, 94.0)),
Rgb::new(142.0, 181.0, 0.0), saturate_leaves(Rgb::new(142.0, 181.0, 0.0)),
lerp, lerp,
) )
.map(|e| e as u8), .map(|e| e as u8),
)), )),
StructureBlock::PineLeaves => Some(Block::new( StructureBlock::PineLeaves => Some(Block::new(
BlockKind::Leaves, BlockKind::Leaves,
Lerp::lerp(Rgb::new(0.0, 60.0, 50.0), Rgb::new(30.0, 100.0, 10.0), lerp) Lerp::lerp(
saturate_leaves(Rgb::new(0.0, 60.0, 50.0)),
saturate_leaves(Rgb::new(30.0, 100.0, 10.0)),
lerp,
)
.map(|e| e as u8), .map(|e| e as u8),
)), )),
StructureBlock::PalmLeavesInner => Some(Block::new( StructureBlock::PalmLeavesInner => Some(Block::new(
@ -597,8 +623,14 @@ pub fn block_from_structure(
) )
.map(|e| e as u8), .map(|e| e as u8),
)), )),
StructureBlock::Water => Some(Block::new(BlockKind::Water, Rgb::new(100, 150, 255))), StructureBlock::Water => Some(Block::new(
StructureBlock::GreenSludge => Some(Block::new(BlockKind::Water, Rgb::new(30, 126, 23))), BlockKind::Water,
saturate_leaves(Rgb::new(100.0, 150.0, 255.0)).map(|e| e as u8),
)),
StructureBlock::GreenSludge => Some(Block::new(
BlockKind::Water,
saturate_leaves(Rgb::new(30.0, 126.0, 23.0)).map(|e| e as u8),
)),
StructureBlock::Acacia => Some(Block::new( StructureBlock::Acacia => Some(Block::new(
BlockKind::Normal, BlockKind::Normal,
Lerp::lerp( Lerp::lerp(
@ -626,15 +658,19 @@ pub fn block_from_structure(
StructureBlock::Liana => Some(Block::new( StructureBlock::Liana => Some(Block::new(
BlockKind::Liana, BlockKind::Liana,
Lerp::lerp( Lerp::lerp(
Rgb::new(0.0, 125.0, 107.0), saturate_leaves(Rgb::new(0.0, 125.0, 107.0)),
Rgb::new(0.0, 155.0, 129.0), saturate_leaves(Rgb::new(0.0, 155.0, 129.0)),
lerp, lerp,
) )
.map(|e| e as u8), .map(|e| e as u8),
)), )),
StructureBlock::Mangrove => Some(Block::new( StructureBlock::Mangrove => Some(Block::new(
BlockKind::Normal, BlockKind::Normal,
Lerp::lerp(Rgb::new(32.0, 56.0, 22.0), Rgb::new(57.0, 69.0, 27.0), lerp) Lerp::lerp(
saturate_leaves(Rgb::new(32.0, 56.0, 22.0)),
saturate_leaves(Rgb::new(57.0, 69.0, 27.0)),
lerp,
)
.map(|e| e as u8), .map(|e| e as u8),
)), )),
StructureBlock::Hollow => Some(Block::empty()), StructureBlock::Hollow => Some(Block::empty()),