From ae66432a1e92ef7d929f6498ea6b5f99a2e2eadb Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 11 Oct 2022 15:49:31 +0100 Subject: [PATCH] Make cheap water look better underwater --- assets/voxygen/shaders/clouds-frag.glsl | 3 +-- assets/voxygen/shaders/fluid-frag/cheap.glsl | 17 ++++++++++------- assets/voxygen/shaders/fluid-frag/shiny.glsl | 8 ++++++-- assets/voxygen/shaders/include/lod.glsl | 6 +++--- assets/voxygen/shaders/include/sky.glsl | 2 +- assets/voxygen/shaders/lod-terrain-frag.glsl | 2 +- assets/voxygen/shaders/skybox-frag.glsl | 2 +- assets/voxygen/shaders/terrain-frag.glsl | 2 +- 8 files changed, 24 insertions(+), 18 deletions(-) diff --git a/assets/voxygen/shaders/clouds-frag.glsl b/assets/voxygen/shaders/clouds-frag.glsl index 8b0512eb63..0e391b5d7f 100644 --- a/assets/voxygen/shaders/clouds-frag.glsl +++ b/assets/voxygen/shaders/clouds-frag.glsl @@ -168,8 +168,7 @@ void main() { #else { #endif - cloud_blend = 1; - /* dist = DIST_CAP; */ + dist = DIST_CAP; } } /* color.rgb = vec3(sin(depth_at(uv) * 3.14159 * 2) * 0.5 + 0.5); */ diff --git a/assets/voxygen/shaders/fluid-frag/cheap.glsl b/assets/voxygen/shaders/fluid-frag/cheap.glsl index 8ae661a7b0..33d0b608e8 100644 --- a/assets/voxygen/shaders/fluid-frag/cheap.glsl +++ b/assets/voxygen/shaders/fluid-frag/cheap.glsl @@ -59,7 +59,7 @@ vec4 water_col(vec4 posx, vec4 posy) { textureLod(sampler2D(t_noise, s_noise), vec2(posx.y, posy.y), 0).x, textureLod(sampler2D(t_noise, s_noise), vec2(posx.z, posy.z), 0).x, textureLod(sampler2D(t_noise, s_noise), vec2(posx.w, posy.w), 0).x - ) - 0.5) * 1.3; + ) - 0.5) * 1.0; } float water_col_vel(vec2 pos){ @@ -108,7 +108,7 @@ void main() { vec3 view_dir = -cam_to_frag; // vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0)); - vec3 water_color = (1.0 - mix(MU_WATER, vec3(0.8, 0.24, 0.08), water_col_vel(f_pos.xy))) * MU_SCATTER; + vec3 water_color = (1.0 - mix(pow(MU_WATER, vec3(0.25)), pow(vec3(0.8, 0.24, 0.08), vec3(0.25)), water_col_vel(f_pos.xy))) * MU_SCATTER; /* vec3 sun_dir = get_sun_dir(time_of_day.x); vec3 moon_dir = get_moon_dir(time_of_day.x); */ @@ -215,15 +215,18 @@ void main() { // 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) + specular_light_point; - float passthrough = max(dot(f_norm, -cam_to_frag), 0) * 0.65; + float passthrough = max(dot(cam_norm, -cam_to_frag), 0) * 0.65; + float min_refl = 0.0; - /* if (medium.x != MEDIUM_WATER) { */ - /* min_refl = min(emitted_light.r, min(emitted_light.g, emitted_light.b)); */ - /* } */ + float opacity = (1.0 - passthrough) * 1.0 / (1.0 + min_refl); + if (medium.x == MEDIUM_WATER) { + // Hack to make the opacity of the surface fade when underwater to avoid artifacts + opacity = min(sqrt(max(opacity, clamp((f_pos.z - cam_pos.z) * 0.05, 0.0, 1.0))), 1.0); + } vec3 surf_color = illuminate(max_light, view_dir, water_color * /* fog_color * */emitted_light, /*surf_color * */water_color * reflected_light); // vec4 color = vec4(surf_color, passthrough * 1.0 / (1.0 + min_refl));// * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (2.0 - log_cam))); - vec4 color = vec4(surf_color, (1.0 - passthrough) * 1.0 / (1.0 + min_refl)); + vec4 color = vec4(surf_color, opacity); tgt_color = color; } diff --git a/assets/voxygen/shaders/fluid-frag/shiny.glsl b/assets/voxygen/shaders/fluid-frag/shiny.glsl index 68f1d5ff79..c71c6b0b8c 100644 --- a/assets/voxygen/shaders/fluid-frag/shiny.glsl +++ b/assets/voxygen/shaders/fluid-frag/shiny.glsl @@ -332,7 +332,7 @@ void main() { // vec3 light, diffuse_light, ambient_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); // 0 = 100% reflection, 1 = translucent water - float passthrough = max(dot(norm, -cam_to_frag), 0) * 0.75; + float passthrough = max(dot(cam_norm, -cam_to_frag), 0) * 0.75; float max_light = 0.0; max_light += get_sun_diffuse2(sun_info, moon_info, cam_norm, /*time_of_day.x*/sun_view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, vec3(k_d), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s, alpha, f_norm, 1.0, emitted_light, reflected_light); @@ -403,10 +403,14 @@ void main() { // float log_cam = log(min(cam_attenuation.r, min(cam_attenuation.g, cam_attenuation.b))); float min_refl = 0.0; + float opacity = (1.0 - passthrough) * 0.5 / (1.0 + min_refl); if (medium.x != MEDIUM_WATER) { min_refl = min(emitted_light.r, min(emitted_light.g, emitted_light.b)); + } else { + // Hack to make the opacity of the surface fade when underwater to avoid artifacts + opacity = min(sqrt(max(opacity, clamp((f_pos.z - cam_pos.z) * 0.05, 0.0, 1.0))), 1.0); } - vec4 color = vec4(surf_color, (1.0 - passthrough) * 0.5 / (1.0 + min_refl));// * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (2.0 - log_cam))); + vec4 color = vec4(surf_color, opacity);// * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (2.0 - log_cam))); // 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, length(cam_attenuation), passthrough)); diff --git a/assets/voxygen/shaders/include/lod.glsl b/assets/voxygen/shaders/include/lod.glsl index d2efde0737..54ca47e900 100644 --- a/assets/voxygen/shaders/include/lod.glsl +++ b/assets/voxygen/shaders/include/lod.glsl @@ -391,13 +391,13 @@ vec3 water_diffuse(vec3 color, vec3 dir, float max_dist) { float f_alt = alt_at(cam_pos.xy); float fluid_alt = max(cam_pos.z + 1, floor(f_alt + 1)); - float water_dist = clamp((fluid_alt - cam_pos.z) / pow(max(dir.z, 0), 5), 0, max_dist); + float water_dist = clamp((fluid_alt - cam_pos.z) / pow(max(dir.z, 0), 2), 0, max_dist); - float fade = pow(0.97, water_dist); + float fade = pow(0.95, water_dist); return mix(vec3(0.0, 0.2, 0.5) * (get_sun_brightness() * get_sun_color() + get_moon_brightness() * get_moon_color()) - * pow(0.99, max((fluid_alt - cam_pos.z) * 12.0 - dir.z * 200, 0)), color.rgb, fade); + * pow(0.99, max((fluid_alt - cam_pos.z) * 12.0 - dir.z * 200, 0)), color.rgb * exp(-MU_WATER * water_dist * 0.1), fade); } else { return color; } diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index 810282037f..1958d31eb3 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -581,7 +581,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q // moon_dir = moon_dir.z <= 0 ? refract(moon_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : moon_dir; // Sun - const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 50.0; + const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 10.0; vec3 sun_halo_color = mix( (sun_dir.x > 0 ? SUN_HALO_DUSK : SUN_HALO_DAWN)* magnetosphere_tint, diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index d18ca00e97..cd9027aa55 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -579,7 +579,7 @@ void main() { vec3 emitted_light, reflected_light; - vec3 mu = medium.x == MEDIUM_WATER/* && f_pos.z <= fluid_alt*/ ? MU_WATER : vec3(0.0); + vec3 mu = false/* && f_pos.z <= fluid_alt*/ ? MU_WATER : vec3(0.0); // NOTE: Default intersection point is camera position, meaning if we fail to intersect we assume the whole camera is in water. vec3 cam_attenuation = compute_attenuation_point(cam_pos.xyz, view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos); // Use f_norm here for better shadows. diff --git a/assets/voxygen/shaders/skybox-frag.glsl b/assets/voxygen/shaders/skybox-frag.glsl index 54da8cbc1b..71af67f185 100644 --- a/assets/voxygen/shaders/skybox-frag.glsl +++ b/assets/voxygen/shaders/skybox-frag.glsl @@ -55,5 +55,5 @@ void main() { } */ vec3 wpos = cam_pos.xyz + /*normalize(f_pos)*/cam_dir * dist; - tgt_color = vec4(cam_attenuation * get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, refractionIndex), 1.0); + tgt_color = vec4(cam_attenuation * get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, medium.x != MEDIUM_WATER, refractionIndex), 1.0); } diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index 1a771dbaf0..8d86b6bd47 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -362,7 +362,7 @@ void main() { // NOTE: Default intersection point is camera position, meaning if we fail to intersect we assume the whole camera is in water. // Computing light attenuation from water. vec3 cam_attenuation = - medium.x == MEDIUM_WATER ? compute_attenuation_point(cam_pos.xyz + focus_off.xyz, view_dir, MU_WATER, fluid_alt + focus_off.z, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos + focus_off.xyz) + false/*medium.x == MEDIUM_WATER*/ ? compute_attenuation_point(cam_pos.xyz + focus_off.xyz, view_dir, MU_WATER, fluid_alt + focus_off.z, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos + focus_off.xyz) : compute_attenuation_point(f_pos + focus_off.xyz, -view_dir, mu, fluid_alt + focus_off.z, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/cam_pos.xyz + focus_off.xyz); // Prevent the sky affecting light when underground