diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index e6989132006..6aa6f4d7ef6 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -210,7 +210,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } -void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) { +void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier, float p_brightness_multiplier) { SkyPushConstant sky_push_constant; memset(&sky_push_constant, 0, sizeof(SkyPushConstant)); @@ -226,6 +226,7 @@ void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineC sky_push_constant.position[2] = p_position.z; sky_push_constant.time = p_time; sky_push_constant.luminance_multiplier = p_luminance_multiplier; + sky_push_constant.brightness_multiplier = p_brightness_multiplier; store_transform_3x3(p_orientation, sky_push_constant.orientation); RenderingDevice::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_fb); @@ -1224,7 +1225,7 @@ void SkyRD::setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_s RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } -void SkyRD::update_radiance_buffers(Ref p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier) { +void SkyRD::update_radiance_buffers(Ref p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier, float p_brightness_multiplier) { ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -1318,7 +1319,7 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i]); - _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier, p_brightness_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); @@ -1339,7 +1340,7 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd, p_render_buffers); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i]); - _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier, p_brightness_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); @@ -1356,7 +1357,7 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd, p_render_buffers); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::DRAW_DEFAULT_ALL, Vector(), 1.0f, 0, Rect2(), RDD::BreadcrumbMarker::SKY_PASS | uint32_t(i)); - _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier, p_brightness_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); @@ -1398,7 +1399,7 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, } } -void SkyRD::update_res_buffers(Ref p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier) { +void SkyRD::update_res_buffers(Ref p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier, float p_brightness_multiplier) { ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -1480,7 +1481,7 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p clear_colors.push_back(Color(0.0, 0.0, 0.0)); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::DRAW_CLEAR_ALL, clear_colors); - _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier); + _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier, p_brightness_multiplier); RD::get_singleton()->draw_list_end(); } @@ -1499,14 +1500,14 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p clear_colors.push_back(Color(0.0, 0.0, 0.0)); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::DRAW_CLEAR_ALL, clear_colors); - _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier); + _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier, p_brightness_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers } -void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier) { +void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier, float p_brightness_multiplier) { ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -1575,7 +1576,7 @@ void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref p_ren texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set; } - _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier); + _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier, p_brightness_multiplier); } void SkyRD::invalidate_sky(Sky *p_sky) { diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index cc753efa01c..ab6c5c7d64b 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -101,8 +101,9 @@ private: float projection[4]; // 16 - 64 float position[3]; // 12 - 76 float time; // 4 - 80 - float pad[3]; // 12 - 92 - float luminance_multiplier; // 4 - 96 + float pad[2]; // 8 - 88 + float luminance_multiplier; // 4 - 92 + float brightness_multiplier; // 4 - 96 // 128 is the max size of a push constant. We can replace "pad" but we can't add any more. }; @@ -133,7 +134,7 @@ private: virtual ~SkyShaderData(); }; - void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier); + void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier, float p_brightness_modifier); public: struct SkySceneState { @@ -296,9 +297,9 @@ public: ~SkyRD(); void setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_size); - void update_radiance_buffers(Ref p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier = 1.0); - void update_res_buffers(Ref p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier = 1.0); - void draw_sky(RD::DrawListID p_draw_list, Ref p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier = 1.0); + void update_radiance_buffers(Ref p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier = 1.0, float p_brightness_multiplier = 1.0); + void update_res_buffers(Ref p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier = 1.0, float p_brightness_multiplier = 1.0); + void draw_sky(RD::DrawListID p_draw_list, Ref p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier = 1.0, float p_brightness_multiplier = 1.0); void invalidate_sky(Sky *p_sky); void update_dirty_skys(); 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 1a48e462054..40975610a7c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1894,7 +1894,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co 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(); + float sky_luminance_multiplier = 1.0 / _render_buffers_get_luminance_multiplier(); + float sky_brightness_multiplier = 1.0; Color clear_color; bool load_color = false; @@ -1960,11 +1961,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co // Setup our sky render information for this frame/viewport sky.setup_sky(p_render_data, screen_size); - sky_energy_multiplier *= bg_energy_multiplier; + sky_brightness_multiplier *= bg_energy_multiplier; RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_energy_multiplier); + sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_luminance_multiplier, sky_brightness_multiplier); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -1973,7 +1974,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (draw_sky || draw_sky_fog_only) { // update sky half/quarter res buffers (if required) - sky.update_res_buffers(rb, p_render_data->environment, time, sky_energy_multiplier); + sky.update_res_buffers(rb, p_render_data->environment, time, sky_luminance_multiplier, sky_brightness_multiplier); } RD::get_singleton()->draw_command_end_label(); @@ -2174,7 +2175,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Draw Sky"); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer); - sky.draw_sky(draw_list, rb, p_render_data->environment, color_only_framebuffer, time, sky_energy_multiplier); + sky.draw_sky(draw_list, rb, p_render_data->environment, color_only_framebuffer, time, sky_luminance_multiplier, sky_brightness_multiplier); RD::get_singleton()->draw_list_end(); RD::get_singleton()->draw_command_end_label(); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 41027ea7773..57b7b11ec5c 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -920,7 +920,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color bool draw_sky_fog_only = false; // We invert luminance_multiplier for sky so that we can combine it with exposure value. float inverse_luminance_multiplier = 1.0 / _render_buffers_get_luminance_multiplier(); - float sky_energy_multiplier = inverse_luminance_multiplier; + float sky_luminance_multiplier = inverse_luminance_multiplier; + float sky_brightness_multiplier = 1.0; Color clear_color = p_default_bg_color; bool load_color = false; @@ -988,11 +989,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color sky.setup_sky(p_render_data, screen_size); - sky_energy_multiplier *= bg_energy_multiplier; + sky_brightness_multiplier *= bg_energy_multiplier; RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_energy_multiplier); + sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_luminance_multiplier, sky_brightness_multiplier); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -1001,7 +1002,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (draw_sky || draw_sky_fog_only) { // update sky half/quarter res buffers (if required) - sky.update_res_buffers(rb, p_render_data->environment, time, sky_energy_multiplier); + sky.update_res_buffers(rb, p_render_data->environment, time, sky_luminance_multiplier, sky_brightness_multiplier); } RD::get_singleton()->draw_command_end_label(); // Setup Sky } @@ -1118,7 +1119,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color // Note, sky.setup should have been called up above and setup stuff we need. - sky.draw_sky(draw_list, rb, p_render_data->environment, framebuffer, time, sky_energy_multiplier); + sky.draw_sky(draw_list, rb, p_render_data->environment, framebuffer, time, sky_luminance_multiplier, sky_brightness_multiplier); RD::get_singleton()->draw_command_end_label(); // Draw Sky } diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index 7bb2e0a539d..105a42d7083 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -17,8 +17,9 @@ layout(push_constant, std430) uniform Params { vec4 projection; // only applicable if not multiview vec3 position; float time; - vec3 pad; + vec2 pad; float luminance_multiplier; + float brightness_multiplier; } params; @@ -57,8 +58,9 @@ layout(push_constant, std430) uniform Params { vec4 projection; // only applicable if not multiview vec3 position; float time; - vec3 pad; + vec2 pad; float luminance_multiplier; + float brightness_multiplier; } params; @@ -255,6 +257,9 @@ void main() { frag_color.rgb = color; frag_color.a = alpha; + // Apply environment 'brightness' setting separately before fog to ensure consistent luminance. + frag_color.rgb = frag_color.rgb * params.brightness_multiplier; + #if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS) // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.