summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/rasterizer.h2
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp66
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp14
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.h3
-rw-r--r--servers/rendering/rendering_server_raster.h1
-rw-r--r--servers/rendering/rendering_server_scene.cpp6
-rw-r--r--servers/rendering/rendering_server_scene.h1
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h1
-rw-r--r--servers/rendering_server.cpp1
-rw-r--r--servers/rendering_server.h1
10 files changed, 72 insertions, 24 deletions
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index cecd313fbd..dad45bafa9 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -517,6 +517,8 @@ public:
virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) = 0;
virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
virtual bool light_directional_get_blend_splits(RID p_light) const = 0;
+ virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0;
+ virtual bool light_directional_is_sky_only(RID p_light) const = 0;
virtual void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) = 0;
virtual RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const = 0;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index f708b6ce00..2b1fea2aa1 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -1187,6 +1187,11 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm
LightInstance *li = light_instance_owner.getornull(p_directional_light_instances[j]);
ERR_CONTINUE(!li);
+
+ if (storage->light_directional_is_sky_only(li->light)) {
+ continue;
+ }
+
Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
dir.y *= rb->sdfgi->y_mult;
dir.normalize();
@@ -4391,6 +4396,11 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
RID light = light_instance_get_base_light(light_instance);
l.type = storage->light_get_type(light);
+ if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_is_sky_only(light)) {
+ light_count--;
+ continue;
+ }
+
l.attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
l.energy = storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
l.radius = to_cell.basis.xform(Vector3(storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();
@@ -5930,7 +5940,40 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
RS::LightType type = storage->light_get_type(base);
switch (type) {
case RS::LIGHT_DIRECTIONAL: {
- if (r_directional_light_count >= cluster.max_directional_lights) {
+ // Copy to SkyDirectionalLightData
+ if (r_directional_light_count < sky_scene_state.max_directional_lights) {
+ SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count];
+ Transform light_transform = light_instance_get_base_transform(li);
+ Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
+
+ sky_light_data.direction[0] = world_direction.x;
+ sky_light_data.direction[1] = world_direction.y;
+ sky_light_data.direction[2] = -world_direction.z;
+
+ float sign = storage->light_is_negative(base) ? -1 : 1;
+ sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
+
+ Color linear_col = storage->light_get_color(base).to_linear();
+ sky_light_data.color[0] = linear_col.r;
+ sky_light_data.color[1] = linear_col.g;
+ sky_light_data.color[2] = linear_col.b;
+
+ sky_light_data.enabled = true;
+
+ float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+ if (angular_diameter > 0.0) {
+ // I know tan(0) is 0, but let's not risk it with numerical precision.
+ // technically this will keep expanding until reaching the sun, but all we care
+ // is expand until we reach the radius of the near plane (there can't be more occluders than that)
+ angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
+ } else {
+ angular_diameter = 0.0;
+ }
+ sky_light_data.size = angular_diameter;
+ sky_scene_state.ubo.directional_light_count++;
+ }
+
+ if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) {
continue;
}
@@ -6073,27 +6116,6 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
}
}
- // Copy to SkyDirectionalLightData
- if (r_directional_light_count < sky_scene_state.max_directional_lights) {
- SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count];
-
- Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
-
- sky_light_data.direction[0] = world_direction.x;
- sky_light_data.direction[1] = world_direction.y;
- sky_light_data.direction[2] = -world_direction.z;
-
- sky_light_data.energy = light_data.energy / Math_PI;
-
- sky_light_data.color[0] = light_data.color[0];
- sky_light_data.color[1] = light_data.color[1];
- sky_light_data.color[2] = light_data.color[2];
-
- sky_light_data.enabled = true;
- sky_light_data.size = angular_diameter;
- sky_scene_state.ubo.directional_light_count++;
- }
-
r_directional_light_count++;
} break;
case RS::LIGHT_SPOT:
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
index e723028e56..0bbbc68c94 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -4950,6 +4950,20 @@ bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const
return light->directional_blend_splits;
}
+void RasterizerStorageRD::light_directional_set_sky_only(RID p_light, bool p_sky_only) {
+ Light *light = light_owner.getornull(p_light);
+ ERR_FAIL_COND(!light);
+
+ light->directional_sky_only = p_sky_only;
+}
+
+bool RasterizerStorageRD::light_directional_is_sky_only(RID p_light) const {
+ const Light *light = light_owner.getornull(p_light);
+ ERR_FAIL_COND_V(!light, false);
+
+ return light->directional_sky_only;
+}
+
RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
index b03a26e200..2fa6ce5867 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
@@ -823,6 +823,7 @@ private:
RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
RS::LightDirectionalShadowDepthRangeMode directional_range_mode = RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE;
bool directional_blend_splits = false;
+ bool directional_sky_only = false;
uint64_t version = 0;
RasterizerScene::InstanceDependency instance_dependency;
@@ -1459,6 +1460,8 @@ public:
void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode);
void light_directional_set_blend_splits(RID p_light, bool p_enable);
bool light_directional_get_blend_splits(RID p_light) const;
+ void light_directional_set_sky_only(RID p_light, bool p_sky_only);
+ bool light_directional_is_sky_only(RID p_light) const;
void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode);
RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const;
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h
index 97477f1d3e..436577fae3 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_raster.h
@@ -337,6 +337,7 @@ public:
BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
BIND2(light_directional_set_blend_splits, RID, bool)
+ BIND2(light_directional_set_sky_only, RID, bool)
BIND2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
/* PROBE API */
diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp
index ae6786090a..b933a550e2 100644
--- a/servers/rendering/rendering_server_scene.cpp
+++ b/servers/rendering/rendering_server_scene.cpp
@@ -2169,7 +2169,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
//check shadow..
if (light) {
- if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base)) {
+ if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base) && !(RSG::storage->light_get_type(E->get()->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_is_sky_only(E->get()->base))) {
lights_with_shadow[directional_shadow_count++] = E->get();
}
//add to list
@@ -2595,7 +2595,8 @@ void RenderingServerScene::render_probes() {
cache->radius != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
cache->attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
cache->spot_angle != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
- cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION)) {
+ cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION) ||
+ cache->sky_only != RSG::storage->light_directional_is_sky_only(instance->base)) {
cache_dirty = true;
}
}
@@ -2664,6 +2665,7 @@ void RenderingServerScene::render_probes() {
cache->attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
cache->spot_angle = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
cache->spot_attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+ cache->sky_only = RSG::storage->light_directional_is_sky_only(instance->base);
idx++;
}
diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h
index 1b0a617627..aa8439c164 100644
--- a/servers/rendering/rendering_server_scene.h
+++ b/servers/rendering/rendering_server_scene.h
@@ -351,6 +351,7 @@ public:
float spot_angle;
float spot_attenuation;
bool has_shadow;
+ bool sky_only;
};
Vector<LightCache> light_cache;
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index c2337f8c9e..d3319c7ed2 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -244,6 +244,7 @@ public:
FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
FUNC2(light_directional_set_blend_splits, RID, bool)
+ FUNC2(light_directional_set_sky_only, RID, bool)
FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
/* PROBE API */
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index e2f1ddb224..4b79660d22 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1618,6 +1618,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("light_directional_set_shadow_mode", "light", "mode"), &RenderingServer::light_directional_set_shadow_mode);
ClassDB::bind_method(D_METHOD("light_directional_set_blend_splits", "light", "enable"), &RenderingServer::light_directional_set_blend_splits);
+ ClassDB::bind_method(D_METHOD("light_directional_set_sky_only", "light", "enable"), &RenderingServer::light_directional_set_sky_only);
ClassDB::bind_method(D_METHOD("light_directional_set_shadow_depth_range_mode", "light", "range_mode"), &RenderingServer::light_directional_set_shadow_depth_range_mode);
ClassDB::bind_method(D_METHOD("reflection_probe_create"), &RenderingServer::reflection_probe_create);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index e50170bdf7..9ffdd15f5a 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -435,6 +435,7 @@ public:
virtual void light_directional_set_shadow_mode(RID p_light, LightDirectionalShadowMode p_mode) = 0;
virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
+ virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0;
enum LightDirectionalShadowDepthRangeMode {
LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE,