diff options
author | Bastiaan Olij <mux213@gmail.com> | 2023-02-08 01:30:03 +1100 |
---|---|---|
committer | Bastiaan Olij <mux213@gmail.com> | 2023-02-10 10:27:59 +1100 |
commit | 694c8ec27375bd95084de50a7ad4decf1029effb (patch) | |
tree | a19c16b2899dd2fcda360a84c8eefa6b37360dcf /servers/rendering/renderer_rd/forward_clustered | |
parent | bdad9770d64914da3b77bee49916419b5df87d1c (diff) |
Add render buffer support to screen space effects
Diffstat (limited to 'servers/rendering/renderer_rd/forward_clustered')
-rw-r--r-- | servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp | 152 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h | 16 |
2 files changed, 70 insertions, 98 deletions
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 59e1f559c7..b273345ab3 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -108,6 +108,10 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::free_data() { // JIC, should already have been cleared if (render_buffers) { render_buffers->clear_context(RB_SCOPE_FORWARD_CLUSTERED); + render_buffers->clear_context(RB_SCOPE_SSDS); + render_buffers->clear_context(RB_SCOPE_SSIL); + render_buffers->clear_context(RB_SCOPE_SSAO); + render_buffers->clear_context(RB_SCOPE_SSR); } if (cluster_builder) { @@ -118,21 +122,6 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::free_data() { if (!render_sdfgi_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_sdfgi_uniform_set)) { RD::get_singleton()->free(render_sdfgi_uniform_set); } - - if (ss_effects_data.linear_depth.is_valid()) { - RD::get_singleton()->free(ss_effects_data.linear_depth); - ss_effects_data.linear_depth = RID(); - ss_effects_data.linear_depth_slices.clear(); - } - - if (ss_effects_data.downsample_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(ss_effects_data.downsample_uniform_set)) { - RD::get_singleton()->free(ss_effects_data.downsample_uniform_set); - ss_effects_data.downsample_uniform_set = RID(); - } - - RenderForwardClustered::get_singleton()->get_ss_effects()->ssao_free(ss_effects_data.ssao); - RenderForwardClustered::get_singleton()->get_ss_effects()->ssil_free(ss_effects_data.ssil); - RenderForwardClustered::get_singleton()->get_ss_effects()->ssr_free(ss_effects_data.ssr); } void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RenderSceneBuffersRD *p_render_buffers) { @@ -1252,7 +1241,7 @@ void RenderForwardClustered::setup_added_decal(const Transform3D &p_transform, c /* Render scene */ -void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection) { +void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections) { ERR_FAIL_NULL(ss_effects); ERR_FAIL_COND(p_render_buffers.is_null()); ERR_FAIL_COND(p_environment.is_null()); @@ -1271,11 +1260,14 @@ void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_bu settings.sharpness = environment_get_ssao_sharpness(p_environment); settings.full_screen_size = p_render_buffers->get_internal_size(); - ss_effects->ssao_allocate_buffers(rb_data->ss_effects_data.ssao, settings, rb_data->ss_effects_data.linear_depth); - ss_effects->generate_ssao(rb_data->ss_effects_data.ssao, p_normal_buffer, p_projection, settings); + ss_effects->ssao_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssao, settings); + + for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) { + ss_effects->generate_ssao(p_render_buffers, rb_data->ss_effects_data.ssao, v, p_normal_buffers[v], p_projections[v], settings); + } } -void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform) { +void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform) { ERR_FAIL_NULL(ss_effects); ERR_FAIL_COND(p_render_buffers.is_null()); ERR_FAIL_COND(p_environment.is_null()); @@ -1292,36 +1284,46 @@ void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_bu settings.normal_rejection = environment_get_ssil_normal_rejection(p_environment); settings.full_screen_size = p_render_buffers->get_internal_size(); - Projection correction; - correction.set_depth_correction(true); - Projection projection = correction * p_projection; + ss_effects->ssil_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssil, settings); + Transform3D transform = p_transform; transform.set_origin(Vector3(0.0, 0.0, 0.0)); - Projection last_frame_projection = rb_data->ss_effects_data.last_frame_projection * Projection(rb_data->ss_effects_data.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse(); - ss_effects->ssil_allocate_buffers(rb_data->ss_effects_data.ssil, settings, rb_data->ss_effects_data.linear_depth); - ss_effects->screen_space_indirect_lighting(rb_data->ss_effects_data.ssil, p_normal_buffer, p_projection, last_frame_projection, settings); - rb_data->ss_effects_data.last_frame_projection = projection; + for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) { + Projection correction; + correction.set_depth_correction(true); + Projection projection = correction * p_projections[v]; + Projection last_frame_projection = rb_data->ss_effects_data.last_frame_projections[v] * Projection(rb_data->ss_effects_data.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse(); + + ss_effects->screen_space_indirect_lighting(p_render_buffers, rb_data->ss_effects_data.ssil, v, p_normal_buffers[v], p_projections[v], last_frame_projection, settings); + + rb_data->ss_effects_data.last_frame_projections[v] = projection; + } rb_data->ss_effects_data.last_frame_transform = transform; } void RenderForwardClustered::_copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers) { ERR_FAIL_COND(p_render_buffers.is_null()); - Ref<RenderBufferDataForwardClustered> rb_data = p_render_buffers->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED); - ERR_FAIL_COND(rb_data.is_null()); - - if (rb_data->ss_effects_data.ssil.last_frame.is_valid()) { + if (p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_LAST_FRAME)) { Size2i size = p_render_buffers->get_internal_size(); - RID texture = p_render_buffers->get_internal_texture(); - copy_effects->copy_to_rect(texture, rb_data->ss_effects_data.ssil.last_frame, Rect2i(0, 0, size.x, size.y)); - - int width = size.x; - int height = size.y; - for (int i = 0; i < rb_data->ss_effects_data.ssil.last_frame_slices.size() - 1; i++) { - width = MAX(1, width >> 1); - height = MAX(1, height >> 1); - copy_effects->make_mipmap(rb_data->ss_effects_data.ssil.last_frame_slices[i], rb_data->ss_effects_data.ssil.last_frame_slices[i + 1], Size2i(width, height)); + uint32_t mipmaps = p_render_buffers->get_texture_format(RB_SCOPE_SSIL, RB_LAST_FRAME).mipmaps; + for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) { + RID source = p_render_buffers->get_internal_texture(v); + RID dest = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_LAST_FRAME, v, 0); + copy_effects->copy_to_rect(source, dest, Rect2i(0, 0, size.x, size.y)); + + int width = size.x; + int height = size.y; + for (uint32_t m = 1; m < mipmaps; m++) { + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + + source = dest; + dest = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_LAST_FRAME, v, m); + + copy_effects->make_mipmap(source, dest, Size2i(width, height)); + } } } } @@ -1421,41 +1423,23 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo } if (rb_data.is_valid() && ss_effects) { - if (p_use_ssao || p_use_ssil) { - Size2i size = rb->get_internal_size(); + // Note, in multiview we're allocating buffers for each eye/view we're rendering. + // This should allow most of the processing to happen in parallel even if we're doing + // drawcalls per eye/view. It will all sync up at the barrier. - bool invalidate_uniform_set = false; - if (rb_data->ss_effects_data.linear_depth.is_null()) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16_SFLOAT; - tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; - tf.width = (size.x + 1) / 2; - tf.height = (size.y + 1) / 2; - tf.mipmaps = 5; - tf.array_layers = 4; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb_data->ss_effects_data.linear_depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb_data->ss_effects_data.linear_depth, "SS Effects Depth"); - for (uint32_t i = 0; i < tf.mipmaps; i++) { - RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb_data->ss_effects_data.linear_depth, 0, i, 1, RD::TEXTURE_SLICE_2D_ARRAY); - rb_data->ss_effects_data.linear_depth_slices.push_back(slice); - RD::get_singleton()->set_resource_name(slice, "SS Effects Depth Mip " + itos(i) + " "); - } - invalidate_uniform_set = true; + if (p_use_ssao || p_use_ssil) { + // Convert our depth buffer data to linear data in + for (uint32_t v = 0; v < rb->get_view_count(); v++) { + ss_effects->downsample_depth(rb, v, p_render_data->scene_data->view_projection[v]); } - RID depth_texture = rb->get_depth_texture(); - ss_effects->downsample_depth(depth_texture, rb_data->ss_effects_data.linear_depth_slices, invalidate_uniform_set, size, p_render_data->scene_data->cam_projection); - } - - if (p_use_ssao) { - // TODO make these proper stereo - _process_ssao(rb, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection); - } + if (p_use_ssao) { + _process_ssao(rb, p_render_data->environment, p_normal_roughness_slices, p_render_data->scene_data->view_projection); + } - if (p_use_ssil) { - // TODO make these proper stereo - _process_ssil(rb, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform); + if (p_use_ssil) { + _process_ssil(rb, p_render_data->environment, p_normal_roughness_slices, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform); + } } } @@ -1514,17 +1498,11 @@ void RenderForwardClustered::_process_ssr(Ref<RenderSceneBuffersRD> p_render_buf ERR_FAIL_COND(p_environment.is_null()); ERR_FAIL_COND(!environment_get_ssr_enabled(p_environment)); - Size2i half_size = Size2i(internal_size.x / 2, internal_size.y / 2); - ss_effects->ssr_allocate_buffers(rb_data->ss_effects_data.ssr, _render_buffers_get_color_format(), half_size, view_count); + ss_effects->ssr_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssr, _render_buffers_get_color_format()); + ss_effects->screen_space_reflection(p_render_buffers, rb_data->ss_effects_data.ssr, p_normal_slices, p_metallic_slices, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), p_projections, p_eye_offsets); - RID texture_slices[RendererSceneRender::MAX_RENDER_VIEWS]; - RID depth_slices[RendererSceneRender::MAX_RENDER_VIEWS]; - for (uint32_t v = 0; v < view_count; v++) { - texture_slices[v] = p_render_buffers->get_internal_texture(v); - depth_slices[v] = p_render_buffers->get_depth_texture(v); - } - ss_effects->screen_space_reflection(rb_data->ss_effects_data.ssr, texture_slices, p_normal_slices, p_metallic_slices, depth_slices, half_size, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), view_count, p_projections, p_eye_offsets); - copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : p_render_buffers->get_internal_texture(), rb_data->ss_effects_data.ssr.output, view_count); + RID output = p_render_buffers->get_texture(RB_SCOPE_SSR, RB_OUTPUT); + copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : p_render_buffers->get_internal_texture(), output, view_count); } void RenderForwardClustered::_process_sss(Ref<RenderSceneBuffersRD> p_render_buffers, const Projection &p_camera) { @@ -2129,14 +2107,16 @@ void RenderForwardClustered::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD RID render_target = p_render_buffers->get_render_target(); - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb_data->ss_effects_data.ssao.ao_final.is_valid()) { + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSAO && p_render_buffers->has_texture(RB_SCOPE_SSAO, RB_FINAL)) { + RID final = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_FINAL, 0, 0); Size2i rtsize = texture_storage->render_target_get_size(render_target); - copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, true); + copy_effects->copy_to_fb_rect(final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, true); } - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb_data->ss_effects_data.ssil.ssil_final.is_valid()) { + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSIL && p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_FINAL)) { + RID final = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_FINAL, 0, 0); Size2i rtsize = texture_storage->render_target_get_size(render_target); - copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false); + copy_effects->copy_to_fb_rect(final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false); } if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && p_render_buffers->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT)) { @@ -3058,7 +3038,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID aot = rb_data.is_valid() ? rb_data->get_ao_texture() : RID(); + RID aot = rb.is_valid() && rb->has_texture(RB_SCOPE_SSAO, RB_FINAL) ? rb->get_texture(RB_SCOPE_SSAO, RB_FINAL) : RID(); RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); @@ -3144,7 +3124,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 20; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID ssil = rb_data.is_valid() ? rb_data->get_ssil_texture() : RID(); + RID ssil = rb.is_valid() && rb->has_texture(RB_SCOPE_SSIL, RB_FINAL) ? rb->get_texture(RB_SCOPE_SSIL, RB_FINAL) : RID(); RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); u.append_id(texture); uniforms.push_back(u); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 8eb17ba6f4..e07d2f2258 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -104,16 +104,11 @@ class RenderForwardClustered : public RendererSceneRenderRD { ClusterBuilderRD *cluster_builder = nullptr; struct SSEffectsData { - RID linear_depth; - Vector<RID> linear_depth_slices; - - RID downsample_uniform_set; - - Projection last_frame_projection; + Projection last_frame_projections[RendererSceneRender::MAX_RENDER_VIEWS]; Transform3D last_frame_transform; - RendererRD::SSEffects::SSAORenderBuffers ssao; RendererRD::SSEffects::SSILRenderBuffers ssil; + RendererRD::SSEffects::SSAORenderBuffers ssao; RendererRD::SSEffects::SSRRenderBuffers ssr; } ss_effects_data; @@ -155,9 +150,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID get_depth_fb(DepthFrameBufferType p_type = DEPTH_FB); RID get_specular_only_fb(); - RID get_ao_texture() const { return ss_effects_data.ssao.ao_final; } - RID get_ssil_texture() const { return ss_effects_data.ssil.ssil_final; } - virtual void configure(RenderSceneBuffersRD *p_render_buffers) override; virtual void free_data() override; }; @@ -600,8 +592,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS); /* Render Scene */ - void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection); - void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform); + void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections); + void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform); void _copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers); void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer); void _process_ssr(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive); |