Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add specialization for directional light split blend and fog to mobile renderer. #99978

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ class SceneShaderForwardMobile {
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;
Expand All @@ -75,7 +78,7 @@ class SceneShaderForwardMobile {
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;
};
Expand All @@ -97,9 +100,18 @@ class SceneShaderForwardMobile {
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;
};
};

Expand All @@ -111,6 +123,10 @@ class SceneShaderForwardMobile {

uint32_t packed_0;
};

uint32_t padding_1;
uint32_t padding_2;
uint32_t padding_3;
};

struct ShaderData : public RendererRD::MaterialStorage::ShaderData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -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() {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) */
Expand Down
10 changes: 10 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/light_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,16 @@ class LightStorage : public RendererLightStorage {
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) {
Expand Down
Loading