From 5866e23e3208fcd2c59e573cdb7e810fc4d8cbfa Mon Sep 17 00:00:00 2001 From: Imbris Date: Sat, 11 Jun 2022 19:06:31 -0400 Subject: [PATCH] Pre-compute view_mat_inv * proj_mat_inv on the CPU before sending to the cloud shader --- assets/voxygen/shaders/clouds-frag.glsl | 54 +++++++++++++++++++++---- assets/voxygen/shaders/include/lod.glsl | 1 + voxygen/src/render/pipelines/clouds.rs | 10 +++-- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/assets/voxygen/shaders/clouds-frag.glsl b/assets/voxygen/shaders/clouds-frag.glsl index 19cc6e9b74..0c40dc067f 100644 --- a/assets/voxygen/shaders/clouds-frag.glsl +++ b/assets/voxygen/shaders/clouds-frag.glsl @@ -42,17 +42,31 @@ layout(location = 0) in vec2 uv; layout (std140, set = 2, binding = 4) uniform u_locals { - mat4 proj_mat_inv; - mat4 view_mat_inv; + //mat4 proj_mat_inv; + //mat4 view_mat_inv; + mat4 all_mat_inv; }; layout(location = 0) out vec4 tgt_color; +// start +// 777 instructions with rain commented out +// 0.55 - 0.58 ms staring at high time area in sky in rain +// 0.48 ms staring at roughly open sky in rain 45 degree +// 0.35 ms staring at feet in rain + +// precombine inversion matrix +// 683 instructions +// 0.55 ms starting at high time arena in sky in rain +// 0.46 ms staring roughly open sky roughly 45 degree in rain +// 0.33 ms staring at feet in rain + + vec3 wpos_at(vec2 uv) { float buf_depth = texture(sampler2D(t_src_depth, s_src_depth), uv).x; - mat4 inv = view_mat_inv * proj_mat_inv;//inverse(all_mat); + //mat4 inv = view_mat_inv * proj_mat_inv;//inverse(all_mat); vec4 clip_space = vec4((uv * 2.0 - 1.0) * vec2(1, -1), buf_depth, 1.0); - vec4 view_space = inv * clip_space; + vec4 view_space = all_mat_inv * clip_space; view_space /= view_space.w; if (buf_depth == 0.0) { vec3 direction = normalize(view_space.xyz); @@ -62,7 +76,7 @@ vec3 wpos_at(vec2 uv) { } } -mat4 spin_in_axis(vec3 axis, float angle) +/*mat4 spin_in_axis(vec3 axis, float angle) { axis = normalize(axis); float s = sin(angle); @@ -73,10 +87,11 @@ mat4 spin_in_axis(vec3 axis, float angle) oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0, 0, 0, 0, 1); -} +}*/ void main() { vec4 color = texture(sampler2D(t_src_color, s_src_color), uv); + color.rgb *= 0.25; #ifdef EXPERIMENTAL_BAREMINIMUM tgt_color = vec4(color.rgb, 1); @@ -93,25 +108,43 @@ void main() { cloud_blend = 1.0 - color.a; dist = DIST_CAP; } - color.rgb = mix(color.rgb, get_cloud_color(color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0), cloud_blend); + //color.rgb = mix(color.rgb, get_cloud_color(color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0), cloud_blend); #if (CLOUD_MODE == CLOUD_MODE_NONE) color.rgb = apply_point_glow(cam_pos.xyz + focus_off.xyz, dir, dist, color.rgb); #else vec3 old_color = color.rgb; + // 0.43 ms extra without this + // 0.01 ms spent on rain_density_at? + // 0.49 -> 0.13 (0.36 ms with full occupancy) + //tgt_color = vec4(color.rgb, 1); + //return; + + // normalized direction from the camera position to the fragment in world, transformed by the relative rain direction dir = (vec4(dir, 0) * rel_rain_dir_mat).xyz; + // stretch z values far from 0 float z = (-1 / (abs(dir.z) - 1) - 1) * sign(dir.z); + // normalize xy to get a 2d direction vec2 dir_2d = normalize(dir.xy); + // view_pos is the angle from x axis (except x and y are flipped, so the + // angle 0 is looking along the y-axis) + // + // combined with stretched z position essentially we unroll a cylinder + // around the z axis while stretching it to make the sections near the + // origin larger in the Z direction vec2 view_pos = vec2(atan2(dir_2d.x, dir_2d.y), z); + // compute camera position in the world vec3 cam_wpos = cam_pos.xyz + focus_off.xyz; + // Rain density is now only based on the cameras current position. // This could be affected by a setting where rain_density_at is instead // called each iteration of the loop. With the current implementation // of rain_dir this has issues with being in a place where it doesn't rain // and seeing rain. + float rain_density = rain_density * 1.0; if (medium.x == MEDIUM_AIR && rain_density > 0.0) { float rain_dist = 50.0; #if (CLOUD_MODE <= CLOUD_MODE_LOW) @@ -133,6 +166,13 @@ void main() { vec2 cell = floor(rain_pos * drop_density) / drop_density; + // For reference: + // + // float hash(vec4 p) { + // p = fract(p * 0.3183099 + 0.1) - fract(p + 23.22121); + // p *= 17.0; + // return (fract(p.x * p.y * (1.0 - p.z) * p.w * (p.x + p.y + p.z + p.w)) - 0.5) * 2.0; + // } float drop_depth = mix( old_rain_dist, rain_dist, diff --git a/assets/voxygen/shaders/include/lod.glsl b/assets/voxygen/shaders/include/lod.glsl index e56e2f5010..d2efde0737 100644 --- a/assets/voxygen/shaders/include/lod.glsl +++ b/assets/voxygen/shaders/include/lod.glsl @@ -28,6 +28,7 @@ vec4 cubic(float v) { return vec4(x, y, z, w) * (1.0/6.0); } +// Computes atan(y, x), except with more stability when x is near 0. float atan2(in float y, in float x) { bool s = (abs(x) > abs(y)); return mix(PI/2.0 - atan(x,y), atan(y,x), s); diff --git a/voxygen/src/render/pipelines/clouds.rs b/voxygen/src/render/pipelines/clouds.rs index f0531bdf85..0360d296d1 100644 --- a/voxygen/src/render/pipelines/clouds.rs +++ b/voxygen/src/render/pipelines/clouds.rs @@ -8,8 +8,9 @@ use vek::*; #[repr(C)] #[derive(Copy, Clone, Debug, Zeroable, Pod)] pub struct Locals { - proj_mat_inv: [[f32; 4]; 4], - view_mat_inv: [[f32; 4]; 4], + //proj_mat_inv: [[f32; 4]; 4], + //view_mat_inv: [[f32; 4]; 4], + all_mat_inv: [[f32; 4]; 4], } impl Default for Locals { @@ -19,8 +20,9 @@ impl Default for Locals { impl Locals { pub fn new(proj_mat_inv: Mat4, view_mat_inv: Mat4) -> Self { Self { - proj_mat_inv: proj_mat_inv.into_col_arrays(), - view_mat_inv: view_mat_inv.into_col_arrays(), + //proj_mat_inv: proj_mat_inv.into_col_arrays(), + //view_mat_inv: view_mat_inv.into_col_arrays(), + all_mat_inv: (view_mat_inv * proj_mat_inv).into_col_arrays(), } } }