diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index 95a5de0b05..034c98edcb 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -257,6 +257,37 @@ void main() { DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos); DirectionalLight moon_info = get_moon_info(moon_dir, point_shadow * moon_shade_frac/*, light_pos*/); + #ifdef EXPERIMENTAL_DIRECTIONALSHADOWMAPTEXELGRID + float offset_scale = 0.5; + vec3 offset_one = dFdx(f_pos) * offset_scale; + vec3 offset_two = dFdy(f_pos) * offset_scale; + vec3 one_up = f_pos + offset_one; + vec3 one_down = f_pos - offset_one; + vec3 two_up = f_pos + offset_two; + vec3 two_down = f_pos - offset_two; + + // Adjust this to change the size of the grid cells relative to the + // number of shadow texels + float grid_cell_to_texel_ratio = 32.0; + + vec2 shadowTexSize = textureSize(sampler2D(t_directed_shadow_maps, s_directed_shadow_maps), 0) / grid_cell_to_texel_ratio; + + vec4 one_up_shadow_tex = texture_mat * vec4(one_up, 1.0); + vec2 oust_snap = floor(one_up_shadow_tex.xy * shadowTexSize / one_up_shadow_tex.w); + vec4 one_down_shadow_tex = texture_mat * vec4(one_down, 1.0); + vec2 odst_snap = floor(one_down_shadow_tex.xy * shadowTexSize / one_down_shadow_tex.w); + vec4 two_up_shadow_tex = texture_mat * vec4(two_up, 1.0); + vec2 tust_snap = floor(two_up_shadow_tex.xy * shadowTexSize / two_up_shadow_tex.w); + vec4 two_down_shadow_tex = texture_mat * vec4(two_down, 1.0); + vec2 tdst_snap = floor(two_down_shadow_tex.xy * shadowTexSize / two_down_shadow_tex.w); + float border = length(max(abs(oust_snap - odst_snap), abs(tust_snap - tdst_snap))); + + if (border != 0.0) { + tgt_color = vec4(vec3(0.0, 0.7, 0.2), 1.0); + return; + } + #endif + float max_light = 0.0; // After shadows are computed, we use a refracted sun and moon direction. diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index 4eee800bfc..9b50e4d4e8 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -462,6 +462,9 @@ pub enum ExperimentalShader { LowGlowNearCamera, /// Disable the fake voxel effect on LoD features. NoLodVoxels, - // Disable the 'pop-in' effect when loading terrain. + /// Disable the 'pop-in' effect when loading terrain. NoTerrainPop, + /// Display grid lines to visualize the distribution of shadow map texels + /// for the directional light from the sun. + DirectionalShadowMapTexelGrid, } diff --git a/voxygen/src/render/pipelines/mod.rs b/voxygen/src/render/pipelines/mod.rs index fe5f1f684d..0fad8f5598 100644 --- a/voxygen/src/render/pipelines/mod.rs +++ b/voxygen/src/render/pipelines/mod.rs @@ -50,7 +50,9 @@ pub struct Globals { /// aligned. view_distance: [f32; 4], time_of_day: [f32; 4], // TODO: Make this f64. + /// Direction of sunlight. sun_dir: [f32; 4], + /// Direction of moonlight. moon_dir: [f32; 4], tick: [f32; 4], /// x, y represent the resolution of the screen; @@ -163,11 +165,13 @@ impl Globals { time_of_day as f32 * TIME_FACTOR } + /// Computes the direction of light from the sun based on the time of day. pub fn get_sun_dir(time_of_day: f64) -> Vec3 { let angle_rad = Self::get_angle_rad(time_of_day); Vec3::new(-angle_rad.sin(), 0.0, angle_rad.cos()) } + /// Computes the direction of light from the moon based on the time of day. pub fn get_moon_dir(time_of_day: f64) -> Vec3 { let angle_rad = Self::get_angle_rad(time_of_day); -Vec3::new(-angle_rad.sin(), 0.0, angle_rad.cos() - 0.5).normalized() diff --git a/voxygen/src/scene/math.rs b/voxygen/src/scene/math.rs index dcf55404e7..41c2ae6749 100644 --- a/voxygen/src/scene/math.rs +++ b/voxygen/src/scene/math.rs @@ -366,6 +366,14 @@ pub fn calc_focused_light_volume_points + co ) */ } +/// Computes an axis aligned bounding box that contains the provided points when +/// transformed into the coordinate space specificed by `mat`. +/// +/// "psr" stands for "Potential shadow receivers" since this function is used to +/// get an Aabb containing the potential points (which represent the extents of +/// the volumes of potential things that will be shadowed) that will be +/// shadowed. +/// /// NOTE: Will not yield useful results if pts is empty! pub fn fit_psr< T: Float + MulAdd,