|
@@ -67,7 +67,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
|
|
void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_roughness_texture() {
|
|
void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_roughness_texture() {
|
|
ERR_FAIL_NULL(render_buffers);
|
|
ERR_FAIL_NULL(render_buffers);
|
|
|
|
|
|
- if (!render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS)) {
|
|
|
|
|
|
+ if (!render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS)) {
|
|
RD::DataFormat format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
|
RD::DataFormat format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
|
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
|
|
|
|
@@ -77,11 +77,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_rou
|
|
usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
}
|
|
}
|
|
|
|
|
|
- render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS, format, usage_bits);
|
|
|
|
|
|
+ render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS, format, usage_bits);
|
|
|
|
|
|
if (render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
|
|
if (render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
|
|
usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
|
|
usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
|
|
- render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, format, usage_bits, render_buffers->get_texture_samples());
|
|
|
|
|
|
+ render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS_MSAA, format, usage_bits, render_buffers->get_texture_samples());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -214,7 +214,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_depth_fb(Depth
|
|
case DEPTH_FB_ROUGHNESS: {
|
|
case DEPTH_FB_ROUGHNESS: {
|
|
ensure_normal_roughness_texture();
|
|
ensure_normal_roughness_texture();
|
|
|
|
|
|
- RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_ROUGHNESS_MSAA : RB_TEX_ROUGHNESS);
|
|
|
|
|
|
+ RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_NORMAL_ROUGHNESS_MSAA : RB_TEX_NORMAL_ROUGHNESS);
|
|
|
|
|
|
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer);
|
|
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer);
|
|
} break;
|
|
} break;
|
|
@@ -222,7 +222,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_depth_fb(Depth
|
|
ensure_normal_roughness_texture();
|
|
ensure_normal_roughness_texture();
|
|
ensure_voxelgi();
|
|
ensure_voxelgi();
|
|
|
|
|
|
- RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_ROUGHNESS_MSAA : RB_TEX_ROUGHNESS);
|
|
|
|
|
|
+ RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_NORMAL_ROUGHNESS_MSAA : RB_TEX_NORMAL_ROUGHNESS);
|
|
RID voxelgi_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_VOXEL_GI_MSAA : RB_TEX_VOXEL_GI);
|
|
RID voxelgi_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_VOXEL_GI_MSAA : RB_TEX_VOXEL_GI);
|
|
|
|
|
|
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer, voxelgi_buffer);
|
|
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer, voxelgi_buffer);
|
|
@@ -1578,6 +1578,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
|
|
|
|
RENDER_TIMESTAMP("Prepare 3D Scene");
|
|
RENDER_TIMESTAMP("Prepare 3D Scene");
|
|
|
|
|
|
|
|
+ // get info about our rendering effects
|
|
|
|
+ bool ce_needs_motion_vectors = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS);
|
|
|
|
+ bool ce_needs_normal_roughness = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_ROUGHNESS);
|
|
|
|
+ bool ce_needs_separate_specular = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_SEPARATE_SPECULAR);
|
|
|
|
+
|
|
// sdfgi first
|
|
// sdfgi first
|
|
_update_sdfgi(p_render_data);
|
|
_update_sdfgi(p_render_data);
|
|
|
|
|
|
@@ -1632,6 +1637,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
bool motion_vectors_required;
|
|
bool motion_vectors_required;
|
|
if (using_debug_mvs) {
|
|
if (using_debug_mvs) {
|
|
motion_vectors_required = true;
|
|
motion_vectors_required = true;
|
|
|
|
+ } else if (ce_needs_motion_vectors) {
|
|
|
|
+ motion_vectors_required = true;
|
|
} else if (!is_reflection_probe && using_taa) {
|
|
} else if (!is_reflection_probe && using_taa) {
|
|
motion_vectors_required = true;
|
|
motion_vectors_required = true;
|
|
} else if (!is_reflection_probe && using_fsr2) {
|
|
} else if (!is_reflection_probe && using_fsr2) {
|
|
@@ -1738,10 +1745,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
if (using_voxelgi) {
|
|
if (using_voxelgi) {
|
|
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
|
|
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
|
|
} else if (p_render_data->environment.is_valid()) {
|
|
} else if (p_render_data->environment.is_valid()) {
|
|
- if (environment_get_ssr_enabled(p_render_data->environment) ||
|
|
|
|
- environment_get_sdfgi_enabled(p_render_data->environment) ||
|
|
|
|
|
|
+ if (using_ssr ||
|
|
|
|
+ using_sdfgi ||
|
|
environment_get_ssao_enabled(p_render_data->environment) ||
|
|
environment_get_ssao_enabled(p_render_data->environment) ||
|
|
using_ssil ||
|
|
using_ssil ||
|
|
|
|
+ ce_needs_normal_roughness ||
|
|
get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER ||
|
|
get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER ||
|
|
scene_state.used_normal_texture) {
|
|
scene_state.used_normal_texture) {
|
|
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
|
|
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
|
|
@@ -1770,7 +1778,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
|
|
|
|
bool using_sss = rb_data.is_valid() && !is_reflection_probe && scene_state.used_sss && ss_effects->sss_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
|
|
bool using_sss = rb_data.is_valid() && !is_reflection_probe && scene_state.used_sss && ss_effects->sss_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
|
|
|
|
|
|
- if (using_sss && !using_separate_specular) {
|
|
|
|
|
|
+ if ((using_sss || ce_needs_separate_specular) && !using_separate_specular) {
|
|
using_separate_specular = true;
|
|
using_separate_specular = true;
|
|
color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
|
color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
|
color_framebuffer = rb_data->get_color_pass_fb(color_pass_flags);
|
|
color_framebuffer = rb_data->get_color_pass_fb(color_pass_flags);
|
|
@@ -1880,6 +1888,17 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
clear_color = p_default_bg_color;
|
|
clear_color = p_default_bg_color;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ RS::ViewportMSAA msaa = rb->get_msaa_3d();
|
|
|
|
+ bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
|
|
|
|
+
|
|
|
|
+ bool ce_pre_opaque_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE);
|
|
|
|
+ bool ce_post_opaque_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE);
|
|
|
|
+ bool ce_pre_transparent_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT);
|
|
|
|
+
|
|
|
|
+ bool ce_pre_opaque_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE);
|
|
|
|
+ bool ce_post_opaque_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE);
|
|
|
|
+ bool ce_pre_transparent_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT);
|
|
|
|
+
|
|
bool debug_voxelgis = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION;
|
|
bool debug_voxelgis = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION;
|
|
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
|
|
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
|
|
bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid();
|
|
bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid();
|
|
@@ -1892,8 +1911,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
}
|
|
}
|
|
|
|
|
|
bool using_ssao = depth_pre_pass && !is_reflection_probe && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment);
|
|
bool using_ssao = depth_pre_pass && !is_reflection_probe && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment);
|
|
- if (depth_pre_pass) { //depth pre pass
|
|
|
|
|
|
|
|
|
|
+ if (depth_pre_pass) { //depth pre pass
|
|
bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi);
|
|
bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi);
|
|
if (needs_pre_resolve) {
|
|
if (needs_pre_resolve) {
|
|
RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (Parallel)");
|
|
RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (Parallel)");
|
|
@@ -1912,28 +1931,42 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
|
|
|
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID(), samplers);
|
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID(), samplers);
|
|
|
|
|
|
- bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi;
|
|
|
|
|
|
+ bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi || ce_pre_opaque_resolved_depth || ce_post_opaque_resolved_depth;
|
|
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count, 0, spec_constant_base_flags);
|
|
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count, 0, spec_constant_base_flags);
|
|
_render_list_with_draw_list(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
|
|
_render_list_with_draw_list(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
|
|
|
|
|
|
RD::get_singleton()->draw_command_end_label();
|
|
RD::get_singleton()->draw_command_end_label();
|
|
|
|
|
|
- if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
|
|
|
|
|
|
+ if (use_msaa) {
|
|
RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)");
|
|
RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)");
|
|
RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)");
|
|
RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)");
|
|
if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) {
|
|
if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
- resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
|
|
|
|
|
|
+ resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[msaa]);
|
|
}
|
|
}
|
|
} else if (finish_depth) {
|
|
} else if (finish_depth) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
- resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
|
|
|
|
|
|
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RD::get_singleton()->draw_command_end_label();
|
|
RD::get_singleton()->draw_command_end_label();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ if (ce_pre_opaque_resolved_color) {
|
|
|
|
+ // We haven't rendered color data yet so...
|
|
|
|
+ WARN_PRINT_ONCE("Pre opaque rendering effects can't access resolved color buffers.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ce_pre_opaque_resolved_depth && !depth_pre_pass) {
|
|
|
|
+ // We haven't rendered depth data yet so...
|
|
|
|
+ WARN_PRINT_ONCE("Pre opaque rendering effects can't access resolved depth buffers.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE, p_render_data);
|
|
|
|
+ }
|
|
|
|
+
|
|
RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS];
|
|
RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS];
|
|
if (rb_data.is_valid() && rb_data->has_normal_roughness()) {
|
|
if (rb_data.is_valid() && rb_data->has_normal_roughness()) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
@@ -1955,8 +1988,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
RENDER_TIMESTAMP("Render Opaque Pass");
|
|
RENDER_TIMESTAMP("Render Opaque Pass");
|
|
|
|
|
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, true);
|
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, true);
|
|
- bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
|
|
|
|
- bool can_continue_depth = !(scene_state.used_depth_texture || scene_state.used_normal_texture) && !using_ssr && !using_sss;
|
|
|
|
|
|
|
|
{
|
|
{
|
|
bool render_motion_pass = !render_list[RENDER_LIST_MOTION].elements.is_empty();
|
|
bool render_motion_pass = !render_list[RENDER_LIST_MOTION].elements.is_empty();
|
|
@@ -2006,6 +2037,22 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ if (ce_post_opaque_resolved_color) {
|
|
|
|
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
|
|
+ RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ce_post_opaque_resolved_depth) {
|
|
|
|
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
|
|
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (debug_voxelgis) {
|
|
if (debug_voxelgis) {
|
|
Projection dc;
|
|
Projection dc;
|
|
dc.set_depth_correction(true);
|
|
dc.set_depth_correction(true);
|
|
@@ -2040,11 +2087,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
RD::get_singleton()->draw_list_end();
|
|
RD::get_singleton()->draw_list_end();
|
|
RD::get_singleton()->draw_command_end_label();
|
|
RD::get_singleton()->draw_command_end_label();
|
|
}
|
|
}
|
|
- if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
|
|
|
|
|
|
+
|
|
|
|
+ if (use_msaa) {
|
|
RENDER_TIMESTAMP("Resolve MSAA");
|
|
RENDER_TIMESTAMP("Resolve MSAA");
|
|
|
|
|
|
- if (!can_continue_color) {
|
|
|
|
- // Handle views individual, might want to look at rewriting our resolve to do both layers in one pass.
|
|
|
|
|
|
+ if (scene_state.used_screen_texture || using_separate_specular || ce_pre_transparent_resolved_color) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
|
|
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
|
|
}
|
|
}
|
|
@@ -2055,13 +2102,18 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (!can_continue_depth) {
|
|
|
|
|
|
+ if (scene_state.used_depth_texture || scene_state.used_normal_texture || using_separate_specular || ce_needs_normal_roughness || ce_pre_transparent_resolved_depth) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
- resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
|
|
|
|
|
|
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ // Don't need to check for depth or color resolve here, we've already triggered it.
|
|
|
|
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_SKY, p_render_data);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (using_separate_specular) {
|
|
if (using_separate_specular) {
|
|
if (using_sss) {
|
|
if (using_sss) {
|
|
RENDER_TIMESTAMP("Sub-Surface Scattering");
|
|
RENDER_TIMESTAMP("Sub-Surface Scattering");
|
|
@@ -2077,12 +2129,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) {
|
|
for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) {
|
|
specular_views[v] = rb_data->get_specular(v);
|
|
specular_views[v] = rb_data->get_specular(v);
|
|
}
|
|
}
|
|
- _process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED);
|
|
|
|
|
|
+ _process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, !use_msaa);
|
|
RD::get_singleton()->draw_command_end_label();
|
|
RD::get_singleton()->draw_command_end_label();
|
|
} else {
|
|
} else {
|
|
//just mix specular back
|
|
//just mix specular back
|
|
RENDER_TIMESTAMP("Merge Specular");
|
|
RENDER_TIMESTAMP("Merge Specular");
|
|
- copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED ? RID() : rb->get_internal_texture(), RID(), p_render_data->scene_data->view_count);
|
|
|
|
|
|
+ copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), !use_msaa ? RID() : rb->get_internal_texture(), RID(), p_render_data->scene_data->view_count);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2116,6 +2168,28 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
_render_buffers_copy_depth_texture(p_render_data);
|
|
_render_buffers_copy_depth_texture(p_render_data);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ if (using_separate_specular) {
|
|
|
|
+ // Our specular will be combined back in (and effects, subsurface scattering and/or ssr applied),
|
|
|
|
+ // so if we've requested this, we need another copy.
|
|
|
|
+ // Fairly unlikely scenario though.
|
|
|
|
+
|
|
|
|
+ if (ce_pre_transparent_resolved_color) {
|
|
|
|
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
|
|
+ RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ce_pre_transparent_resolved_depth) {
|
|
|
|
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
|
|
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
|
|
|
|
+ }
|
|
|
|
+
|
|
RENDER_TIMESTAMP("Render 3D Transparent Pass");
|
|
RENDER_TIMESTAMP("Render 3D Transparent Pass");
|
|
|
|
|
|
RD::get_singleton()->draw_command_begin_label("Render 3D Transparent Pass");
|
|
RD::get_singleton()->draw_command_begin_label("Render 3D Transparent Pass");
|
|
@@ -2142,11 +2216,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
|
|
|
|
RD::get_singleton()->draw_command_begin_label("Resolve");
|
|
RD::get_singleton()->draw_command_begin_label("Resolve");
|
|
|
|
|
|
- if (rb_data.is_valid() && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
|
|
|
|
- bool resolve_velocity_buffer = (using_taa || using_fsr2) && rb->has_velocity_buffer(true);
|
|
|
|
|
|
+ if (rb_data.is_valid() && use_msaa) {
|
|
|
|
+ bool resolve_velocity_buffer = (using_taa || using_fsr2 || ce_needs_motion_vectors) && rb->has_velocity_buffer(true);
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
|
|
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
|
|
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
|
|
- resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
|
|
|
|
|
|
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
|
|
|
|
|
|
if (resolve_velocity_buffer) {
|
|
if (resolve_velocity_buffer) {
|
|
RD::get_singleton()->texture_resolve_multisample(rb->get_velocity_buffer(true, v), rb->get_velocity_buffer(false, v));
|
|
RD::get_singleton()->texture_resolve_multisample(rb->get_velocity_buffer(true, v), rb->get_velocity_buffer(false, v));
|
|
@@ -2156,6 +2230,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|
|
|
|
|
RD::get_singleton()->draw_command_end_label();
|
|
RD::get_singleton()->draw_command_end_label();
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data);
|
|
|
|
+ }
|
|
|
|
+
|
|
RD::get_singleton()->draw_command_begin_label("Copy framebuffer for SSIL");
|
|
RD::get_singleton()->draw_command_begin_label("Copy framebuffer for SSIL");
|
|
if (using_ssil) {
|
|
if (using_ssil) {
|
|
RENDER_TIMESTAMP("Copy Final Framebuffer (SSIL)");
|
|
RENDER_TIMESTAMP("Copy Final Framebuffer (SSIL)");
|