diff --git a/assets/voxygen/shaders/figure-frag.glsl b/assets/voxygen/shaders/figure-frag.glsl index 7a9055fd78..7f4bdac8fc 100644 --- a/assets/voxygen/shaders/figure-frag.glsl +++ b/assets/voxygen/shaders/figure-frag.glsl @@ -5,6 +5,8 @@ in vec3 f_pos; in vec3 f_col; flat in vec3 f_norm; +in float f_alt; +in vec4 f_shadow; layout (std140) uniform u_locals { @@ -23,18 +25,35 @@ uniform u_bones { #include #include -#include +#include 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); + // vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0); + // vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/); + vec3 view_dir = -cam_to_frag; + + 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); */ + float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir); + float moon_shade_frac = horizon_at2(f_shadow, f_alt, 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 = /*1.0;*/sun_shade_frac + moon_shade_frac; vec3 surf_color = /*srgb_to_linear*/(model_col.rgb * f_col); - vec3 k_a = vec3(0.5); + vec3 k_a = vec3(1.0); vec3 k_d = vec3(0.5); vec3 k_s = vec3(0.5); float alpha = 2.0; @@ -42,12 +61,16 @@ void main() { 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_frac = /*vec3(1.0);*//*vec3(max(dot(-f_norm, sun_dir) * 0.5 + 0.5, 0.0));*/light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), alpha); // vec3 point_light = light_at(f_pos, f_norm); // vec3 light, diffuse_light, ambient_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); + //get_sun_diffuse(f_norm, time_of_day.x, view_dir, k_a * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), k_d * point_shadow * shade_frac, k_s * point_shadow * shade_frac, alpha, emitted_light, reflected_light); + get_sun_diffuse2(f_norm, sun_dir, moon_dir, view_dir, k_a * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), k_d * point_shadow * shade_frac, k_s * point_shadow * shade_frac, alpha, emitted_light, reflected_light); lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light); + /* vec3 point_light = light_at(f_pos, f_norm); + emitted_light += point_light; + reflected_light += point_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); @@ -62,7 +85,7 @@ void main() { 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, 0.5, true, clouds); + vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds); vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a); tgt_color = vec4(color, 1.0); diff --git a/assets/voxygen/shaders/figure-vert.glsl b/assets/voxygen/shaders/figure-vert.glsl index eced69e5ea..4215a7f292 100644 --- a/assets/voxygen/shaders/figure-vert.glsl +++ b/assets/voxygen/shaders/figure-vert.glsl @@ -1,6 +1,7 @@ #version 330 core #include +#include in vec3 v_pos; in vec3 v_norm; @@ -25,6 +26,8 @@ uniform u_bones { out vec3 f_pos; out vec3 f_col; flat out vec3 f_norm; +out float f_alt; +out vec4 f_shadow; void main() { // Pre-calculate bone matrix @@ -42,6 +45,10 @@ void main() { vec4(v_norm, 0.0) ).xyz); + // Also precalculate shadow texture and estimated terrain altitude. + f_alt = alt_at(f_pos.xy); + f_shadow = textureBicubic(t_horizon, pos_to_uv(f_pos.xy)); + gl_Position = all_mat * vec4(f_pos, 1); gl_Position.z = -1000.0 / (gl_Position.z + 10000.0); } diff --git a/assets/voxygen/shaders/fluid-frag/cheap.glsl b/assets/voxygen/shaders/fluid-frag/cheap.glsl index 3b4e83915f..bcbf46c35f 100644 --- a/assets/voxygen/shaders/fluid-frag/cheap.glsl +++ b/assets/voxygen/shaders/fluid-frag/cheap.glsl @@ -20,6 +20,7 @@ out vec4 tgt_color; #include #include +#include void main() { // First 3 normals are negative, next 3 are positive @@ -33,11 +34,21 @@ void main() { vec3 f_norm = normals[norm_axis + norm_dir]; vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); - vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0)); + // vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0); + // vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/); + vec3 view_dir = -cam_to_frag; + // vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0)); + vec3 surf_color = /*srgb_to_linear*/(vec3(0.2, 0.5, 1.0)); - vec3 k_a = 0.5 * surf_color; - vec3 k_d = vec3(1.0); - vec3 k_s = 0.5 * vec3(1.0); + vec3 sun_dir = get_sun_dir(time_of_day.x); + vec3 moon_dir = get_moon_dir(time_of_day.x); + 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 shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac; + + vec3 k_a = vec3(0.5); + vec3 k_d = vec3(0.5) * surf_color; + vec3 k_s = vec3(0.5) * surf_color; float alpha = 0.255; vec3 emitted_light, reflected_light; @@ -47,8 +58,11 @@ void main() { // vec3 emitted_light, reflected_light; // vec3 light, diffuse_light, ambient_light; float point_shadow = shadow_at(f_pos,f_norm); + // 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(1.0), alpha); + // vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0)); - get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, k_a * f_light * point_shadow, vec3(0.0), k_s * f_light * point_shadow, alpha, emitted_light, reflected_light); + get_sun_diffuse(f_norm, time_of_day.x, /*-cam_to_frag*/view_dir, k_a * f_light * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), vec3(0.0), k_s * f_light * point_shadow * shade_frac, alpha, emitted_light, reflected_light); // get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 0.0); // diffuse_light *= f_light * point_shadow; // ambient_light *= f_light, point_shadow; @@ -57,16 +71,30 @@ void main() { // diffuse_light += point_light; // reflected_light += point_light; // vec3 surf_color = srgb_to_linear(vec3(0.4, 0.7, 2.0)) * light * diffuse_light * ambient_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, 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); + /*vec3 point_light = light_at(f_pos, f_norm); + emitted_light += point_light; + reflected_light += point_light; */ + + vec3 diffuse_light_point = vec3(0.0); + lights_at(f_pos, f_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, f_norm, view_dir, vec3(0.0), vec3(0.0), vec3(1.0), alpha, dump_light, specular_light_point); + + float reflected_light_point = length(diffuse_light_point) + f_light * point_shadow; + reflected_light += k_d * (diffuse_light_point + f_light * point_shadow * shade_frac) + k_s * specular_light_point; float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x); vec4 clouds; - vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, cam_pos.xyz, f_pos, 0.25, true, clouds); + vec3 fog_color = get_sky_color(cam_to_frag, time_of_day.x, cam_pos.xyz, f_pos, 0.25, true, clouds); - float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag), 0.5); + float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag/*view_dir*/), -cam_to_frag/*view_dir*/), 0.5); - surf_color = illuminate(emitted_light, reflected_light); - vec4 color = mix(vec4(surf_color, 1.0), vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*//*(f_light * point_shadow + point_light)*/reflected_light * 0.25)), passthrough); + surf_color = illuminate(surf_color * emitted_light, /*surf_color * */reflected_light); + vec4 color = mix(vec4(surf_color, 1.0), vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*//*(f_light * point_shadow + point_light)*/reflected_light_point/* * 0.25*/)), passthrough); tgt_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a); } diff --git a/assets/voxygen/shaders/fluid-frag/shiny.glsl b/assets/voxygen/shaders/fluid-frag/shiny.glsl index 23360a25b2..b7ea945f5d 100644 --- a/assets/voxygen/shaders/fluid-frag/shiny.glsl +++ b/assets/voxygen/shaders/fluid-frag/shiny.glsl @@ -22,6 +22,7 @@ out vec4 tgt_color; #include #include +#include vec3 warp_normal(vec3 norm, vec3 pos, float time) { return normalize(norm @@ -68,8 +69,9 @@ 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); + // vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0); + // vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/); + vec3 view_dir = -cam_to_frag; float frag_dist = length(f_pos - cam_pos.xyz); vec3 b_norm; @@ -106,24 +108,39 @@ 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; vec3 surf_color = /*srgb_to_linear*/(vec3(0.2, 0.5, 1.0)); - vec3 k_a = vec3(1.0); - vec3 k_d = surf_color; + vec3 sun_dir = get_sun_dir(time_of_day.x); + vec3 moon_dir = get_moon_dir(time_of_day.x); + 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 shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac; + + vec3 k_a = vec3(0.5); + vec3 k_d = 0.5 * 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); + 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(1.0), alpha); // 0 = 100% reflection, 1 = translucent water - float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag/*-view_dir*/), -cam_to_frag/*view_dir*/), 0.5); + float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag/*view_dir*/), -cam_to_frag/*view_dir*/), 0.5); + + get_sun_diffuse(norm, time_of_day.x, view_dir, k_a * f_light * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), vec3(0.0), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s * f_light * point_shadow * shade_frac, alpha, emitted_light, reflected_light); + 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; + + float reflected_light_point = length(diffuse_light_point/*.r*/) + f_light * point_shadow; + reflected_light += k_d * (diffuse_light_point + f_light * point_shadow * shade_frac) + k_s * specular_light_point; + /* vec3 point_light = light_at(f_pos, norm); + emitted_light += point_light; + reflected_light += point_light; */ + // 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; @@ -136,7 +153,7 @@ void main() { 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, 0.25, true, clouds); + vec3 fog_color = get_sky_color(cam_to_frag/*-view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.25, true, clouds); // vec3 reflect_ray_dir = reflect(cam_to_frag, norm); // Hack to prevent the reflection ray dipping below the horizon and creating weird blue spots in the water @@ -151,7 +168,7 @@ void main() { // 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)); + 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 = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a); } diff --git a/assets/voxygen/shaders/include/lod.glsl b/assets/voxygen/shaders/include/lod.glsl index 36587b24b7..9ebbb04152 100644 --- a/assets/voxygen/shaders/include/lod.glsl +++ b/assets/voxygen/shaders/include/lod.glsl @@ -1,20 +1,10 @@ #include #include +#include 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; return vec2(uv_pos.x, 1.0 - uv_pos.y); @@ -65,7 +55,7 @@ vec4 textureBicubic(sampler2D sampler, vec2 texCoords) { } float alt_at(vec2 pos) { - return texture/*textureBicubic*/(t_map, pos_to_uv(pos)).a * (1300.0) + 140.0; + return texture/*textureBicubic*/(t_map, pos_to_uv(pos)).a * (/*1300.0*/1278.7266845703125) + 140.0; //+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0; return 0.0 @@ -74,10 +64,12 @@ 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) { +float horizon_at2(vec4 f_horizons, float alt, 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; + const float MIN_LIGHT = 0.115/*0.0*/; + + // return 1.0; /* let shade_frac = horizon_map @@ -106,30 +98,38 @@ float horizon_at(vec3 pos, /*float time_of_day*/vec3 light_dir) { }) .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; + // vec2 f_horizon; if (light_dir.z >= 0) { - return MIN_LIGHT; + return 0.0; } - if (light_dir.x >= 0) { + /* if (light_dir.x >= 0) { f_horizon = f_horizons.rg; + // f_horizon = f_horizons.ba; } else { f_horizon = f_horizons.ba; + // f_horizon = f_horizons.rg; } + return 1.0; */ + /* bvec2 f_mode = lessThan(vec2(light_dir.x), vec2(1.0)); + f_horizon = mix(f_horizons.ba, f_horizons.rg, f_mode); */ + // f_horizon = mix(f_horizons.rg, f_horizons.ba, clamp(light_dir.x * 10000.0, 0.0, 1.0)); + vec2 f_horizon = mix(f_horizons.rg, f_horizons.ba, bvec2(light_dir.x < 0.0)); + // vec2 f_horizon = mix(f_horizons.ba, f_horizons.rg, clamp(light_dir.x * 10000.0, 0.0, 1.0)); + // f_horizon = mix(f_horizons.ba, f_horizons.rg, bvec2(lessThan(light_dir.xx, vec2(0.0)))); 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; + //if (deltah < 0.0001/* || angle < 0.0001 || abs(light_dir.x) < 0.0001*/) { + // return 1.0; + /*} else */{ + float lighta = /*max*/(-light_dir.z/*, 0.0*/) / max(abs(light_dir.x), 0.0001); + // NOTE: Ideally, deltah <= 0.0 is a sign we have an oblique horizon angle. + float deltax = max(deltah, 0.0) / max(angle, 0.0001); 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); + float deltay = lighty - deltah + max(pos.z - alt, 0.0); + // NOTE: the "real" deltah should always be >= 0, so we know we're only handling the 0 case with max. + float s = max(min(max(deltay, 0.0) / max(deltax, 0.0001) / 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; @@ -143,10 +143,17 @@ float horizon_at(vec3 pos, /*float time_of_day*/vec3 light_dir) { // 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); + // return max(/*0.2 + 0.8 * */(s * s * (3.0 - 2.0 * s)), MIN_LIGHT); } } +float horizon_at(vec3 pos, /*float time_of_day*/vec3 light_dir) { + vec4 f_horizons = textureBicubic(t_horizon, pos_to_uv(pos.xy)); + f_horizons.xyz = /*linear_to_srgb*/(f_horizons.xyz); + float alt = alt_at(pos.xy); + return horizon_at2(f_horizons, alt, pos, light_dir); +} + vec2 splay(vec2 pos) { return pos * pow(length(pos) * 0.5, 3.0); } @@ -182,6 +189,6 @@ vec3 lod_pos(vec2 v_pos, vec2 focus_pos) { vec3 lod_col(vec2 pos) { //return vec3(0, 0.5, 0); - return linear_to_srgb(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; } diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index 9565b27303..8e8208d367 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -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.1; // 0.025; // 0.1; +const float PERSISTENT_AMBIANCE = 0.025; // 0.1; // 0.025; // 0.1; float get_sun_brightness(vec3 sun_dir) { return max(-sun_dir.z + 0.6, 0.0) * 0.9; @@ -111,6 +111,41 @@ void get_sun_diffuse(vec3 norm, float time_of_day, vec3 dir, vec3 k_a, vec3 k_d, ambient_light = vec3(SUN_AMBIANCE * sun_light + moon_light); */ } +void 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.1; + + float sun_light = get_sun_brightness(sun_dir); + float moon_light = get_moon_brightness(moon_dir); + + vec3 sun_color = get_sun_color(sun_dir); + vec3 moon_color = get_moon_color(moon_dir); + + vec3 sun_chroma = sun_color * sun_light; + vec3 moon_chroma = moon_color * moon_light; + + /* float NLsun = max(dot(-norm, sun_dir), 0); + float NLmoon = max(dot(-norm, moon_dir), 0); + vec3 E = -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(-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 * 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 = + sun_chroma * mix(1.0, max(dot(-norm, sun_dir) * 0.5 + 0.5, 0.0), diffusion) + + moon_chroma * mix(1.0, pow(dot(-norm, moon_dir) * 2.0, 2.0), diffusion) + + PERSISTENT_AMBIANCE; + ambient_light = vec3(SUN_AMBIANCE * sun_light + moon_light); */ +} + + // This has been extracted into a function to allow quick exit when detecting a star. float is_star_at(vec3 dir) { float star_scale = 80.0; diff --git a/assets/voxygen/shaders/include/srgb.glsl b/assets/voxygen/shaders/include/srgb.glsl index 9654e7fb6b..6f98bd2ade 100644 --- a/assets/voxygen/shaders/include/srgb.glsl +++ b/assets/voxygen/shaders/include/srgb.glsl @@ -7,15 +7,26 @@ vec3 srgb_to_linear(vec3 srgb) { return mix(higher, lower, cutoff); } +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)) + ); +} + // Phong reflection. // // 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/* && dot(s_norm, -light_dir) > 0.0*/) { - vec3 H = normalize(light_dir + dir); + //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); - } - return vec3(0.0); + return k_d * ndotL + mix(k_s * pow(max(dot(norm, H), 0.0), alpha * 4.0), vec3(0.0), bvec3(ndotL == 0.0)); + // } + // return vec3(0.0); } diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index 01e99f45aa..d4d2082c4d 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -5,7 +5,8 @@ #include in vec3 f_pos; -in vec3 f_norm; +// in vec3 f_norm; +// in vec4 f_shadow; out vec4 tgt_color; @@ -16,22 +17,26 @@ 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); + // 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); + vec3 view_dir = -cam_to_frag; + // vec3 view_dir = 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; // = 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)); + + // 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 = f_norm; + /* 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)), @@ -44,15 +49,15 @@ void main() { 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); + /* float my_alt = alt_at(f_pos.xy); + float sun_shade_frac = horizon_at2(f_shadow, my_alt, f_pos, sun_dir); + float moon_shade_frac = horizon_at2(f_shadow, my_alt, f_pos, moon_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); // 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); @@ -62,9 +67,17 @@ void main() { float shade_frac = sun_shade_frac + moon_shade_frac; // float brightness_denominator = (ambient_sides + vec3(SUN_AMBIANCE * sun_light + moon_light); + float alpha = 2.0; + + vec3 emitted_light, reflected_light; + // Use f_norm here for better shadows. + vec3 light_frac = light_reflection_factor(f_norm/*l_norm*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), alpha); + // vec3 light, diffuse_light, ambient_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); + get_sun_diffuse2(f_norm/*l_norm*/, sun_dir, moon_dir, 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), alpha, emitted_light, reflected_light); + // emitted_light = vec3(1.0); + // reflected_light = vec3(0.0); // emitted_light += 0.5 * vec3(SUN_AMBIANCE * sun_shade_frac * sun_light + moon_shade_frac * moon_light) * f_col * (ambient_sides + 1.0); @@ -79,13 +92,13 @@ void main() { 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 fog_color = get_sky_color(cam_to_frag/*view_dir*/, 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); diff --git a/assets/voxygen/shaders/lod-terrain-vert.glsl b/assets/voxygen/shaders/lod-terrain-vert.glsl index 170e490cc0..3a895e9b05 100644 --- a/assets/voxygen/shaders/lod-terrain-vert.glsl +++ b/assets/voxygen/shaders/lod-terrain-vert.glsl @@ -12,20 +12,24 @@ uniform u_locals { }; out vec3 f_pos; -out vec3 f_norm; -out float f_light; +// out vec3 f_norm; +// out vec4 f_shadow; +// out float f_light; void main() { f_pos = lod_pos(v_pos, focus_pos.xy); - f_norm = lod_norm(f_pos.xy); + // f_norm = lod_norm(f_pos.xy); + + // f_shadow = textureBicubic(t_horizon, pos_to_uv(f_pos.xy)); //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 = 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); - f_light = 1.0; + // f_light = 1.0; gl_Position = proj_mat * diff --git a/assets/voxygen/shaders/sprite-frag.glsl b/assets/voxygen/shaders/sprite-frag.glsl index f07ed32810..8eb6b11a3b 100644 --- a/assets/voxygen/shaders/sprite-frag.glsl +++ b/assets/voxygen/shaders/sprite-frag.glsl @@ -11,15 +11,32 @@ out vec4 tgt_color; #include #include +#include const float RENDER_DIST = 112.0; 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); + // vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0); + // vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/); + vec3 view_dir = -cam_to_frag; + + 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*//*linear_to_srgb*/(f_col); vec3 k_a = vec3(1.0); vec3 k_d = vec3(0.5); @@ -29,7 +46,12 @@ void main() { 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); + float vert_light = f_light; + vec3 light_frac = light_reflection_factor(/*f_norm*/vec3(0, 0, 1.0), view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), 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(0.0, -1.0, 0.0), vec3(1.0), vec3(1.0), 2.0); + light_frac += light_reflection_factor(f_norm, view_dir, vec3(0.0, 1.0, 0.0), vec3(1.0), vec3(1.0), 2.0); */ // vec3 light, diffuse_light, ambient_light; // vec3 emitted_light, reflected_light; @@ -37,7 +59,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 * (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, /*cam_to_frag*/view_dir, k_a * vert_light * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), k_d * vert_light * point_shadow * shade_frac, k_s * vert_light * point_shadow * shade_frac, 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; @@ -45,13 +67,18 @@ void main() { // light += point_light; // diffuse_light += point_light; // reflected_light += point_light; + lights_at(f_pos, f_norm, cam_to_frag, k_a, k_d, k_s, alpha, emitted_light, reflected_light); + /* vec3 point_light = light_at(f_pos, f_norm); + emitted_light += point_light; + reflected_light += point_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); vec4 clouds; - vec3 fog_color = get_sky_color(cam_to_frag, time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds); + vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds); vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a); tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (RENDER_DIST - FADE_DIST)) / FADE_DIST, 0, 1)); diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index ab2dea79e5..71993842f5 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -4,6 +4,8 @@ in vec3 f_pos; flat in uint f_pos_norm; +in float f_alt; +in vec4 f_shadow; in vec3 f_col; in float f_light; @@ -25,36 +27,43 @@ 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); + // vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0); + // vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/); + vec3 view_dir = -cam_to_frag; + // vec3 view_dir = normalize(f_pos - cam_pos.xyz); 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); + /* float sun_shade_frac = horizon_at(f_pos, sun_dir); + float moon_shade_frac = horizon_at(f_pos, moon_dir); */ + float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir); + float moon_shade_frac = horizon_at2(f_shadow, f_alt, 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 shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac; vec3 surf_color = /*srgb_to_linear*/(f_col); vec3 k_a = vec3(1.0); vec3 k_d = vec3(0.5); vec3 k_s = vec3(0.5); - float alpha = 2.0; + 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_frac = light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(1.0), alpha); 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, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light); + /* vec3 point_light = light_at(f_pos, f_norm); + emitted_light += point_light; + reflected_light += point_light; */ // float point_shadow = shadow_at(f_pos, f_norm); // vec3 point_light = light_at(f_pos, f_norm); @@ -78,7 +87,7 @@ void main() { 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 fog_color = get_sky_color(cam_to_frag/*view_dir*/, 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); diff --git a/assets/voxygen/shaders/terrain-vert.glsl b/assets/voxygen/shaders/terrain-vert.glsl index 47322fd3bc..0407eddc7c 100644 --- a/assets/voxygen/shaders/terrain-vert.glsl +++ b/assets/voxygen/shaders/terrain-vert.glsl @@ -2,6 +2,7 @@ #include #include +#include in uint v_pos_norm; in uint v_col_light; @@ -14,6 +15,8 @@ uniform u_locals { out vec3 f_pos; flat out uint f_pos_norm; +out float f_alt; +out vec4 f_shadow; out vec3 f_col; out float f_light; @@ -29,6 +32,10 @@ void main() { f_pos_norm = v_pos_norm; + // Also precalculate shadow texture and estimated terrain altitude. + f_alt = alt_at(f_pos.xy); + f_shadow = textureBicubic(t_horizon, pos_to_uv(f_pos.xy)); + gl_Position = all_mat * vec4(f_pos, 1); diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index 3ca05435d4..b68377c67b 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -23,13 +23,16 @@ pub struct CharSelectionState { impl CharSelectionState { /// Create a new `CharSelectionState`. pub fn new(global_state: &mut GlobalState, client: Rc>) -> Self { + let scene = Scene::new( + global_state.window.renderer_mut(), + &client.borrow(), + &global_state.settings, + Some("fixture.selection_bg"), + ); Self { char_selection_ui: CharSelectionUi::new(global_state), client, - scene: Scene::new( - global_state.window.renderer_mut(), - Some("fixture.selection_bg"), - ), + scene, } } } diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index f4ec260afd..6d90ea52e4 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -31,7 +31,7 @@ pub use self::{ }, Globals, Light, Shadow, }, - renderer::{Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt}, + renderer::{LodColorFmt, Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt}, texture::Texture, }; pub use gfx::texture::{FilterMethod, WrapMode}; diff --git a/voxygen/src/render/pipelines/figure.rs b/voxygen/src/render/pipelines/figure.rs index ace2a54533..fdb580f457 100644 --- a/voxygen/src/render/pipelines/figure.rs +++ b/voxygen/src/render/pipelines/figure.rs @@ -34,6 +34,9 @@ gfx_defines! { lights: gfx::ConstantBuffer = "u_lights", shadows: gfx::ConstantBuffer = "u_shadows", + map: gfx::TextureSampler<[f32; 4]> = "t_map", + horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", + noise: gfx::TextureSampler = "t_noise", tgt_color: gfx::RenderTarget = "tgt_color", diff --git a/voxygen/src/render/pipelines/fluid.rs b/voxygen/src/render/pipelines/fluid.rs index ec13e96df9..2f092057d9 100644 --- a/voxygen/src/render/pipelines/fluid.rs +++ b/voxygen/src/render/pipelines/fluid.rs @@ -22,6 +22,8 @@ gfx_defines! { globals: gfx::ConstantBuffer = "u_globals", lights: gfx::ConstantBuffer = "u_lights", shadows: gfx::ConstantBuffer = "u_shadows", + map: gfx::TextureSampler<[f32; 4]> = "t_map", + horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", noise: gfx::TextureSampler = "t_noise", waves: gfx::TextureSampler<[f32; 4]> = "t_waves", diff --git a/voxygen/src/render/pipelines/sprite.rs b/voxygen/src/render/pipelines/sprite.rs index 31178e4b1d..81a981d774 100644 --- a/voxygen/src/render/pipelines/sprite.rs +++ b/voxygen/src/render/pipelines/sprite.rs @@ -32,6 +32,9 @@ gfx_defines! { lights: gfx::ConstantBuffer = "u_lights", shadows: gfx::ConstantBuffer = "u_shadows", + map: gfx::TextureSampler<[f32; 4]> = "t_map", + horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon", + noise: gfx::TextureSampler = "t_noise", tgt_color: gfx::BlendTarget = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA), diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index efcd190b92..61daab86e8 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -41,6 +41,9 @@ pub type WinColorView = gfx::handle::RenderTargetView; +/// Represents the formt of LOD map color targets. +pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); //[gfx::format::U8Norm; 4]; + /// A handle to a render color target as a resource. pub type TgtColorRes = gfx::handle::ShaderResourceView< gfx_backend::Resources, @@ -416,12 +419,17 @@ impl Renderer { pub fn max_texture_size(&self) -> usize { self.factory.get_capabilities().max_texture_size } /// Create a new texture from the provided image. - pub fn create_texture( + pub fn create_texture( &mut self, image: &image::DynamicImage, filter_method: Option, wrap_mode: Option, - ) -> Result { + ) -> Result, RenderError> + where + F::Surface: gfx::format::TextureSurface, + F::Channel: gfx::format::TextureChannel, + ::DataType: Copy, + { Texture::new(&mut self.factory, image, filter_method, wrap_mode) } @@ -524,6 +532,8 @@ impl Renderer { bones: &Consts, lights: &Consts, shadows: &Consts, + map: &Texture, + horizon: &Texture, ) { self.encoder.draw( &gfx::Slice { @@ -542,6 +552,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(), }, @@ -557,8 +569,8 @@ impl Renderer { locals: &Consts, lights: &Consts, shadows: &Consts, - map: &Texture, /* <(gfx::format::R8, gfx::format::Unorm)> */ - horizon: &Texture, /* <(gfx::format::R8, gfx::format::Unorm)> */ + map: &Texture, + horizon: &Texture, ) { self.encoder.draw( &gfx::Slice { @@ -593,6 +605,8 @@ impl Renderer { locals: &Consts, lights: &Consts, shadows: &Consts, + map: &Texture, + horizon: &Texture, waves: &Texture, ) { self.encoder.draw( @@ -610,6 +624,8 @@ impl Renderer { globals: globals.buf.clone(), lights: lights.buf.clone(), shadows: shadows.buf.clone(), + map: (map.srv.clone(), map.sampler.clone()), + horizon: (horizon.srv.clone(), horizon.sampler.clone()), noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()), waves: (waves.srv.clone(), waves.sampler.clone()), tgt_color: self.tgt_color_view.clone(), @@ -627,6 +643,8 @@ impl Renderer { instances: &Instances, lights: &Consts, shadows: &Consts, + map: &Texture, + horizon: &Texture, ) { self.encoder.draw( &gfx::Slice { @@ -644,6 +662,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(), }, @@ -657,8 +677,8 @@ impl Renderer { model: &Model, globals: &Consts, locals: &Consts, - map: &Texture, - horizon: &Texture, + map: &Texture, + horizon: &Texture, ) { self.encoder.draw( &gfx::Slice { @@ -683,14 +703,18 @@ impl Renderer { } /// Queue the rendering of the provided UI element in the upcoming frame. - pub fn render_ui_element( + pub fn render_ui_element>( &mut self, model: &Model, - tex: &Texture, + tex: &Texture, scissor: Aabr, globals: &Consts, locals: &Consts, - ) { + ) where + F::Surface: gfx::format::TextureSurface, + F::Channel: gfx::format::TextureChannel, + ::DataType: Copy, + { let Aabr { min, max } = scissor; self.encoder.draw( &gfx::Slice { diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs index bb29781c25..b41e1a3b50 100644 --- a/voxygen/src/scene/camera.rs +++ b/voxygen/src/scene/camera.rs @@ -70,7 +70,7 @@ impl Camera { /// and position of the camera. pub fn compute_dependents(&mut self, terrain: &impl ReadVol) { let dist = { - let (start, end) = ( + /* let (start, end) = ( self.focus + (Vec3::new( -f32::sin(self.ori.x) * f32::cos(self.ori.y), @@ -91,7 +91,8 @@ impl Camera { (_, Ok(None)) => self.dist, (_, Err(_)) => self.dist, } - .max(0.0) + .max(0.0) */ + self.dist.max(0.0) }; self.dependents.view_mat = Mat4::::identity() diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 5fa3f1e485..fba637036e 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -16,7 +16,7 @@ use crate::{ render::{Consts, FigureBoneData, FigureLocals, Globals, Light, Renderer, Shadow}, scene::{ camera::{Camera, CameraMode}, - SceneData, + Lod, SceneData, }, }; use common::{ @@ -1365,6 +1365,7 @@ impl FigureMgr { globals: &Consts, lights: &Consts, shadows: &Consts, + lod: &Lod, camera: &Camera, ) { let ecs = state.ecs(); @@ -1597,7 +1598,16 @@ impl FigureMgr { ) }), } { - renderer.render_figure(model, globals, locals, bone_consts, lights, shadows); + renderer.render_figure( + model, + globals, + locals, + bone_consts, + lights, + shadows, + &lod.map, + &lod.horizon, + ); } else { trace!("Body has no saved figure"); } diff --git a/voxygen/src/scene/lod.rs b/voxygen/src/scene/lod.rs index 7c6ecc8dd5..4b0df1b498 100644 --- a/voxygen/src/scene/lod.rs +++ b/voxygen/src/scene/lod.rs @@ -1,7 +1,8 @@ use crate::{ render::{ pipelines::lod_terrain::{Locals, Vertex}, - Consts, FilterMethod, Globals, LodTerrainPipeline, Mesh, Model, Quad, Renderer, Texture, + Consts, FilterMethod, Globals, LodColorFmt, LodTerrainPipeline, Mesh, Model, Quad, + Renderer, Texture, }, settings::Settings, }; @@ -12,8 +13,8 @@ use vek::*; pub struct Lod { model: Option<(u32, Model)>, locals: Consts, - pub map: Texture, - pub horizon: Texture, + pub map: Texture, + pub horizon: Texture, tgt_detail: u32, } @@ -23,7 +24,7 @@ impl Lod { model: None, locals: renderer.create_consts(&[Locals::default()]).unwrap(), map: renderer - .create_texture(&client.lod_base, Some(FilterMethod::Trilinear), None) + .create_texture(&client.lod_base, Some(FilterMethod::Bilinear), None) .expect("Failed to generate map texture"), horizon: renderer .create_texture(&client.lod_horizon, Some(FilterMethod::Trilinear), None) @@ -34,7 +35,7 @@ impl Lod { pub fn set_detail(&mut self, detail: u32) { self.tgt_detail = detail.max(100).min(2500); } - pub fn maintain(&mut self, renderer: &mut Renderer) { + pub fn maintain(&mut self, renderer: &mut Renderer, _time_of_day: f64) { if self .model .as_ref() diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index bbee0b6634..ce2795aab9 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -357,7 +357,8 @@ impl Scene { .expect("Failed to update global constants"); // Maintain LoD. - self.lod.maintain(renderer); + self.lod + .maintain(renderer, scene_data.state.get_time_of_day()); // Maintain the terrain. self.terrain.maintain( @@ -406,6 +407,7 @@ impl Scene { &self.globals, &self.lights, &self.shadows, + &self.lod, &self.camera, ); self.lod.render(renderer, &self.globals); @@ -418,6 +420,7 @@ impl Scene { &self.globals, &self.lights, &self.shadows, + &self.lod, self.camera.get_focus_pos(), ); diff --git a/voxygen/src/scene/simple.rs b/voxygen/src/scene/simple.rs index 34aaec83e4..be39ed184b 100644 --- a/voxygen/src/scene/simple.rs +++ b/voxygen/src/scene/simple.rs @@ -11,9 +11,12 @@ use crate::{ scene::{ camera::{self, Camera, CameraMode}, figure::{load_mesh, FigureModelCache, FigureState}, + Lod, }, + settings::Settings, window::{Event, PressState}, }; +use client::Client; use common::{ comp::{humanoid, Body, Loadout}, terrain::BlockKind, @@ -58,6 +61,7 @@ pub struct Scene { skybox: Skybox, postprocess: PostProcess, + lod: Lod, backdrop: Option<(Model, FigureState)>, figure_model_cache: FigureModelCache, @@ -76,7 +80,12 @@ pub struct SceneData { } impl Scene { - pub fn new(renderer: &mut Renderer, backdrop: Option<&str>) -> Self { + pub fn new( + renderer: &mut Renderer, + client: &Client, + settings: &Settings, + backdrop: Option<&str>, + ) -> Self { let resolution = renderer.get_resolution().map(|e| e as f32); let mut camera = Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson); @@ -100,6 +109,8 @@ impl Scene { .create_consts(&[PostProcessLocals::default()]) .unwrap(), }, + lod: Lod::new(renderer, client, settings), + figure_model_cache: FigureModelCache::new(), figure_state: FigureState::new(renderer, CharacterSkeleton::new()), @@ -231,6 +242,8 @@ impl Scene { self.figure_state.bone_consts(), &self.lights, &self.shadows, + &self.lod.map, + &self.lod.horizon, ); } @@ -242,6 +255,8 @@ impl Scene { state.bone_consts(), &self.lights, &self.shadows, + &self.lod.map, + &self.lod.horizon, ); } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index ed3b6cef4b..5d7e6403b2 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -1429,6 +1429,7 @@ impl Terrain { globals: &Consts, lights: &Consts, shadows: &Consts, + lod: &Lod, focus_pos: Vec3, ) { let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| { @@ -1459,6 +1460,8 @@ impl Terrain { &instances, lights, shadows, + &lod.map, + &lod.horizon, ); } } @@ -1476,7 +1479,16 @@ impl Terrain { .map(|model| (model, &chunk.locals)) }) .for_each(|(model, locals)| { - renderer.render_fluid_chunk(model, globals, locals, lights, shadows, &self.waves) + renderer.render_fluid_chunk( + model, + globals, + locals, + lights, + shadows, + &lod.map, + &lod.horizon, + &self.waves, + ) }); } } diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 4f87c53f04..a3d7d1095a 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -1328,8 +1328,9 @@ impl WorldSim { 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; + /* let z_cache = block_gen.get_z_cache(wpos); + sample.alt = alt.max(z_cache.get_z_limits(&mut block_gen).2); */ sample.alt = alt.max(BlockGen::get_cliff_height( &mut block_gen.column_gen, &mut block_gen.column_cache,