diff options
Diffstat (limited to 'servers/rendering/renderer_rd')
37 files changed, 275 insertions, 153 deletions
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index e661fd9217..41df6107a8 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -62,15 +62,17 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() { defines = "\n#define USE_ATTACHMENT\n"; } + RD::PipelineRasterizationState rasterization_state; + rasterization_state.enable_depth_clamp = true; Vector<String> versions; versions.push_back(""); cluster_render.cluster_render_shader.initialize(versions, defines); cluster_render.shader_version = cluster_render.cluster_render_shader.version_create(); cluster_render.shader = cluster_render.cluster_render_shader.version_get_shader(cluster_render.shader_version, 0); - cluster_render.shader_pipelines[ClusterRender::PIPELINE_NORMAL] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); + cluster_render.shader_pipelines[ClusterRender::PIPELINE_NORMAL] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, rasterization_state, RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); RD::PipelineMultisampleState ms; ms.sample_count = RD::TEXTURE_SAMPLES_4; - cluster_render.shader_pipelines[ClusterRender::PIPELINE_MSAA] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), ms, RD::PipelineDepthStencilState(), blend_state, 0); + cluster_render.shader_pipelines[ClusterRender::PIPELINE_MSAA] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, rasterization_state, ms, RD::PipelineDepthStencilState(), blend_state, 0); } { Vector<String> versions; diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index fd6409d6bf..1568867663 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -107,8 +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 MULTIVIEW\n"); // COPY_TO_FB_MULTIVIEW - copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_MULTIVIEW_WITH_DEPTH + 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 copy_to_fb.shader.initialize(copy_modes); @@ -583,7 +583,7 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); ERR_FAIL_COND(shader.is_null()); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, p_rect); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); if (p_secondary.is_valid()) { @@ -982,7 +982,7 @@ void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, con RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); ERR_FAIL_COND(shader.is_null()); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_region); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, p_region); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer))); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); diff --git a/servers/rendering/renderer_rd/effects/debug_effects.cpp b/servers/rendering/renderer_rd/effects/debug_effects.cpp index a57a65fd5a..017ad41fdc 100644 --- a/servers/rendering/renderer_rd/effects/debug_effects.cpp +++ b/servers/rendering/renderer_rd/effects/debug_effects.cpp @@ -282,7 +282,7 @@ void DebugEffects::draw_shadow_frustum(RID p_light, const Projection &p_cam_proj // And draw our frustum. RD::FramebufferFormatID fb_format_id = RD::get_singleton()->framebuffer_get_format(p_dest_fb); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, rect); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, rect); RID pipeline = shadow_frustum.pipelines[SFP_TRANSPARENT].get_render_pipeline(frustum.vertex_format, fb_format_id); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, pipeline); @@ -326,7 +326,7 @@ void DebugEffects::draw_shadow_frustum(RID p_light, const Projection &p_cam_proj rect.size.x *= atlas_rect_norm.size.x; rect.size.y *= atlas_rect_norm.size.y; - draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, rect); + draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, rect); pipeline = shadow_frustum.pipelines[SFP_TRANSPARENT].get_render_pipeline(frustum.vertex_format, fb_format_id); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, pipeline); diff --git a/servers/rendering/renderer_rd/effects/fsr2.cpp b/servers/rendering/renderer_rd/effects/fsr2.cpp index bebbf51d51..925352a7d1 100644 --- a/servers/rendering/renderer_rd/effects/fsr2.cpp +++ b/servers/rendering/renderer_rd/effects/fsr2.cpp @@ -527,6 +527,7 @@ FSR2Effect::FSR2Effect() { "\n#define FFX_GLSL 1\n" "\n#define FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS 1\n" "\n#define FFX_FSR2_OPTION_HDR_COLOR_INPUT 1\n" + "\n#define FFX_FSR2_OPTION_INVERTED_DEPTH 1\n" "\n#define FFX_FSR2_OPTION_GODOT_REACTIVE_MASK_CLAMP 1\n" "\n#define FFX_FSR2_OPTION_GODOT_DERIVE_INVALID_MOTION_VECTORS 1\n"; @@ -808,7 +809,7 @@ FSR2Effect::~FSR2Effect() { FSR2Context *FSR2Effect::create_context(Size2i p_internal_size, Size2i p_target_size) { FSR2Context *context = memnew(RendererRD::FSR2Context); - context->fsr_desc.flags = FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE; + context->fsr_desc.flags = FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE | FFX_FSR2_ENABLE_DEPTH_INVERTED; context->fsr_desc.maxRenderSize.width = p_internal_size.x; context->fsr_desc.maxRenderSize.height = p_internal_size.y; context->fsr_desc.displaySize.width = p_target_size.x; diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp index bdd687d9f4..3db82c8fbd 100644 --- a/servers/rendering/renderer_rd/effects/ss_effects.cpp +++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp @@ -483,8 +483,12 @@ void SSEffects::downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uin downsample_uniform_set = uniform_set_cache->get_cache_vec(shader, 2, u_depths); } - float depth_linearize_mul = -p_projection.columns[3][2] * 0.5; - float depth_linearize_add = p_projection.columns[2][2]; + Projection correction; + correction.set_depth_correction(false); + Projection temp = correction * p_projection; + + float depth_linearize_mul = -temp.columns[3][2]; + float depth_linearize_add = temp.columns[2][2]; if (depth_linearize_mul * depth_linearize_add < 0) { depth_linearize_add = -depth_linearize_add; } diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.cpp b/servers/rendering/renderer_rd/effects/tone_mapper.cpp index ee0b6adb4d..e943071f0e 100644 --- a/servers/rendering/renderer_rd/effects/tone_mapper.cpp +++ b/servers/rendering/renderer_rd/effects/tone_mapper.cpp @@ -47,12 +47,12 @@ ToneMapper::ToneMapper() { tonemap_modes.push_back("\n#define SUBPASS\n#define USE_1D_LUT\n"); // multiview versions of our shaders - tonemap_modes.push_back("\n#define MULTIVIEW\n"); - tonemap_modes.push_back("\n#define MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n"); - tonemap_modes.push_back("\n#define MULTIVIEW\n#define USE_1D_LUT\n"); - tonemap_modes.push_back("\n#define MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n#define USE_1D_LUT\n"); - tonemap_modes.push_back("\n#define MULTIVIEW\n#define SUBPASS\n"); - tonemap_modes.push_back("\n#define MULTIVIEW\n#define SUBPASS\n#define USE_1D_LUT\n"); + tonemap_modes.push_back("\n#define USE_MULTIVIEW\n"); + tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n"); + tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define USE_1D_LUT\n"); + tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n#define USE_1D_LUT\n"); + tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define SUBPASS\n"); + tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define SUBPASS\n#define USE_1D_LUT\n"); tonemap.shader.initialize(tonemap_modes); @@ -130,7 +130,7 @@ void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Ton tonemap.push_constant.flags |= p_settings.convert_to_srgb ? TONEMAP_FLAG_CONVERT_TO_SRGB : 0; if (p_settings.view_count > 1) { - // Use MULTIVIEW versions + // Use USE_MULTIVIEW versions mode += 6; } @@ -196,7 +196,7 @@ void ToneMapper::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_col int mode = p_settings.use_1d_color_correction ? TONEMAP_MODE_SUBPASS_1D_LUT : TONEMAP_MODE_SUBPASS; if (p_settings.view_count > 1) { - // Use MULTIVIEW versions + // Use USE_MULTIVIEW versions mode += 6; } diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp index 41a6b2d622..30c318fb9a 100644 --- a/servers/rendering/renderer_rd/effects/vrs.cpp +++ b/servers/rendering/renderer_rd/effects/vrs.cpp @@ -32,7 +32,10 @@ #include "../renderer_compositor_rd.h" #include "../storage_rd/texture_storage.h" #include "../uniform_set_cache_rd.h" + +#ifndef _3D_DISABLED #include "servers/xr_server.h" +#endif // _3D_DISABLED using namespace RendererRD; @@ -40,7 +43,7 @@ VRS::VRS() { { Vector<String> vrs_modes; vrs_modes.push_back("\n"); // VRS_DEFAULT - vrs_modes.push_back("\n#define MULTIVIEW\n"); // VRS_MULTIVIEW + vrs_modes.push_back("\n#define USE_MULTIVIEW\n"); // VRS_MULTIVIEW vrs_shader.shader.initialize(vrs_modes); @@ -124,6 +127,7 @@ void VRS::update_vrs_texture(RID p_vrs_fb, RID p_render_target) { copy_vrs(rd_texture, p_vrs_fb, layers > 1); } } +#ifndef _3D_DISABLED } else if (vrs_mode == RS::VIEWPORT_VRS_XR) { Ref<XRInterface> interface = XRServer::get_singleton()->get_primary_interface(); if (interface.is_valid()) { @@ -138,6 +142,7 @@ void VRS::update_vrs_texture(RID p_vrs_fb, RID p_render_target) { } } } +#endif // _3D_DISABLED } RD::get_singleton()->draw_command_end_label(); diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 78ab6f3650..48537a97d9 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -509,9 +509,7 @@ Vector3i Fog::_point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_position.z = Math::pow(float(fog_position.z), float(1.0 / volumetric_fog_detail_spread)); fog_position = fog_position * fog_size - Vector3(0.5, 0.5, 0.5); - fog_position.x = CLAMP(fog_position.x, 0.0, fog_size.x); - fog_position.y = CLAMP(fog_position.y, 0.0, fog_size.y); - fog_position.z = CLAMP(fog_position.z, 0.0, fog_size.z); + fog_position = fog_position.clamp(Vector3(), fog_size); return Vector3i(fog_position); } @@ -680,8 +678,8 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P max = Vector3i(1, 1, 1); for (int j = 0; j < 8; j++) { - min = Vector3i(MIN(min.x, points[j].x), MIN(min.y, points[j].y), MIN(min.z, points[j].z)); - max = Vector3i(MAX(max.x, points[j].x), MAX(max.y, points[j].y), MAX(max.z, points[j].z)); + min = min.min(points[j]); + max = max.max(points[j]); } kernel_size = max - min; @@ -931,9 +929,10 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P uniforms.push_back(u); } - if (fog->copy_uniform_set.is_null()) { - fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0); + if (fog->copy_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog->copy_uniform_set)) { + RD::get_singleton()->free(fog->copy_uniform_set); } + fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0); if (!gi_dependent_sets_valid) { fog->gi_dependent_sets.process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 6da828df45..c7752f8a86 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -3407,7 +3407,7 @@ void GI::init(SkyRD *p_sky) { RD::PipelineDepthStencilState ds; ds.enable_depth_test = true; ds.enable_depth_write = true; - ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; + ds.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL; voxel_gi_debug_shader_version_pipelines[i].setup(voxel_gi_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0); } @@ -3575,7 +3575,7 @@ void GI::init(SkyRD *p_sky) { RD::PipelineDepthStencilState ds; ds.enable_depth_test = true; ds.enable_depth_write = true; - ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; + ds.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL; for (int i = 0; i < SDFGIShader::PROBE_DEBUG_MAX; i++) { // TODO check if version is enabled @@ -3725,6 +3725,12 @@ void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBu } rbgi->uniform_set[v] = RID(); } + + if (p_render_buffers->has_custom_data(RB_SCOPE_FOG)) { + // VoxelGI instances have changed, so we need to update volumetric fog. + Ref<RendererRD::Fog::VolumetricFog> fog = p_render_buffers->get_custom_data(RB_SCOPE_FOG); + fog->sync_gi_dependent_sets_validity(true); + } } if (p_voxel_gi_instances.size() > 0) { @@ -3804,8 +3810,13 @@ void GI::process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_nor rbgi->scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SceneData)); } + Projection correction; + correction.set_depth_correction(false); + for (uint32_t v = 0; v < p_view_count; v++) { - RendererRD::MaterialStorage::store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]); + Projection temp = correction * p_projections[v]; + + RendererRD::MaterialStorage::store_camera(temp.inverse(), scene_data.inv_projection[v]); scene_data.eye_offset[v][0] = p_eye_offsets[v].x; scene_data.eye_offset[v][1] = p_eye_offsets[v].y; scene_data.eye_offset[v][2] = p_eye_offsets[v].z; diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 41609dc74d..27c07f23fa 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -141,7 +141,7 @@ void SkyRD::SkyShaderData::set_code(const String &p_code) { for (int i = 0; i < SKY_VERSION_MAX; i++) { RD::PipelineDepthStencilState depth_stencil_state; depth_stencil_state.enable_depth_test = true; - depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; + depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL; if (scene_singleton->sky.sky_shader.shader.is_variant_enabled(i)) { RID shader_variant = scene_singleton->sky.sky_shader.shader.version_get_shader(version, i); @@ -1174,6 +1174,7 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con } Projection correction; + correction.set_depth_correction(false, true); correction.add_jitter_offset(p_jitter); sky_scene_state.view_count = p_view_count; @@ -1184,10 +1185,12 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con for (uint32_t i = 0; i < p_view_count; i++) { Projection view_inv_projection = (correction * p_view_projections[i]).inverse(); if (p_view_count > 1) { + // Reprojection is used when we need to have things in combined space. RendererRD::MaterialStorage::store_camera(p_cam_projection * view_inv_projection, sky_scene_state.ubo.combined_reprojection[i]); } else { + // This is unused so just reset to identity. Projection ident; - RendererRD::MaterialStorage::store_camera(correction, sky_scene_state.ubo.combined_reprojection[i]); + RendererRD::MaterialStorage::store_camera(ident, sky_scene_state.ubo.combined_reprojection[i]); } RendererRD::MaterialStorage::store_camera(view_inv_projection, sky_scene_state.ubo.view_inv_projections[i]); 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 fa6e78750b..0e69ad99b8 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -546,6 +546,8 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MULTIVIEW); VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MULTIVIEW | COLOR_PASS_FLAG_MOTION_VECTORS); VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MOTION_VECTORS); + VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_SEPARATE_SPECULAR | COLOR_PASS_FLAG_MULTIVIEW | COLOR_PASS_FLAG_MOTION_VECTORS); + VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT | COLOR_PASS_FLAG_MULTIVIEW | COLOR_PASS_FLAG_MOTION_VECTORS); default: { ERR_FAIL_MSG("Invalid color pass flag combination " + itos(p_params->color_pass_flags)); } @@ -1130,6 +1132,7 @@ void RenderForwardClustered::_update_sdfgi(RenderDataRD *p_render_data) { } if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) { + RENDER_TIMESTAMP("Render SDFGI"); Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); float exposure_normalization = 1.0; @@ -1401,7 +1404,8 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo } } - //cube shadows are rendered in their own way + RENDER_TIMESTAMP("Render OmniLight Shadows"); + // Cube shadows are rendered in their own way. for (const int &index : p_render_data->cube_shadows) { _render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info, viewport_size, p_render_data->scene_data->cam_transform); } @@ -1457,6 +1461,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo // drawcalls per eye/view. It will all sync up at the barrier. if (p_use_ssao || p_use_ssil) { + RENDER_TIMESTAMP("Prepare Depth for SSAO/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]); @@ -1472,6 +1477,8 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo } } + RENDER_TIMESTAMP("Pre Opaque Render"); + if (current_cluster_builder) { // Note: when rendering stereoscopic (multiview) we are using our combined frustum projection to create // our cluster data. We use reprojection in the shader to adjust for our left/right eye. @@ -1504,6 +1511,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo } if (rb_data.is_valid()) { + RENDER_TIMESTAMP("Update Volumetric Fog"); bool directional_shadows = RendererRD::LightStorage::get_singleton()->has_directional_shadows(directional_light_count); _update_volumetric_fog(rb, p_render_data->environment, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, p_render_data->scene_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, p_render_data->voxel_gi_count, *p_render_data->fog_volumes); } @@ -1615,15 +1623,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co gi.setup_voxel_gi_instances(p_render_data, p_render_data->render_buffers, p_render_data->scene_data->cam_transform, *p_render_data->voxel_gi_instances, p_render_data->voxel_gi_count); } else { - ERR_PRINT("No render buffer nor reflection atlas, bug"); //should never happen, will crash + ERR_PRINT("No render buffer nor reflection atlas, bug"); // Should never happen! current_cluster_builder = nullptr; + return; // No point in continuing, we'll just crash. } - if (current_cluster_builder != nullptr) { - p_render_data->cluster_buffer = current_cluster_builder->get_cluster_buffer(); - p_render_data->cluster_size = current_cluster_builder->get_cluster_size(); - p_render_data->cluster_max_elements = current_cluster_builder->get_max_cluster_elements(); - } + ERR_FAIL_NULL(current_cluster_builder); + + p_render_data->cluster_buffer = current_cluster_builder->get_cluster_buffer(); + p_render_data->cluster_size = current_cluster_builder->get_cluster_size(); + p_render_data->cluster_max_elements = current_cluster_builder->get_max_cluster_elements(); _update_vrs(rb); @@ -1964,6 +1973,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co WARN_PRINT_ONCE("Pre opaque rendering effects can't access resolved depth buffers."); } + RENDER_TIMESTAMP("Process Pre Opaque Compositor Effects"); _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE, p_render_data); } @@ -1975,6 +1985,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, normal_roughness_views, rb_data.is_valid() && rb_data->has_voxelgi() ? rb_data->get_voxelgi() : RID()); + RENDER_TIMESTAMP("Render Opaque Pass"); + RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count; @@ -1985,8 +1997,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, true, using_motion_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); { @@ -2011,7 +2021,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co uint32_t opaque_color_pass_flags = using_motion_pass ? (color_pass_flags & ~COLOR_PASS_FLAG_MOTION_VECTORS) : color_pass_flags; RID opaque_framebuffer = using_motion_pass ? rb_data->get_color_pass_fb(opaque_color_pass_flags) : color_framebuffer; 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, PASS_MODE_COLOR, opaque_color_pass_flags, 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, opaque_framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, depth_pre_pass ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 1.0, 0); + _render_list_with_draw_list(&render_list_params, opaque_framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, depth_pre_pass ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 0.0, 0); } RD::get_singleton()->draw_command_end_label(); @@ -2050,6 +2060,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } } + RENDER_TIMESTAMP("Process Post Opaque Compositor Effects"); _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data); } @@ -2110,6 +2121,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } { + RENDER_TIMESTAMP("Process Post Sky Compositor Effects"); // 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); } @@ -2187,6 +2199,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } } + RENDER_TIMESTAMP("Process Pre Transparent Compositor Effects"); _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data); } @@ -2231,6 +2244,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_end_label(); { + RENDER_TIMESTAMP("Process Post Transparent Compositor Effects"); _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data); } @@ -2626,7 +2640,7 @@ void RenderForwardClustered::_render_shadow_end() { for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) { RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, 0, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from); - _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector<Color>(), 1.0, 0, shadow_pass.rect); + _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector<Color>(), 0.0, 0, shadow_pass.rect); } RD::get_singleton()->draw_command_end_label(); @@ -2726,7 +2740,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform Color(0, 0, 0, 0) }; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 1.0, 0, p_region); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); RD::get_singleton()->draw_list_end(); } @@ -2776,7 +2790,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance Color(0, 0, 0, 0), Color(0, 0, 0, 0) }; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 1.0, 0, p_region); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region); const int uv_offset_count = 9; static const Vector2 uv_offsets[uv_offset_count] = { @@ -2882,7 +2896,7 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu } RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, 0, true, false, rp_uniform_set, false); - _render_list_with_draw_list(&render_list_params, E->value, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2()); + _render_list_with_draw_list(&render_list_params, E->value, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, Rect2()); } RD::get_singleton()->draw_command_end_label(); @@ -4262,7 +4276,7 @@ RenderForwardClustered::RenderForwardClustered() { sampler.mag_filter = RD::SAMPLER_FILTER_NEAREST; sampler.min_filter = RD::SAMPLER_FILTER_NEAREST; sampler.enable_compare = true; - sampler.compare_op = RD::COMPARE_OP_LESS; + sampler.compare_op = RD::COMPARE_OP_GREATER; shadow_sampler = RD::get_singleton()->sampler_create(sampler); } 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 12af8822b4..1f12d92754 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -379,7 +379,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { template <PassMode p_pass_mode, uint32_t p_color_pass_flags = 0> _FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element); void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element); - void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); + void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 0.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); void _update_instance_data_buffer(RenderListType p_render_list); void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 55c6c420eb..209fabeddf 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -260,7 +260,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { if (depth_test != DEPTH_TEST_DISABLED) { depth_stencil_state.enable_depth_test = true; - depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; + depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL; depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false; } bool depth_pre_pass_enabled = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")); @@ -737,7 +737,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { default_shader = material_storage->shader_allocate(); material_storage->shader_initialize(default_shader); material_storage->shader_set_code(default_shader, R"( -// Default 3D material shader (clustered). +// Default 3D material shader (Forward+). shader_type spatial; @@ -768,11 +768,11 @@ void fragment() { material_storage->shader_initialize(overdraw_material_shader); // Use relatively low opacity so that more "layers" of overlapping objects can be distinguished. material_storage->shader_set_code(overdraw_material_shader, R"( -// 3D editor Overdraw debug draw mode shader (clustered). +// 3D editor Overdraw debug draw mode shader (Forward+). shader_type spatial; -render_mode blend_add, unshaded; +render_mode blend_add, unshaded, fog_disabled; void fragment() { ALBEDO = vec3(0.4, 0.8, 0.8); @@ -792,11 +792,11 @@ void fragment() { debug_shadow_splits_material_shader = material_storage->shader_allocate(); material_storage->shader_initialize(debug_shadow_splits_material_shader); material_storage->shader_set_code(debug_shadow_splits_material_shader, R"( -// 3D debug shadow splits mode shader(mobile). +// 3D debug shadow splits mode shader (Forward+). shader_type spatial; -render_mode debug_shadow_splits; +render_mode debug_shadow_splits, fog_disabled; void fragment() { ALBEDO = vec3(1.0, 1.0, 1.0); @@ -827,7 +827,7 @@ void fragment() { sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler.enable_compare = true; - sampler.compare_op = RD::COMPARE_OP_LESS; + sampler.compare_op = RD::COMPARE_OP_GREATER; shadow_sampler = RD::get_singleton()->sampler_create(sampler); } } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index ac93aca6bb..48c9cda253 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -777,7 +777,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (rb->get_scaling_3d_mode() != RS::VIEWPORT_SCALING_3D_MODE_OFF) { // can't do blit subpass because we're scaling using_subpass_post_process = false; - } else if (p_render_data->environment.is_valid() && (environment_get_glow_enabled(p_render_data->environment) || RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) || RSG::camera_attributes->camera_attributes_uses_dof(p_render_data->camera_attributes))) { + } else if (p_render_data->environment.is_valid() && (environment_get_glow_enabled(p_render_data->environment) || RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) || RSG::camera_attributes->camera_attributes_uses_dof(p_render_data->camera_attributes) || environment_get_background(p_render_data->environment) == RS::ENV_BG_CANVAS)) { // can't do blit subpass because we're using post processes using_subpass_post_process = false; } @@ -984,7 +984,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color } } - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 1.0, 0); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 0.0, 0); RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); if (copy_canvas) { @@ -1385,7 +1385,7 @@ void RenderForwardMobile::_render_shadow_end() { for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) { RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from); - _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector<Color>(), 1.0, 0, shadow_pass.rect); + _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector<Color>(), 0.0, 0, shadow_pass.rect); } RD::get_singleton()->draw_command_end_label(); @@ -1437,7 +1437,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c Color(0, 0, 0, 0), Color(0, 0, 0, 0) }; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 1.0, 0, p_region); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); RD::get_singleton()->draw_list_end(); } @@ -1483,7 +1483,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *> Color(0, 0, 0, 0) }; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 1.0, 0, p_region); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region); const int uv_offset_count = 9; static const Vector2 uv_offsets[uv_offset_count] = { @@ -2835,6 +2835,11 @@ RenderForwardMobile::~RenderForwardMobile() { for (const RID &rid : scene_state.uniform_buffers) { RD::get_singleton()->free(rid); } + for (uint32_t i = 0; i < RENDER_LIST_MAX; i++) { + if (scene_state.instance_buffer[i].is_valid()) { + RD::get_singleton()->free(scene_state.instance_buffer[i]); + } + } RD::get_singleton()->free(scene_state.lightmap_buffer); RD::get_singleton()->free(scene_state.lightmap_capture_buffer); memdelete_arr(scene_state.lightmap_captures); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 5c02204627..f29503e5ec 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -350,7 +350,7 @@ private: template <PassMode p_pass_mode> _FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element); void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element); - void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); + void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 0.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); RenderList render_list[RENDER_LIST_MAX]; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 3592ee2f6d..a2f112669c 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -271,7 +271,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { if (depth_test != DEPTH_TEST_DISABLED) { depth_stencil_state.enable_depth_test = true; - depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; + depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL; depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false; } @@ -641,7 +641,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { default_shader = material_storage->shader_allocate(); material_storage->shader_initialize(default_shader); material_storage->shader_set_code(default_shader, R"( -// Default 3D material shader (mobile). +// Default 3D material shader (Mobile). shader_type spatial; @@ -671,11 +671,11 @@ void fragment() { material_storage->shader_initialize(overdraw_material_shader); // Use relatively low opacity so that more "layers" of overlapping objects can be distinguished. material_storage->shader_set_code(overdraw_material_shader, R"( -// 3D editor Overdraw debug draw mode shader (mobile). +// 3D editor Overdraw debug draw mode shader (Mobile). shader_type spatial; -render_mode blend_add, unshaded; +render_mode blend_add, unshaded, fog_disabled; void fragment() { ALBEDO = vec3(0.4, 0.8, 0.8); @@ -696,11 +696,11 @@ void fragment() { material_storage->shader_initialize(debug_shadow_splits_material_shader); // Use relatively low opacity so that more "layers" of overlapping objects can be distinguished. material_storage->shader_set_code(debug_shadow_splits_material_shader, R"( -// 3D debug shadow splits mode shader(mobile). +// 3D debug shadow splits mode shader (Mobile). shader_type spatial; -render_mode debug_shadow_splits; +render_mode debug_shadow_splits, fog_disabled; void fragment() { ALBEDO = vec3(1.0, 1.0, 1.0); @@ -731,7 +731,7 @@ void fragment() { sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler.enable_compare = true; - sampler.compare_op = RD::COMPARE_OP_LESS; + sampler.compare_op = RD::COMPARE_OP_GREATER; shadow_sampler = RD::get_singleton()->sampler_create(sampler); } } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 00604d0d4b..6f56711151 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -34,6 +34,7 @@ #include "core/math/geometry_2d.h" #include "core/math/math_defs.h" #include "core/math/math_funcs.h" +#include "core/math/transform_interpolator.h" #include "renderer_compositor_rd.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/particles_storage.h" @@ -406,7 +407,7 @@ _FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primit return (p_indices - subtractor[p_primitive]) / divisor[p_primitive]; } -void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info) { +void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used, const Point2 &p_offset, RenderingMethod::RenderInfo *r_render_info) { //create an empty push constant RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); @@ -425,6 +426,11 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend PushConstant push_constant; Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform; + + if (p_offset.x || p_offset.y) { + base_transform *= Transform2D(0, p_offset / p_item->xform_curr.get_scale()); // TODO: Interpolate or explain why not needed. + } + Transform2D draw_transform; _update_transform_2d_to_mat2x3(base_transform, push_constant.world); @@ -1240,7 +1246,23 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co } } - _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants, r_sdf_used, r_render_info); + if (!ci->repeat_size.x && !ci->repeat_size.y) { + _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants, r_sdf_used, Point2(), r_render_info); + } else { + Point2 start_pos = ci->repeat_size * -(ci->repeat_times / 2); + Point2 end_pos = ci->repeat_size * ci->repeat_times + ci->repeat_size + start_pos; + Point2 pos = start_pos; + + do { + do { + _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants, r_sdf_used, pos, r_render_info); + pos.y += ci->repeat_size.y; + } while (pos.y < end_pos.y); + + pos.x += ci->repeat_size.x; + pos.y = start_pos.y; + } while (pos.x < end_pos.x); + } prev_material = material; } @@ -1345,7 +1367,15 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p ERR_CONTINUE(!clight); } - Vector2 canvas_light_pos = p_canvas_transform.xform(l->xform.get_origin()); //convert light position to canvas coordinates, as all computation is done in canvas coords to avoid precision loss + Transform2D final_xform; + if (!RSG::canvas->_interpolation_data.interpolation_enabled || !l->interpolated) { + final_xform = l->xform_curr; + } else { + real_t f = Engine::get_singleton()->get_physics_interpolation_fraction(); + TransformInterpolator::interpolate_transform_2d(l->xform_prev, l->xform_curr, final_xform, f); + } + // Convert light position to canvas coordinates, as all computation is done in canvas coordinates to avoid precision loss. + Vector2 canvas_light_pos = p_canvas_transform.xform(final_xform.get_origin()); state.light_uniforms[index].position[0] = canvas_light_pos.x; state.light_uniforms[index].position[1] = canvas_light_pos.y; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 6da3774fc2..c7c5d34314 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -424,7 +424,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { double debug_redraw_time = 1.0; inline void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size, bool p_texture_is_data = false); //recursive, so regular inline used instead. - void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info = nullptr); + void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used, const Point2 &p_offset, RenderingMethod::RenderInfo *r_render_info = nullptr); void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false, RenderingMethod::RenderInfo *r_render_info = nullptr); _FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 62ecec3991..e61bb9eae8 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1153,12 +1153,19 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render PagedArray<RID> empty; - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { render_data.lights = ∅ render_data.reflection_probes = ∅ render_data.voxel_gi_instances = ∅ } + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED || + get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW || + get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING || + get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) { + render_data.decals = ∅ + } + Color clear_color; if (p_render_buffers.is_valid() && p_reflection_probe.is_null()) { clear_color = texture_storage->render_target_get_clear_request_color(rb->get_render_target()); diff --git a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl index fe770ac065..48c1b0a3f6 100644 --- a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl @@ -32,9 +32,9 @@ layout(set = 1, binding = 0) uniform sampler2D source_bokeh; float get_depth_at_pos(vec2 uv) { float depth = textureLod(source_depth, uv, 0.0).x * 2.0 - 1.0; if (params.orthogonal) { - depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0; + depth = -(depth * (params.z_far - params.z_near) - (params.z_far + params.z_near)) / 2.0; } else { - depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); + depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near + depth * (params.z_far - params.z_near)); } return depth; } diff --git a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl index 947aa793d9..2010b58474 100644 --- a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl @@ -53,9 +53,9 @@ layout(set = 2, binding = 0) uniform sampler2D original_weight; float get_depth_at_pos(vec2 uv) { float depth = textureLod(source_depth, uv, 0.0).x * 2.0 - 1.0; if (params.orthogonal) { - depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0; + depth = -(depth * (params.z_far - params.z_near) - (params.z_far + params.z_near)) / 2.0; } else { - depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); + depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near + depth * (params.z_far - params.z_near)); } return depth; } 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 1b065a8dd3..7192e596eb 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl @@ -4,14 +4,14 @@ #VERSION_DEFINES -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW #ifdef has_VK_KHR_multiview #extension GL_EXT_multiview : enable #define ViewIndex gl_ViewIndex #else // has_VK_KHR_multiview #define ViewIndex 0 #endif // has_VK_KHR_multiview -#endif //MULTIVIEW +#endif //USE_MULTIVIEW #define FLAG_FLIP_Y (1 << 0) #define FLAG_USE_SECTION (1 << 1) @@ -22,7 +22,7 @@ #define FLAG_LINEAR (1 << 6) #define FLAG_NORMAL (1 << 7) -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW layout(location = 0) out vec3 uv_interp; #else layout(location = 0) out vec2 uv_interp; @@ -41,7 +41,7 @@ params; void main() { vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp.xy = base_arr[gl_VertexIndex]; -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW uv_interp.z = ViewIndex; #endif vec2 vpos = uv_interp.xy; @@ -62,14 +62,14 @@ void main() { #VERSION_DEFINES -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW #ifdef has_VK_KHR_multiview #extension GL_EXT_multiview : enable #define ViewIndex gl_ViewIndex #else // has_VK_KHR_multiview #define ViewIndex 0 #endif // has_VK_KHR_multiview -#endif //MULTIVIEW +#endif //USE_MULTIVIEW #define FLAG_FLIP_Y (1 << 0) #define FLAG_USE_SECTION (1 << 1) @@ -91,24 +91,24 @@ layout(push_constant, std430) uniform Params { params; #ifndef MODE_SET_COLOR -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW layout(location = 0) in vec3 uv_interp; #else layout(location = 0) in vec2 uv_interp; #endif -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW layout(set = 0, binding = 0) uniform sampler2DArray source_color; #ifdef MODE_TWO_SOURCES layout(set = 1, binding = 0) uniform sampler2DArray source_depth; layout(location = 1) out float depth; #endif /* MODE_TWO_SOURCES */ -#else /* MULTIVIEW */ +#else /* USE_MULTIVIEW */ layout(set = 0, binding = 0) uniform sampler2D source_color; #ifdef MODE_TWO_SOURCES layout(set = 1, binding = 0) uniform sampler2D source_color2; #endif /* MODE_TWO_SOURCES */ -#endif /* MULTIVIEW */ +#endif /* USE_MULTIVIEW */ #endif /* !SET_COLOR */ layout(location = 0) out vec4 frag_color; @@ -129,7 +129,7 @@ void main() { frag_color = params.color; #else -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec3 uv = uv_interp; #else vec2 uv = uv_interp; @@ -165,19 +165,19 @@ void main() { } #endif /* MODE_PANORAMA_TO_DP */ -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec4 color = textureLod(source_color, uv, 0.0); #ifdef MODE_TWO_SOURCES // In multiview our 2nd input will be our depth map depth = textureLod(source_depth, uv, 0.0).r; #endif /* MODE_TWO_SOURCES */ -#else /* MULTIVIEW */ +#else /* USE_MULTIVIEW */ vec4 color = textureLod(source_color, uv, 0.0); #ifdef MODE_TWO_SOURCES color += textureLod(source_color2, uv, 0.0); #endif /* MODE_TWO_SOURCES */ -#endif /* MULTIVIEW */ +#endif /* USE_MULTIVIEW */ if (bool(params.flags & FLAG_FORCE_LUMINANCE)) { color.rgb = vec3(max(max(color.r, color.g), color.b)); diff --git a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl index e77d0de719..3fb93dda35 100644 --- a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl @@ -77,8 +77,8 @@ void main() { float depth_fix = 1.0 / dot(normal, unorm); depth = 2.0 * depth - 1.0; - float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); - depth = (linear_depth * depth_fix) / params.z_far; - + float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near + depth * (params.z_far - params.z_near)); + // linear_depth equal to view space depth + depth = (params.z_far - linear_depth * depth_fix) / params.z_far; gl_FragDepth = depth; } diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl index 51caa67d3c..d9e21b8cd1 100644 --- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl @@ -98,9 +98,9 @@ void main() { // unproject our Z value so we can use it directly. depth = depth * 2.0 - 1.0; if (params.orthogonal) { - depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; + depth = -(depth * (params.camera_z_far - params.camera_z_near) - (params.camera_z_far + params.camera_z_near)) / 2.0; } else { - depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near + depth * (params.camera_z_far - params.camera_z_near)); } depth = -depth; } diff --git a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl index 33ec991107..38eec2b61a 100644 --- a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl @@ -4,7 +4,7 @@ #VERSION_DEFINES -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW #ifdef has_VK_KHR_multiview #extension GL_EXT_multiview : enable #endif @@ -24,27 +24,27 @@ void main() { #VERSION_DEFINES -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW #ifdef has_VK_KHR_multiview #extension GL_EXT_multiview : enable #define ViewIndex gl_ViewIndex #else // has_VK_KHR_multiview #define ViewIndex 0 #endif // has_VK_KHR_multiview -#endif //MULTIVIEW +#endif //USE_MULTIVIEW layout(location = 0) in vec2 uv_interp; #ifdef SUBPASS layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput input_color; -#elif defined(MULTIVIEW) +#elif defined(USE_MULTIVIEW) layout(set = 0, binding = 0) uniform sampler2DArray source_color; #else layout(set = 0, binding = 0) uniform sampler2D source_color; #endif layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW layout(set = 2, binding = 0) uniform sampler2DArray source_glow; #else layout(set = 2, binding = 0) uniform sampler2D source_glow; @@ -125,7 +125,7 @@ float h1(float a) { return 1.0f + w3(a) / (w2(a) + w3(a)); } -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec4 texture2D_bicubic(sampler2DArray tex, vec2 uv, int p_lod) { float lod = float(p_lod); vec2 tex_size = vec2(params.glow_texture_size >> p_lod); @@ -153,7 +153,7 @@ vec4 texture2D_bicubic(sampler2DArray tex, vec2 uv, int p_lod) { } #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod) -#else // MULTIVIEW +#else // USE_MULTIVIEW vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) { float lod = float(p_lod); @@ -182,15 +182,15 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) { } #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod) -#endif // !MULTIVIEW +#endif // !USE_MULTIVIEW #else // USE_GLOW_FILTER_BICUBIC -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, vec3(m_uv, ViewIndex), float(m_lod)) -#else // MULTIVIEW +#else // USE_MULTIVIEW #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, m_uv, float(m_lod)) -#endif // !MULTIVIEW +#endif // !USE_MULTIVIEW #endif // !USE_GLOW_FILTER_BICUBIC @@ -273,11 +273,11 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o } } -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec3 gather_glow(sampler2DArray tex, vec2 uv) { // sample all selected glow levels, view is added to uv later #else vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels -#endif // defined(MULTIVIEW) +#endif // defined(USE_MULTIVIEW) vec3 glow = vec3(0.0f); if (params.glow_levels[0] > 0.0001) { @@ -364,7 +364,7 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { const float FXAA_REDUCE_MUL = (1.0 / 8.0); const float FXAA_SPAN_MAX = 8.0; -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-0.5, -0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(0.5, -0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-0.5, 0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier; @@ -399,7 +399,7 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { dir * rcpDirMin)) * params.pixel_size; -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz) * params.luminance_multiplier; vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz) * params.luminance_multiplier; #else @@ -430,9 +430,9 @@ vec3 screen_space_dither(vec2 frag_coord) { void main() { #ifdef SUBPASS - // SUBPASS and MULTIVIEW can be combined but in that case we're already reading from the correct layer + // SUBPASS and USE_MULTIVIEW can be combined but in that case we're already reading from the correct layer vec4 color = subpassLoad(input_color); -#elif defined(MULTIVIEW) +#elif defined(USE_MULTIVIEW) vec4 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f); #else vec4 color = textureLod(source_color, uv_interp, 0.0f); diff --git a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl index d3d39a8b92..23b0373eef 100644 --- a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl @@ -4,16 +4,16 @@ #VERSION_DEFINES -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW #ifdef has_VK_KHR_multiview #extension GL_EXT_multiview : enable #define ViewIndex gl_ViewIndex #else // has_VK_KHR_multiview #define ViewIndex 0 #endif // has_VK_KHR_multiview -#endif //MULTIVIEW +#endif //USE_MULTIVIEW -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW layout(location = 0) out vec3 uv_interp; #else layout(location = 0) out vec2 uv_interp; @@ -23,7 +23,7 @@ void main() { vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0); uv_interp.xy = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW uv_interp.z = ViewIndex; #endif } @@ -34,36 +34,36 @@ void main() { #VERSION_DEFINES -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW #ifdef has_VK_KHR_multiview #extension GL_EXT_multiview : enable #define ViewIndex gl_ViewIndex #else // has_VK_KHR_multiview #define ViewIndex 0 #endif // has_VK_KHR_multiview -#endif //MULTIVIEW +#endif //USE_MULTIVIEW -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW layout(location = 0) in vec3 uv_interp; layout(set = 0, binding = 0) uniform sampler2DArray source_color; -#else /* MULTIVIEW */ +#else /* USE_MULTIVIEW */ layout(location = 0) in vec2 uv_interp; layout(set = 0, binding = 0) uniform sampler2D source_color; -#endif /* MULTIVIEW */ +#endif /* USE_MULTIVIEW */ layout(location = 0) out uint frag_color; void main() { -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec3 uv = uv_interp; #else vec2 uv = uv_interp; #endif -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW vec4 color = textureLod(source_color, uv, 0.0); frag_color = uint(color.r * 255.0); -#else /* MULTIVIEW */ +#else /* USE_MULTIVIEW */ vec4 color = textureLod(source_color, uv, 0.0); // for user supplied VRS map we do a color mapping @@ -75,5 +75,5 @@ void main() { // note 1x4, 4x1, 1x8, 8x1, 2x8 and 8x2 are not supported // 4x8, 8x4 and 8x8 are only available on some GPUs -#endif /* MULTIVIEW */ +#endif /* USE_MULTIVIEW */ } diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl index 80ed34cda1..480172f9dc 100644 --- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl @@ -174,9 +174,9 @@ vec3 reconstruct_position(ivec2 screen_pos) { pos.z = pos.z * 2.0 - 1.0; if (params.orthogonal) { - pos.z = ((pos.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0; + pos.z = -(pos.z * (params.z_far - params.z_near) - (params.z_far + params.z_near)) / 2.0; } else { - pos.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - pos.z * (params.z_far - params.z_near)); + pos.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near + pos.z * (params.z_far - params.z_near)); } pos.z = -pos.z; diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index 4e5b11aed8..35457a2482 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -25,7 +25,7 @@ params; void main() { vec2 base_arr[3] = vec2[](vec2(-1.0, -3.0), vec2(-1.0, 1.0), vec2(3.0, 1.0)); uv_interp = base_arr[gl_VertexIndex]; - gl_Position = vec4(uv_interp, 1.0, 1.0); + gl_Position = vec4(uv_interp, 0.0, 1.0); } #[fragment] @@ -158,7 +158,7 @@ vec3 interleaved_gradient_noise(vec2 pos) { vec4 volumetric_fog_process(vec2 screen_uv) { #ifdef USE_MULTIVIEW - vec4 reprojected = sky_scene_data.combined_reprojection[ViewIndex] * (vec4(screen_uv * 2.0 - 1.0, 1.0, 1.0) * sky_scene_data.z_far); + vec4 reprojected = sky_scene_data.combined_reprojection[ViewIndex] * vec4(screen_uv * 2.0 - 1.0, 0.0, 1.0); // Unproject at the far plane vec3 fog_pos = vec3(reprojected.xy / reprojected.w, 1.0) * 0.5 + 0.5; #else vec3 fog_pos = vec3(screen_uv, 1.0); @@ -187,9 +187,11 @@ void main() { vec3 cube_normal; #ifdef USE_MULTIVIEW // In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject. - vec4 unproject = vec4(uv_interp.x, -uv_interp.y, 1.0, 1.0); + vec4 unproject = vec4(uv_interp.x, -uv_interp.y, 0.0, 1.0); // unproject at the far plane vec4 unprojected = sky_scene_data.view_inv_projections[ViewIndex] * unproject; cube_normal = unprojected.xyz / unprojected.w; + + // Unproject will give us the position between the eyes, need to re-offset cube_normal += sky_scene_data.view_eye_offsets[ViewIndex].xyz; #else cube_normal.z = -1.0; diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index 57b9a4c320..d0cfe6a3b8 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -416,7 +416,7 @@ void main() { } float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; - float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * INV_FOG_FADE); + float shadow = exp(min(0.0, (pssm_coord.z - depth)) * z_range * INV_FOG_FADE); shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance @@ -519,7 +519,7 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = mix(1.0 - omni_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * INV_FOG_FADE)); + shadow_attenuation = mix(1.0 - omni_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (pos.z - depth)) / omni_lights.data[light_index].inv_radius * INV_FOG_FADE)); } total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g) * omni_lights.data[light_index].volumetric_fog_energy; } @@ -597,7 +597,7 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = mix(1.0 - spot_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * INV_FOG_FADE)); + shadow_attenuation = mix(1.0 - spot_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (pos.z - depth)) / spot_lights.data[light_index].inv_radius * INV_FOG_FADE)); } total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g) * spot_lights.data[light_index].volumetric_fog_energy; } diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 6eae64c04e..359d7799e5 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -487,8 +487,8 @@ void vertex_shader(vec3 vertex_input, #ifdef MODE_RENDER_DEPTH if (scene_data.pancake_shadows) { - if (gl_Position.z <= 0.00001) { - gl_Position.z = 0.00001; + if (gl_Position.z >= 0.9999) { + gl_Position.z = 0.9999; } } #endif diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 259edc63a0..c26313092b 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -475,8 +475,8 @@ void main() { #ifdef MODE_RENDER_DEPTH if (scene_data.pancake_shadows) { - if (gl_Position.z <= 0.00001) { - gl_Position.z = 0.00001; + if (gl_Position.z >= 0.9999) { + gl_Position.z = 0.9999; } } #endif // MODE_RENDER_DEPTH diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index e9722bad1f..47e6fe5873 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -454,7 +454,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { vec3 v0 = abs(basis_normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); vec3 tangent = normalize(cross(v0, basis_normal)); vec3 bitangent = normalize(cross(tangent, basis_normal)); - float z_norm = shadow_len * omni_lights.data[idx].inv_radius; + float z_norm = 1.0 - shadow_len * omni_lights.data[idx].inv_radius; tangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale; bitangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale; @@ -479,7 +479,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { pos.xy = uv_rect.xy + pos.xy * uv_rect.zw; float d = textureLod(sampler2D(shadow_atlas, SAMPLER_LINEAR_CLAMP), pos.xy, 0.0).r; - if (d < z_norm) { + if (d > z_norm) { blocker_average += d; blocker_count += 1.0; } @@ -488,11 +488,11 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { if (blocker_count > 0.0) { //blockers found, do soft shadow blocker_average /= blocker_count; - float penumbra = (z_norm - blocker_average) / blocker_average; + float penumbra = (z_norm + blocker_average) / blocker_average; tangent *= penumbra; bitangent *= penumbra; - z_norm -= omni_lights.data[idx].inv_radius * omni_lights.data[idx].shadow_bias; + z_norm += omni_lights.data[idx].inv_radius * omni_lights.data[idx].shadow_bias; shadow = 0.0; for (uint i = 0; i < sc_penumbra_shadow_samples; i++) { @@ -536,6 +536,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { vec2 pos = shadow_sample.xy / shadow_sample.z; float depth = shadow_len - omni_lights.data[idx].shadow_bias; depth *= omni_lights.data[idx].inv_radius; + depth = 1.0 - depth; shadow = mix(1.0, sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth), omni_lights.data[idx].shadow_opacity); } @@ -706,7 +707,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { vec4 v = vec4(vertex + normal_bias, 1.0); vec4 splane = (spot_lights.data[idx].shadow_matrix * v); - splane.z -= spot_lights.data[idx].shadow_bias / (light_length * spot_lights.data[idx].inv_radius); + splane.z += spot_lights.data[idx].shadow_bias / (light_length * spot_lights.data[idx].inv_radius); splane /= splane.w; float shadow; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 2786af65eb..d1ff9fc362 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -668,7 +668,9 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light->directional_blend_splits; for (int j = 0; j < 4; j++) { Rect2 atlas_rect = light_instance->shadow_transform[j].atlas_rect; - Projection matrix = light_instance->shadow_transform[j].camera; + Projection correction; + correction.set_depth_correction(false, true, false); + Projection matrix = correction * light_instance->shadow_transform[j].camera; float split = light_instance->shadow_transform[MIN(limit, j)].split; Projection bias; @@ -967,7 +969,9 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged Projection bias; bias.set_light_bias(); - Projection cm = light_instance->shadow_transform[0].camera; + Projection correction; + correction.set_depth_correction(false, true, false); + Projection cm = correction * light_instance->shadow_transform[0].camera; Projection shadow_mtx = bias * cm * modelview; RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrix); @@ -1370,6 +1374,17 @@ void LightStorage::reflection_probe_instance_set_transform(RID p_instance, const rpi->dirty = true; } +bool LightStorage::reflection_probe_has_atlas_index(RID p_instance) { + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); + ERR_FAIL_NULL_V(rpi, false); + + if (rpi->atlas.is_null()) { + return false; + } + + return rpi->atlas_index >= 0; +} + void LightStorage::reflection_probe_release_atlas_index(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_NULL(rpi); @@ -1384,6 +1399,14 @@ void LightStorage::reflection_probe_release_atlas_index(RID p_instance) { // TODO investigate if this is enough? shouldn't we be freeing our textures and framebuffers? + if (rpi->rendering) { + // We were cancelled mid rendering, trigger refresh. + rpi->rendering = false; + rpi->dirty = true; + rpi->processing_layer = 1; + rpi->processing_side = 0; + } + rpi->atlas_index = -1; rpi->atlas = RID(); } @@ -1535,11 +1558,10 @@ bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_NULL_V(rpi, false); ERR_FAIL_COND_V(!rpi->rendering, false); - ERR_FAIL_COND_V(rpi->atlas.is_null(), false); ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); if (!atlas || rpi->atlas_index == -1) { - //does not belong to an atlas anymore, cancel (was removed from atlas or atlas changed while rendering) + // Does not belong to an atlas anymore, cancel (was removed from atlas or atlas changed while rendering). rpi->rendering = false; return false; } diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index b3d27cc6ed..b3d6bf5254 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -277,7 +277,6 @@ private: int processing_layer = 1; int processing_side = 0; - uint32_t render_step = 0; uint64_t last_pass = 0; uint32_t cull_mask = 0; @@ -848,6 +847,7 @@ public: virtual RID reflection_probe_instance_create(RID p_probe) override; virtual void reflection_probe_instance_free(RID p_instance) override; virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override; + virtual bool reflection_probe_has_atlas_index(RID p_instance) override; virtual void reflection_probe_release_atlas_index(RID p_instance) override; virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override; virtual bool reflection_probe_instance_has_reflection(RID p_instance) override; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index a854e78f53..c9c7c53d04 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -620,8 +620,9 @@ AABB ParticlesStorage::particles_get_current_aabb(RID p_particles) { total_amount *= particles->trail_bind_poses.size(); } + uint32_t particle_data_size = sizeof(ParticleData) + sizeof(float) * 4 * particles->userdata_count; Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(particles->particle_buffer); - ERR_FAIL_COND_V(buffer.size() != (int)(total_amount * sizeof(ParticleData)), AABB()); + ERR_FAIL_COND_V(buffer.size() != (int)(total_amount * particle_data_size), AABB()); Transform3D inv = particles->emission_transform.affine_inverse(); @@ -630,7 +631,6 @@ AABB ParticlesStorage::particles_get_current_aabb(RID p_particles) { bool first = true; const uint8_t *data_ptr = (const uint8_t *)buffer.ptr(); - uint32_t particle_data_size = sizeof(ParticleData) + sizeof(float) * particles->userdata_count; for (int i = 0; i < total_amount; i++) { const ParticleData &particle_data = *(const ParticleData *)&data_ptr[particle_data_size * i]; @@ -1388,6 +1388,11 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) { } } void ParticlesStorage::update_particles() { + if (!particle_update_list.first()) { + return; + } + + RENDER_TIMESTAMP("Update GPUParticles"); uint32_t frame = RSG::rasterizer->get_frame_number(); bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0; while (particle_update_list.first()) { @@ -1452,6 +1457,11 @@ void ParticlesStorage::update_particles() { if (uint32_t(history_size) != particles->frame_history.size()) { particles->frame_history.resize(history_size); memset(particles->frame_history.ptr(), 0, sizeof(ParticlesFrameParams) * history_size); + // Set the frame number so that we are able to distinguish an uninitialized + // frame from the true frame number zero. See issue #88712 for details. + for (int i = 0; i < history_size; i++) { + particles->frame_history[i].frame = UINT32_MAX; + } } if (uint32_t(trail_steps) != particles->trail_params.size() || particles->frame_params_buffer.is_null()) { diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp index 8dc74820e2..c5d74d395f 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp @@ -128,6 +128,13 @@ void RenderSceneBuffersRD::cleanup() { free_named_texture(E.value); } named_textures.clear(); + + // Clear weight_buffer / blur textures. + for (const WeightBuffers &weight_buffer : weight_buffers) { + if (weight_buffer.weight.is_valid()) { + RD::get_singleton()->free(weight_buffer.weight); + } + } } void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_config) { diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index dd94982f1a..da046bf6b1 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -2965,7 +2965,7 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const dd.emission_rect[3] = 0; } - Color modulate = decal->modulate; + Color modulate = decal->modulate.srgb_to_linear(); dd.modulate[0] = modulate.r; dd.modulate[1] = modulate.g; dd.modulate[2] = modulate.b; @@ -3637,8 +3637,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) { } rt->process_size = size * scale / 100; - rt->process_size.x = MAX(rt->process_size.x, 1); - rt->process_size.y = MAX(rt->process_size.y, 1); + rt->process_size = rt->process_size.max(Size2i(1, 1)); tformat.format = RD::DATA_FORMAT_R16G16_SINT; tformat.width = rt->process_size.width; |
