Skip to content

Commit

Permalink
Merge pull request #46694 from JFonS/fix_directional_disabling
Browse files Browse the repository at this point in the history
[3.2] Various light culling fixes
  • Loading branch information
akien-mga authored Mar 8, 2021
2 parents 118567c + f24f582 commit 0e0d73c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
4 changes: 2 additions & 2 deletions drivers/gles2/rasterizer_scene_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
35 changes: 23 additions & 12 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);

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

Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gles3/rasterizer_scene_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ class RasterizerSceneGLES3 : public RasterizerScene {

LightInstance *directional_light;
LightInstance *directional_lights[RenderList::MAX_DIRECTIONAL_LIGHTS];
RID first_directional_light;

RenderList render_list;

Expand Down

0 comments on commit 0e0d73c

Please sign in to comment.