diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index a3a873a2d175..35a8aa51143f 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -107,6 +107,7 @@ 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 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 +120,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 +551,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(); @@ -568,6 +586,10 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_NORMAL; } + if (p_occlusion_culling_buffer) { + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_OCCLUSION_CULLING_BUFFER; + } + if (p_src_rect != Rect2()) { copy_to_fb.push_constant.section[0] = p_src_rect.position.x; copy_to_fb.push_constant.section[1] = p_src_rect.position.y; diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index b6fc95d0f11d..e1469ffa7b1f 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. @@ -192,6 +193,7 @@ class CopyEffects { COPY_TO_FB_FLAG_LINEAR = (1 << 6), COPY_TO_FB_FLAG_NORMAL = (1 << 7), COPY_TO_FB_FLAG_USE_SRC_SECTION = (1 << 8), + COPY_TO_FB_FLAG_OCCLUSION_CULLING_BUFFER = (1 << 9), }; struct CopyToFbPushConstant { @@ -329,7 +331,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 7ef42aa79147..897884dedae1 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..a3b707e3a2a4 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl @@ -84,6 +84,7 @@ void main() { #define FLAG_ALPHA_TO_ONE (1 << 5) #define FLAG_LINEAR (1 << 6) #define FLAG_NORMAL (1 << 7) +#define FLAG_OCCLUSION_CULLING_BUFFER (1 << 9) layout(push_constant, std430) uniform Params { vec4 section; @@ -202,6 +203,13 @@ void main() { if (bool(params.flags & FLAG_NORMAL)) { color.rgb = normalize(color.rgb * 2.0 - 1.0) * 0.5 + 0.5; } + if (bool(params.flags & FLAG_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); + } frag_color = color / params.luminance_multiplier; #endif // MODE_SET_COLOR