From b0ac9f36f755dd06f7c17c46150568064790864f Mon Sep 17 00:00:00 2001 From: Joshua Yanovski Date: Fri, 3 Apr 2020 07:56:11 +0200 Subject: [PATCH 1/2] Use bicubic interpolation for terrain. --- assets/voxygen/shaders/include/lod.glsl | 46 +++++++++++++++++++- assets/voxygen/shaders/lod-terrain-frag.glsl | 5 +-- voxygen/src/hud/settings_window.rs | 7 ++- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/assets/voxygen/shaders/include/lod.glsl b/assets/voxygen/shaders/include/lod.glsl index ab39ed72f9..c9a2e64474 100644 --- a/assets/voxygen/shaders/include/lod.glsl +++ b/assets/voxygen/shaders/include/lod.glsl @@ -7,6 +7,50 @@ vec2 pos_to_uv(vec2 pos) { return vec2(uv_pos.x, 1.0 - uv_pos.y); } +// textureBicubic from https://stackoverflow.com/a/42179924 +vec4 cubic(float v) { + vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v; + vec4 s = n * n * n; + float x = s.x; + float y = s.y - 4.0 * s.x; + float z = s.z - 4.0 * s.y + 6.0 * s.x; + float w = 6.0 - x - y - z; + return vec4(x, y, z, w) * (1.0/6.0); +} + +vec4 textureBicubic(sampler2D sampler, vec2 texCoords) { + vec2 texSize = textureSize(sampler, 0); + vec2 invTexSize = 1.0 / texSize; + + texCoords = texCoords * texSize - 0.5; + + + vec2 fxy = fract(texCoords); + texCoords -= fxy; + + vec4 xcubic = cubic(fxy.x); + vec4 ycubic = cubic(fxy.y); + + vec4 c = texCoords.xxyy + vec2 (-0.5, +1.5).xyxy; + + vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw); + vec4 offset = c + vec4 (xcubic.yw, ycubic.yw) / s; + + offset *= invTexSize.xxyy; + + vec4 sample0 = texture(sampler, offset.xz); + vec4 sample1 = texture(sampler, offset.yz); + vec4 sample2 = texture(sampler, offset.xw); + vec4 sample3 = texture(sampler, offset.yw); + + float sx = s.x / (s.x + s.y); + float sy = s.z / (s.z + s.w); + + return mix( + mix(sample3, sample2, sx), mix(sample1, sample0, sx) + , sy); +} + float alt_at(vec2 pos) { return texture(t_map, pos_to_uv(pos)).a * (1300.0) + 140.0; //+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0; @@ -52,6 +96,6 @@ vec3 lod_pos(vec2 v_pos, vec2 focus_pos) { vec3 lod_col(vec2 pos) { //return vec3(0, 0.5, 0); - return texture(t_map, pos_to_uv(pos)).rgb; + return 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/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index 4ae0f782b6..cdad89b649 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -2,7 +2,6 @@ #include #include -#include #include in vec3 f_pos; @@ -19,7 +18,7 @@ void main() { 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(srgb_to_linear(f_col), light, diffuse_light, ambient_light); + vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light); float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x); @@ -27,7 +26,7 @@ void main() { vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), 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); - float mist_factor = max(1 - (f_pos.z + (texture(t_noise, f_pos.xy * 0.0005 + time_of_day.x * 0.001).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, clamp(mist_factor * 0.00005 * distance(f_pos.xy, focus_pos.xy), 0, 0.3)); diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs index d59dc38dc0..aa8f9869e0 100644 --- a/voxygen/src/hud/settings_window.rs +++ b/voxygen/src/hud/settings_window.rs @@ -1612,7 +1612,8 @@ impl<'a> Widget for SettingsWindow<'a> { .set(state.ids.lod_detail_text, ui); if let Some(new_val) = ImageSlider::discrete( - ((self.global_state.settings.graphics.lod_detail as f32 / 100.0).log(5.0) * 10.0).round() as i32, + ((self.global_state.settings.graphics.lod_detail as f32 / 100.0).log(5.0) * 10.0) + .round() as i32, 0, 20, self.imgs.slider_indicator, @@ -1625,7 +1626,9 @@ impl<'a> Widget for SettingsWindow<'a> { .pad_track((5.0, 5.0)) .set(state.ids.lod_detail_slider, ui) { - events.push(Event::AdjustLodDetail((5.0f32.powf(new_val as f32 / 10.0) * 100.0) as u32)); + events.push(Event::AdjustLodDetail( + (5.0f32.powf(new_val as f32 / 10.0) * 100.0) as u32, + )); } Text::new(&format!( From 8b149ad11ad4bb75018fcf9519baec27d1c95951 Mon Sep 17 00:00:00 2001 From: Joshua Yanovski Date: Sat, 4 Apr 2020 02:32:39 +0200 Subject: [PATCH 2/2] Trying out a new lighting model. --- assets/voxygen/shaders/figure-frag.glsl | 36 +++++++++---- assets/voxygen/shaders/fluid-frag/cheap.glsl | 36 +++++++++---- assets/voxygen/shaders/fluid-frag/shiny.glsl | 57 +++++++++++++------- assets/voxygen/shaders/include/light.glsl | 53 ++++++++++++++++++ assets/voxygen/shaders/include/sky.glsl | 41 ++++++++++++-- assets/voxygen/shaders/include/srgb.glsl | 15 +++++- assets/voxygen/shaders/lod-terrain-frag.glsl | 15 ++++-- assets/voxygen/shaders/sprite-frag.glsl | 38 +++++++++---- assets/voxygen/shaders/terrain-frag.glsl | 48 +++++++++++++---- 9 files changed, 270 insertions(+), 69 deletions(-) diff --git a/assets/voxygen/shaders/figure-frag.glsl b/assets/voxygen/shaders/figure-frag.glsl index aba60bf8d5..c408aac687 100644 --- a/assets/voxygen/shaders/figure-frag.glsl +++ b/assets/voxygen/shaders/figure-frag.glsl @@ -28,19 +28,37 @@ uniform u_bones { out vec4 tgt_color; void main() { - vec3 light, diffuse_light, ambient_light; - get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0); + vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); + 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; + float alpha = 2.0; + + vec3 emitted_light, reflected_light; + float point_shadow = shadow_at(f_pos, f_norm); - diffuse_light *= point_shadow; - ambient_light *= point_shadow; - vec3 point_light = light_at(f_pos, f_norm); - light += point_light; - diffuse_light += point_light; - vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), light, diffuse_light, ambient_light); + // 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); + + 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); + // 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); + // diffuse_light *= point_shadow; + // ambient_light *= point_shadow; + // vec3 point_light = light_at(f_pos, f_norm); + // light += point_light; + // 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); 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.5, true, clouds); + vec3 fog_color = get_sky_color(cam_to_frag, 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/fluid-frag/cheap.glsl b/assets/voxygen/shaders/fluid-frag/cheap.glsl index f3c92ab429..3b4e83915f 100644 --- a/assets/voxygen/shaders/fluid-frag/cheap.glsl +++ b/assets/voxygen/shaders/fluid-frag/cheap.glsl @@ -32,17 +32,32 @@ void main() { // Use an array to avoid conditional branching vec3 f_norm = normals[norm_axis + norm_dir]; - vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); + vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); + vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0)); - vec3 light, diffuse_light, ambient_light; - get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 0.0); + vec3 k_a = 0.5 * surf_color; + vec3 k_d = vec3(1.0); + vec3 k_s = 0.5 * vec3(1.0); + float alpha = 0.255; + + vec3 emitted_light, reflected_light; + + // float point_shadow = shadow_at(f_pos, f_norm); + // vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); + // vec3 emitted_light, reflected_light; + // vec3 light, diffuse_light, ambient_light; float point_shadow = shadow_at(f_pos,f_norm); - diffuse_light *= f_light * point_shadow; - ambient_light *= f_light, point_shadow; - vec3 point_light = light_at(f_pos, f_norm); - light += point_light; - diffuse_light += point_light; - vec3 surf_color = srgb_to_linear(vec3(0.4, 0.7, 2.0)) * light * diffuse_light * ambient_light; + // 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, light, diffuse_light, ambient_light, 0.0); + // diffuse_light *= f_light * point_shadow; + // ambient_light *= f_light, point_shadow; + // vec3 point_light = light_at(f_pos, f_norm); + // light += point_light; + // 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); float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x); vec4 clouds; @@ -50,7 +65,8 @@ void main() { float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag), 0.5); - vec4 color = mix(vec4(surf_color, 1.0), vec4(surf_color, 1.0 / (1.0 + diffuse_light * 0.25)), passthrough); + 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); 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 8d06ee468c..63de7173ff 100644 --- a/assets/voxygen/shaders/fluid-frag/shiny.glsl +++ b/assets/voxygen/shaders/fluid-frag/shiny.glsl @@ -93,32 +93,51 @@ void main() { vec3 norm = f_norm * nmap.z + b_norm * nmap.x + c_norm * nmap.y; - vec3 light, diffuse_light, ambient_light; - get_sun_diffuse(norm, time_of_day.x, light, diffuse_light, ambient_light, 0.0); - float point_shadow = shadow_at(f_pos, norm); - diffuse_light *= f_light * point_shadow; - ambient_light *= f_light, point_shadow; - vec3 point_light = light_at(f_pos, norm); - light += point_light; - diffuse_light += point_light; - vec3 surf_color = srgb_to_linear(vec3(0.2, 0.5, 1.0)) * light * diffuse_light * ambient_light; + + vec4 _clouds; + vec3 reflect_ray_dir = reflect(cam_to_frag, norm); + 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; + float alpha = 0.255; + + vec3 emitted_light, reflected_light; + // vec3 light, diffuse_light, ambient_light; + 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); + // 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; + // vec3 point_light = light_at(f_pos, norm); + // light += point_light; + // 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); 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); - vec3 reflect_ray_dir = reflect(cam_to_frag, norm); + // 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 - reflect_ray_dir.z = max(reflect_ray_dir.z, 0.01); + // reflect_ray_dir.z = max(reflect_ray_dir.z, 0.01); - vec4 _clouds; - vec3 reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.25, false, _clouds) * f_light; + // vec4 _clouds; + // 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); - // 0 = 100% reflection, 1 = translucent water - float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag), 0.5); + // 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 * 0.25)), passthrough); + // 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; - tgt_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a); + tgt_color = 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/light.glsl b/assets/voxygen/shaders/include/light.glsl index 6bb73e5cc9..8df3dbdb22 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -70,3 +70,56 @@ float shadow_at(vec3 wpos, vec3 wnorm) { } return min(shadow, 1.0); } + +void lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, inout vec3 emitted_light, inout vec3 reflected_light/*, out float shadow*/) { + // shadow = 0.0; + vec3 ambient_light = vec3(0.0); + + const float LIGHT_AMBIENCE = 0.025; + + for (uint i = 0u; i < light_shadow_count.x; i ++) { + + // Only access the array once + Light L = lights[i]; + + vec3 light_pos = L.light_pos.xyz; + + // Pre-calculate difference between light and fragment + vec3 difference = light_pos - wpos; + + float strength = pow(attenuation_strength(difference), 0.6); + + // Multiply the vec3 only once + vec3 color = /*srgb_to_linear*/(L.light_col.rgb) * (strength * L.light_col.a); + + // // Only access the array once + // Shadow S = shadows[i]; + + // vec3 shadow_pos = S.shadow_pos_radius.xyz; + // float radius = S.shadow_pos_radius.w; + + // vec3 diff = shadow_pos - wpos; + // if (diff.z >= 0.0) { + // diff.z = -sign(diff.z) * diff.z * 0.1; + // } + + // float shade = max(pow(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z, 0.25) / pow(radius * radius * 0.5, 0.25), /*0.5*/0.0); + + // shadow = min(shadow, shade); + + // Compute reflectance. + vec3 light_dir = normalize(-difference); + reflected_light += color * light_reflection_factor(wnorm, cam_to_frag, light_dir, k_d, k_s, alpha); + + // light += color * (max(0, max(dot(normalize(difference), wnorm), 0.15)) + LIGHT_AMBIENCE); + // 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 = max(dot(wnorm, light_dir) - 0.15, 0.15); + // float ambient_sides = 0.0; + ambient_light += color * (ambient_sides + LIGHT_AMBIENCE); + } + + // shadow = shadow_at(wpos, wnorm); + // float shadow = shadow_at(wpos, wnorm); + emitted_light += k_a * ambient_light/* * shadow*/;// min(shadow, 1.0); +} diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index 141e9dde04..7109144695 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -1,4 +1,5 @@ #include +#include #include const float PI = 3.141592; @@ -36,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; +const float PERSISTENT_AMBIANCE = 0.025; // 0.1; float get_sun_brightness(vec3 sun_dir) { return max(-sun_dir.z + 0.6, 0.0) * 0.9; @@ -62,7 +63,18 @@ vec3 get_moon_color(vec3 moon_dir) { return vec3(0.05, 0.05, 0.6); } -void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diffuse_light, out vec3 ambient_light, float diffusion) { +// Calculates extra emission and reflectance (due to sunlight / moonlight). +// +// reflectence = k_a * i_a + i_a,persistent +// emittence = Σ { m ∈ lights } i_m * shadow_m * get_light_reflected(light_m) +// +// Note that any shadowing to be done that would block the sun and moon, aside from heightmap shadowing (that will be +// implemented sooon), should be implicitly provided via k_a, k_d, and k_s. For instance, shadowing via ambient occlusion. +// +// Also note that the emitted light calculation is kind of lame... we probabbly need something a bit nicer if we ever want to do +// anything interesting here. +// void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diffuse_light, out vec3 ambient_light, float diffusion +void get_sun_diffuse(vec3 norm, float time_of_day, 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; vec3 sun_dir = get_sun_dir(time_of_day); @@ -77,12 +89,26 @@ void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diff vec3 sun_chroma = sun_color * sun_light; vec3 moon_chroma = moon_color * moon_light; - light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE; + /* 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)) * 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); + + /* 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); + ambient_light = vec3(SUN_AMBIANCE * sun_light + moon_light); */ } // This has been extracted into a function to allow quick exit when detecting a star. @@ -215,7 +241,12 @@ float fog(vec3 f_pos, vec3 focus_pos, uint medium) { return pow(clamp((max(fog, mist) - min_fog) / (max_fog - min_fog), 0.0, 1.0), 1.7); } -vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) { +/* vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) { float avg_col = (color.r + color.g + color.b) / 3.0; return ((color - avg_col) * light + (diffuse + ambience) * avg_col) * (diffuse + ambience); +} */ +vec3 illuminate(vec3 emitted, vec3 reflected) { + const float gamma = /*0.5*/1.0;//1.0; + vec3 color = emitted + reflected; + return srgb_to_linear(/*0.5*//*0.125 * */vec3(pow(color.x, gamma), pow(color.y, gamma), pow(color.z, gamma))); } diff --git a/assets/voxygen/shaders/include/srgb.glsl b/assets/voxygen/shaders/include/srgb.glsl index 4eaf579e17..40b39b7b85 100644 --- a/assets/voxygen/shaders/include/srgb.glsl +++ b/assets/voxygen/shaders/include/srgb.glsl @@ -5,4 +5,17 @@ vec3 srgb_to_linear(vec3 srgb) { vec3 lower = srgb/vec3(12.92); return mix(higher, lower, cutoff); -} \ No newline at end of file +} + +// 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) { + 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); +} diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index cdad89b649..8b2eb7e0cc 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -16,19 +16,24 @@ void main() { vec3 f_col = lod_col(f_pos.xy); - 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 emitted_light, reflected_light; + vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); + // 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); + // 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); 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, 1.0, true, 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); 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, 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)); tgt_color = vec4(color, 1.0); } diff --git a/assets/voxygen/shaders/sprite-frag.glsl b/assets/voxygen/shaders/sprite-frag.glsl index 302bd0faeb..2a57206683 100644 --- a/assets/voxygen/shaders/sprite-frag.glsl +++ b/assets/voxygen/shaders/sprite-frag.glsl @@ -16,19 +16,39 @@ const float RENDER_DIST = 112.0; const float FADE_DIST = 32.0; void main() { - vec3 light, diffuse_light, ambient_light; - get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0); + vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); + 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; + float alpha = 2.0; + + vec3 emitted_light, reflected_light; + float point_shadow = shadow_at(f_pos, f_norm); - diffuse_light *= f_light * point_shadow; - ambient_light *= f_light, point_shadow; - vec3 point_light = light_at(f_pos, f_norm); - light += point_light; - diffuse_light += point_light; - vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light); + + // vec3 light, diffuse_light, ambient_light; + // vec3 emitted_light, reflected_light; + // float point_shadow = shadow_at(f_pos,f_norm); + // 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, light, diffuse_light, ambient_light, 1.0); + // float point_shadow = shadow_at(f_pos, f_norm); + // diffuse_light *= f_light * point_shadow; + // ambient_light *= f_light * point_shadow; + // 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); + // 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(normalize(f_pos - cam_pos.xyz), time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds); + vec3 fog_color = get_sky_color(cam_to_frag, 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 97fcbfb4e1..04d9c6b412 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -23,20 +23,46 @@ void main() { // Use an array to avoid conditional branching vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u]; - vec3 light, diffuse_light, ambient_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; - ambient_light *= f_light * point_shadow; - vec3 point_light = light_at(f_pos, f_norm); - light += point_light; - diffuse_light += point_light; - vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light); + vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz); + + 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; + float alpha = 2.0; + + vec3 emitted_light, reflected_light; + float point_shadow = shadow_at(f_pos, f_norm); + + 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); + + 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 point_shadow = shadow_at(f_pos, f_norm); + // 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 * f_light, k_d * f_light, k_s * f_light, alpha, 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; + // ambient_light *= f_light * point_shadow; + // vec3 point_light = light_at(f_pos, f_norm); + // light += point_light; + // diffuse_light += point_light; + // reflected_light += point_light; + // reflected_light += light_reflection_factor(norm, cam_to_frag, , vec3 k_d, vec3 k_s, float alpha) { + + // 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); 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, 1.0, true, clouds); - vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a); + 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); tgt_color = vec4(color, 1.0); }