From 28239366b827528358106d84b63e7ff22f394b27 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 21 Jul 2023 03:02:11 +0200 Subject: [PATCH] Make the occlusion culling debug draw mode draw a translucent overlay This allows for easy, depth-aware navigation in the 3D editor while being able to view which meshes are occluders and which meshes aren't. Co-authored-by: myaaaaaaaaa <103326468+myaaaaaaaaa@users.noreply.github.com> --- .../renderer_rd/effects/copy_effects.cpp | 31 ++++++++++++++++--- .../renderer_rd/effects/copy_effects.h | 3 +- .../renderer_rd/renderer_scene_render_rd.cpp | 2 +- .../shaders/effects/copy_to_fb.glsl | 8 +++++ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index 808c82f712a9..245257c27f34 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -107,6 +107,8 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); // COPY_TO_FB_COPY_PANORAMA_TO_DP copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_COPY2 copy_modes.push_back("\n#define MODE_SET_COLOR\n"); // COPY_TO_FB_SET_COLOR + copy_modes.push_back("\n#define MODE_OCCLUSION_CULLING_BUFFER\n"); // COPY_TO_FB_OCCLUSION_CULLING_BUFFER + copy_modes.push_back("\n#define USE_MULTIVIEW\n"); // COPY_TO_FB_MULTIVIEW copy_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_MULTIVIEW_WITH_DEPTH @@ -119,11 +121,28 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { copy_to_fb.shader_version = copy_to_fb.shader.version_create(); - //use additive - for (int i = 0; i < COPY_TO_FB_MAX; i++) { if (copy_to_fb.shader.is_variant_enabled(i)) { - copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + RD::PipelineColorBlendState blend_state; + if (i == COPY_TO_FB_OCCLUSION_CULLING_BUFFER) { + // Use additive blend mode. + RD::PipelineColorBlendState::Attachment ba; + ba.enable_blend = true; + ba.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE; + ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE; + ba.color_blend_op = RD::BLEND_OP_ADD; + ba.alpha_blend_op = RD::BLEND_OP_MAXIMUM; + + RD::PipelineColorBlendState blend_additive; + blend_additive.attachments.push_back(ba); + blend_state = blend_additive; + } else { + blend_state = RD::PipelineColorBlendState::create_disabled(); + } + + copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); } else { copy_to_fb.pipelines[i].clear(); } @@ -533,7 +552,7 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff RD::get_singleton()->draw_list_draw(draw_list, true); } -void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear, bool p_normal, const Rect2 &p_src_rect) { +void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear, bool p_normal, const Rect2 &p_src_rect, bool p_occlusion_culling_buffer) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -586,6 +605,10 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW; } else { mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY; + + if (p_occlusion_culling_buffer) { + mode = COPY_TO_FB_OCCLUSION_CULLING_BUFFER; + } } RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index b6fc95d0f11d..e810bcd5ef0b 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -173,6 +173,7 @@ class CopyEffects { COPY_TO_FB_COPY_PANORAMA_TO_DP, COPY_TO_FB_COPY2, COPY_TO_FB_SET_COLOR, + COPY_TO_FB_OCCLUSION_CULLING_BUFFER, // These variants are disabled unless XR shaders are enabled. // They should be listed last. @@ -329,7 +330,7 @@ class CopyEffects { void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); - void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false, bool p_normal = false, const Rect2 &p_src_rect = Rect2()); + void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false, bool p_normal = false, const Rect2 &p_src_rect = Rect2(), bool p_occlusion_culling_buffer = false); void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); void copy_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_source_rd_texture, bool p_linear = false); void copy_raster(RID p_source_texture, RID p_dest_framebuffer); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 4417f6832cd8..1e5947a318eb 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -898,7 +898,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(const RenderDataRD *p_ren if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) { if (p_render_data->occluder_debug_tex.is_valid()) { Size2i rtsize = texture_storage->render_target_get_size(render_target); - copy_effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_render_data->occluder_debug_tex), texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize), true, false); + copy_effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_render_data->occluder_debug_tex), texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize), true, false, false, false, RID(), false, false, false, false, Rect2(), true); } } diff --git a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl index 26ee06aa03e7..8b2c78a018b7 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl @@ -203,6 +203,14 @@ void main() { color.rgb = normalize(color.rgb * 2.0 - 1.0) * 0.5 + 0.5; } +#ifdef MODE_OCCLUSION_CULLING_BUFFER + // Modify result to make the background partially visible, + // which helps with 3D navigation. + // This relies on the additive blend state from the `CopyEffects()` constructor. + color.a = (1.0 - color.r) * 0.5; + color.rgb = vec3(1.0, 0.0, 0.0); +#endif // MODE_OCCLUSION_CULLING_BUFFER + frag_color = color / params.luminance_multiplier; #endif // MODE_SET_COLOR }