1
0
Fork 0

Add specialization for directional light split blend and fog.

This commit is contained in:
Dario 2024-12-03 12:59:56 -03:00
parent 0f20e67d8d
commit fa7615be9e
6 changed files with 96 additions and 26 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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 {

View File

@ -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);
}

View File

@ -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) */

View File

@ -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) {