diff options
author | reduz <reduzio@gmail.com> | 2021-02-06 11:51:56 -0300 |
---|---|---|
committer | reduz <reduzio@gmail.com> | 2021-02-06 15:08:21 -0300 |
commit | 8faf23b52b0147eea6903e84973893802d97d339 (patch) | |
tree | c672077cff56f43a5a318e89be7c2e956de4aa6e /servers/rendering | |
parent | fa2f7693bb9efc44755b1b693b22ec2788910a0d (diff) |
Simplify Volumetric Fog
-Always use temporal reproject, it just loos way better than any other filter.
-By always using termporal reproject, the shadowmap reduction can be done away with, massively improving performance.
-Disadvantage of temporal reproject is update latency so..
-Made sure a gaussian filter runs in XY after fog, this allows to keep stability and lower latency.
Diffstat (limited to 'servers/rendering')
-rw-r--r-- | servers/rendering/renderer_rd/effects_rd.cpp | 71 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/effects_rd.h | 18 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.cpp | 255 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.h | 24 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_storage_rd.cpp | 2 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/shaders/SCsub | 1 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/shaders/shadow_reduce.glsl | 163 | ||||
-rw-r--r-- | servers/rendering/renderer_scene.h | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_scene_cull.h | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_scene_render.h | 5 | ||||
-rw-r--r-- | servers/rendering/rendering_server_default.h | 4 | ||||
-rw-r--r-- | servers/rendering/rendering_server_wrap_mt.h | 4 |
12 files changed, 17 insertions, 538 deletions
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 8269328597..a9cadb40df 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -1423,60 +1423,6 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI RD::get_singleton()->compute_list_end(p_barrier); } -void EffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) { - uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, (uint32_t)p_shrink_limit, 0, 0, 0 }; - - uint32_t height = p_source_rect.size.height; - if (true) { // subgroup support, @TODO must detect them - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[p_shrink_limit == 1 ? SHADOW_REDUCE_REDUCE_SUBGROUPS_8 : SHADOW_REDUCE_REDUCE_SUBGROUPS]); - height /= 2; //cause kernel is 8x4 - } else { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_REDUCE]); - } - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_shadow), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_shadow), 1); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, height, 1); -} -void EffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) { - uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, 0, 0, 0, 0 }; - - switch (p_filter) { - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED: - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW: { - push_constant[5] = 0; - } break; - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM: { - push_constant[5] = 9; - } break; - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH: { - push_constant[5] = 18; - } break; - } - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_FILTER]); - if (p_vertical) { - push_constant[6] = 1; - push_constant[7] = 0; - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_shadow), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_backing_shadow), 1); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1); - } - if (p_vertical && p_horizontal) { - RD::get_singleton()->compute_list_add_barrier(compute_list); - } - if (p_horizontal) { - push_constant[6] = 0; - push_constant[7] = 1; - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_backing_shadow), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_shadow), 1); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1); - } -} - void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { Sort::PushConstant push_constant; push_constant.total_elements = p_size; @@ -1973,22 +1919,6 @@ EffectsRD::EffectsRD() { } { - Vector<String> shadow_reduce_modes; - shadow_reduce_modes.push_back("\n#define MODE_REDUCE\n"); - shadow_reduce_modes.push_back("\n#define MODE_REDUCE_SUBGROUP\n"); - shadow_reduce_modes.push_back("\n#define MODE_REDUCE_SUBGROUP\n#define MODE_REDUCE_8\n"); - shadow_reduce_modes.push_back("\n#define MODE_FILTER\n"); - - shadow_reduce.shader.initialize(shadow_reduce_modes); - - shadow_reduce.shader_version = shadow_reduce.shader.version_create(); - - for (int i = 0; i < SHADOW_REDUCE_MAX; i++) { - shadow_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(shadow_reduce.shader.version_get_shader(shadow_reduce.shader_version, i)); - } - } - - { Vector<String> sort_modes; sort_modes.push_back("\n#define MODE_SORT_BLOCK\n"); sort_modes.push_back("\n#define MODE_SORT_STEP\n"); @@ -2076,5 +2006,4 @@ EffectsRD::~EffectsRD() { ssr_scale.shader.version_free(ssr_scale.shader_version); sss.shader.version_free(sss.shader_version); tonemap.shader.version_free(tonemap.shader_version); - shadow_reduce.shader.version_free(shadow_reduce.shader_version); } diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 7ae5ea2f37..1ba25e301b 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -46,7 +46,6 @@ #include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/shadow_reduce.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h" @@ -597,20 +596,6 @@ class EffectsRD { RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels } resolve; - enum ShadowReduceMode { - SHADOW_REDUCE_REDUCE, - SHADOW_REDUCE_REDUCE_SUBGROUPS, - SHADOW_REDUCE_REDUCE_SUBGROUPS_8, - SHADOW_REDUCE_FILTER, - SHADOW_REDUCE_MAX - }; - - struct ShadowReduce { - ShadowReduceShaderRD shader; - RID shader_version; - RID pipelines[SHADOW_REDUCE_MAX]; - } shadow_reduce; - enum SortMode { SORT_MODE_BLOCK, SORT_MODE_STEP, @@ -767,9 +752,6 @@ public: void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); - void reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RenderingDevice::ComputeListID compute_list); - void filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RS::EnvVolumetricFogShadowFilter p_filter, RenderingDevice::ComputeListID compute_list, bool p_vertical = true, bool p_horizontal = true); - void sort_buffer(RID p_uniform_set, int p_size); EffectsRD(); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 11a1eb3ca9..14bcfc85c8 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3151,7 +3151,7 @@ float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) c return env->fog_aerial_perspective; } -void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) { +void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -3165,7 +3165,6 @@ void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_ena env->volumetric_fog_light_energy = p_light_energy; env->volumetric_fog_length = p_length; env->volumetric_fog_detail_spread = p_detail_spread; - env->volumetric_fog_shadow_filter = p_shadow_filter; env->volumetric_fog_gi_inject = p_gi_inject; env->volumetric_fog_temporal_reprojection = p_temporal_reprojection; env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount; @@ -3179,25 +3178,6 @@ void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_siz void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) { volumetric_fog_filter_active = p_enable; } -void RendererSceneRenderRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) { - p_shrink_size = nearest_power_of_2_templated(p_shrink_size); - if (volumetric_fog_directional_shadow_shrink == (uint32_t)p_shrink_size) { - return; - } - - _clear_shadow_shrink_stages(directional_shadow.shrink_stages); -} -void RendererSceneRenderRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) { - p_shrink_size = nearest_power_of_2_templated(p_shrink_size); - if (volumetric_fog_positional_shadow_shrink == (uint32_t)p_shrink_size) { - return; - } - - for (uint32_t i = 0; i < shadow_atlas_owner.get_rid_count(); i++) { - ShadowAtlas *sa = shadow_atlas_owner.get_ptr_by_index(i); - _clear_shadow_shrink_stages(sa->shrink_stages); - } -} void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { sdfgi_ray_count = p_ray_count; @@ -3649,7 +3629,6 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool if (shadow_atlas->depth.is_valid()) { RD::get_singleton()->free(shadow_atlas->depth); shadow_atlas->depth = RID(); - _clear_shadow_shrink_stages(shadow_atlas->shrink_stages); } for (int i = 0; i < 4; i++) { //clear subdivisions @@ -3948,7 +3927,6 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p if (directional_shadow.depth.is_valid()) { RD::get_singleton()->free(directional_shadow.depth); - _clear_shadow_shrink_stages(directional_shadow.shrink_stages); directional_shadow.depth = RID(); _base_uniforms_changed(); } @@ -6480,8 +6458,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance; RID base = li->light; - cluster.lights_instances[i] = li->self; - Transform light_transform = li->transform; float sign = storage->light_is_negative(base) ? -1 : 1; @@ -6820,49 +6796,6 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { rb->volumetric_fog = nullptr; } -void RendererSceneRenderRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) { - //create fog mipmaps - uint32_t fog_texture_size = p_target_size; - uint32_t base_texture_size = p_base_size; - - ShadowShrinkStage first; - first.size = base_texture_size; - first.texture = p_base; - shrink_stages.push_back(first); //put depth first in case we dont find smaller ones - - while (fog_texture_size < base_texture_size) { - base_texture_size = MAX(base_texture_size / 8, fog_texture_size); - - ShadowShrinkStage s; - s.size = base_texture_size; - - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16_UNORM; - tf.width = base_texture_size; - tf.height = base_texture_size; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; - - if (base_texture_size == fog_texture_size) { - s.filter_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT; - } - - s.texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - - shrink_stages.push_back(s); - } -} - -void RendererSceneRenderRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) { - for (int i = 1; i < shrink_stages.size(); i++) { - RD::get_singleton()->free(shrink_stages[i].texture); - if (shrink_stages[i].filter_texture.is_valid()) { - RD::get_singleton()->free(shrink_stages[i].filter_texture); - } - } - shrink_stages.clear(); -} - void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -6926,173 +6859,6 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG); } - //update directional shadow - - RENDER_TIMESTAMP("Downsample Shadows"); - - if (p_use_directional_shadows) { - RD::get_singleton()->draw_command_begin_label("Downsample Directional Shadows"); - - if (directional_shadow.shrink_stages.is_empty()) { - if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { - //invalidate uniform set, we will need a new one - RD::get_singleton()->free(rb->volumetric_fog->uniform_set); - rb->volumetric_fog->uniform_set = RID(); - } - _allocate_shadow_shrink_stages(directional_shadow.depth, directional_shadow.size, directional_shadow.shrink_stages, volumetric_fog_directional_shadow_shrink); - } - - if (directional_shadow.shrink_stages.size() > 1) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - for (int i = 1; i < directional_shadow.shrink_stages.size(); i++) { - int32_t src_size = directional_shadow.shrink_stages[i - 1].size; - int32_t dst_size = directional_shadow.shrink_stages[i].size; - Rect2i r(0, 0, src_size, src_size); - int32_t shrink_limit = 8 / (src_size / dst_size); - - storage->get_effects()->reduce_shadow(directional_shadow.shrink_stages[i - 1].texture, directional_shadow.shrink_stages[i].texture, Size2i(src_size, src_size), r, shrink_limit, compute_list); - RD::get_singleton()->compute_list_add_barrier(compute_list); - if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && directional_shadow.shrink_stages[i].filter_texture.is_valid()) { - Rect2i rf(0, 0, dst_size, dst_size); - storage->get_effects()->filter_shadow(directional_shadow.shrink_stages[i].texture, directional_shadow.shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), rf, env->volumetric_fog_shadow_filter, compute_list); - } - } - RD::get_singleton()->compute_list_end(); - } - RD::get_singleton()->draw_command_end_label(); - } - - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); - - if (shadow_atlas) { - //shrink shadows that need to be shrunk - - RD::get_singleton()->draw_command_begin_label("Downsample Positional Shadows"); - - bool force_shrink_shadows = false; - - if (shadow_atlas->shrink_stages.is_empty()) { - if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { - //invalidate uniform set, we will need a new one - RD::get_singleton()->free(rb->volumetric_fog->uniform_set); - rb->volumetric_fog->uniform_set = RID(); - } - _allocate_shadow_shrink_stages(shadow_atlas->depth, shadow_atlas->size, shadow_atlas->shrink_stages, volumetric_fog_positional_shadow_shrink); - force_shrink_shadows = true; - } - - if (rb->volumetric_fog->last_shadow_filter != env->volumetric_fog_shadow_filter) { - //if shadow filter changed, invalidate caches - rb->volumetric_fog->last_shadow_filter = env->volumetric_fog_shadow_filter; - force_shrink_shadows = true; - } - - cluster.lights_shadow_rect_cache_count = 0; - - for (uint32_t i = 0; i < cluster.omni_light_count + cluster.spot_light_count; i++) { - Cluster::LightData &ld = i < cluster.omni_light_count ? cluster.omni_lights[i] : cluster.spot_lights[i - cluster.omni_light_count]; - - if (ld.shadow_enabled != 0) { - RID li = cluster.lights_instances[i]; - - ERR_CONTINUE(!shadow_atlas->shadow_owners.has(li)); - - uint32_t key = shadow_atlas->shadow_owners[li]; - - uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; - uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK; - - ERR_CONTINUE((int)shadow >= shadow_atlas->quadrants[quadrant].shadows.size()); - - ShadowAtlas::Quadrant::Shadow &s = shadow_atlas->quadrants[quadrant].shadows.write[shadow]; - - if (!force_shrink_shadows && s.fog_version == s.version) { - continue; //do not update, no need - } - - s.fog_version = s.version; - - uint32_t quadrant_size = shadow_atlas->size >> 1; - - Rect2i atlas_rect; - - atlas_rect.position.x = (quadrant & 1) * quadrant_size; - atlas_rect.position.y = (quadrant >> 1) * quadrant_size; - - uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision); - atlas_rect.position.x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; - atlas_rect.position.y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; - - atlas_rect.size.x = shadow_size; - atlas_rect.size.y = shadow_size; - - cluster.lights_shadow_rect_cache[cluster.lights_shadow_rect_cache_count] = atlas_rect; - - cluster.lights_shadow_rect_cache_count++; - - if (cluster.lights_shadow_rect_cache_count == cluster.max_lights * 2) { - break; //light limit reached - } - } - } - - if (cluster.lights_shadow_rect_cache_count > 0) { - //there are shadows to be shrunk, try to do them in parallel - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - - for (int i = 1; i < shadow_atlas->shrink_stages.size(); i++) { - int32_t base_size = shadow_atlas->shrink_stages[0].size; - int32_t src_size = shadow_atlas->shrink_stages[i - 1].size; - int32_t dst_size = shadow_atlas->shrink_stages[i].size; - - uint32_t rect_divisor = base_size / src_size; - - int32_t shrink_limit = 8 / (src_size / dst_size); - - //shrink in parallel for more performance - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i src_rect = cluster.lights_shadow_rect_cache[j]; - - src_rect.position /= rect_divisor; - src_rect.size /= rect_divisor; - - storage->get_effects()->reduce_shadow(shadow_atlas->shrink_stages[i - 1].texture, shadow_atlas->shrink_stages[i].texture, Size2i(src_size, src_size), src_rect, shrink_limit, compute_list); - } - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && shadow_atlas->shrink_stages[i].filter_texture.is_valid()) { - uint32_t filter_divisor = base_size / dst_size; - - //filter in parallel for more performance - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i dst_rect = cluster.lights_shadow_rect_cache[j]; - - dst_rect.position /= filter_divisor; - dst_rect.size /= filter_divisor; - - storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, true, false); - } - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i dst_rect = cluster.lights_shadow_rect_cache[j]; - - dst_rect.position /= filter_divisor; - dst_rect.size /= filter_divisor; - - storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, false, true); - } - } - } - - RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); - } - - RD::get_singleton()->draw_command_end_label(); - } - //update volumetric fog if (rb->volumetric_fog->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { @@ -7104,10 +6870,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - if (shadow_atlas == nullptr || shadow_atlas->shrink_stages.size() == 0) { + ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { - u.ids.push_back(shadow_atlas->shrink_stages[shadow_atlas->shrink_stages.size() - 1].texture); + u.ids.push_back(shadow_atlas->depth); } uniforms.push_back(u); @@ -7117,10 +6884,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - if (directional_shadow.shrink_stages.size() == 0) { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + if (directional_shadow.depth.is_valid()) { + u.ids.push_back(directional_shadow.depth); } else { - u.ids.push_back(directional_shadow.shrink_stages[directional_shadow.shrink_stages.size() - 1].texture); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); } @@ -9079,10 +8846,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { cluster.spot_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights); //defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(cluster.max_lights) + "\n"; - //used for volumetric fog shrinking - cluster.lights_instances = memnew_arr(RID, cluster.max_lights * 2); - cluster.lights_shadow_rect_cache = memnew_arr(Rect2i, cluster.max_lights * 2); - cluster.max_directional_lights = MAX_DIRECTIONAL_LIGHTS; uint32_t directional_light_buffer_size = cluster.max_directional_lights * sizeof(Cluster::DirectionalLightData); cluster.directional_lights = memnew_arr(Cluster::DirectionalLightData, cluster.max_directional_lights); @@ -9134,8 +8897,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth")); environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter")); - environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink")); - environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink")); cull_argument.set_page_pool(&cull_argument_pool); @@ -9197,8 +8958,6 @@ RendererSceneRenderRD::~RendererSceneRenderRD() { memdelete_arr(cluster.spot_lights); memdelete_arr(cluster.omni_light_sort); memdelete_arr(cluster.spot_light_sort); - memdelete_arr(cluster.lights_shadow_rect_cache); - memdelete_arr(cluster.lights_instances); memdelete_arr(cluster.reflections); memdelete_arr(cluster.reflection_sort); memdelete_arr(cluster.decals); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index e6415255a1..8b4f41b6f7 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -591,8 +591,6 @@ private: RID fb; //for copying Map<RID, uint32_t> shadow_owners; - - Vector<ShadowShrinkStage> shrink_stages; }; RID_Owner<ShadowAtlas> shadow_atlas_owner; @@ -626,13 +624,8 @@ private: bool use_16_bits = false; int current_light = 0; - Vector<ShadowShrinkStage> shrink_stages; - } directional_shadow; - void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size); - void _clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages); - void _update_directional_shadow_atlas(); /* SHADOW CUBEMAPS */ @@ -743,10 +736,9 @@ private: float volumetric_fog_light_energy = 0.0; float volumetric_fog_length = 64.0; float volumetric_fog_detail_spread = 2.0; - RS::EnvVolumetricFogShadowFilter volumetric_fog_shadow_filter = RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW; float volumetric_fog_gi_inject = 0.0; - bool volumetric_fog_temporal_reprojection = false; - float volumetric_fog_temporal_reprojection_amount = 0.95; + bool volumetric_fog_temporal_reprojection = true; + float volumetric_fog_temporal_reprojection_amount = 0.9; /// Glow @@ -1471,10 +1463,6 @@ private: uint32_t omni_light_count = 0; uint32_t spot_light_count = 0; - RID *lights_instances; - Rect2i *lights_shadow_rect_cache; - uint32_t lights_shadow_rect_cache_count = 0; - DirectionalLightData *directional_lights; uint32_t max_directional_lights; RID directional_light_buffer; @@ -1594,9 +1582,7 @@ private: uint32_t volumetric_fog_depth = 128; uint32_t volumetric_fog_size = 128; - bool volumetric_fog_filter_active = false; - uint32_t volumetric_fog_directional_shadow_shrink = 512; - uint32_t volumetric_fog_positional_shadow_shrink = 512; + bool volumetric_fog_filter_active = true; void _volumetric_fog_erase(RenderBuffers *rb); void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count); @@ -1721,12 +1707,10 @@ public: float environment_get_fog_height_density(RID p_env) const; float environment_get_fog_aerial_perspective(RID p_env) const; - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount); + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount); virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth); virtual void environment_set_volumetric_fog_filter_active(bool p_enable); - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size); - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size); void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index f9c22dd4bf..a1358f94fa 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -5371,7 +5371,7 @@ RID RendererStorageRD::light_create(RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0; + light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; return light_owner.make_rid(light); diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub index 1b0197c1c1..c192574ff2 100644 --- a/servers/rendering/renderer_rd/shaders/SCsub +++ b/servers/rendering/renderer_rd/shaders/SCsub @@ -39,7 +39,6 @@ if "RD_GLSL" in env["BUILDERS"]: env.RD_GLSL("sdfgi_debug.glsl") env.RD_GLSL("sdfgi_debug_probes.glsl") env.RD_GLSL("volumetric_fog.glsl") - env.RD_GLSL("shadow_reduce.glsl") env.RD_GLSL("particles.glsl") env.RD_GLSL("particles_copy.glsl") env.RD_GLSL("sort.glsl") diff --git a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl deleted file mode 100644 index a29b24e560..0000000000 --- a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl +++ /dev/null @@ -1,163 +0,0 @@ -#[compute] - -#version 450 - -VERSION_DEFINES - -#define BLOCK_SIZE 8 - -#ifdef MODE_REDUCE_SUBGROUP - -#extension GL_KHR_shader_subgroup_ballot : enable -#extension GL_KHR_shader_subgroup_arithmetic : enable - -//nvidia friendly, max 32 -layout(local_size_x = 8, local_size_y = 4, local_size_z = 1) in; - -#else - -layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; - -#endif - -#ifdef MODE_REDUCE - -shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE]; -const uint swizzle_table[BLOCK_SIZE] = uint[](0, 4, 2, 6, 1, 5, 3, 7); -const uint unswizzle_table[BLOCK_SIZE] = uint[](0, 0, 0, 1, 0, 2, 1, 3); - -#endif - -#if defined(MODE_REDUCE) || defined(MODE_REDUCE_SUBGROUP) -layout(set = 0, binding = 0) uniform sampler2D source_depth; -#else -layout(r16, set = 0, binding = 0) uniform restrict readonly image2D source_depth; -#endif -layout(r16, set = 1, binding = 0) uniform restrict writeonly image2D dst_depth; - -layout(push_constant, binding = 1, std430) uniform Params { - ivec2 source_size; - ivec2 source_offset; - uint min_size; - uint gaussian_kernel_version; - ivec2 filter_dir; -} -params; - -void main() { -#ifdef MODE_REDUCE_SUBGROUP - - uvec2 local_pos = gl_LocalInvocationID.xy; - ivec2 image_offset = params.source_offset; - ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy * ivec2(1, 2)); - - float depth = texelFetch(source_depth, min(image_pos, params.source_size - ivec2(1)), 0).r; - depth += texelFetch(source_depth, min(image_pos + ivec2(0, 1), params.source_size - ivec2(1)), 0).r; - depth *= 0.5; - -#ifdef MODE_REDUCE_8 - //fast version, reduce all - float depth_average = subgroupAdd(depth) / 32.0; - if (local_pos == uvec2(0)) { - imageStore(dst_depth, image_pos / 8, vec4(depth_average)); - } -#else - //bit slower version, reduce by regions - uint group_size = (8 / params.min_size); - uvec2 group_id = local_pos / (8 / params.min_size); - - uvec4 mask; - float depth_average = 0; - - while (true) { - uvec2 first = subgroupBroadcastFirst(group_id); - mask = subgroupBallot(first == group_id); - if (first == group_id) { - depth_average = subgroupAdd(depth); - break; - } - } - - depth_average /= float(group_size * group_size); - - if (local_pos == group_id) { - imageStore(dst_depth, image_pos / int(group_size), vec4(depth_average)); - } -#endif - -#endif - -#ifdef MODE_REDUCE - - uvec2 pos = gl_LocalInvocationID.xy; - - ivec2 image_offset = params.source_offset; - ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy); - uint dst_t = swizzle_table[pos.y] * BLOCK_SIZE + swizzle_table[pos.x]; - tmp_data[dst_t] = texelFetch(source_depth, min(image_pos, params.source_size - ivec2(1)), 0).r; - ivec2 image_size = params.source_size; - - uint t = pos.y * BLOCK_SIZE + pos.x; - - //neighbours - uint size = BLOCK_SIZE; - - do { - groupMemoryBarrier(); - barrier(); - - size >>= 1; - image_size >>= 1; - image_offset >>= 1; - - if (all(lessThan(pos, uvec2(size)))) { - uint nx = t + size; - uint ny = t + (BLOCK_SIZE * size); - uint nxy = ny + size; - - tmp_data[t] += tmp_data[nx]; - tmp_data[t] += tmp_data[ny]; - tmp_data[t] += tmp_data[nxy]; - tmp_data[t] /= 4.0; - } - - } while (size > params.min_size); - - if (all(lessThan(pos, uvec2(size)))) { - image_pos = ivec2(unswizzle_table[size + pos.x], unswizzle_table[size + pos.y]); - image_pos += image_offset + ivec2(gl_WorkGroupID.xy) * int(size); - - image_size = max(ivec2(1), image_size); //in case image size became 0 - - if (all(lessThan(image_pos, uvec2(image_size)))) { - imageStore(dst_depth, image_pos, vec4(tmp_data[t])); - } - } -#endif - -#ifdef MODE_FILTER - - ivec2 image_pos = params.source_offset + ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThanEqual(image_pos, params.source_size))) { - return; - } - - ivec2 clamp_min = ivec2(params.source_offset); - ivec2 clamp_max = ivec2(params.source_size) - 1; - - //gaussian kernel, size 9, sigma 4 - const int kernel_size = 9; - const float gaussian_kernel[kernel_size * 3] = float[]( - 0.000229, 0.005977, 0.060598, 0.241732, 0.382928, 0.241732, 0.060598, 0.005977, 0.000229, - 0.028532, 0.067234, 0.124009, 0.179044, 0.20236, 0.179044, 0.124009, 0.067234, 0.028532, - 0.081812, 0.101701, 0.118804, 0.130417, 0.134535, 0.130417, 0.118804, 0.101701, 0.081812); - float accum = 0.0; - for (int i = 0; i < kernel_size; i++) { - ivec2 ofs = clamp(image_pos + params.filter_dir * (i - kernel_size / 2), clamp_min, clamp_max); - accum += imageLoad(source_depth, ofs).r * gaussian_kernel[params.gaussian_kernel_version + i]; - } - - imageStore(dst_depth, image_pos, vec4(accum)); - -#endif -} diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index aabfa36829..e8966414ab 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -122,12 +122,10 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index d6ee2f9890..d6d730af15 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -991,12 +991,10 @@ public: PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - PASS11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter, bool, float) + PASS10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) PASS2(environment_set_volumetric_fog_volume_size, int, int) PASS1(environment_set_volumetric_fog_filter_active, bool) - PASS1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - PASS1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount) diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index c8b5f0728c..72fcdd3758 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -117,12 +117,9 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; - + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 1479352876..823d28c669 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -615,12 +615,10 @@ public: BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - BIND11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter, bool, float) + BIND10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) BIND2(environment_set_volumetric_fog_volume_size, int, int) BIND1(environment_set_volumetric_fog_filter_active, bool) - BIND1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - BIND1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 2422bc3506..81e202780e 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -520,12 +520,10 @@ public: FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - FUNC11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter, bool, float) + FUNC10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) FUNC2(environment_set_volumetric_fog_volume_size, int, int) FUNC1(environment_set_volumetric_fog_filter_active, bool) - FUNC1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - FUNC1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) |