diff options
Diffstat (limited to 'servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp')
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp index 72000e824a..1c035d5d55 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp @@ -898,6 +898,8 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { return; } + directional_shadow.size = p_size; + if (directional_shadow.depth.is_valid()) { RD::get_singleton()->free(directional_shadow.depth); directional_shadow.depth = RID(); @@ -925,17 +927,34 @@ void RasterizerSceneRD::set_directional_shadow_count(int p_count) { directional_shadow.current_light = 0; } +static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p_shadow_index) { + + int split_h = 1; + int split_v = 1; + + while (split_h * split_v < p_shadow_count) { + if (split_h == split_v) { + split_h <<= 1; + } else { + split_v <<= 1; + } + } + + Rect2i rect(0, 0, p_size, p_size); + rect.size.width /= split_h; + rect.size.height /= split_v; + + rect.position.x = rect.size.width * (p_shadow_index % split_h); + rect.position.y = rect.size.height * (p_shadow_index / split_h); + + return rect; +} + int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0); - int shadow_size; - - if (directional_shadow.light_count == 1) { - shadow_size = directional_shadow.size; - } else { - shadow_size = directional_shadow.size / 2; //more than 4 not supported anyway - } + Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0); LightInstance *light_instance = light_instance_owner.getornull(p_light_intance); ERR_FAIL_COND_V(!light_instance, 0); @@ -943,11 +962,11 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { switch (storage->light_directional_get_shadow_mode(light_instance->light)) { case VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: break; //none - case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: - case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: shadow_size /= 2; break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: r.size.height /= 2; break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: r.size /= 2; break; } - return shadow_size; + return MAX(r.size.width, r.size.height); } ////////////////////////////////////////////////// @@ -1112,27 +1131,9 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas if (storage->light_get_type(light_instance->light) == VS::LIGHT_DIRECTIONAL) { //set pssm stuff if (light_instance->last_scene_shadow_pass != scene_pass) { - //assign rect if unassigned - light_instance->light_directional_index = directional_shadow.current_light; - light_instance->last_scene_shadow_pass = scene_pass; + light_instance->directional_rect = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light); directional_shadow.current_light++; - - if (directional_shadow.light_count == 1) { - light_instance->directional_rect = Rect2(0, 0, directional_shadow.size, directional_shadow.size); - } else if (directional_shadow.light_count == 2) { - light_instance->directional_rect = Rect2(0, 0, directional_shadow.size, directional_shadow.size / 2); - if (light_instance->light_directional_index == 1) { - light_instance->directional_rect.position.x += light_instance->directional_rect.size.x; - } - } else { //3 and 4 - light_instance->directional_rect = Rect2(0, 0, directional_shadow.size / 2, directional_shadow.size / 2); - if (light_instance->light_directional_index & 1) { - light_instance->directional_rect.position.x += light_instance->directional_rect.size.x; - } - if (light_instance->light_directional_index / 2) { - light_instance->directional_rect.position.y += light_instance->directional_rect.size.y; - } - } + light_instance->last_scene_shadow_pass = scene_pass; } light_projection = light_instance->shadow_transform[p_pass].camera; @@ -1168,6 +1169,11 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } } + light_instance->shadow_transform[p_pass].atlas_rect = atlas_rect; + + light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size; + light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size; + float bias_mult = Math::lerp(1.0f, light_instance->shadow_transform[p_pass].bias_scale, storage->light_get_param(light_instance->light, VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE)); zfar = storage->light_get_param(light_instance->light, VS::LIGHT_PARAM_RANGE); bias = storage->light_get_param(light_instance->light, VS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult; |