Merge pull request #46694 from JFonS/fix_directional_disabling

[3.2] Various light culling fixes
This commit is contained in:
Rémi Verschelde 2021-03-08 16:17:43 +01:00 committed by GitHub
commit 0e0d73c011
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 14 deletions

View file

@ -2317,8 +2317,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
if (!unshaded && e->light_index < RenderList::MAX_LIGHTS) {
light = render_light_instances[e->light_index];
if (e->instance->baked_light && light->light_ptr->bake_mode == VS::LIGHT_BAKE_ALL) {
light = NULL; // Don't use this light, it is already included in the lightmap
if ((e->instance->baked_light && light->light_ptr->bake_mode == VS::LIGHT_BAKE_ALL) || (e->instance->layer_mask & light->light_ptr->cull_mask) == 0) {
light = NULL; // Don't use this light, it is culled or already included in the lightmap
}
}

View file

@ -2038,7 +2038,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
int current_blend_mode = -1;
int prev_shading = -1;
uint32_t prev_shading = 0xFFFFFFFF;
RasterizerStorageGLES3::Skeleton *prev_skeleton = NULL;
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, true); //by default unshaded (easier to set)
@ -2060,16 +2060,20 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
bool rebind = first;
int shading = (e->sort_key >> RenderList::SORT_KEY_SHADING_SHIFT) & RenderList::SORT_KEY_SHADING_MASK;
uint32_t shading = (e->sort_key >> RenderList::SORT_KEY_SHADING_SHIFT) & RenderList::SORT_KEY_SHADING_MASK;
if (!p_shadow) {
bool use_directional = directional_light != NULL;
if (p_directional_add) {
if (e->sort_key & SORT_KEY_UNSHADED_FLAG || !(e->instance->layer_mask & directional_light->light_ptr->cull_mask)) {
continue;
use_directional = use_directional && !(e->instance->baked_light && directional_light->light_ptr->bake_mode == VS::LightBakeMode::LIGHT_BAKE_ALL);
use_directional = use_directional && ((e->instance->layer_mask & directional_light->light_ptr->cull_mask) != 0);
use_directional = use_directional && ((e->sort_key & SORT_KEY_UNSHADED_FLAG) == 0);
if (!use_directional) {
continue; // It's a directional-only pass and the directional light is disabled
}
shading &= ~1; //ignore the ignore directional for base pass
} else {
use_directional = use_directional && (e->sort_key & SORT_KEY_NO_DIRECTIONAL_FLAG) == 0;
}
if (shading != prev_shading) {
@ -2107,7 +2111,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING, !p_directional_add);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, (e->sort_key & SORT_KEY_VERTEX_LIT_FLAG));
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, false);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, use_directional);
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW, false);
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4, false);
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2, false);
@ -2117,9 +2121,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, use_radiance_map);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, state.used_contact_shadows);
if (p_directional_add || (directional_light && (e->sort_key & SORT_KEY_NO_DIRECTIONAL_FLAG) == 0)) {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, true);
if (use_directional) {
if (p_directional_shadows && directional_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW, true);
@ -2382,8 +2384,12 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
e->geometry->index = current_geometry_index++;
}
if (!p_depth_pass && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) {
e->sort_key |= SORT_KEY_NO_DIRECTIONAL_FLAG;
// We sort only by the first directional light. The rest of directional lights will be drawn in additive passes that are skipped if disabled.
if (first_directional_light.is_valid() && light_instance_owner.owns(first_directional_light)) {
RasterizerStorageGLES3::Light *directional = light_instance_owner.getptr(first_directional_light)->light_ptr;
if ((e->instance->layer_mask & directional->cull_mask) == 0 || (e->instance->baked_light && directional->bake_mode == VS::LightBakeMode::LIGHT_BAKE_ALL)) {
e->sort_key |= SORT_KEY_NO_DIRECTIONAL_FLAG;
}
}
e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT;
@ -2806,6 +2812,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
state.directional_light_count = 0;
directional_light = NULL;
first_directional_light = RID();
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
@ -2821,6 +2828,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
case VS::LIGHT_DIRECTIONAL: {
if (state.directional_light_count == 0) {
first_directional_light = p_light_cull_result[i];
}
if (state.directional_light_count < RenderList::MAX_DIRECTIONAL_LIGHTS) {
directional_lights[state.directional_light_count++] = li;
}

View file

@ -831,6 +831,7 @@ public:
LightInstance *directional_light;
LightInstance *directional_lights[RenderList::MAX_DIRECTIONAL_LIGHTS];
RID first_directional_light;
RenderList render_list;