diff options
Diffstat (limited to 'servers/rendering/renderer_rd/renderer_scene_render_rd.cpp')
| -rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.cpp | 778 |
1 files changed, 528 insertions, 250 deletions
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index fd797b1cab..a1c2f4f49c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -48,8 +48,8 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) { } void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); bool needs_sdfgi = env && env->sdfgi_enabled; if (!needs_sdfgi) { @@ -83,7 +83,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment } int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers) const { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, 0); @@ -113,7 +113,7 @@ AABB RendererSceneRenderRD::sdfgi_get_pending_region_bounds(RID p_render_buffers AABB bounds; Vector3i from; Vector3i size; - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, AABB()); ERR_FAIL_COND_V(rb->sdfgi == nullptr, AABB()); @@ -126,7 +126,7 @@ uint32_t RendererSceneRenderRD::sdfgi_get_pending_region_cascade(RID p_render_bu AABB bounds; Vector3i from; Vector3i size; - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, -1); ERR_FAIL_COND_V(rb->sdfgi == nullptr, -1); @@ -164,139 +164,139 @@ void RendererSceneRenderRD::environment_initialize(RID p_rid) { } void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->background = p_bg; } void RendererSceneRenderRD::environment_set_sky(RID p_env, RID p_sky) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->sky = p_sky; } void RendererSceneRenderRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->sky_custom_fov = p_scale; } void RendererSceneRenderRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->sky_orientation = p_orientation; } void RendererSceneRenderRD::environment_set_bg_color(RID p_env, const Color &p_color) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->bg_color = p_color; } void RendererSceneRenderRD::environment_set_bg_energy(RID p_env, float p_energy) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->bg_energy = p_energy; } void RendererSceneRenderRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->canvas_max_layer = p_max_layer; } void RendererSceneRenderRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_ambient_light(p_color, p_ambient, p_energy, p_sky_contribution, p_reflection_source, p_ao_color); } RS::EnvironmentBG RendererSceneRenderRD::environment_get_background(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); return env->background; } RID RendererSceneRenderRD::environment_get_sky(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RID()); return env->sky; } float RendererSceneRenderRD::environment_get_sky_custom_fov(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->sky_custom_fov; } Basis RendererSceneRenderRD::environment_get_sky_orientation(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Basis()); return env->sky_orientation; } Color RendererSceneRenderRD::environment_get_bg_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->bg_color; } float RendererSceneRenderRD::environment_get_bg_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->bg_energy; } int RendererSceneRenderRD::environment_get_canvas_max_layer(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->canvas_max_layer; } Color RendererSceneRenderRD::environment_get_ambient_light_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ambient_light; } RS::EnvironmentAmbientSource RendererSceneRenderRD::environment_get_ambient_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); return env->ambient_source; } float RendererSceneRenderRD::environment_get_ambient_light_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_light_energy; } float RendererSceneRenderRD::environment_get_ambient_sky_contribution(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_sky_contribution; } RS::EnvironmentReflectionSource RendererSceneRenderRD::environment_get_reflection_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED); return env->reflection_source; } Color RendererSceneRenderRD::environment_get_ao_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ao_color; } void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_tonemap(p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale); } void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_glow(p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap); } @@ -310,7 +310,7 @@ void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) } void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); if (!is_dynamic_gi_supported()) { @@ -321,58 +321,58 @@ void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS:: } void RendererSceneRenderRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_fog(p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_fog_aerial_perspective); } bool RendererSceneRenderRD::environment_is_fog_enabled(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->fog_enabled; } Color RendererSceneRenderRD::environment_get_fog_light_color(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->fog_light_color; } float RendererSceneRenderRD::environment_get_fog_light_energy(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_light_energy; } float RendererSceneRenderRD::environment_get_fog_sun_scatter(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_sun_scatter; } float RendererSceneRenderRD::environment_get_fog_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_density; } float RendererSceneRenderRD::environment_get_fog_height(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_height; } float RendererSceneRenderRD::environment_get_fog_height_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_height_density; } float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_aerial_perspective; } void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); if (!is_volumetric_supported()) { @@ -403,7 +403,7 @@ void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::Env } void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_ssr(p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance); @@ -418,7 +418,7 @@ RS::EnvironmentSSRRoughnessQuality RendererSceneRenderRD::environment_get_ssr_ro } void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_ssao(p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect); @@ -434,30 +434,30 @@ void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQual } bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->ssao_enabled; } float RendererSceneRenderRD::environment_get_ssao_ao_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0.0); return env->ssao_ao_channel_affect; } float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0.0); return env->ssao_direct_light_affect; } bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->ssr_enabled; } bool RendererSceneRenderRD::environment_is_sdfgi_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->sdfgi_enabled; } @@ -467,7 +467,7 @@ bool RendererSceneRenderRD::is_environment(RID p_env) const { } Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Ref<Image>()); if (env->background == RS::ENV_BG_CAMERA_FEED || env->background == RS::ENV_BG_CANVAS || env->background == RS::ENV_BG_KEEP) { @@ -522,7 +522,7 @@ RID RendererSceneRenderRD::reflection_atlas_create() { } void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) { - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas); ERR_FAIL_COND(!ra); if (ra->size == p_reflection_size && ra->count == p_reflection_count) { @@ -557,7 +557,7 @@ void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_ref } int RendererSceneRenderRD::reflection_atlas_get_size(RID p_ref_atlas) const { - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas); ERR_FAIL_COND_V(!ra, 0); return ra->size; @@ -573,7 +573,7 @@ RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) { } void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!rpi); rpi->transform = p_transform; @@ -581,13 +581,13 @@ void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instan } void RendererSceneRenderRD::reflection_probe_release_atlas_index(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!rpi); if (rpi->atlas.is_null()) { return; //nothing to release } - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND(!atlas); ERR_FAIL_INDEX(rpi->atlas_index, atlas->reflections.size()); atlas->reflections.write[rpi->atlas_index].owner = RID(); @@ -596,7 +596,7 @@ void RendererSceneRenderRD::reflection_probe_release_atlas_index(RID p_instance) } bool RendererSceneRenderRD::reflection_probe_instance_needs_redraw(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); if (rpi->rendering) { @@ -615,18 +615,18 @@ bool RendererSceneRenderRD::reflection_probe_instance_needs_redraw(RID p_instanc } bool RendererSceneRenderRD::reflection_probe_instance_has_reflection(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); return rpi->atlas.is_valid(); } bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_reflection_atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas); ERR_FAIL_COND_V(!atlas, false); - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); RD::get_singleton()->draw_command_begin_label("Reflection probe render"); @@ -701,7 +701,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc uint64_t pass_min = 0; for (int i = 0; i < atlas->reflections.size(); i++) { - ReflectionProbeInstance *rpi2 = reflection_probe_instance_owner.getornull(atlas->reflections[i].owner); + ReflectionProbeInstance *rpi2 = reflection_probe_instance_owner.get_or_null(atlas->reflections[i].owner); if (rpi2->last_pass < pass_min) { pass_min = rpi2->last_pass; rpi->atlas_index = i; @@ -733,12 +733,12 @@ RID RendererSceneRenderRD::reflection_probe_create_framebuffer(RID p_color, RID } bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); ERR_FAIL_COND_V(!rpi->rendering, false); ERR_FAIL_COND_V(rpi->atlas.is_null(), false); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + 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) rpi->rendering = false; @@ -779,30 +779,30 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins } uint32_t RendererSceneRenderRD::reflection_probe_instance_get_resolution(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, 0); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND_V(!atlas, 0); return atlas->size; } RID RendererSceneRenderRD::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, RID()); ERR_FAIL_INDEX_V(p_index, 6, RID()); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND_V(!atlas, RID()); return atlas->reflections[rpi->atlas_index].fbs[p_index]; } RID RendererSceneRenderRD::reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, RID()); ERR_FAIL_INDEX_V(p_index, 6, RID()); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND_V(!atlas, RID()); return atlas->depth_fb; } @@ -829,7 +829,7 @@ void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) { } void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); p_size = next_power_of_2(p_size); @@ -850,8 +850,8 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool } //erase shadow atlas reference from lights - for (Map<RID, uint32_t>::Element *E = shadow_atlas->shadow_owners.front(); E; E = E->next()) { - LightInstance *li = light_instance_owner.getornull(E->key()); + for (const KeyValue<RID, uint32_t> &E : shadow_atlas->shadow_owners) { + LightInstance *li = light_instance_owner.get_or_null(E.key); ERR_CONTINUE(!li); li->shadow_atlases.erase(p_atlas); } @@ -860,11 +860,11 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool shadow_atlas->shadow_owners.clear(); shadow_atlas->size = p_size; - shadow_atlas->use_16_bits = p_size; + shadow_atlas->use_16_bits = p_16_bits; } void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_INDEX(p_quadrant, 4); ERR_FAIL_INDEX(p_subdivision, 16384); @@ -886,7 +886,7 @@ void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, i for (int i = 0; i < shadow_atlas->quadrants[p_quadrant].shadows.size(); i++) { if (shadow_atlas->quadrants[p_quadrant].shadows[i].owner.is_valid()) { shadow_atlas->shadow_owners.erase(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); - LightInstance *li = light_instance_owner.getornull(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); + LightInstance *li = light_instance_owner.get_or_null(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); ERR_CONTINUE(!li); li->shadow_atlases.erase(p_atlas); } @@ -935,7 +935,7 @@ bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, //look for an empty space int sc = shadow_atlas->quadrants[qidx].shadows.size(); - ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptrw(); + const ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptr(); int found_free_idx = -1; //found a free one int found_used_idx = -1; //found existing one, must steal it @@ -947,7 +947,7 @@ bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, break; } - LightInstance *sli = light_instance_owner.getornull(sarr[j].owner); + LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner); ERR_CONTINUE(!sli); if (sli->last_scene_pass != scene_pass) { @@ -980,11 +980,83 @@ bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, return false; } +bool RendererSceneRenderRD::_shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) { + for (int i = p_quadrant_count - 1; i >= 0; i--) { + int qidx = p_in_quadrants[i]; + + if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) { + return false; + } + + //look for an empty space + int sc = shadow_atlas->quadrants[qidx].shadows.size(); + const ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptr(); + + int found_idx = -1; + uint64_t min_pass = 0; // sum of currently selected spots, try to get the least recently used pair + + for (int j = 0; j < sc - 1; j++) { + uint64_t pass = 0; + + if (sarr[j].owner.is_valid()) { + LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner); + ERR_CONTINUE(!sli); + + if (sli->last_scene_pass == scene_pass) { + continue; + } + + //was just allocated, don't kill it so soon, wait a bit.. + if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) { + continue; + } + pass += sli->last_scene_pass; + } + + if (sarr[j + 1].owner.is_valid()) { + LightInstance *sli = light_instance_owner.get_or_null(sarr[j + 1].owner); + ERR_CONTINUE(!sli); + + if (sli->last_scene_pass == scene_pass) { + continue; + } + + //was just allocated, don't kill it so soon, wait a bit.. + if (p_tick - sarr[j + 1].alloc_tick < shadow_atlas_realloc_tolerance_msec) { + continue; + } + pass += sli->last_scene_pass; + } + + if (found_idx == -1 || pass < min_pass) { + found_idx = j; + min_pass = pass; + + // we found two empty spots, no need to check the rest + if (pass == 0) { + break; + } + } + } + + if (found_idx == -1) { + continue; //nothing found + } + + r_quadrant = qidx; + r_shadow = found_idx; + + return true; + } + + return false; +} + bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND_V(!shadow_atlas, false); - LightInstance *li = light_instance_owner.getornull(p_light_intance); + LightInstance *li = light_instance_owner.get_or_null(p_light_intance); ERR_FAIL_COND_V(!li, false); if (shadow_atlas->size == 0 || shadow_atlas->smallest_subdiv == 0) { @@ -1025,94 +1097,104 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i uint64_t tick = OS::get_singleton()->get_ticks_msec(); - //see if it already exists + uint32_t old_key = ShadowAtlas::SHADOW_INVALID; + uint32_t old_quadrant = ShadowAtlas::SHADOW_INVALID; + uint32_t old_shadow = ShadowAtlas::SHADOW_INVALID; + int old_subdivision = -1; + + bool should_realloc = false; + bool should_redraw = false; if (shadow_atlas->shadow_owners.has(p_light_intance)) { - //it does! - uint32_t key = shadow_atlas->shadow_owners[p_light_intance]; - uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; - uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK; + old_key = shadow_atlas->shadow_owners[p_light_intance]; + old_quadrant = (old_key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; + old_shadow = old_key & ShadowAtlas::SHADOW_INDEX_MASK; - bool should_realloc = shadow_atlas->quadrants[q].subdivision != (uint32_t)best_subdiv && (shadow_atlas->quadrants[q].shadows[s].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec); - bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version; + should_realloc = shadow_atlas->quadrants[old_quadrant].subdivision != (uint32_t)best_subdiv && (shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec); + should_redraw = shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].version != p_light_version; if (!should_realloc) { - shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version; + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = p_light_version; //already existing, see if it should redraw or it's just OK return should_redraw; } - int new_quadrant, new_shadow; + old_subdivision = shadow_atlas->quadrants[old_quadrant].subdivision; + } - //find a better place - if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, shadow_atlas->quadrants[q].subdivision, tick, new_quadrant, new_shadow)) { - //found a better place! - ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; - if (sh->owner.is_valid()) { - //is taken, but is invalid, erasing it - shadow_atlas->shadow_owners.erase(sh->owner); - LightInstance *sli = light_instance_owner.getornull(sh->owner); - sli->shadow_atlases.erase(p_atlas); - } + bool is_omni = li->light_type == RS::LIGHT_OMNI; + bool found_shadow = false; + int new_quadrant = -1; + int new_shadow = -1; - //erase previous - shadow_atlas->quadrants[q].shadows.write[s].version = 0; - shadow_atlas->quadrants[q].shadows.write[s].owner = RID(); + if (is_omni) { + found_shadow = _shadow_atlas_find_omni_shadows(shadow_atlas, valid_quadrants, valid_quadrant_count, old_subdivision, tick, new_quadrant, new_shadow); + } else { + found_shadow = _shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, old_subdivision, tick, new_quadrant, new_shadow); + } - sh->owner = p_light_intance; - sh->alloc_tick = tick; - sh->version = p_light_version; - li->shadow_atlases.insert(p_atlas); - - //make new key - key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT; - key |= new_shadow; - //update it in map - shadow_atlas->shadow_owners[p_light_intance] = key; - //make it dirty, as it should redraw anyway - return true; + if (found_shadow) { + if (old_quadrant != ShadowAtlas::SHADOW_INVALID) { + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = 0; + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].owner = RID(); + + if (old_key & ShadowAtlas::OMNI_LIGHT_FLAG) { + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow + 1].version = 0; + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow + 1].owner = RID(); + } } - //no better place for this shadow found, keep current + uint32_t new_key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT; + new_key |= new_shadow; - //already existing, see if it should redraw or it's just OK + ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; + _shadow_atlas_invalidate_shadow(sh, p_atlas, shadow_atlas, new_quadrant, new_shadow); - shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version; + sh->owner = p_light_intance; + sh->alloc_tick = tick; + sh->version = p_light_version; - return should_redraw; - } + if (is_omni) { + new_key |= ShadowAtlas::OMNI_LIGHT_FLAG; - int new_quadrant, new_shadow; + int new_omni_shadow = new_shadow + 1; + ShadowAtlas::Quadrant::Shadow *extra_sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_omni_shadow]; + _shadow_atlas_invalidate_shadow(extra_sh, p_atlas, shadow_atlas, new_quadrant, new_omni_shadow); - //find a better place - if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, -1, tick, new_quadrant, new_shadow)) { - //found a better place! - ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; - if (sh->owner.is_valid()) { - //is taken, but is invalid, erasing it - shadow_atlas->shadow_owners.erase(sh->owner); - LightInstance *sli = light_instance_owner.getornull(sh->owner); - sli->shadow_atlases.erase(p_atlas); + extra_sh->owner = p_light_intance; + extra_sh->alloc_tick = tick; + extra_sh->version = p_light_version; } - sh->owner = p_light_intance; - sh->alloc_tick = tick; - sh->version = p_light_version; li->shadow_atlases.insert(p_atlas); - //make new key - uint32_t key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT; - key |= new_shadow; //update it in map - shadow_atlas->shadow_owners[p_light_intance] = key; + shadow_atlas->shadow_owners[p_light_intance] = new_key; //make it dirty, as it should redraw anyway - return true; } - //no place to allocate this light, apologies + return should_redraw; +} + +void RendererSceneRenderRD::_shadow_atlas_invalidate_shadow(RendererSceneRenderRD::ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, RendererSceneRenderRD::ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx) { + if (p_shadow->owner.is_valid()) { + LightInstance *sli = light_instance_owner.get_or_null(p_shadow->owner); + uint32_t old_key = p_shadow_atlas->shadow_owners[p_shadow->owner]; - return false; + if (old_key & ShadowAtlas::OMNI_LIGHT_FLAG) { + uint32_t s = old_key & ShadowAtlas::SHADOW_INDEX_MASK; + uint32_t omni_shadow_idx = p_shadow_idx + (s == (uint32_t)p_shadow_idx ? 1 : -1); + RendererSceneRenderRD::ShadowAtlas::Quadrant::Shadow *omni_shadow = &p_shadow_atlas->quadrants[p_quadrant].shadows.write[omni_shadow_idx]; + omni_shadow->version = 0; + omni_shadow->owner = RID(); + } + + p_shadow->version = 0; + p_shadow->owner = RID(); + sli->shadow_atlases.erase(p_atlas); + p_shadow_atlas->shadow_owners.erase(p_shadow->owner); + } } void RendererSceneRenderRD::_update_directional_shadow_atlas() { @@ -1137,6 +1219,7 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p } directional_shadow.size = p_size; + directional_shadow.use_16_bits = p_16_bits; if (directional_shadow.depth.is_valid()) { RD::get_singleton()->free(directional_shadow.depth); @@ -1177,7 +1260,7 @@ int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0); - LightInstance *light_instance = light_instance_owner.getornull(p_light_intance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_intance); ERR_FAIL_COND_V(!light_instance, 0); switch (storage->light_directional_get_shadow_mode(light_instance->light)) { @@ -1213,7 +1296,7 @@ void RendererSceneRenderRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokeh } void RendererSceneRenderRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) { - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + CameraEffects *camfx = camera_effects_owner.get_or_null(p_camera_effects); ERR_FAIL_COND(!camfx); camfx->dof_blur_far_enabled = p_far_enable; @@ -1228,7 +1311,7 @@ void RendererSceneRenderRD::camera_effects_set_dof_blur(RID p_camera_effects, bo } void RendererSceneRenderRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + CameraEffects *camfx = camera_effects_owner.get_or_null(p_camera_effects); ERR_FAIL_COND(!camfx); camfx->override_exposure_enabled = p_enable; @@ -1238,7 +1321,7 @@ void RendererSceneRenderRD::camera_effects_set_custom_exposure(RID p_camera_effe RID RendererSceneRenderRD::light_instance_create(RID p_light) { RID li = light_instance_owner.make_rid(LightInstance()); - LightInstance *light_instance = light_instance_owner.getornull(li); + LightInstance *light_instance = light_instance_owner.get_or_null(li); light_instance->self = li; light_instance->light = p_light; @@ -1251,21 +1334,21 @@ RID RendererSceneRenderRD::light_instance_create(RID p_light) { } void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->transform = p_transform; } void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->aabb = p_aabb; } void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); ERR_FAIL_INDEX(p_pass, 6); @@ -1281,7 +1364,7 @@ void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_inst } void RendererSceneRenderRD::light_instance_mark_visible(RID p_light_instance) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->last_scene_pass = scene_pass; @@ -1324,7 +1407,7 @@ RID RendererSceneRenderRD::decal_instance_create(RID p_decal) { } void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) { - DecalInstance *di = decal_instance_owner.getornull(p_decal); + DecalInstance *di = decal_instance_owner.get_or_null(p_decal); ERR_FAIL_COND(!di); di->transform = p_transform; } @@ -1337,7 +1420,7 @@ RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) { return lightmap_instance_owner.make_rid(li); } void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) { - LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap); + LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!li); li->transform = p_transform; } @@ -1369,7 +1452,7 @@ void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_ins } void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); if (!rb->sdfgi) { @@ -1464,6 +1547,85 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { base_width = MAX(1, base_width >> 1); base_height = MAX(1, base_height >> 1); } + + if (!_render_buffers_can_be_storage()) { + // create 4 weight textures, 2 full size, 2 half size + + tf.format = RD::DATA_FORMAT_R16_SFLOAT; // We could probably use DATA_FORMAT_R8_SNORM if we don't pre-multiply by blur_size but that depends on whether we can remove DEPTH_GAP + tf.width = rb->width; + tf.height = rb->height; + tf.texture_type = rb->view_count > 1 ? RD::TEXTURE_TYPE_2D_ARRAY : RD::TEXTURE_TYPE_2D; + tf.array_layers = rb->view_count; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.mipmaps = 1; + for (uint32_t i = 0; i < 4; i++) { + // associated blur texture + RID texture; + if (i == 0) { + texture = rb->texture; + } else if (i == 1) { + texture = rb->blur[0].mipmaps[0].texture; + } else if (i == 2) { + texture = rb->blur[1].mipmaps[0].texture; + } else if (i == 3) { + texture = rb->blur[0].mipmaps[1].texture; + } + + // create weight texture + rb->weight_buffers[i].weight = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + // create frame buffer + Vector<RID> fb; + fb.push_back(texture); + fb.push_back(rb->weight_buffers[i].weight); + rb->weight_buffers[i].fb = RD::get_singleton()->framebuffer_create(fb); + + if (i == 1) { + // next 2 are half size + tf.width = MAX(1, tf.width >> 1); + tf.height = MAX(1, tf.height >> 1); + } + } + + { + // and finally an FB for just our base weights + Vector<RID> fb; + fb.push_back(rb->weight_buffers[0].weight); + rb->base_weight_fb = RD::get_singleton()->framebuffer_create(fb); + } + } +} + +void RendererSceneRenderRD::_allocate_depth_backbuffer_textures(RenderBuffers *rb) { + ERR_FAIL_COND(!rb->depth_back_texture.is_null()); + + { + RD::TextureFormat tf; + if (rb->view_count > 1) { + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + } + // We're not using this as a depth stencil, just copying our data into this. May need to look into using a different format on mobile, maybe R16? + tf.format = RD::DATA_FORMAT_R32_SFLOAT; + + tf.width = rb->width; + tf.height = rb->height; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; + tf.array_layers = rb->view_count; // create a layer for every view + + tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; // set this as color attachment because we're copying data into it, it's not actually used as a depth buffer + + rb->depth_back_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); + } + + if (!_render_buffers_can_be_storage()) { + // create framebuffer so we can write into this... + + Vector<RID> fb; + fb.push_back(rb->depth_back_texture); + + rb->depth_back_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, rb->view_count); + } } void RendererSceneRenderRD::_allocate_luminance_textures(RenderBuffers *rb) { @@ -1532,6 +1694,16 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { rb->depth_texture = RID(); } + if (rb->depth_back_fb.is_valid()) { + RD::get_singleton()->free(rb->depth_back_fb); + rb->depth_back_fb = RID(); + } + + if (rb->depth_back_texture.is_valid()) { + RD::get_singleton()->free(rb->depth_back_texture); + rb->depth_back_texture = RID(); + } + for (int i = 0; i < 2; i++) { for (int m = 0; m < rb->blur[i].mipmaps.size(); m++) { // do we free the texture slice here? or is it enough to free the main texture? @@ -1618,7 +1790,7 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { } void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); bool can_use_effects = rb->width >= 8 && rb->height >= 8; @@ -1636,7 +1808,7 @@ void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatri } void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); bool can_use_effects = rb->width >= 8 && rb->height >= 8; @@ -1647,7 +1819,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb return; } - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); ERR_FAIL_COND(!env); ERR_FAIL_COND(!env->ssr_enabled); @@ -1688,10 +1860,10 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb } void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); ERR_FAIL_COND(!env); RENDER_TIMESTAMP("Process SSAO"); @@ -1832,13 +2004,65 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ssao.downsample_uniform_set, rb->ssao.gather_uniform_set, rb->ssao.importance_map_uniform_set); } +void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) { + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); + ERR_FAIL_COND(!rb); + + RD::get_singleton()->draw_command_begin_label("Copy screen texture"); + + if (rb->blur[0].texture.is_null()) { + _allocate_blur_textures(rb); + } + + // @TODO IMPLEMENT MULTIVIEW, all effects need to support stereo buffers or effects are only applied to the left eye + + bool can_use_storage = _render_buffers_can_be_storage(); + + if (can_use_storage) { + storage->get_effects()->copy_to_rect(rb->texture, rb->blur[0].mipmaps[0].texture, Rect2i(0, 0, rb->width, rb->height)); + for (int i = 1; i < rb->blur[0].mipmaps.size(); i++) { + storage->get_effects()->make_mipmap(rb->blur[0].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i].texture, Size2i(rb->blur[0].mipmaps[i].width, rb->blur[0].mipmaps[i].height)); + } + } else { + storage->get_effects()->copy_to_fb_rect(rb->texture, rb->blur[0].mipmaps[0].fb, Rect2i(0, 0, rb->width, rb->height)); + for (int i = 1; i < rb->blur[0].mipmaps.size(); i++) { + storage->get_effects()->make_mipmap_raster(rb->blur[0].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i].fb, Size2i(rb->blur[0].mipmaps[i].width, rb->blur[0].mipmaps[i].height)); + } + } + + RD::get_singleton()->draw_command_end_label(); +} + +void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data) { + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); + ERR_FAIL_COND(!rb); + + RD::get_singleton()->draw_command_begin_label("Copy depth texture"); + + if (rb->depth_back_texture.is_null()) { + _allocate_depth_backbuffer_textures(rb); + } + + // @TODO IMPLEMENT MULTIVIEW, all effects need to support stereo buffers or effects are only applied to the left eye + + bool can_use_storage = _render_buffers_can_be_storage(); + + if (can_use_storage) { + storage->get_effects()->copy_to_rect(rb->depth_texture, rb->depth_back_texture, Rect2i(0, 0, rb->width, rb->height)); + } else { + storage->get_effects()->copy_to_fb_rect(rb->depth_texture, rb->depth_back_fb, Rect2i(0, 0, rb->width, rb->height)); + } + + RD::get_singleton()->draw_command_end_label(); +} + void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); //glow (if enabled) - CameraEffects *camfx = camera_effects_owner.getornull(p_render_data->camera_effects); + CameraEffects *camfx = camera_effects_owner.get_or_null(p_render_data->camera_effects); bool can_use_effects = rb->width >= 8 && rb->height >= 8; bool can_use_storage = _render_buffers_can_be_storage(); @@ -1851,11 +2075,34 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende _allocate_blur_textures(rb); } + EffectsRD::BokehBuffers buffers; + + // textures we use + buffers.base_texture_size = Size2i(rb->width, rb->height); + buffers.base_texture = rb->texture; + buffers.depth_texture = rb->depth_texture; + buffers.secondary_texture = rb->blur[0].mipmaps[0].texture; + buffers.half_texture[0] = rb->blur[1].mipmaps[0].texture; + buffers.half_texture[1] = rb->blur[0].mipmaps[1].texture; + + float bokeh_size = camfx->dof_blur_amount * 64.0; if (can_use_storage) { - float bokeh_size = camfx->dof_blur_amount * 64.0; - storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); + storage->get_effects()->bokeh_dof(buffers, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); } else { - storage->get_effects()->blur_dof_raster(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->texture_fb, rb->blur[0].mipmaps[0].texture, rb->blur[0].mipmaps[0].fb, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, camfx->dof_blur_amount, dof_blur_quality, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); + // set framebuffers + buffers.base_fb = rb->texture_fb; + buffers.secondary_fb = rb->weight_buffers[1].fb; + buffers.half_fb[0] = rb->weight_buffers[2].fb; + buffers.half_fb[1] = rb->weight_buffers[3].fb; + buffers.weight_texture[0] = rb->weight_buffers[0].weight; + buffers.weight_texture[1] = rb->weight_buffers[1].weight; + buffers.weight_texture[2] = rb->weight_buffers[2].weight; + buffers.weight_texture[3] = rb->weight_buffers[3].weight; + + // set weight buffers + buffers.base_weight_fb = rb->base_weight_fb; + + storage->get_effects()->bokeh_dof_raster(buffers, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); } RD::get_singleton()->draw_command_end_label(); } @@ -1990,6 +2237,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } } + tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier(); tonemap.view_count = p_render_data->view_count; storage->get_effects()->tonemapper(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), tonemap); @@ -2003,10 +2251,10 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data) { RD::get_singleton()->draw_command_begin_label("Post Process Subpass"); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); bool can_use_effects = rb->width >= 8 && rb->height >= 8; @@ -2054,6 +2302,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr tonemap.use_debanding = rb->use_debanding; tonemap.texture_size = Vector2i(rb->width, rb->height); + tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier(); tonemap.view_count = p_render_data->view_count; storage->get_effects()->tonemapper(draw_list, p_source_texture, RD::get_singleton()->framebuffer_get_format(p_framebuffer), tonemap); @@ -2062,7 +2311,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr } void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_data) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); storage->render_target_disable_clear_request(rb->render_target); @@ -2071,7 +2320,7 @@ void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) { EffectsRD *effects = storage->get_effects(); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS) { @@ -2137,7 +2386,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID } void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->adjustments_enabled = p_enable; @@ -2149,7 +2398,7 @@ void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, } RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->blur[0].texture.is_valid()) { return RID(); //not valid at the moment @@ -2157,15 +2406,31 @@ RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_b return rb->blur[0].texture; } +RID RendererSceneRenderRD::render_buffers_get_back_depth_texture(RID p_render_buffers) { + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); + ERR_FAIL_COND_V(!rb, RID()); + if (!rb->depth_back_texture.is_valid()) { + return RID(); //not valid at the moment + } + return rb->depth_back_texture; +} + +RID RendererSceneRenderRD::render_buffers_get_depth_texture(RID p_render_buffers) { + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); + ERR_FAIL_COND_V(!rb, RID()); + + return rb->depth_texture; +} + RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->ssao.ao_final; } RID RendererSceneRenderRD::render_buffers_get_voxel_gi_buffer(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (rb->gi.voxel_gi_buffer.is_null()) { rb->gi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::VoxelGIData) * RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES); @@ -2178,31 +2443,31 @@ RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() { } RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->ambient_buffer; } RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->reflection_buffer; } uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); return rb->sdfgi->cascades.size(); } bool RendererSceneRenderRD::render_buffers_is_sdfgi_enabled(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, false); return rb->sdfgi != nullptr; } RID RendererSceneRenderRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); ERR_FAIL_COND_V(!rb->sdfgi, RID()); @@ -2210,7 +2475,7 @@ RID RendererSceneRenderRD::render_buffers_get_sdfgi_irradiance_probes(RID p_rend } Vector3 RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_buffers, uint32_t p_cascade) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, Vector3()); ERR_FAIL_COND_V(!rb->sdfgi, Vector3()); ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), Vector3()); @@ -2219,7 +2484,7 @@ Vector3 RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_offset(RID p_ren } Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_render_buffers, uint32_t p_cascade) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, Vector3i()); ERR_FAIL_COND_V(!rb->sdfgi, Vector3i()); ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), Vector3i()); @@ -2229,14 +2494,14 @@ Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RI } float RendererSceneRenderRD::render_buffers_get_sdfgi_normal_bias(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); return rb->sdfgi->normal_bias; } float RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_render_buffers, uint32_t p_cascade) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), 0); @@ -2244,7 +2509,7 @@ float RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_r return float(rb->sdfgi->cascade_size) * rb->sdfgi->cascades[p_cascade].cell_size / float(rb->sdfgi->probe_axis_count - 1); } uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); @@ -2252,7 +2517,7 @@ uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_count(RID } uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_size(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); @@ -2260,7 +2525,7 @@ uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_size(RID p_rend } bool RendererSceneRenderRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, false); ERR_FAIL_COND_V(!rb->sdfgi, false); @@ -2268,14 +2533,14 @@ bool RendererSceneRenderRD::render_buffers_is_sdfgi_using_occlusion(RID p_render } float RendererSceneRenderRD::render_buffers_get_sdfgi_energy(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0.0); ERR_FAIL_COND_V(!rb->sdfgi, 0.0); return rb->sdfgi->energy; } RID RendererSceneRenderRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); ERR_FAIL_COND_V(!rb->sdfgi, RID()); @@ -2283,20 +2548,20 @@ RID RendererSceneRenderRD::render_buffers_get_sdfgi_occlusion_texture(RID p_rend } bool RendererSceneRenderRD::render_buffers_has_volumetric_fog(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, false); return rb->volumetric_fog != nullptr; } RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_texture(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, RID()); return rb->volumetric_fog->fog_map; } RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->volumetric_fog) { @@ -2307,16 +2572,20 @@ RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID } float RendererSceneRenderRD::render_buffers_get_volumetric_fog_end(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0); return rb->volumetric_fog->length; } float RendererSceneRenderRD::render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0); return rb->volumetric_fog->spread; } +float RendererSceneRenderRD::_render_buffers_get_luminance_multiplier() { + return 1.0; +} + RD::DataFormat RendererSceneRenderRD::_render_buffers_get_color_format() { return RD::DATA_FORMAT_R16G16B16A16_SFLOAT; } @@ -2328,7 +2597,9 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() { void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) { ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view"); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); + + // Should we add an overrule per viewport? rb->width = p_width; rb->height = p_height; rb->render_target = p_render_target; @@ -2375,8 +2646,8 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p tf.format = RD::DATA_FORMAT_R32_SFLOAT; } - tf.width = p_width; - tf.height = p_height; + tf.width = rb->width; + tf.height = rb->height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; tf.array_layers = rb->view_count; // create a layer for every view @@ -2398,10 +2669,10 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p } RID target_texture = storage->render_target_get_rd_texture(rb->render_target); - rb->data->configure(rb->texture, rb->depth_texture, target_texture, p_width, p_height, p_msaa, p_view_count); + rb->data->configure(rb->texture, rb->depth_texture, target_texture, rb->width, rb->height, p_msaa, p_view_count); if (is_clustered_enabled()) { - rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture); + rb->cluster_builder->setup(Size2i(rb->width, rb->height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture); } } @@ -2530,7 +2801,7 @@ bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const { } RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_get_data(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, nullptr); return rb->data; } @@ -2543,7 +2814,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti break; } - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_reflections[i]); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_reflections[i]); if (!rpi) { continue; } @@ -2629,7 +2900,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const r_directional_light_soft_shadows = false; for (int i = 0; i < (int)p_lights.size(); i++) { - LightInstance *li = light_instance_owner.getornull(p_lights[i]); + LightInstance *li = light_instance_owner.get_or_null(p_lights[i]); if (!li) { continue; } @@ -2777,7 +3048,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; float bias_scale = li->shadow_transform[j].bias_scale; - light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale; + light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale; light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size; light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale; light_data.shadow_z_range[j] = li->shadow_transform[j].farplane; @@ -2858,7 +3129,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const ShadowAtlas *shadow_atlas = nullptr; if (p_shadow_atlas.is_valid() && p_using_shadows) { - shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); } bool using_forward_ids = _uses_forward_ids(); @@ -2947,22 +3218,19 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.shadow_enabled = true; - if (type == RS::LIGHT_SPOT) { - light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0); - float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0; - shadow_texel_size *= light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); - - light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size; + float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0; + if (type == RS::LIGHT_SPOT) { + light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0; } else { //omni - light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0; - float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); - light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space + light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS); } light_data.transmittance_bias = storage->light_get_transmittance_bias(base); - Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas); + Vector2i omni_offset; + Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas, omni_offset); light_data.atlas_rect[0] = rect.position.x; light_data.atlas_rect[1] = rect.position.y; @@ -2973,7 +3241,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base); if (type == RS::LIGHT_OMNI) { - light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another Transform3D proj = (inverse_transform * light_transform).inverse(); RendererStorageRD::store_transform(proj, light_data.shadow_matrix); @@ -2985,6 +3252,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF } + light_data.direction[0] = omni_offset.x * float(rect.size.width); + light_data.direction[1] = omni_offset.y * float(rect.size.height); } else if (type == RS::LIGHT_SPOT) { Transform3D modelview = (inverse_transform * light_transform).inverse(); CameraMatrix bias; @@ -3043,7 +3312,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const break; } - DecalInstance *di = decal_instance_owner.getornull(p_decals[i]); + DecalInstance *di = decal_instance_owner.get_or_null(p_decals[i]); if (!di) { continue; } @@ -3103,7 +3372,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Vector3 decal_extents = storage->decal_get_extents(decal); Transform3D scale_xform; - scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z)); + scale_xform.basis.scale(decal_extents); Transform3D to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse(); RendererStorageRD::store_transform(to_decal_xform, dd.xform); @@ -3226,9 +3495,9 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count) { ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); float ratio = float(rb->width) / float((rb->width + rb->height) / 2); uint32_t target_width = uint32_t(float(volumetric_fog_size) * ratio); @@ -3297,7 +3566,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { @@ -3619,7 +3888,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { if (p_render_data->render_buffers.is_valid()) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); if (rb->sdfgi != nullptr) { return true; } @@ -3630,14 +3899,14 @@ bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_da void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { if (p_render_data->render_buffers.is_valid()) { if (p_use_gi) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { return; } - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); - rb->sdfgi->update_probes(env, sky.sky_owner.getornull(env->sky)); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); + rb->sdfgi->update_probes(env, sky.sky_owner.get_or_null(env->sky)); } } } @@ -3654,7 +3923,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time if (p_render_data->render_buffers.is_valid() && p_use_gi) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi != nullptr) { rb->sdfgi->store_probes(); @@ -3669,7 +3938,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier(); { for (int i = 0; i < render_state.render_shadow_count; i++) { - LightInstance *li = light_instance_owner.getornull(render_state.render_shadows[i].light); + LightInstance *li = light_instance_owner.get_or_null(render_state.render_shadows[i].light); if (storage->light_get_type(li->light) == RS::LIGHT_DIRECTIONAL) { render_state.directional_shadows.push_back(i); @@ -3789,7 +4058,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData // getting this here now so we can direct call a bunch of things more easily RenderBuffers *rb = nullptr; if (p_render_buffers.is_valid()) { - rb = render_buffers_owner.getornull(p_render_buffers); + rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); } @@ -3871,7 +4140,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData //assign render indices to voxel_gi_instances if (is_dynamic_gi_supported()) { for (uint32_t i = 0; i < (uint32_t)p_voxel_gi_instances.size(); i++) { - RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.getornull(p_voxel_gi_instances[i]); + RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]); if (voxel_gi_inst) { voxel_gi_inst->render_index = i; } @@ -3882,8 +4151,8 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData // render_data.render_buffers == p_render_buffers so we can use our already retrieved rb current_cluster_builder = rb->cluster_builder; } else if (reflection_probe_instance_owner.owns(render_data.reflection_probe)) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_data.reflection_probe); - ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(render_data.reflection_probe); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(rpi->atlas); if (!ra) { ERR_PRINT("reflection probe has no reflection atlas! Bug?"); current_cluster_builder = nullptr; @@ -3897,7 +4166,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData render_state.voxel_gi_count = 0; - if (rb != nullptr) { + if (rb != nullptr && is_dynamic_gi_supported()) { if (rb->sdfgi) { rb->sdfgi->update_cascades(); rb->sdfgi->pre_process_gi(render_data.cam_transform, &render_data, this); @@ -3961,7 +4230,7 @@ void RendererSceneRenderRD::_debug_draw_cluster(RID p_render_buffers) { } void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { - LightInstance *light_instance = light_instance_owner.getornull(p_light); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light); ERR_FAIL_COND(!light_instance); Rect2i atlas_rect; @@ -3970,6 +4239,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, bool using_dual_paraboloid = false; bool using_dual_paraboloid_flip = false; + Vector2i dual_paraboloid_offset; RID render_fb; RID render_texture; float zfar; @@ -3995,10 +4265,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, light_projection = light_instance->shadow_transform[p_pass].camera; light_transform = light_instance->shadow_transform[p_pass].transform; - atlas_rect.position.x = light_instance->directional_rect.position.x; - atlas_rect.position.y = light_instance->directional_rect.position.y; - atlas_rect.size.width = light_instance->directional_rect.size.x; - atlas_rect.size.height = light_instance->directional_rect.size.y; + atlas_rect = light_instance->directional_rect; if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { atlas_rect.size.width /= 2; @@ -4009,8 +4276,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } else if (p_pass == 2) { atlas_rect.position.y += atlas_rect.size.height; } else if (p_pass == 3) { - atlas_rect.position.x += atlas_rect.size.width; - atlas_rect.position.y += atlas_rect.size.height; + atlas_rect.position += atlas_rect.size; } } else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { atlas_rect.size.height /= 2; @@ -4035,7 +4301,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } else { //set from shadow atlas - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light)); @@ -4063,6 +4329,9 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) { + bool wrap = (shadow + 1) % shadow_atlas->quadrants[quadrant].subdivision == 0; + dual_paraboloid_offset = wrap ? Vector2i(1 - shadow_atlas->quadrants[quadrant].subdivision, 1) : Vector2i(1, 0); + if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { ShadowCubemap *cubemap = _get_shadow_cubemap(shadow_size / 2); @@ -4082,12 +4351,16 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } } else { + atlas_rect.position.x += 1; + atlas_rect.position.y += 1; + atlas_rect.size.x -= 2; + atlas_rect.size.y -= 2; + + atlas_rect.position += p_pass * atlas_rect.size * dual_paraboloid_offset; + light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; - atlas_rect.size.height /= 2; - atlas_rect.position.y += p_pass * atlas_rect.size.height; - using_dual_paraboloid = true; using_dual_paraboloid_flip = p_pass == 1; render_fb = shadow_atlas->fb; @@ -4112,14 +4385,11 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, _render_shadow_end(); //reblit Rect2 atlas_rect_norm = atlas_rect; - atlas_rect_norm.position.x /= float(atlas_size); - atlas_rect_norm.position.y /= float(atlas_size); - atlas_rect_norm.size.x /= float(atlas_size); - atlas_rect_norm.size.y /= float(atlas_size); - atlas_rect_norm.size.height /= 2; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false); - atlas_rect_norm.position.y += atlas_rect_norm.size.height; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true); + atlas_rect_norm.position /= float(atlas_size); + atlas_rect_norm.size /= float(atlas_size); + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false); + atlas_rect_norm.position += Vector2(dual_paraboloid_offset) * atlas_rect_norm.size; + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true); //restore transform so it can be properly used light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0); @@ -4154,7 +4424,7 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, bool RendererSceneRenderRD::free(RID p_rid) { if (render_buffers_owner.owns(p_rid)) { - RenderBuffers *rb = render_buffers_owner.getornull(p_rid); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_rid); _free_render_buffer_data(rb); memdelete(rb->data); if (rb->sdfgi) { @@ -4177,24 +4447,24 @@ bool RendererSceneRenderRD::free(RID p_rid) { camera_effects_owner.free(p_rid); } else if (reflection_atlas_owner.owns(p_rid)) { reflection_atlas_set_size(p_rid, 0, 0); - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_rid); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_rid); if (ra->cluster_builder) { memdelete(ra->cluster_builder); } reflection_atlas_owner.free(p_rid); } else if (reflection_probe_instance_owner.owns(p_rid)) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_rid); _free_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id); reflection_probe_release_atlas_index(p_rid); reflection_probe_instance_owner.free(p_rid); } else if (decal_instance_owner.owns(p_rid)) { - DecalInstance *di = decal_instance_owner.getornull(p_rid); + DecalInstance *di = decal_instance_owner.get_or_null(p_rid); _free_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id); decal_instance_owner.free(p_rid); } else if (lightmap_instance_owner.owns(p_rid)) { lightmap_instance_owner.free(p_rid); } else if (gi.voxel_gi_instance_owner.owns(p_rid)) { - RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.getornull(p_rid); + RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid); if (voxel_gi->texture.is_valid()) { RD::get_singleton()->free(voxel_gi->texture); RD::get_singleton()->free(voxel_gi->write_buffer); @@ -4210,17 +4480,23 @@ bool RendererSceneRenderRD::free(RID p_rid) { sky.update_dirty_skys(); sky.free_sky(p_rid); } else if (light_instance_owner.owns(p_rid)) { - LightInstance *light_instance = light_instance_owner.getornull(p_rid); + LightInstance *light_instance = light_instance_owner.get_or_null(p_rid); //remove from shadow atlases.. for (Set<RID>::Element *E = light_instance->shadow_atlases.front(); E; E = E->next()) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(E->get()); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E->get()); ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_rid)); uint32_t key = shadow_atlas->shadow_owners[p_rid]; uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK; shadow_atlas->quadrants[q].shadows.write[s].owner = RID(); + + if (key & ShadowAtlas::OMNI_LIGHT_FLAG) { + // Omni lights use two atlas spots, make sure to clear the other as well + shadow_atlas->quadrants[q].shadows.write[s + 1].owner = RID(); + } + shadow_atlas->shadow_owners.erase(p_rid); } @@ -4418,10 +4694,12 @@ uint32_t RendererSceneRenderRD::get_max_elements() const { } RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { - max_cluster_elements = get_max_elements(); - storage = p_storage; singleton = this; +} + +void RendererSceneRenderRD::init() { + max_cluster_elements = get_max_elements(); directional_shadow.size = GLOBAL_GET("rendering/shadows/directional_shadow/size"); directional_shadow.use_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits"); @@ -4523,8 +4801,8 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { } RendererSceneRenderRD::~RendererSceneRenderRD() { - for (Map<int, ShadowCubemap>::Element *E = shadow_cubemaps.front(); E; E = E->next()) { - RD::get_singleton()->free(E->get().cubemap); + for (const KeyValue<int, ShadowCubemap> &E : shadow_cubemaps) { + RD::get_singleton()->free(E.value.cubemap); } if (sky.sky_scene_state.uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky.sky_scene_state.uniform_set)) { |
