From fcb00ca0481fdbaddeb8186e399975efc67f49bb Mon Sep 17 00:00:00 2001 From: JFonS Date: Sun, 30 Aug 2020 20:16:24 +0200 Subject: [PATCH] Disable lights for objects with baked lighting Don't apply lighting to objects when they have a lightmap texture and the light is set to BAKE_ALL. This prevents applying the same direct light twice on the same object and makes setting up scenes with mixed lighting much easier. --- doc/classes/VisualServer.xml | 19 ++++++++++++++++++- drivers/dummy/rasterizer_dummy.h | 2 ++ drivers/gles2/rasterizer_scene_gles2.cpp | 3 +++ drivers/gles2/rasterizer_storage_gles2.cpp | 17 +++++++++++++---- drivers/gles2/rasterizer_storage_gles2.h | 4 +++- drivers/gles3/rasterizer_scene_gles3.cpp | 9 +++++++-- drivers/gles3/rasterizer_storage_gles3.cpp | 18 ++++++++++++++---- drivers/gles3/rasterizer_storage_gles3.h | 4 +++- scene/3d/light.cpp | 2 +- servers/visual/rasterizer.h | 2 ++ servers/visual/visual_server_raster.h | 1 + servers/visual/visual_server_scene.cpp | 4 ++-- servers/visual/visual_server_wrap_mt.h | 1 + servers/visual_server.cpp | 5 +++++ servers/visual_server.h | 10 ++++++++++ 15 files changed, 85 insertions(+), 16 deletions(-) diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 6642152749e9..9b925c3b72a9 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -2152,6 +2152,17 @@ Sets whether to use a dual paraboloid or a cubemap for the shadow map. Dual paraboloid is faster but may suffer from artifacts. Equivalent to [member OmniLight.omni_shadow_mode]. + + + + + + + + + Sets the bake mode for this light, see [enum LightBakeMode] for options. The bake mode affects how the light will be baked in [BakedLightmap]s and [GIProbe]s. + + @@ -2250,7 +2261,7 @@ - Sets whether GI probes capture light information from this light. + Sets whether GI probes capture light information from this light. [i]Deprecated method.[/i] Use [method light_set_bake_mode] instead. This method is only kept for compatibility reasons and calls [method light_set_bake_mode] internally, setting the bake mode to [constant LIGHT_BAKE_DISABLED] or [constant LIGHT_BAKE_INDIRECT] depending on the given parameter. @@ -4517,6 +4528,12 @@ Represents the size of the [enum LightParam] enum. + + + + + + Use a dual paraboloid shadow map for omni lights. diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 091951ba1032..589d166afd8f 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -491,6 +491,7 @@ class RasterizerStorageDummy : public RasterizerStorage { void light_set_cull_mask(RID p_light, uint32_t p_mask) {} void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {} void light_set_use_gi(RID p_light, bool p_enabled) {} + void light_set_bake_mode(RID p_light, VS::LightBakeMode p_bake_mode) {} void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) {} void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail) {} @@ -511,6 +512,7 @@ class RasterizerStorageDummy : public RasterizerStorage { float light_get_param(RID p_light, VS::LightParam p_param) { return 0.0; } Color light_get_color(RID p_light) { return Color(); } bool light_get_use_gi(RID p_light) { return false; } + VS::LightBakeMode light_get_bake_mode(RID p_light) { return VS::LightBakeMode::LIGHT_BAKE_DISABLED; } uint64_t light_get_version(RID p_light) const { return 0; } /* PROBE API */ diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 5d777d8985ed..2a1f89dc61e3 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -2300,6 +2300,9 @@ 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->light_mode == LightMode::LIGHTMODE_LIGHTMAP && light->light_ptr->bake_mode == VS::LIGHT_BAKE_ALL) { + light = NULL; // Don't use this light, it is already included in the lightmap + } } if (light != prev_light) { diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index c0edbed780b3..2d2412bbd083 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -3816,7 +3816,7 @@ RID RasterizerStorageGLES2::light_create(VS::LightType p_type) { light->directional_blend_splits = false; light->directional_range_mode = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; light->reverse_cull = false; - light->use_gi = true; + light->bake_mode = VS::LIGHT_BAKE_INDIRECT; light->version = 0; return light_owner.make_rid(light); @@ -3905,10 +3905,15 @@ void RasterizerStorageGLES2::light_set_reverse_cull_face_mode(RID p_light, bool } void RasterizerStorageGLES2::light_set_use_gi(RID p_light, bool p_enabled) { + WARN_DEPRECATED_MSG("'VisualServer.light_set_use_gi' is deprecated and will be removed in a future version. Use 'VisualServer.light_set_bake_mode' instead."); + light_set_bake_mode(p_light, p_enabled ? VS::LightBakeMode::LIGHT_BAKE_INDIRECT : VS::LightBakeMode::LIGHT_BAKE_DISABLED); +} + +void RasterizerStorageGLES2::light_set_bake_mode(RID p_light, VS::LightBakeMode p_bake_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); - light->use_gi = p_enabled; + light->bake_mode = p_bake_mode; light->version++; light->instance_change_notify(true, false); @@ -4010,10 +4015,14 @@ Color RasterizerStorageGLES2::light_get_color(RID p_light) { } bool RasterizerStorageGLES2::light_get_use_gi(RID p_light) { + return light_get_bake_mode(p_light) != VS::LightBakeMode::LIGHT_BAKE_DISABLED; +} + +VS::LightBakeMode RasterizerStorageGLES2::light_get_bake_mode(RID p_light) { Light *light = light_owner.getornull(p_light); - ERR_FAIL_COND_V(!light, false); + ERR_FAIL_COND_V(!light, VS::LightBakeMode::LIGHT_BAKE_DISABLED); - return light->use_gi; + return light->bake_mode; } bool RasterizerStorageGLES2::light_has_shadow(RID p_light) const { diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 88119b775299..59fd4a4a2c89 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -932,10 +932,10 @@ class RasterizerStorageGLES2 : public RasterizerStorage { bool shadow; bool negative; bool reverse_cull; - bool use_gi; uint32_t cull_mask; + VS::LightBakeMode bake_mode; VS::LightOmniShadowMode omni_shadow_mode; VS::LightOmniShadowDetail omni_shadow_detail; @@ -960,6 +960,7 @@ class RasterizerStorageGLES2 : public RasterizerStorage { virtual void light_set_cull_mask(RID p_light, uint32_t p_mask); virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); virtual void light_set_use_gi(RID p_light, bool p_enabled); + virtual void light_set_bake_mode(RID p_light, VS::LightBakeMode p_bake_mode); virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode); virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail); @@ -980,6 +981,7 @@ class RasterizerStorageGLES2 : public RasterizerStorage { virtual float light_get_param(RID p_light, VS::LightParam p_param); virtual Color light_get_color(RID p_light); virtual bool light_get_use_gi(RID p_light); + virtual VS::LightBakeMode light_get_bake_mode(RID p_light); virtual AABB light_get_aabb(RID p_light) const; virtual uint64_t light_get_version(RID p_light) const; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 5a6dde58c446..ce7951ab5adf 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1849,8 +1849,13 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform for (int i = 0; i < lc; i++) { LightInstance *li = light_instance_owner.getornull(lights[i]); - if (!li || li->last_pass != render_pass) //not visible - continue; + if (!li || li->last_pass != render_pass) { + continue; // Not visible + } + + if (e->instance->baked_light && li->light_ptr->bake_mode == VS::LightBakeMode::LIGHT_BAKE_ALL) { + continue; // This light is already included in the lightmap + } if (li && li->light_ptr->type == VS::LIGHT_OMNI) { if (omni_count < maxobj && e->instance->layer_mask & li->light_ptr->cull_mask) { diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 823aaa2f5513..c95717cf4a80 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -5479,7 +5479,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) { light->directional_blend_splits = false; light->directional_range_mode = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; light->reverse_cull = false; - light->use_gi = true; + light->bake_mode = VS::LIGHT_BAKE_INDIRECT; light->version = 0; return light_owner.make_rid(light); @@ -5572,14 +5572,20 @@ void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool } void RasterizerStorageGLES3::light_set_use_gi(RID p_light, bool p_enabled) { + WARN_DEPRECATED_MSG("'VisualServer.light_set_use_gi' is deprecated and will be removed in a future version. Use 'VisualServer.light_set_bake_mode' instead."); + light_set_bake_mode(p_light, p_enabled ? VS::LightBakeMode::LIGHT_BAKE_INDIRECT : VS::LightBakeMode::LIGHT_BAKE_DISABLED); +} + +void RasterizerStorageGLES3::light_set_bake_mode(RID p_light, VS::LightBakeMode p_bake_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); - light->use_gi = p_enabled; + light->bake_mode = p_bake_mode; light->version++; light->instance_change_notify(true, false); } + void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { Light *light = light_owner.getornull(p_light); @@ -5686,10 +5692,14 @@ Color RasterizerStorageGLES3::light_get_color(RID p_light) { } bool RasterizerStorageGLES3::light_get_use_gi(RID p_light) { + return light_get_bake_mode(p_light) != VS::LightBakeMode::LIGHT_BAKE_DISABLED; +} + +VS::LightBakeMode RasterizerStorageGLES3::light_get_bake_mode(RID p_light) { Light *light = light_owner.getornull(p_light); - ERR_FAIL_COND_V(!light, false); + ERR_FAIL_COND_V(!light, VS::LightBakeMode::LIGHT_BAKE_DISABLED); - return light->use_gi; + return light->bake_mode; } bool RasterizerStorageGLES3::light_has_shadow(RID p_light) const { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 2db6d1482081..c3a691a0f29f 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -939,7 +939,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage { bool shadow; bool negative; bool reverse_cull; - bool use_gi; + VS::LightBakeMode bake_mode; uint32_t cull_mask; VS::LightOmniShadowMode omni_shadow_mode; VS::LightOmniShadowDetail omni_shadow_detail; @@ -962,6 +962,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage { virtual void light_set_cull_mask(RID p_light, uint32_t p_mask); virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); virtual void light_set_use_gi(RID p_light, bool p_enabled); + virtual void light_set_bake_mode(RID p_light, VS::LightBakeMode p_bake_mode); virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode); virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail); @@ -982,6 +983,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage { virtual float light_get_param(RID p_light, VS::LightParam p_param); virtual Color light_get_color(RID p_light); virtual bool light_get_use_gi(RID p_light); + virtual VS::LightBakeMode light_get_bake_mode(RID p_light); virtual AABB light_get_aabb(RID p_light) const; virtual uint64_t light_get_version(RID p_light) const; diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 09d696bccd9f..281a379fc09f 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -159,7 +159,7 @@ PoolVector Light::get_faces(uint32_t p_usage_flags) const { void Light::set_bake_mode(BakeMode p_mode) { bake_mode = p_mode; - VS::get_singleton()->light_set_use_gi(light, p_mode != BAKE_DISABLED); + VS::get_singleton()->light_set_bake_mode(light, VS::LightBakeMode(bake_mode)); } Light::BakeMode Light::get_bake_mode() const { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 847e5f183bad..6d5d81e2ed14 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -379,6 +379,7 @@ class RasterizerStorage { virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; virtual void light_set_use_gi(RID p_light, bool p_enable) = 0; + virtual void light_set_bake_mode(RID p_light, VS::LightBakeMode p_bake_mode) = 0; virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) = 0; virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail) = 0; @@ -399,6 +400,7 @@ class RasterizerStorage { virtual float light_get_param(RID p_light, VS::LightParam p_param) = 0; virtual Color light_get_color(RID p_light) = 0; virtual bool light_get_use_gi(RID p_light) = 0; + virtual VS::LightBakeMode light_get_bake_mode(RID p_light) = 0; virtual uint64_t light_get_version(RID p_light) const = 0; /* PROBE API */ diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index d9cef62c732c..e6f73369a283 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -314,6 +314,7 @@ class VisualServerRaster : public VisualServer { BIND2(light_set_cull_mask, RID, uint32_t) BIND2(light_set_reverse_cull_face_mode, RID, bool) BIND2(light_set_use_gi, RID, bool) + BIND2(light_set_bake_mode, RID, LightBakeMode) BIND2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) BIND2(light_omni_set_shadow_detail, RID, LightOmniShadowDetail) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index f7420b766391..11590353e2a6 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -3120,7 +3120,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) { for (List::Element *E = p_gi_probe->scenario->directional_lights.front(); E; E = E->next()) { - if (!VSG::storage->light_get_use_gi(E->get()->base)) + if (VSG::storage->light_get_bake_mode(E->get()->base) == VS::LightBakeMode::LIGHT_BAKE_DISABLED) continue; InstanceGIProbeData::LightCache lc; @@ -3143,7 +3143,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) { for (Set::Element *E = probe_data->lights.front(); E; E = E->next()) { - if (!VSG::storage->light_get_use_gi(E->get()->base)) + if (VSG::storage->light_get_bake_mode(E->get()->base) == VS::LightBakeMode::LIGHT_BAKE_DISABLED) continue; InstanceGIProbeData::LightCache lc; diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 2a3c976aee4f..edea558dec2f 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -250,6 +250,7 @@ class VisualServerWrapMT : public VisualServer { FUNC2(light_set_cull_mask, RID, uint32_t) FUNC2(light_set_reverse_cull_face_mode, RID, bool) FUNC2(light_set_use_gi, RID, bool) + FUNC2(light_set_bake_mode, RID, LightBakeMode) FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) FUNC2(light_omni_set_shadow_detail, RID, LightOmniShadowDetail) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index d88ef711da73..17af8f835c39 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1772,6 +1772,7 @@ void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("light_set_cull_mask", "light", "mask"), &VisualServer::light_set_cull_mask); ClassDB::bind_method(D_METHOD("light_set_reverse_cull_face_mode", "light", "enabled"), &VisualServer::light_set_reverse_cull_face_mode); ClassDB::bind_method(D_METHOD("light_set_use_gi", "light", "enabled"), &VisualServer::light_set_use_gi); + ClassDB::bind_method(D_METHOD("light_set_bake_mode", "light", "bake_mode"), &VisualServer::light_set_bake_mode); ClassDB::bind_method(D_METHOD("light_omni_set_shadow_mode", "light", "mode"), &VisualServer::light_omni_set_shadow_mode); ClassDB::bind_method(D_METHOD("light_omni_set_shadow_detail", "light", "detail"), &VisualServer::light_omni_set_shadow_detail); @@ -2154,6 +2155,10 @@ void VisualServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); + BIND_ENUM_CONSTANT(LIGHT_BAKE_DISABLED); + BIND_ENUM_CONSTANT(LIGHT_BAKE_INDIRECT); + BIND_ENUM_CONSTANT(LIGHT_BAKE_ALL); + BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID); BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_CUBE); BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DETAIL_VERTICAL); diff --git a/servers/visual_server.h b/servers/visual_server.h index 5876f089fa03..d794693cce33 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -442,6 +442,15 @@ class VisualServer : public Object { virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; virtual void light_set_use_gi(RID p_light, bool p_enable) = 0; + // bake mode + enum LightBakeMode { + LIGHT_BAKE_DISABLED, + LIGHT_BAKE_INDIRECT, + LIGHT_BAKE_ALL + }; + + virtual void light_set_bake_mode(RID p_light, LightBakeMode p_bake_mode) = 0; + // omni light enum LightOmniShadowMode { LIGHT_OMNI_SHADOW_DUAL_PARABOLOID, @@ -1098,6 +1107,7 @@ VARIANT_ENUM_CAST(VisualServer::Features); VARIANT_ENUM_CAST(VisualServer::MultimeshTransformFormat); VARIANT_ENUM_CAST(VisualServer::MultimeshColorFormat); VARIANT_ENUM_CAST(VisualServer::MultimeshCustomDataFormat); +VARIANT_ENUM_CAST(VisualServer::LightBakeMode); VARIANT_ENUM_CAST(VisualServer::LightOmniShadowMode); VARIANT_ENUM_CAST(VisualServer::LightOmniShadowDetail); VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowMode);