From 0eb06da057e8e912d6f9b3de4b3efbd3dc46624c Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 26 May 2023 18:32:01 +0200 Subject: [PATCH] Jitter shadow map dithering pattern across frames when TAA is enabled This improves shadow quality by reducing the visibility of the noisy pattern caused by dithering. This jittering also applies when FSR2 is enabled, as it provides its own form of temporal antialiasing. Co-authored-by: Clay John --- .../renderer_rd/renderer_scene_render_rd.cpp | 1 + .../scene_forward_clustered.glsl | 16 ++++----- .../forward_mobile/scene_forward_mobile.glsl | 36 +++++++++---------- .../renderer_rd/shaders/scene_data_inc.glsl | 4 +-- .../shaders/scene_forward_lights_inc.glsl | 28 +++++++-------- .../storage_rd/render_scene_data_rd.cpp | 1 + .../storage_rd/render_scene_data_rd.h | 3 +- servers/rendering/renderer_scene_cull.cpp | 6 ++-- servers/rendering/renderer_scene_render.cpp | 3 +- servers/rendering/renderer_scene_render.h | 3 +- 10 files changed, 54 insertions(+), 47 deletions(-) diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 7d6d5018d07..0c21fec2824 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1131,6 +1131,7 @@ void RendererSceneRenderRD::render_scene(const Ref &p_render scene_data.cam_orthogonal = p_camera_data->is_orthogonal; scene_data.camera_visible_layers = p_camera_data->visible_layers; scene_data.taa_jitter = p_camera_data->taa_jitter; + scene_data.taa_frame_count = p_camera_data->taa_frame_count; scene_data.main_cam_transform = p_camera_data->main_transform; scene_data.flip_y = !p_reflection_probe.is_valid(); diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index a441b1667d2..400451ec36b 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -1886,7 +1886,7 @@ void fragment_shader(in SceneData scene_data) { float range_begin = directional_lights.data[i].shadow_range_begin.x; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); blend_count++; } @@ -1902,7 +1902,7 @@ void fragment_shader(in SceneData scene_data) { float range_begin = directional_lights.data[i].shadow_range_begin.y; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; - float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); if (blend_count == 0) { shadow = s; @@ -1927,7 +1927,7 @@ void fragment_shader(in SceneData scene_data) { float range_begin = directional_lights.data[i].shadow_range_begin.z; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; - float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); if (blend_count == 0) { shadow = s; @@ -1952,7 +1952,7 @@ void fragment_shader(in SceneData scene_data) { float range_begin = directional_lights.data[i].shadow_range_begin.w; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; - float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); if (blend_count == 0) { shadow = s; @@ -2003,7 +2003,7 @@ void fragment_shader(in SceneData scene_data) { pssm_coord /= pssm_coord.w; - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor + (1.0 - blur_factor) * float(directional_lights.data[i].blend_splits)), pssm_coord); + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor + (1.0 - blur_factor) * float(directional_lights.data[i].blend_splits)), pssm_coord, scene_data.taa_frame_count); if (directional_lights.data[i].blend_splits) { float pssm_blend; @@ -2037,7 +2037,7 @@ void fragment_shader(in SceneData scene_data) { pssm_coord /= pssm_coord.w; - float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor2 + (1.0 - blur_factor2) * float(directional_lights.data[i].blend_splits)), pssm_coord); + float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor2 + (1.0 - blur_factor2) * float(directional_lights.data[i].blend_splits)), pssm_coord, scene_data.taa_frame_count); shadow = mix(shadow, shadow2, pssm_blend); } } @@ -2220,7 +2220,7 @@ void fragment_shader(in SceneData scene_data) { continue; // Statically baked light and object uses lightmap, skip } - float shadow = light_process_omni_shadow(light_index, vertex, normal); + float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count); shadow = blur_shadow(shadow); @@ -2292,7 +2292,7 @@ void fragment_shader(in SceneData scene_data) { continue; // Statically baked light and object uses lightmap, skip } - float shadow = light_process_spot_shadow(light_index, vertex, normal); + float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count); shadow = blur_shadow(shadow); diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 92a8e2be326..17c7b756c3f 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -1450,9 +1450,9 @@ void main() { float range_begin = directional_lights.data[i].shadow_range_begin.x; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); } } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); @@ -1467,9 +1467,9 @@ void main() { float range_begin = directional_lights.data[i].shadow_range_begin.y; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); } } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); @@ -1484,9 +1484,9 @@ void main() { float range_begin = directional_lights.data[i].shadow_range_begin.z; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); } } else { vec4 v = vec4(vertex, 1.0); @@ -1501,9 +1501,9 @@ void main() { float range_begin = directional_lights.data[i].shadow_range_begin.w; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); } } @@ -1522,9 +1522,9 @@ void main() { float range_begin = directional_lights.data[i].shadow_range_begin.y; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); } pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); @@ -1539,9 +1539,9 @@ void main() { float range_begin = directional_lights.data[i].shadow_range_begin.z; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); @@ -1555,9 +1555,9 @@ void main() { float range_begin = directional_lights.data[i].shadow_range_begin.w; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale, scene_data.taa_frame_count); } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord, scene_data.taa_frame_count); } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); @@ -1627,7 +1627,7 @@ void main() { pssm_coord /= pssm_coord.w; - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor + (1.0 - blur_factor) * float(directional_lights.data[i].blend_splits)), pssm_coord); + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor + (1.0 - blur_factor) * float(directional_lights.data[i].blend_splits)), pssm_coord, scene_data.taa_frame_count); if (directional_lights.data[i].blend_splits) { float pssm_blend; @@ -1661,7 +1661,7 @@ void main() { pssm_coord /= pssm_coord.w; - float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor2 + (1.0 - blur_factor2) * float(directional_lights.data[i].blend_splits)), pssm_coord); + float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor2 + (1.0 - blur_factor2) * float(directional_lights.data[i].blend_splits)), pssm_coord, scene_data.taa_frame_count); shadow = mix(shadow, shadow2, pssm_blend); } @@ -1767,7 +1767,7 @@ void main() { break; } - float shadow = light_process_omni_shadow(light_index, vertex, normal); + float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count); shadow = blur_shadow(shadow); @@ -1812,7 +1812,7 @@ void main() { break; } - float shadow = light_process_spot_shadow(light_index, vertex, normal); + float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count); shadow = blur_shadow(shadow); diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl index 67542d61fd0..a2fef216f5c 100644 --- a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl @@ -52,11 +52,11 @@ struct SceneData { uint fog_mode; highp float fog_density; highp float fog_height; - highp float fog_height_density; + highp float fog_height_density; highp float fog_depth_curve; - highp float pad; highp float fog_depth_begin; + highp float taa_frame_count; mediump vec3 fog_light_color; highp float fog_depth_end; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 748fb59531b..14a4dc7089d 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -264,7 +264,7 @@ float quick_hash(vec2 pos) { return fract(magic.z * fract(dot(pos, magic.xy))); } -float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { +float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord, float taa_frame_count) { vec2 pos = coord.xy; float depth = coord.z; @@ -275,7 +275,7 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve mat2 disk_rotation; { - float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float r = quick_hash(gl_FragCoord.xy + vec2(taa_frame_count * 5.588238)) * 2.0 * M_PI; float sr = sin(r); float cr = cos(r); disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); @@ -290,7 +290,7 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve return avg * (1.0 / float(sc_directional_soft_shadow_samples)); } -float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) { +float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord, float taa_frame_count) { vec2 pos = coord.xy; float depth = coord.z; @@ -301,7 +301,7 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) { mat2 disk_rotation; { - float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float r = quick_hash(gl_FragCoord.xy + vec2(taa_frame_count * 5.588238)) * 2.0 * M_PI; float sr = sin(r); float cr = cos(r); disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); @@ -316,7 +316,7 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) { return avg * (1.0 / float(sc_soft_shadow_samples)); } -float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec4 uv_rect, vec2 flip_offset, float depth) { +float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec4 uv_rect, vec2 flip_offset, float depth, float taa_frame_count) { //if only one sample is taken, take it from the center if (sc_soft_shadow_samples == 0) { vec2 pos = coord * 0.5 + 0.5; @@ -326,7 +326,7 @@ float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec mat2 disk_rotation; { - float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float r = quick_hash(gl_FragCoord.xy + vec2(taa_frame_count * 5.588238)) * 2.0 * M_PI; float sr = sin(r); float cr = cos(r); disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); @@ -359,14 +359,14 @@ float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec return avg * (1.0 / float(sc_soft_shadow_samples)); } -float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) { +float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale, float taa_frame_count) { //find blocker float blocker_count = 0.0; float blocker_average = 0.0; mat2 disk_rotation; { - float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float r = quick_hash(gl_FragCoord.xy + vec2(taa_frame_count * 5.588238)) * 2.0 * M_PI; float sr = sin(r); float cr = cos(r); disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); @@ -412,7 +412,7 @@ float get_omni_attenuation(float distance, float inv_range, float decay) { return nd * pow(max(distance, 0.0001), -decay); } -float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { +float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal, float taa_frame_count) { #ifndef SHADOWS_DISABLED if (omni_lights.data[idx].shadow_opacity > 0.001) { // there is a shadowmap @@ -444,7 +444,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { mat2 disk_rotation; { - float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float r = quick_hash(gl_FragCoord.xy + vec2(taa_frame_count * 5.588238)) * 2.0 * M_PI; float sr = sin(r); float cr = cos(r); disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); @@ -537,7 +537,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { float depth = shadow_len - omni_lights.data[idx].shadow_bias; depth *= omni_lights.data[idx].inv_radius; depth = 1.0 - depth; - shadow = mix(1.0, sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth), omni_lights.data[idx].shadow_opacity); + shadow = mix(1.0, sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth, taa_frame_count), omni_lights.data[idx].shadow_opacity); } return shadow; @@ -698,7 +698,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v specular_light); } -float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { +float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal, float taa_frame_count) { #ifndef SHADOWS_DISABLED if (spot_lights.data[idx].shadow_opacity > 0.001) { vec3 light_rel_vec = spot_lights.data[idx].position - vertex; @@ -729,7 +729,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { mat2 disk_rotation; { - float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float r = quick_hash(gl_FragCoord.xy + vec2(taa_frame_count * 5.588238)) * 2.0 * M_PI; float sr = sin(r); float cr = cos(r); disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); @@ -770,7 +770,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { } else { //hard shadow vec3 shadow_uv = vec3(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z); - shadow = mix(1.0, sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data_block.data.shadow_atlas_pixel_size, shadow_uv), spot_lights.data[idx].shadow_opacity); + shadow = mix(1.0, sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data_block.data.shadow_atlas_pixel_size, shadow_uv, taa_frame_count), spot_lights.data[idx].shadow_opacity); } return shadow; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp index 148a556b461..660836facf6 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp @@ -112,6 +112,7 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p ubo.taa_jitter[0] = taa_jitter.x; ubo.taa_jitter[1] = taa_jitter.y; + ubo.taa_frame_count = taa_frame_count; ubo.z_far = z_far; ubo.z_near = z_near; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h index b2c93acd44d..4a70482d72f 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h @@ -48,6 +48,7 @@ public: Transform3D cam_transform; Projection cam_projection; Vector2 taa_jitter; + float taa_frame_count = 0.0f; uint32_t camera_visible_layers; bool cam_orthogonal = false; bool flip_y = false; @@ -148,8 +149,8 @@ private: float fog_height_density; float fog_depth_curve; - float pad; float fog_depth_begin; + float taa_frame_count; // Used to add break up samples over multiple frames. Value is an integer from 0 to taa_phase_count -1. float fog_light_color[3]; float fog_depth_end; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 286944641c4..43abb22e3d8 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2700,6 +2700,7 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu ERR_FAIL_NULL(camera); Vector2 jitter; + float taa_frame_count = 0.0f; if (p_jitter_phase_count > 0) { uint32_t current_jitter_count = camera_jitter_array.size(); if (p_jitter_phase_count != current_jitter_count) { @@ -2713,6 +2714,7 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu } jitter = camera_jitter_array[RSG::rasterizer->get_frame_number() % p_jitter_phase_count] / p_viewport_size; + taa_frame_count = float(RSG::rasterizer->get_frame_number() % p_jitter_phase_count); } RendererSceneRender::CameraData camera_data; @@ -2755,7 +2757,7 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu } break; } - camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, camera->visible_layers); + camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, taa_frame_count, camera->visible_layers); } else { // Setup our camera for our XR interface. // We can support multiple views here each with their own camera @@ -2777,7 +2779,7 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu } if (view_count == 1) { - camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, camera->visible_layers); + camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, p_jitter_phase_count, camera->visible_layers); } else if (view_count == 2) { camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect); } else { diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index 76c779900fb..797ba7eaf74 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -33,7 +33,7 @@ ///////////////////////////////////////////////////////////////////////////// // CameraData -void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter, const uint32_t p_visible_layers) { +void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter, float p_taa_frame_count, const uint32_t p_visible_layers) { view_count = 1; is_orthogonal = p_is_orthogonal; vaspect = p_vaspect; @@ -45,6 +45,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, view_offset[0] = Transform3D(); view_projection[0] = p_projection; taa_jitter = p_taa_jitter; + taa_frame_count = p_taa_frame_count; } void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) { diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 3446f5dd1bb..72ccbcdf119 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -307,8 +307,9 @@ public: Transform3D view_offset[RendererSceneRender::MAX_RENDER_VIEWS]; Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; Vector2 taa_jitter; + float taa_frame_count = 0.0f; - void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), uint32_t p_visible_layers = 0xFFFFFFFF); + void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), float p_taa_frame_count = 0.0f, uint32_t p_visible_layers = 0xFFFFFFFF); void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect); };