diff options
Diffstat (limited to 'servers')
-rw-r--r-- | servers/rendering/rasterizer.h | 2 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp | 66 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp | 14 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_storage_rd.h | 3 | ||||
-rw-r--r-- | servers/rendering/rendering_server_raster.h | 1 | ||||
-rw-r--r-- | servers/rendering/rendering_server_scene.cpp | 6 | ||||
-rw-r--r-- | servers/rendering/rendering_server_scene.h | 1 | ||||
-rw-r--r-- | servers/rendering/rendering_server_wrap_mt.h | 1 | ||||
-rw-r--r-- | servers/rendering_server.cpp | 1 | ||||
-rw-r--r-- | servers/rendering_server.h | 1 |
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, |