diff options
Diffstat (limited to 'servers/rendering/renderer_rd/forward_clustered')
-rw-r--r-- | servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp | 82 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h | 11 |
2 files changed, 69 insertions, 24 deletions
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 8754e90647..8421598275 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -906,8 +906,9 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - float bg_energy = environment_get_bg_energy(p_render_data->environment); - scene_state.ubo.ambient_light_color_energy[3] = bg_energy; + float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment); + + scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier; scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); @@ -916,9 +917,9 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); color = color.srgb_to_linear(); - scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; - scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy; - scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy; + scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; + scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; + scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { @@ -987,6 +988,25 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.ss_effects_flags = 0; } + if (p_render_data->camera_attributes.is_valid()) { + scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + scene_state.ubo.IBL_exposure_normalization = 1.0; + if (is_environment(p_render_data->environment)) { + RID sky_rid = environment_get_sky(p_render_data->environment); + if (sky_rid.is_valid()) { + float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment) / _render_buffers_get_luminance_multiplier(); + scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky.sky_get_baked_exposure(sky_rid)); + } + } + } else if (scene_state.ubo.emissive_exposure_normalization > 0.0) { + // This branch is triggered when using render_material(). + // Emissive is set outside the function, so don't set it. + // IBL isn't used don't set it. + } else { + scene_state.ubo.emissive_exposure_normalization = 1.0; + scene_state.ubo.IBL_exposure_normalization = 1.0; + } + scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active(); scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount(); scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit(); @@ -1383,7 +1403,7 @@ void RenderForwardClustered::_setup_voxelgis(const PagedArray<RID> &p_voxelgis) } } -void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) { +void RenderForwardClustered::_setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) { scene_state.lightmaps_used = 0; for (int i = 0; i < (int)p_lightmaps.size(); i++) { if (i >= (int)scene_state.max_lightmaps) { @@ -1395,6 +1415,13 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis; to_lm = to_lm.inverse().transposed(); //will transform normals RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); + scene_state.lightmaps[i].exposure_normalization = 1.0; + if (p_render_data->camera_attributes.is_valid()) { + float baked_exposure = RendererRD::LightStorage::get_singleton()->lightmap_get_baked_exposure_normalization(lightmap); + float enf = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + scene_state.lightmaps[i].exposure_normalization = enf / baked_exposure; + } + scene_state.lightmap_ids[i] = p_lightmaps[i]; scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap); @@ -1513,9 +1540,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co scene_state.ubo.viewport_size[0] = screen_size.x; scene_state.ubo.viewport_size[1] = screen_size.y; + scene_state.ubo.emissive_exposure_normalization = -1.0; + RD::get_singleton()->draw_command_begin_label("Render Setup"); - _setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform); + _setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->cam_transform); _setup_voxelgis(*p_render_data->voxel_gi_instances); _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); @@ -1539,6 +1568,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RID radiance_texture; bool draw_sky = false; bool draw_sky_fog_only = false; + // We invert luminance_multiplier for sky so that we can combine it with exposure value. + float sky_energy_multiplier = 1.0 / _render_buffers_get_luminance_multiplier(); Color clear_color; bool keep_color = false; @@ -1547,13 +1578,19 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black } else if (is_environment(p_render_data->environment)) { RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment); - float bg_energy = environment_get_bg_energy(p_render_data->environment); + float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment); + bg_energy_multiplier *= environment_get_bg_intensity(p_render_data->environment); + + if (p_render_data->camera_attributes.is_valid()) { + bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } + switch (bg_mode) { case RS::ENV_BG_CLEAR_COLOR: { clear_color = p_default_bg_color; - clear_color.r *= bg_energy; - clear_color.g *= bg_energy; - clear_color.b *= bg_energy; + clear_color.r *= bg_energy_multiplier; + clear_color.g *= bg_energy_multiplier; + clear_color.b *= bg_energy_multiplier; if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); @@ -1561,9 +1598,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } break; case RS::ENV_BG_COLOR: { clear_color = environment_get_bg_color(p_render_data->environment); - clear_color.r *= bg_energy; - clear_color.g *= bg_energy; - clear_color.b *= bg_energy; + clear_color.r *= bg_energy_multiplier; + clear_color.g *= bg_energy_multiplier; + clear_color.b *= bg_energy_multiplier; if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); @@ -1594,11 +1631,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co projection = correction * p_render_data->cam_projection; } - sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->cam_transform, screen_size, this); + + sky_energy_multiplier *= bg_energy_multiplier; RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time); + sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time, sky_energy_multiplier); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -1753,9 +1792,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co Projection correction; correction.set_depth_correction(true); Projection projection = correction * p_render_data->cam_projection; - sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time); + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier); } else { - sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier); } RD::get_singleton()->draw_command_end_label(); } @@ -2000,7 +2039,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -2018,6 +2057,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = false; scene_state.ubo.opaque_prepass_threshold = 0.0f; + scene_state.ubo.emissive_exposure_normalization = p_exposure_normalization; _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); @@ -2064,6 +2104,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = true; scene_state.ubo.opaque_prepass_threshold = 0.0; + scene_state.ubo.emissive_exposure_normalization = -1.0; _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); @@ -2119,7 +2160,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { +void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) { RENDER_TIMESTAMP("Render SDFGI"); RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel"); @@ -2187,6 +2228,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i RendererRD::MaterialStorage::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds); + scene_state.ubo.emissive_exposure_normalization = p_exposure_normalization; _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); 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 7e71406af8..3d74f6769e 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -218,6 +218,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { struct LightmapData { float normal_xform[12]; + float pad[3]; + float exposure_normalization; }; struct LightmapCaptureData { @@ -324,7 +326,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { uint32_t pancake_shadows; float taa_jitter[2]; - uint32_t pad[2]; + float emissive_exposure_normalization; // Needed to normalize emissive when using physical units. + float IBL_exposure_normalization; }; struct PushConstant { @@ -397,7 +400,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); void _setup_voxelgis(const PagedArray<RID> &p_voxelgis); - void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform); + void _setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform); struct RenderElementInfo { enum { MAX_REPEATS = (1 << 20) - 1 }; @@ -618,9 +621,9 @@ protected: virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) override; virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) override; virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override; public: |