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 e93b7f0339d..e2d6796566b 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -1005,13 +1005,20 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color { base_specialization.use_directional_soft_shadows = p_render_data->directional_light_count > 0 ? p_render_data->directional_light_soft_shadows : false; base_specialization.directional_lights = p_render_data->directional_light_count; + base_specialization.directional_light_blend_splits = light_storage->get_directional_light_blend_splits(p_render_data->directional_light_count); if (!is_environment(p_render_data->environment) || !environment_get_fog_enabled(p_render_data->environment)) { base_specialization.disable_fog = true; - } - - if (p_render_data->environment.is_valid() && environment_get_fog_mode(p_render_data->environment) == RS::EnvironmentFogMode::ENV_FOG_MODE_DEPTH) { - base_specialization.use_depth_fog = true; + base_specialization.use_fog_aerial_perspective = false; + base_specialization.use_fog_sun_scatter = false; + base_specialization.use_fog_height_density = false; + base_specialization.use_depth_fog = false; + } else { + base_specialization.disable_fog = false; + base_specialization.use_fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment) > 0.0; + base_specialization.use_fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment) > 0.001; + base_specialization.use_fog_height_density = abs(environment_get_fog_height_density(p_render_data->environment)) >= 0.0001; + base_specialization.use_depth_fog = p_render_data->environment.is_valid() && environment_get_fog_mode(p_render_data->environment) == RS::EnvironmentFogMode::ENV_FOG_MODE_DEPTH; } base_specialization.scene_use_ambient_cubemap = use_ambient_cubemap; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 4525b50b6e5..6274dd76440 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -238,6 +238,7 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli "SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0, "SPEC PACKED #1:", p_pipeline_key.shader_specialization.packed_1, "SPEC PACKED #2:", p_pipeline_key.shader_specialization.packed_2, + "SPEC PACKED #3:", p_pipeline_key.shader_specialization.packed_3, "RENDER PASS:", p_pipeline_key.render_pass, "WIREFRAME:", p_pipeline_key.wireframe); #endif @@ -328,7 +329,12 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli specialization_constants.push_back(sc); sc.constant_id = 2; - sc.float_value = p_pipeline_key.shader_specialization.packed_2; + sc.int_value = p_pipeline_key.shader_specialization.packed_2; + sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT; + specialization_constants.push_back(sc); + + sc.constant_id = 3; + sc.float_value = p_pipeline_key.shader_specialization.packed_3; sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT; specialization_constants.push_back(sc); diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index e2549d1f006..a40c5446c74 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -67,6 +67,9 @@ public: uint32_t projector_use_mipmaps : 1; uint32_t disable_fog : 1; uint32_t use_depth_fog : 1; + uint32_t use_fog_aerial_perspective : 1; + uint32_t use_fog_sun_scatter : 1; + uint32_t use_fog_height_density : 1; uint32_t use_lightmap_bicubic_filter : 1; uint32_t multimesh : 1; uint32_t multimesh_format_2d : 1; @@ -75,7 +78,7 @@ public: uint32_t scene_use_ambient_cubemap : 1; uint32_t scene_use_reflection_cubemap : 1; uint32_t scene_roughness_limiter_enabled : 1; - uint32_t padding : 5; + uint32_t padding_0 : 2; uint32_t soft_shadow_samples : 6; uint32_t penumbra_shadow_samples : 6; }; @@ -97,9 +100,18 @@ public: uint32_t packed_1; }; + union { + struct { + uint32_t directional_light_blend_splits : 8; + uint32_t padding_1 : 24; + }; + + uint32_t packed_2; + }; + union { float luminance_multiplier; - float packed_2; + float packed_3; }; }; @@ -111,6 +123,10 @@ public: uint32_t packed_0; }; + + uint32_t padding_1; + uint32_t padding_2; + uint32_t padding_3; }; struct ShaderData : public RendererRD::MaterialStorage::ShaderData { diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 0cb34557ea8..f72b576f28f 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -768,7 +768,7 @@ layout(location = 0) out mediump vec4 frag_color; vec4 fog_process(vec3 vertex) { vec3 fog_color = scene_data_block.data.fog_light_color; - if (scene_data_block.data.fog_aerial_perspective > 0.0) { + if (sc_use_fog_aerial_perspective()) { vec3 sky_fog_color = vec3(0.0); vec3 cube_view = scene_data_block.data.radiance_inverse_xform * vertex; // mip_level always reads from the second mipmap and higher so the fog is always slightly blurred @@ -784,7 +784,7 @@ vec4 fog_process(vec3 vertex) { fog_color = mix(fog_color, sky_fog_color, scene_data_block.data.fog_aerial_perspective); } - if (scene_data_block.data.fog_sun_scatter > 0.001) { + if (sc_use_fog_sun_scatter()) { vec4 sun_scatter = vec4(0.0); float sun_total = 0.0; vec3 view = normalize(vertex); @@ -806,7 +806,7 @@ vec4 fog_process(vec3 vertex) { fog_amount = 1 - exp(min(0.0, -length(vertex) * scene_data_block.data.fog_density)); } - if (abs(scene_data_block.data.fog_height_density) >= 0.0001) { + if (sc_use_fog_height_density()) { float y = (scene_data_block.data.inv_view_matrix * vec4(vertex, 1.0)).y; float y_dist = y - scene_data_block.data.fog_height; @@ -1497,9 +1497,11 @@ void main() { pssm_coord /= pssm_coord.w; - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor + (1.0 - blur_factor) * float(directional_lights.data[i].blend_splits)), pssm_coord, scene_data.taa_frame_count); + bool blend_split = sc_directional_light_blend_split(i); + float blend_split_weight = blend_split ? 1.0f : 0.0f; + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor + (1.0 - blur_factor) * blend_split_weight), pssm_coord, scene_data.taa_frame_count); - if (directional_lights.data[i].blend_splits) { + if (blend_split) { float pssm_blend; float blur_factor2; @@ -1531,7 +1533,7 @@ void main() { pssm_coord /= pssm_coord.w; - float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor2 + (1.0 - blur_factor2) * float(directional_lights.data[i].blend_splits)), pssm_coord, scene_data.taa_frame_count); + float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale * (blur_factor2 + (1.0 - blur_factor2) * blend_split_weight), pssm_coord, scene_data.taa_frame_count); shadow = mix(shadow, shadow2, pssm_blend); } diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl index 2cc86482f6f..5e4719c4988 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl @@ -23,8 +23,12 @@ layout(push_constant, std430) uniform DrawCall { #ifdef UBERSHADER uint sc_packed_0; uint sc_packed_1; - float sc_packed_2; + uint sc_packed_2; + float sc_packed_3; uint uc_packed_0; + uint uc_padding_1; + uint uc_padding_2; + uint uc_padding_3; #endif } draw_call; @@ -46,10 +50,14 @@ uint sc_packed_1() { return draw_call.sc_packed_1; } -float sc_packed_2() { +uint sc_packed_2() { return draw_call.sc_packed_2; } +float sc_packed_3() { + return draw_call.sc_packed_3; +} + uint uc_cull_mode() { return (draw_call.uc_packed_0 >> 0) & 3U; } @@ -59,7 +67,8 @@ uint uc_cull_mode() { // Pull the constants from the pipeline's specialization constants. layout(constant_id = 0) const uint pso_sc_packed_0 = 0; layout(constant_id = 1) const uint pso_sc_packed_1 = 0; -layout(constant_id = 2) const float pso_sc_packed_2 = 2.0; +layout(constant_id = 2) const uint pso_sc_packed_2 = 0; +layout(constant_id = 3) const float pso_sc_packed_3 = 2.0; uint sc_packed_0() { return pso_sc_packed_0; @@ -69,10 +78,14 @@ uint sc_packed_1() { return pso_sc_packed_1; } -float sc_packed_2() { +uint sc_packed_2() { return pso_sc_packed_2; } +float sc_packed_3() { + return pso_sc_packed_3; +} + #endif bool sc_use_light_projector() { @@ -103,38 +116,50 @@ bool sc_use_depth_fog() { return ((sc_packed_0() >> 6) & 1U) != 0; } -bool sc_use_lightmap_bicubic_filter() { +bool sc_use_fog_aerial_perspective() { return ((sc_packed_0() >> 7) & 1U) != 0; } -bool sc_multimesh() { +bool sc_use_fog_sun_scatter() { return ((sc_packed_0() >> 8) & 1U) != 0; } -bool sc_multimesh_format_2d() { +bool sc_use_fog_height_density() { return ((sc_packed_0() >> 9) & 1U) != 0; } -bool sc_multimesh_has_color() { +bool sc_use_lightmap_bicubic_filter() { return ((sc_packed_0() >> 10) & 1U) != 0; } -bool sc_multimesh_has_custom_data() { +bool sc_multimesh() { return ((sc_packed_0() >> 11) & 1U) != 0; } -bool sc_scene_use_ambient_cubemap() { +bool sc_multimesh_format_2d() { return ((sc_packed_0() >> 12) & 1U) != 0; } -bool sc_scene_use_reflection_cubemap() { +bool sc_multimesh_has_color() { return ((sc_packed_0() >> 13) & 1U) != 0; } -bool sc_scene_roughness_limiter_enabled() { +bool sc_multimesh_has_custom_data() { return ((sc_packed_0() >> 14) & 1U) != 0; } +bool sc_scene_use_ambient_cubemap() { + return ((sc_packed_0() >> 15) & 1U) != 0; +} + +bool sc_scene_use_reflection_cubemap() { + return ((sc_packed_0() >> 16) & 1U) != 0; +} + +bool sc_scene_roughness_limiter_enabled() { + return ((sc_packed_0() >> 17) & 1U) != 0; +} + uint sc_soft_shadow_samples() { return (sc_packed_0() >> 20) & 63U; } @@ -171,8 +196,12 @@ uint sc_decals() { return (sc_packed_1() >> 28) & 15U; } +bool sc_directional_light_blend_split(uint i) { + return ((sc_packed_2() >> i) & 1U) != 0; +} + float sc_luminance_multiplier() { - return sc_packed_2(); + return sc_packed_3(); } /* Set 0: Base Pass (never changes) */ diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 1a92c5470dc..b5f1523123d 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -799,6 +799,16 @@ public: RID get_spot_light_buffer() { return spot_light_buffer; } RID get_directional_light_buffer() { return directional_light_buffer; } uint32_t get_max_directional_lights() { return max_directional_lights; } + uint32_t get_directional_light_blend_splits(uint32_t p_directional_light_count) const { + uint32_t blend_splits = 0; + for (uint32_t i = 0; i < p_directional_light_count; i++) { + if (directional_lights[i].blend_splits) { + blend_splits |= 1U << i; + } + } + + return blend_splits; + } bool has_directional_shadows(const uint32_t p_directional_light_count) { for (uint32_t i = 0; i < p_directional_light_count; i++) { if (directional_lights[i].shadow_opacity > 0.001) {