Various light culling fixes
GLES3 changes: This commit makes it possible to disable 3D directional lights by using the light's cull mask. It also automatically disables directionals when the object has baked lighting and the light is set to "bake all". GLES2 changes: Added a check for the light cull mask, since it was previously ignored.
This commit is contained in:
parent
f2ad10f957
commit
f24f582ba5
3 changed files with 26 additions and 14 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -831,6 +831,7 @@ public:
|
|||
|
||||
LightInstance *directional_light;
|
||||
LightInstance *directional_lights[RenderList::MAX_DIRECTIONAL_LIGHTS];
|
||||
RID first_directional_light;
|
||||
|
||||
RenderList render_list;
|
||||
|
||||
|
|
Loading…
Reference in a new issue