From 8e7a8aa4f9c585e08cdd126dc44b335b7a2937e2 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 21 Jan 2020 12:57:59 +0000 Subject: [PATCH 1/2] Shader optimisations --- assets/voxygen/shaders/figure-vert.glsl | 2 +- assets/voxygen/shaders/fluid-vert.glsl | 3 +- .../shaders/include/cloud/regular.glsl | 47 +++++++++---------- assets/voxygen/shaders/include/globals.glsl | 1 + assets/voxygen/shaders/include/light.glsl | 2 +- assets/voxygen/shaders/include/sky.glsl | 30 +++++------- assets/voxygen/shaders/sprite-vert.glsl | 3 +- assets/voxygen/shaders/terrain-vert.glsl | 15 ++---- voxygen/src/render/pipelines/mod.rs | 2 + 9 files changed, 44 insertions(+), 61 deletions(-) diff --git a/assets/voxygen/shaders/figure-vert.glsl b/assets/voxygen/shaders/figure-vert.glsl index dbaf30f964..01261fb948 100644 --- a/assets/voxygen/shaders/figure-vert.glsl +++ b/assets/voxygen/shaders/figure-vert.glsl @@ -42,6 +42,6 @@ void main() { vec4(v_norm, 0.0) ).xyz); - gl_Position = proj_mat * view_mat * vec4(f_pos, 1); + gl_Position = all_mat * vec4(f_pos, 1); gl_Position.z = 1.0 / (1.0 - gl_Position.z - 10.0); } diff --git a/assets/voxygen/shaders/fluid-vert.glsl b/assets/voxygen/shaders/fluid-vert.glsl index 52ae08b420..44ca08f3ca 100644 --- a/assets/voxygen/shaders/fluid-vert.glsl +++ b/assets/voxygen/shaders/fluid-vert.glsl @@ -38,8 +38,7 @@ void main() { f_pos_norm = v_pos_norm; gl_Position = - proj_mat * - view_mat * + all_mat * vec4(f_pos, 1); gl_Position.z = 1.0 / (1.0 - gl_Position.z - 10.0); } diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 6471572b55..6062365a51 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -5,36 +5,39 @@ const float CLOUD_HEIGHT_MIN = CLOUD_AVG_HEIGHT - 50.0; const float CLOUD_HEIGHT_MAX = CLOUD_AVG_HEIGHT + 50.0; const float CLOUD_THRESHOLD = 0.3; const float CLOUD_SCALE = 5.0; -const float CLOUD_DENSITY = 50.0; +const float CLOUD_DENSITY = 80.0; float vsum(vec3 v) { return v.x + v.y + v.z; } vec2 cloud_at(vec3 pos) { + vec2 scaled_pos = pos.xy / CLOUD_SCALE; + float tick_offs = 0.0 - + texture(t_noise, pos.xy * 0.0001 - tick.x * 0.001).x * 0.5 - + texture(t_noise, pos.xy * 0.000003).x * 5.0; + + texture(t_noise, scaled_pos * 0.0005 - time_of_day.x * 0.00002).x * 0.5 + + texture(t_noise, scaled_pos * 0.000015).x * 5.0; float value = ( 0.0 - + texture(t_noise, pos.xy / CLOUD_SCALE * 0.0003 + tick_offs).x - + texture(t_noise, pos.xy / CLOUD_SCALE * 0.0009 - tick_offs).x * 0.5 - + texture(t_noise, pos.xy / CLOUD_SCALE * 0.0025 - tick.x * 0.01).x * 0.25 - + texture(t_noise, pos.xy / CLOUD_SCALE * 0.008 + tick.x * 0.02).x * 0.15 - + texture(t_noise, pos.xy / CLOUD_SCALE * 0.02 + tick_offs + tick.x * 0.02).x * 0.1 + + texture(t_noise, scaled_pos * 0.0003 + tick_offs).x + + texture(t_noise, scaled_pos * 0.0009 - tick_offs).x * 0.5 + + texture(t_noise, scaled_pos * 0.0025 - time_of_day.x * 0.0002).x * 0.25 + + texture(t_noise, scaled_pos * 0.008 + time_of_day.x * 0.0004).x * 0.15 + + texture(t_noise, scaled_pos * 0.02 + tick_offs + time_of_day.x * 0.0004).x * 0.1 ) / 3.0; float density = max((value - CLOUD_THRESHOLD) - abs(pos.z - CLOUD_AVG_HEIGHT) / 400.0, 0.0) * CLOUD_DENSITY; - float shade = ((pos.z - CLOUD_AVG_HEIGHT) * 1.8 / (CLOUD_AVG_HEIGHT - CLOUD_HEIGHT_MIN) + 0.5); + const float SHADE_GRADIENT = 1.8 / (CLOUD_AVG_HEIGHT - CLOUD_HEIGHT_MIN); + float shade = ((pos.z - CLOUD_AVG_HEIGHT) * SHADE_GRADIENT + 0.5); return vec2(shade, density / (1.0 + vsum(abs(pos - cam_pos.xyz)) / 5000)); } vec4 get_cloud_color(vec3 dir, vec3 origin, float time_of_day, float max_dist, float quality) { - - const float INCR = 0.1; + const int ITERS = 10; + const float INCR = 1.0 / ITERS; float mind = (CLOUD_HEIGHT_MIN - origin.z) / dir.z; float maxd = (CLOUD_HEIGHT_MAX - origin.z) / dir.z; @@ -42,28 +45,22 @@ vec4 get_cloud_color(vec3 dir, vec3 origin, float time_of_day, float max_dist, f float start = max(min(mind, maxd), 0.0); float delta = min(abs(mind - maxd), max_dist); - bool do_cast = true; - if (mind < 0.0 && maxd < 0.0) { - do_cast = false; - } - - float incr = INCR; - - float fuzz = sin(texture(t_noise, dir.xz * 100000.0 + tick.x).x * 100.0) * incr * delta; + float fuzz = sin(texture(t_noise, dir.xz * 100000.0 + tick.x).x * 100.0) * INCR * delta * pow(maxd - mind, 0.5); float cloud_shade = 1.0; float passthrough = 1.0; - if (do_cast) { - for (float d = 0.0; d < 1.0; d += incr) { - float dist = start + d * delta; - dist += fuzz * pow(maxd - mind, 0.5) * 0.01 * min(pow(dist * 0.005, 2.0), 1.0); + if ((mind > 0.0 || maxd > 0.0) && start < max_dist) { + float dist = start; + for (int i = 0; i < ITERS; i ++) { + dist += fuzz * 0.01 * min(pow(dist * 0.005, 2.0), 1.0); vec3 pos = origin + dir * min(dist, max_dist); vec2 sample = cloud_at(pos); - float integral = sample.y * incr; - passthrough *= max(1.0 - integral, 0.0); + float integral = sample.y * INCR; + passthrough *= 1.0 - integral; cloud_shade = mix(cloud_shade, sample.x, passthrough * integral); + dist += INCR * delta; } } diff --git a/assets/voxygen/shaders/include/globals.glsl b/assets/voxygen/shaders/include/globals.glsl index 12996de625..471320a7ef 100644 --- a/assets/voxygen/shaders/include/globals.glsl +++ b/assets/voxygen/shaders/include/globals.glsl @@ -2,6 +2,7 @@ layout (std140) uniform u_globals { mat4 view_mat; mat4 proj_mat; + mat4 all_mat; vec4 cam_pos; vec4 focus_pos; vec4 view_distance; diff --git a/assets/voxygen/shaders/include/light.glsl b/assets/voxygen/shaders/include/light.glsl index 93dfa8318e..c17a834c66 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -66,7 +66,7 @@ float shadow_at(vec3 wpos, vec3 wnorm) { vec3 diff = shadow_pos - wpos; if (diff.z >= 0.0) { - diff.z = diff.z * 0.1; + diff.z = sign(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); diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index 6ea6be10d0..98ef2399b0 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -82,33 +82,27 @@ void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diff light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE; diffuse_light = sun_chroma * mix(1.0, max(dot(-norm, sun_dir) * 0.6 + 0.4, 0.0), diffusion) + - moon_chroma * mix(1.0, pow(max(dot(-norm, moon_dir) * 2.0, 0.0), 2.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 = 30.0; + float star_scale = 80.0; - for (int i = 0; i < 2; i ++) { - for (int j = 0; j < 2; j ++) { - for (int k = 0; k < 2; k ++) { - // Star positions - vec3 pos = (floor(dir * star_scale) + vec3(i, j, k) - vec3(0.5)) / star_scale; + // Star positions + vec3 pos = (floor(dir * star_scale) - 0.5) / star_scale; - // Noisy offsets - pos += (3.0 / star_scale) * rand_perm_3(pos); + // Noisy offsets + pos += (3.0 / star_scale) * rand_perm_3(pos); - // Find distance to fragment - float dist = length(normalize(pos) - dir); + // Find distance to fragment + float dist = length(normalize(pos) - dir); - // Star threshold - if (dist < 0.0015) { - return 1.0; - } - } - } + // Star threshold + if (dist < 0.0015) { + return 1.0; } return 0.0; @@ -121,7 +115,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q // Add white dots for stars. Note these flicker and jump due to FXAA float star = 0.0; - if (with_stars) { + if (with_stars && sun_dir.z > 0.0) { star = is_star_at(dir); } diff --git a/assets/voxygen/shaders/sprite-vert.glsl b/assets/voxygen/shaders/sprite-vert.glsl index 6bbb5ea71f..ed3f84ea86 100644 --- a/assets/voxygen/shaders/sprite-vert.glsl +++ b/assets/voxygen/shaders/sprite-vert.glsl @@ -50,8 +50,7 @@ void main() { f_light = 1.0; gl_Position = - proj_mat * - view_mat * + all_mat * vec4(f_pos, 1); gl_Position.z = 1.0 / (1.0 - gl_Position.z - 10.0); } diff --git a/assets/voxygen/shaders/terrain-vert.glsl b/assets/voxygen/shaders/terrain-vert.glsl index cf273f6207..fedaafb9c1 100644 --- a/assets/voxygen/shaders/terrain-vert.glsl +++ b/assets/voxygen/shaders/terrain-vert.glsl @@ -18,28 +18,19 @@ out vec3 f_col; out float f_light; void main() { - f_pos = vec3( - float((v_pos_norm >> 0) & 0x00FFu), - float((v_pos_norm >> 8) & 0x00FFu), - float((v_pos_norm >> 16) & 0x1FFFu) - ) + model_offs; + f_pos = vec3((uvec3(v_pos_norm) >> uvec3(0, 8, 16)) & uvec3(0xFFu, 0xFFu, 0x1FFFu)) + model_offs; f_pos.z *= min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0); f_pos.z -= 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0); - f_col = vec3( - float((v_col_light >> 8) & 0xFFu), - float((v_col_light >> 16) & 0xFFu), - float((v_col_light >> 24) & 0xFFu) - ) / 255.0; + f_col = vec3((uvec3(v_col_light) >> uvec3(8, 16, 24)) & uvec3(0xFFu)) / 255.0; f_light = float(v_col_light & 0xFFu) / 255.0; f_pos_norm = v_pos_norm; gl_Position = - proj_mat * - view_mat * + all_mat * vec4(f_pos, 1); gl_Position.z = 1.0 / (1.0 - gl_Position.z - 10.0); } diff --git a/voxygen/src/render/pipelines/mod.rs b/voxygen/src/render/pipelines/mod.rs index 1d25d2dc9b..097321b299 100644 --- a/voxygen/src/render/pipelines/mod.rs +++ b/voxygen/src/render/pipelines/mod.rs @@ -21,6 +21,7 @@ gfx_defines! { constant Globals { view_mat: [[f32; 4]; 4] = "view_mat", proj_mat: [[f32; 4]; 4] = "proj_mat", + all_mat: [[f32; 4]; 4] = "all_mat", cam_pos: [f32; 4] = "cam_pos", focus_pos: [f32; 4] = "focus_pos", // TODO: Fix whatever alignment issue requires these uniforms to be aligned. @@ -62,6 +63,7 @@ impl Globals { Self { view_mat: arr_to_mat(view_mat.into_col_array()), proj_mat: arr_to_mat(proj_mat.into_col_array()), + all_mat: arr_to_mat((proj_mat * view_mat).into_col_array()), cam_pos: Vec4::from(cam_pos).into_array(), focus_pos: Vec4::from(focus_pos).into_array(), view_distance: [view_distance; 4], From 34c88708af981b16a6fca700adf5112f3ec6e6e0 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 21 Jan 2020 13:14:25 +0000 Subject: [PATCH 2/2] Adjusted cloud fuzz factor --- assets/voxygen/shaders/include/cloud/regular.glsl | 2 +- assets/voxygen/shaders/include/sky.glsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 6062365a51..8fa9df2d25 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -45,7 +45,7 @@ vec4 get_cloud_color(vec3 dir, vec3 origin, float time_of_day, float max_dist, f float start = max(min(mind, maxd), 0.0); float delta = min(abs(mind - maxd), max_dist); - float fuzz = sin(texture(t_noise, dir.xz * 100000.0 + tick.x).x * 100.0) * INCR * delta * pow(maxd - mind, 0.5); + float fuzz = sin(texture(t_noise, dir.xz * 100000.0 + tick.x).x * 100.0) * INCR * delta * pow(maxd - mind, 0.3) * 2.0; float cloud_shade = 1.0; float passthrough = 1.0; diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index 98ef2399b0..447b90ef62 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -81,7 +81,7 @@ void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diff light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE; diffuse_light = - sun_chroma * mix(1.0, max(dot(-norm, sun_dir) * 0.6 + 0.4, 0.0), diffusion) + + 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);