mirror of
https://github.com/godotengine/godot.git
synced 2024-11-24 21:22:48 +00:00
Add shadow_caster_mask
to Light3D.
This commit is contained in:
parent
88f3b5f9d5
commit
a54b71bbdf
@ -115,6 +115,9 @@
|
||||
<member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0">
|
||||
Blurs the edges of the shadow. Can be used to hide pixel artifacts in low-resolution shadow maps. A high value can impact performance, make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible.
|
||||
</member>
|
||||
<member name="shadow_caster_mask" type="int" setter="set_shadow_caster_mask" getter="get_shadow_caster_mask" default="4294967295">
|
||||
The light will only cast shadows using objects in the selected layers.
|
||||
</member>
|
||||
<member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false">
|
||||
If [code]true[/code], the light will cast real-time shadows. This has a significant performance cost. Only enable shadow rendering when it makes a noticeable difference in the scene's appearance, and consider using [member distance_fade_enabled] to hide the light when far away from the [Camera3D].
|
||||
</member>
|
||||
|
@ -2111,6 +2111,14 @@
|
||||
If [code]true[/code], light will cast shadows. Equivalent to [member Light3D.shadow_enabled].
|
||||
</description>
|
||||
</method>
|
||||
<method name="light_set_shadow_caster_mask">
|
||||
<return type="void" />
|
||||
<param index="0" name="light" type="RID" />
|
||||
<param index="1" name="mask" type="int" />
|
||||
<description>
|
||||
Sets the shadow caster mask for this 3D light. Shadows will only be cast using objects in the selected layers. Equivalent to [member Light3D.shadow_caster_mask].
|
||||
</description>
|
||||
</method>
|
||||
<method name="lightmap_create">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
|
@ -213,6 +213,23 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
|
||||
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void LightStorage::light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) {
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_NULL(light);
|
||||
|
||||
light->shadow_caster_mask = p_caster_mask;
|
||||
|
||||
light->version++;
|
||||
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
uint32_t LightStorage::light_get_shadow_caster_mask(RID p_light) const {
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_NULL_V(light, 0);
|
||||
|
||||
return light->shadow_caster_mask;
|
||||
}
|
||||
|
||||
void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_NULL(light);
|
||||
|
@ -59,6 +59,7 @@ struct Light {
|
||||
RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC;
|
||||
uint32_t max_sdfgi_cascade = 2;
|
||||
uint32_t cull_mask = 0xFFFFFFFF;
|
||||
uint32_t shadow_caster_mask = 0xFFFFFFFF;
|
||||
bool distance_fade = false;
|
||||
real_t distance_fade_begin = 40.0;
|
||||
real_t distance_fade_shadow = 50.0;
|
||||
@ -326,6 +327,8 @@ public:
|
||||
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) override;
|
||||
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override;
|
||||
virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override;
|
||||
virtual void light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) override;
|
||||
virtual uint32_t light_get_shadow_caster_mask(RID p_light) const override;
|
||||
virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override;
|
||||
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override {}
|
||||
|
||||
|
@ -146,6 +146,15 @@ bool Light3D::get_shadow_reverse_cull_face() const {
|
||||
return reverse_cull;
|
||||
}
|
||||
|
||||
void Light3D::set_shadow_caster_mask(uint32_t p_caster_mask) {
|
||||
shadow_caster_mask = p_caster_mask;
|
||||
RS::get_singleton()->light_set_shadow_caster_mask(light, shadow_caster_mask);
|
||||
}
|
||||
|
||||
uint32_t Light3D::get_shadow_caster_mask() const {
|
||||
return shadow_caster_mask;
|
||||
}
|
||||
|
||||
AABB Light3D::get_aabb() const {
|
||||
if (type == RenderingServer::LIGHT_DIRECTIONAL) {
|
||||
return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
|
||||
@ -300,7 +309,7 @@ bool Light3D::is_editor_only() const {
|
||||
}
|
||||
|
||||
void Light3D::_validate_property(PropertyInfo &p_property) const {
|
||||
if (!shadow && (p_property.name == "shadow_bias" || p_property.name == "shadow_normal_bias" || p_property.name == "shadow_reverse_cull_face" || p_property.name == "shadow_transmittance_bias" || p_property.name == "shadow_opacity" || p_property.name == "shadow_blur" || p_property.name == "distance_fade_shadow")) {
|
||||
if (!shadow && (p_property.name == "shadow_bias" || p_property.name == "shadow_normal_bias" || p_property.name == "shadow_reverse_cull_face" || p_property.name == "shadow_transmittance_bias" || p_property.name == "shadow_opacity" || p_property.name == "shadow_blur" || p_property.name == "distance_fade_shadow" || p_property.name == "shadow_caster_mask")) {
|
||||
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
}
|
||||
|
||||
@ -354,6 +363,9 @@ void Light3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_reverse_cull_face", "enable"), &Light3D::set_shadow_reverse_cull_face);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_reverse_cull_face"), &Light3D::get_shadow_reverse_cull_face);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_caster_mask", "caster_mask"), &Light3D::set_shadow_caster_mask);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_caster_mask"), &Light3D::get_shadow_caster_mask);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode);
|
||||
|
||||
@ -388,6 +400,7 @@ void Light3D::_bind_methods() {
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_OPACITY);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BLUR);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_caster_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_shadow_caster_mask", "get_shadow_caster_mask");
|
||||
|
||||
ADD_GROUP("Distance Fade", "distance_fade_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled");
|
||||
|
@ -75,6 +75,7 @@ private:
|
||||
bool negative = false;
|
||||
bool reverse_cull = false;
|
||||
uint32_t cull_mask = 0;
|
||||
uint32_t shadow_caster_mask = 0xFFFFFFFF;
|
||||
bool distance_fade_enabled = false;
|
||||
real_t distance_fade_begin = 40.0;
|
||||
real_t distance_fade_shadow = 50.0;
|
||||
@ -136,6 +137,9 @@ public:
|
||||
void set_shadow_reverse_cull_face(bool p_enable);
|
||||
bool get_shadow_reverse_cull_face() const;
|
||||
|
||||
void set_shadow_caster_mask(uint32_t p_caster_mask);
|
||||
uint32_t get_shadow_caster_mask() const;
|
||||
|
||||
void set_bake_mode(BakeMode p_mode);
|
||||
BakeMode get_bake_mode() const;
|
||||
|
||||
|
@ -78,6 +78,8 @@ public:
|
||||
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) override {}
|
||||
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override {}
|
||||
virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override {}
|
||||
virtual void light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) override {}
|
||||
virtual uint32_t light_get_shadow_caster_mask(RID p_light) const override { return 0xFFFFFFFF; }
|
||||
virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override {}
|
||||
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override {}
|
||||
|
||||
|
@ -285,6 +285,23 @@ void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled)
|
||||
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void LightStorage::light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) {
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_NULL(light);
|
||||
|
||||
light->shadow_caster_mask = p_caster_mask;
|
||||
|
||||
light->version++;
|
||||
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
uint32_t LightStorage::light_get_shadow_caster_mask(RID p_light) const {
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_NULL_V(light, 0);
|
||||
|
||||
return light->shadow_caster_mask;
|
||||
}
|
||||
|
||||
void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_NULL(light);
|
||||
|
@ -72,6 +72,7 @@ private:
|
||||
RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC;
|
||||
uint32_t max_sdfgi_cascade = 2;
|
||||
uint32_t cull_mask = 0xFFFFFFFF;
|
||||
uint32_t shadow_caster_mask = 0xFFFFFFFF;
|
||||
bool distance_fade = false;
|
||||
real_t distance_fade_begin = 40.0;
|
||||
real_t distance_fade_shadow = 50.0;
|
||||
@ -474,6 +475,8 @@ public:
|
||||
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) override;
|
||||
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override;
|
||||
virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override;
|
||||
virtual void light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) override;
|
||||
virtual uint32_t light_get_shadow_caster_mask(RID p_light) const override;
|
||||
virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override;
|
||||
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override;
|
||||
|
||||
|
@ -2139,6 +2139,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in
|
||||
cull.shadow_count = p_shadow_index + 1;
|
||||
cull.shadows[p_shadow_index].cascade_count = splits;
|
||||
cull.shadows[p_shadow_index].light_instance = light->instance;
|
||||
cull.shadows[p_shadow_index].caster_mask = RSG::light_storage->light_get_shadow_caster_mask(p_instance->base);
|
||||
|
||||
for (int i = 0; i < splits; i++) {
|
||||
RENDER_TIMESTAMP("Cull DirectionalLight3D, Split " + itos(i));
|
||||
@ -2369,7 +2370,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||
|
||||
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
||||
Instance *instance = instance_shadow_cull_result[j];
|
||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
|
||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask & RSG::light_storage->light_get_shadow_caster_mask(p_instance->base))) {
|
||||
continue;
|
||||
} else {
|
||||
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
||||
@ -2451,7 +2452,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||
|
||||
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
||||
Instance *instance = instance_shadow_cull_result[j];
|
||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
|
||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask & RSG::light_storage->light_get_shadow_caster_mask(p_instance->base))) {
|
||||
continue;
|
||||
} else {
|
||||
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
||||
@ -2518,7 +2519,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||
|
||||
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
||||
Instance *instance = instance_shadow_cull_result[j];
|
||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
|
||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask & RSG::light_storage->light_get_shadow_caster_mask(p_instance->base))) {
|
||||
continue;
|
||||
} else {
|
||||
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
||||
@ -2978,7 +2979,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
|
||||
if (IN_FRUSTUM(cull_data.cull->shadows[j].cascades[k].frustum) && VIS_CHECK) {
|
||||
uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
|
||||
|
||||
if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS && LAYER_CHECK) {
|
||||
if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS && (LAYER_CHECK & cull_data.cull->shadows[j].caster_mask)) {
|
||||
cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry);
|
||||
mesh_visible = true;
|
||||
}
|
||||
|
@ -1084,6 +1084,7 @@ public:
|
||||
struct Cull {
|
||||
struct Shadow {
|
||||
RID light_instance;
|
||||
uint32_t caster_mask;
|
||||
struct Cascade {
|
||||
Frustum frustum;
|
||||
|
||||
|
@ -377,6 +377,7 @@ public:
|
||||
FUNC2(light_set_cull_mask, RID, uint32_t)
|
||||
FUNC5(light_set_distance_fade, RID, bool, float, float, float)
|
||||
FUNC2(light_set_reverse_cull_face_mode, RID, bool)
|
||||
FUNC2(light_set_shadow_caster_mask, RID, uint32_t)
|
||||
FUNC2(light_set_bake_mode, RID, LightBakeMode)
|
||||
FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t)
|
||||
|
||||
|
@ -59,6 +59,8 @@ public:
|
||||
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0;
|
||||
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) = 0;
|
||||
virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0;
|
||||
virtual void light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) = 0;
|
||||
virtual uint32_t light_get_shadow_caster_mask(RID p_light) const = 0;
|
||||
virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) = 0;
|
||||
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0;
|
||||
|
||||
|
@ -2467,6 +2467,7 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("light_set_cull_mask", "light", "mask"), &RenderingServer::light_set_cull_mask);
|
||||
ClassDB::bind_method(D_METHOD("light_set_distance_fade", "decal", "enabled", "begin", "shadow", "length"), &RenderingServer::light_set_distance_fade);
|
||||
ClassDB::bind_method(D_METHOD("light_set_reverse_cull_face_mode", "light", "enabled"), &RenderingServer::light_set_reverse_cull_face_mode);
|
||||
ClassDB::bind_method(D_METHOD("light_set_shadow_caster_mask", "light", "mask"), &RenderingServer::light_set_shadow_caster_mask);
|
||||
ClassDB::bind_method(D_METHOD("light_set_bake_mode", "light", "bake_mode"), &RenderingServer::light_set_bake_mode);
|
||||
ClassDB::bind_method(D_METHOD("light_set_max_sdfgi_cascade", "light", "cascade"), &RenderingServer::light_set_max_sdfgi_cascade);
|
||||
|
||||
|
@ -508,6 +508,7 @@ public:
|
||||
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0;
|
||||
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) = 0;
|
||||
virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0;
|
||||
virtual void light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) = 0;
|
||||
|
||||
enum LightBakeMode {
|
||||
LIGHT_BAKE_DISABLED,
|
||||
|
Loading…
Reference in New Issue
Block a user