Browse Source

Move light, reflection probe and lightmap into LightStorage

Bastiaan Olij 3 years ago
parent
commit
b6faf6c6c0
27 changed files with 2175 additions and 1788 deletions
  1. 3 0
      drivers/gles3/rasterizer_gles3.h
  2. 0 254
      drivers/gles3/rasterizer_storage_gles3.cpp
  3. 2 89
      drivers/gles3/rasterizer_storage_gles3.h
  4. 316 0
      drivers/gles3/storage/light_storage.cpp
  5. 154 0
      drivers/gles3/storage/light_storage.h
  6. 3 0
      servers/rendering/dummy/rasterizer_dummy.h
  7. 0 87
      servers/rendering/dummy/rasterizer_storage_dummy.h
  8. 135 0
      servers/rendering/dummy/storage/light_storage.h
  9. 2 0
      servers/rendering/renderer_compositor.h
  10. 10 6
      servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
  11. 9 6
      servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
  12. 2 0
      servers/rendering/renderer_rd/renderer_compositor_rd.cpp
  13. 3 0
      servers/rendering/renderer_rd/renderer_compositor_rd.h
  14. 31 31
      servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
  15. 83 80
      servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
  16. 7 6
      servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
  17. 17 737
      servers/rendering/renderer_rd/renderer_storage_rd.cpp
  18. 0 302
      servers/rendering/renderer_rd/renderer_storage_rd.h
  19. 788 0
      servers/rendering/renderer_rd/storage_rd/light_storage.cpp
  20. 370 0
      servers/rendering/renderer_rd/storage_rd/light_storage.h
  21. 81 81
      servers/rendering/renderer_scene_cull.cpp
  22. 0 93
      servers/rendering/renderer_storage.h
  23. 1 0
      servers/rendering/rendering_server_default.cpp
  24. 16 16
      servers/rendering/rendering_server_default.h
  25. 1 0
      servers/rendering/rendering_server_globals.cpp
  26. 2 0
      servers/rendering/rendering_server_globals.h
  27. 139 0
      servers/rendering/storage/light_storage.h

+ 3 - 0
drivers/gles3/rasterizer_gles3.h

@@ -38,6 +38,7 @@
 #include "rasterizer_storage_gles3.h"
 #include "servers/rendering/renderer_compositor.h"
 #include "storage/config.h"
+#include "storage/light_storage.h"
 #include "storage/material_storage.h"
 #include "storage/mesh_storage.h"
 #include "storage/texture_storage.h"
@@ -54,6 +55,7 @@ protected:
 	GLES3::TextureStorage texture_storage;
 	GLES3::MaterialStorage material_storage;
 	GLES3::MeshStorage mesh_storage;
+	GLES3::LightStorage light_storage;
 	RasterizerStorageGLES3 storage;
 	RasterizerCanvasGLES3 canvas;
 	RasterizerSceneGLES3 scene;
@@ -61,6 +63,7 @@ protected:
 	void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect);
 
 public:
+	RendererLightStorage *get_light_storage() { return &light_storage; }
 	RendererMaterialStorage *get_material_storage() { return &material_storage; }
 	RendererMeshStorage *get_mesh_storage() { return &mesh_storage; }
 	RendererTextureStorage *get_texture_storage() { return &texture_storage; }

+ 0 - 254
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -56,209 +56,9 @@ RID RasterizerStorageGLES3::sky_create() {
 void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) {
 }
 
-/* Light API */
-
-RID RasterizerStorageGLES3::directional_light_allocate() {
-	return RID();
-}
-
-void RasterizerStorageGLES3::directional_light_initialize(RID p_rid) {
-}
-
-RID RasterizerStorageGLES3::omni_light_allocate() {
-	return RID();
-}
-
-void RasterizerStorageGLES3::omni_light_initialize(RID p_rid) {
-}
-
-RID RasterizerStorageGLES3::spot_light_allocate() {
-	return RID();
-}
-
-void RasterizerStorageGLES3::spot_light_initialize(RID p_rid) {
-}
-
-RID RasterizerStorageGLES3::reflection_probe_allocate() {
-	return RID();
-}
-
-void RasterizerStorageGLES3::reflection_probe_initialize(RID p_rid) {
-}
-
-void RasterizerStorageGLES3::light_set_color(RID p_light, const Color &p_color) {
-}
-
-void RasterizerStorageGLES3::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
-}
-
-void RasterizerStorageGLES3::light_set_shadow(RID p_light, bool p_enabled) {
-}
-
-void RasterizerStorageGLES3::light_set_projector(RID p_light, RID p_texture) {
-}
-
-void RasterizerStorageGLES3::light_set_negative(RID p_light, bool p_enable) {
-}
-
-void RasterizerStorageGLES3::light_set_cull_mask(RID p_light, uint32_t p_mask) {
-}
-
-void RasterizerStorageGLES3::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
-}
-
-void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
-}
-
-void RasterizerStorageGLES3::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
-}
-
-void RasterizerStorageGLES3::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
-}
-
-void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
-}
-
-void RasterizerStorageGLES3::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
-}
-
-void RasterizerStorageGLES3::light_directional_set_blend_splits(RID p_light, bool p_enable) {
-}
-
-bool RasterizerStorageGLES3::light_directional_get_blend_splits(RID p_light) const {
-	return false;
-}
-
-void RasterizerStorageGLES3::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) {
-}
-
-RS::LightDirectionalSkyMode RasterizerStorageGLES3::light_directional_get_sky_mode(RID p_light) const {
-	return RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY;
-}
-
-RS::LightDirectionalShadowMode RasterizerStorageGLES3::light_directional_get_shadow_mode(RID p_light) {
-	return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
-}
-
-RS::LightOmniShadowMode RasterizerStorageGLES3::light_omni_get_shadow_mode(RID p_light) {
-	return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
-}
-
-bool RasterizerStorageGLES3::light_has_shadow(RID p_light) const {
-	return false;
-}
-
-bool RasterizerStorageGLES3::light_has_projector(RID p_light) const {
-	return false;
-}
-
-RS::LightType RasterizerStorageGLES3::light_get_type(RID p_light) const {
-	return RS::LIGHT_OMNI;
-}
-
-AABB RasterizerStorageGLES3::light_get_aabb(RID p_light) const {
-	return AABB();
-}
-
-float RasterizerStorageGLES3::light_get_param(RID p_light, RS::LightParam p_param) {
-	return 0.0;
-}
-
-Color RasterizerStorageGLES3::light_get_color(RID p_light) {
-	return Color();
-}
-
-RS::LightBakeMode RasterizerStorageGLES3::light_get_bake_mode(RID p_light) {
-	return RS::LIGHT_BAKE_DISABLED;
-}
-
-uint32_t RasterizerStorageGLES3::light_get_max_sdfgi_cascade(RID p_light) {
-	return 0;
-}
-
-uint64_t RasterizerStorageGLES3::light_get_version(RID p_light) const {
-	return 0;
-}
-
-/* PROBE API */
-
-void RasterizerStorageGLES3::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
-}
-
-AABB RasterizerStorageGLES3::reflection_probe_get_aabb(RID p_probe) const {
-	return AABB();
-}
-
-RS::ReflectionProbeUpdateMode RasterizerStorageGLES3::reflection_probe_get_update_mode(RID p_probe) const {
-	return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE;
-}
-
-uint32_t RasterizerStorageGLES3::reflection_probe_get_cull_mask(RID p_probe) const {
-	return 0;
-}
-
-Vector3 RasterizerStorageGLES3::reflection_probe_get_extents(RID p_probe) const {
-	return Vector3();
-}
-
-Vector3 RasterizerStorageGLES3::reflection_probe_get_origin_offset(RID p_probe) const {
-	return Vector3();
-}
-
-float RasterizerStorageGLES3::reflection_probe_get_origin_max_distance(RID p_probe) const {
-	return 0.0;
-}
-
-bool RasterizerStorageGLES3::reflection_probe_renders_shadows(RID p_probe) const {
-	return false;
-}
-
 void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
 }
 
-void RasterizerStorageGLES3::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {
-}
-
-float RasterizerStorageGLES3::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
-	return 0.0;
-}
-
 /* VOXEL GI API */
 
 RID RasterizerStorageGLES3::voxel_gi_allocate() {
@@ -359,60 +159,6 @@ uint32_t RasterizerStorageGLES3::voxel_gi_get_version(RID p_voxel_gi) {
 	return 0;
 }
 
-/* LIGHTMAP CAPTURE */
-RID RasterizerStorageGLES3::lightmap_allocate() {
-	return RID();
-}
-
-void RasterizerStorageGLES3::lightmap_initialize(RID p_rid) {
-}
-
-void RasterizerStorageGLES3::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
-}
-
-void RasterizerStorageGLES3::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
-}
-
-void RasterizerStorageGLES3::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
-}
-
-void RasterizerStorageGLES3::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
-}
-
-PackedVector3Array RasterizerStorageGLES3::lightmap_get_probe_capture_points(RID p_lightmap) const {
-	return PackedVector3Array();
-}
-
-PackedColorArray RasterizerStorageGLES3::lightmap_get_probe_capture_sh(RID p_lightmap) const {
-	return PackedColorArray();
-}
-
-PackedInt32Array RasterizerStorageGLES3::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
-	return PackedInt32Array();
-}
-
-PackedInt32Array RasterizerStorageGLES3::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
-	return PackedInt32Array();
-}
-
-AABB RasterizerStorageGLES3::lightmap_get_aabb(RID p_lightmap) const {
-	return AABB();
-}
-
-void RasterizerStorageGLES3::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
-}
-
-bool RasterizerStorageGLES3::lightmap_is_interior(RID p_lightmap) const {
-	return false;
-}
-
-void RasterizerStorageGLES3::lightmap_set_probe_capture_update_speed(float p_speed) {
-}
-
-float RasterizerStorageGLES3::lightmap_get_probe_capture_update_speed() const {
-	return 0;
-}
-
 /* OCCLUDER */
 
 void RasterizerStorageGLES3::occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {

+ 2 - 89
drivers/gles3/rasterizer_storage_gles3.h

@@ -114,6 +114,8 @@ public:
 	/////////////////////////////////////////////////////////////////////////////////////////
 
 public:
+	virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
+
 	/* SKY API */
 	// not sure if used in godot 4?
 	struct Sky {
@@ -128,78 +130,6 @@ public:
 	RID sky_create();
 	void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size);
 
-	/* Light API */
-
-	RID directional_light_allocate() override;
-	void directional_light_initialize(RID p_rid) override;
-	RID omni_light_allocate() override;
-	void omni_light_initialize(RID p_rid) override;
-	RID spot_light_allocate() override;
-	void spot_light_initialize(RID p_rid) override;
-	RID reflection_probe_allocate() override;
-	void reflection_probe_initialize(RID p_rid) override;
-
-	void light_set_color(RID p_light, const Color &p_color) override;
-	void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override;
-	void light_set_shadow(RID p_light, bool p_enabled) override;
-	void light_set_projector(RID p_light, RID p_texture) override;
-	void light_set_negative(RID p_light, bool p_enable) override;
-	void light_set_cull_mask(RID p_light, uint32_t p_mask) override;
-	void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override;
-	void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override;
-	void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override;
-	void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override;
-
-	void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override;
-
-	void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override;
-	void light_directional_set_blend_splits(RID p_light, bool p_enable) override;
-	bool light_directional_get_blend_splits(RID p_light) const override;
-	void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) override;
-	RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const override;
-
-	RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override;
-	RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override;
-
-	bool light_has_shadow(RID p_light) const override;
-	bool light_has_projector(RID p_light) const override;
-
-	RS::LightType light_get_type(RID p_light) const override;
-	AABB light_get_aabb(RID p_light) const override;
-	float light_get_param(RID p_light, RS::LightParam p_param) override;
-	Color light_get_color(RID p_light) override;
-	RS::LightBakeMode light_get_bake_mode(RID p_light) override;
-	uint32_t light_get_max_sdfgi_cascade(RID p_light) override;
-	uint64_t light_get_version(RID p_light) const override;
-
-	/* PROBE API */
-
-	void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override;
-	void reflection_probe_set_intensity(RID p_probe, float p_intensity) override;
-	void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override;
-	void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override;
-	void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override;
-	void reflection_probe_set_max_distance(RID p_probe, float p_distance) override;
-	void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override;
-	void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override;
-	void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override;
-	void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override;
-	void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override;
-	void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override;
-	void reflection_probe_set_resolution(RID p_probe, int p_resolution) override;
-	void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override;
-	float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override;
-
-	AABB reflection_probe_get_aabb(RID p_probe) const override;
-	RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
-	uint32_t reflection_probe_get_cull_mask(RID p_probe) const override;
-	Vector3 reflection_probe_get_extents(RID p_probe) const override;
-	Vector3 reflection_probe_get_origin_offset(RID p_probe) const override;
-	float reflection_probe_get_origin_max_distance(RID p_probe) const override;
-	bool reflection_probe_renders_shadows(RID p_probe) const override;
-
-	void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
-
 	/* VOXEL GI API */
 
 	RID voxel_gi_allocate() override;
@@ -241,23 +171,6 @@ public:
 
 	uint32_t voxel_gi_get_version(RID p_voxel_gi) override;
 
-	/* LIGHTMAP CAPTURE */
-	RID lightmap_allocate() override;
-	void lightmap_initialize(RID p_rid) override;
-	void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override;
-	void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override;
-	void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override;
-	void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override;
-	PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override;
-	PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override;
-	PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override;
-	PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override;
-	AABB lightmap_get_aabb(RID p_lightmap) const override;
-	void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override;
-	bool lightmap_is_interior(RID p_lightmap) const override;
-	void lightmap_set_probe_capture_update_speed(float p_speed) override;
-	float lightmap_get_probe_capture_update_speed() const override;
-
 	/* OCCLUDER */
 
 	void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices);

+ 316 - 0
drivers/gles3/storage/light_storage.cpp

@@ -0,0 +1,316 @@
+/*************************************************************************/
+/*  light_storage.cpp                                                    */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifdef GLES3_ENABLED
+
+#include "light_storage.h"
+#include "config.h"
+
+using namespace GLES3;
+
+LightStorage *LightStorage::singleton = nullptr;
+
+LightStorage *LightStorage::get_singleton() {
+	return singleton;
+}
+
+LightStorage::LightStorage() {
+	singleton = this;
+}
+
+LightStorage::~LightStorage() {
+	singleton = nullptr;
+}
+
+/* Light API */
+
+RID LightStorage::directional_light_allocate() {
+	return RID();
+}
+
+void LightStorage::directional_light_initialize(RID p_rid) {
+}
+
+RID LightStorage::omni_light_allocate() {
+	return RID();
+}
+
+void LightStorage::omni_light_initialize(RID p_rid) {
+}
+
+RID LightStorage::spot_light_allocate() {
+	return RID();
+}
+
+void LightStorage::spot_light_initialize(RID p_rid) {
+}
+
+void LightStorage::light_free(RID p_rid) {
+}
+
+void LightStorage::light_set_color(RID p_light, const Color &p_color) {
+}
+
+void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
+}
+
+void LightStorage::light_set_shadow(RID p_light, bool p_enabled) {
+}
+
+void LightStorage::light_set_projector(RID p_light, RID p_texture) {
+}
+
+void LightStorage::light_set_negative(RID p_light, bool p_enable) {
+}
+
+void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
+}
+
+void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
+}
+
+void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
+}
+
+void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
+}
+
+void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
+}
+
+void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
+}
+
+void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
+}
+
+void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) {
+}
+
+bool LightStorage::light_directional_get_blend_splits(RID p_light) const {
+	return false;
+}
+
+void LightStorage::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) {
+}
+
+RS::LightDirectionalSkyMode LightStorage::light_directional_get_sky_mode(RID p_light) const {
+	return RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY;
+}
+
+RS::LightDirectionalShadowMode LightStorage::light_directional_get_shadow_mode(RID p_light) {
+	return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
+}
+
+RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) {
+	return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
+}
+
+bool LightStorage::light_has_shadow(RID p_light) const {
+	return false;
+}
+
+bool LightStorage::light_has_projector(RID p_light) const {
+	return false;
+}
+
+RS::LightType LightStorage::light_get_type(RID p_light) const {
+	return RS::LIGHT_OMNI;
+}
+
+AABB LightStorage::light_get_aabb(RID p_light) const {
+	return AABB();
+}
+
+float LightStorage::light_get_param(RID p_light, RS::LightParam p_param) {
+	return 0.0;
+}
+
+Color LightStorage::light_get_color(RID p_light) {
+	return Color();
+}
+
+RS::LightBakeMode LightStorage::light_get_bake_mode(RID p_light) {
+	return RS::LIGHT_BAKE_DISABLED;
+}
+
+uint32_t LightStorage::light_get_max_sdfgi_cascade(RID p_light) {
+	return 0;
+}
+
+uint64_t LightStorage::light_get_version(RID p_light) const {
+	return 0;
+}
+
+/* PROBE API */
+
+RID LightStorage::reflection_probe_allocate() {
+	return RID();
+}
+
+void LightStorage::reflection_probe_initialize(RID p_rid) {
+}
+
+void LightStorage::reflection_probe_free(RID p_rid) {
+}
+
+void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
+}
+
+void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
+}
+
+void LightStorage::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {
+}
+
+void LightStorage::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {
+}
+
+void LightStorage::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {
+}
+
+void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
+}
+
+void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
+}
+
+void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
+}
+
+void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
+}
+
+void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
+}
+
+void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
+}
+
+void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
+}
+
+void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
+}
+
+AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
+	return AABB();
+}
+
+RS::ReflectionProbeUpdateMode LightStorage::reflection_probe_get_update_mode(RID p_probe) const {
+	return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE;
+}
+
+uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {
+	return 0;
+}
+
+Vector3 LightStorage::reflection_probe_get_extents(RID p_probe) const {
+	return Vector3();
+}
+
+Vector3 LightStorage::reflection_probe_get_origin_offset(RID p_probe) const {
+	return Vector3();
+}
+
+float LightStorage::reflection_probe_get_origin_max_distance(RID p_probe) const {
+	return 0.0;
+}
+
+bool LightStorage::reflection_probe_renders_shadows(RID p_probe) const {
+	return false;
+}
+
+void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {
+}
+
+float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
+	return 0.0;
+}
+
+/* LIGHTMAP CAPTURE */
+
+RID LightStorage::lightmap_allocate() {
+	return RID();
+}
+
+void LightStorage::lightmap_initialize(RID p_rid) {
+}
+
+void LightStorage::lightmap_free(RID p_rid) {
+}
+
+void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
+}
+
+void LightStorage::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
+}
+
+void LightStorage::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
+}
+
+void LightStorage::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
+}
+
+PackedVector3Array LightStorage::lightmap_get_probe_capture_points(RID p_lightmap) const {
+	return PackedVector3Array();
+}
+
+PackedColorArray LightStorage::lightmap_get_probe_capture_sh(RID p_lightmap) const {
+	return PackedColorArray();
+}
+
+PackedInt32Array LightStorage::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
+	return PackedInt32Array();
+}
+
+PackedInt32Array LightStorage::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
+	return PackedInt32Array();
+}
+
+AABB LightStorage::lightmap_get_aabb(RID p_lightmap) const {
+	return AABB();
+}
+
+void LightStorage::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
+}
+
+bool LightStorage::lightmap_is_interior(RID p_lightmap) const {
+	return false;
+}
+
+void LightStorage::lightmap_set_probe_capture_update_speed(float p_speed) {
+}
+
+float LightStorage::lightmap_get_probe_capture_update_speed() const {
+	return 0;
+}
+
+#endif // !GLES3_ENABLED

+ 154 - 0
drivers/gles3/storage/light_storage.h

@@ -0,0 +1,154 @@
+/*************************************************************************/
+/*  light_storage.h                                                      */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef LIGHT_STORAGE_GLES3_H
+#define LIGHT_STORAGE_GLES3_H
+
+#ifdef GLES3_ENABLED
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/self_list.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering/storage/light_storage.h"
+
+namespace GLES3 {
+
+class LightStorage : public RendererLightStorage {
+private:
+	static LightStorage *singleton;
+
+public:
+	static LightStorage *get_singleton();
+
+	LightStorage();
+	virtual ~LightStorage();
+
+	/* Light API */
+
+	virtual RID directional_light_allocate() override;
+	virtual void directional_light_initialize(RID p_rid) override;
+	virtual RID omni_light_allocate() override;
+	virtual void omni_light_initialize(RID p_rid) override;
+	virtual RID spot_light_allocate() override;
+	virtual void spot_light_initialize(RID p_rid) override;
+
+	virtual void light_free(RID p_rid) override;
+
+	virtual void light_set_color(RID p_light, const Color &p_color) override;
+	virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override;
+	virtual void light_set_shadow(RID p_light, bool p_enabled) override;
+	virtual void light_set_projector(RID p_light, RID p_texture) override;
+	virtual void light_set_negative(RID p_light, bool p_enable) override;
+	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_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;
+
+	virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override;
+
+	virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override;
+	virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) override;
+	virtual bool light_directional_get_blend_splits(RID p_light) const override;
+	virtual void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) override;
+	virtual RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const override;
+
+	virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override;
+	virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override;
+
+	virtual bool light_has_shadow(RID p_light) const override;
+	virtual bool light_has_projector(RID p_light) const override;
+
+	virtual RS::LightType light_get_type(RID p_light) const override;
+	virtual AABB light_get_aabb(RID p_light) const override;
+	virtual float light_get_param(RID p_light, RS::LightParam p_param) override;
+	virtual Color light_get_color(RID p_light) override;
+	virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override;
+	virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override;
+	virtual uint64_t light_get_version(RID p_light) const override;
+
+	/* PROBE API */
+
+	virtual RID reflection_probe_allocate() override;
+	virtual void reflection_probe_initialize(RID p_rid) override;
+	virtual void reflection_probe_free(RID p_rid) override;
+
+	virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override;
+	virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) override;
+	virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override;
+	virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override;
+	virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override;
+	virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) override;
+	virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override;
+	virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override;
+	virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override;
+	virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override;
+	virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override;
+	virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override;
+	virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) override;
+	virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override;
+	virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override;
+
+	virtual AABB reflection_probe_get_aabb(RID p_probe) const override;
+	virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
+	virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override;
+	virtual Vector3 reflection_probe_get_extents(RID p_probe) const override;
+	virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override;
+	virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override;
+	virtual bool reflection_probe_renders_shadows(RID p_probe) const override;
+
+	/* LIGHTMAP CAPTURE */
+
+	virtual RID lightmap_allocate() override;
+	virtual void lightmap_initialize(RID p_rid) override;
+	virtual void lightmap_free(RID p_rid) override;
+
+	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override;
+	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override;
+	virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override;
+	virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override;
+	virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override;
+	virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override;
+	virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override;
+	virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override;
+	virtual AABB lightmap_get_aabb(RID p_lightmap) const override;
+	virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override;
+	virtual bool lightmap_is_interior(RID p_lightmap) const override;
+	virtual void lightmap_set_probe_capture_update_speed(float p_speed) override;
+	virtual float lightmap_get_probe_capture_update_speed() const override;
+};
+
+} // namespace GLES3
+
+#endif // !GLES3_ENABLED
+
+#endif // !LIGHT_STORAGE_GLES3_H

+ 3 - 0
servers/rendering/dummy/rasterizer_dummy.h

@@ -37,6 +37,7 @@
 #include "servers/rendering/dummy/rasterizer_canvas_dummy.h"
 #include "servers/rendering/dummy/rasterizer_scene_dummy.h"
 #include "servers/rendering/dummy/rasterizer_storage_dummy.h"
+#include "servers/rendering/dummy/storage/light_storage.h"
 #include "servers/rendering/dummy/storage/material_storage.h"
 #include "servers/rendering/dummy/storage/mesh_storage.h"
 #include "servers/rendering/dummy/storage/texture_storage.h"
@@ -50,6 +51,7 @@ private:
 
 protected:
 	RasterizerCanvasDummy canvas;
+	RendererDummy::LightStorage light_storage;
 	RendererDummy::MaterialStorage material_storage;
 	RendererDummy::MeshStorage mesh_storage;
 	RendererDummy::TextureStorage texture_storage;
@@ -57,6 +59,7 @@ protected:
 	RasterizerSceneDummy scene;
 
 public:
+	RendererLightStorage *get_light_storage() override { return &light_storage; };
 	RendererMaterialStorage *get_material_storage() override { return &material_storage; };
 	RendererMeshStorage *get_mesh_storage() override { return &mesh_storage; };
 	RendererTextureStorage *get_texture_storage() override { return &texture_storage; };

+ 0 - 87
servers/rendering/dummy/rasterizer_storage_dummy.h

@@ -36,76 +36,6 @@
 
 class RasterizerStorageDummy : public RendererStorage {
 public:
-	/* Light API */
-
-	RID directional_light_allocate() override { return RID(); }
-	void directional_light_initialize(RID p_rid) override {}
-	RID omni_light_allocate() override { return RID(); }
-	void omni_light_initialize(RID p_rid) override {}
-	RID spot_light_allocate() override { return RID(); }
-	void spot_light_initialize(RID p_rid) override {}
-	RID reflection_probe_allocate() override { return RID(); }
-	void reflection_probe_initialize(RID p_rid) override {}
-
-	void light_set_color(RID p_light, const Color &p_color) override {}
-	void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {}
-	void light_set_shadow(RID p_light, bool p_enabled) override {}
-	void light_set_projector(RID p_light, RID p_texture) override {}
-	void light_set_negative(RID p_light, bool p_enable) override {}
-	void light_set_cull_mask(RID p_light, uint32_t p_mask) override {}
-	void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override {}
-	void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override {}
-	void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override {}
-	void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override {}
-
-	void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override {}
-
-	void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override {}
-	void light_directional_set_blend_splits(RID p_light, bool p_enable) override {}
-	bool light_directional_get_blend_splits(RID p_light) const override { return false; }
-	void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) override {}
-	RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const override { return RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; }
-
-	RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override { return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; }
-	RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override { return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; }
-
-	bool light_has_shadow(RID p_light) const override { return false; }
-	bool light_has_projector(RID p_light) const override { return false; }
-
-	RS::LightType light_get_type(RID p_light) const override { return RS::LIGHT_OMNI; }
-	AABB light_get_aabb(RID p_light) const override { return AABB(); }
-	float light_get_param(RID p_light, RS::LightParam p_param) override { return 0.0; }
-	Color light_get_color(RID p_light) override { return Color(); }
-	RS::LightBakeMode light_get_bake_mode(RID p_light) override { return RS::LIGHT_BAKE_DISABLED; }
-	uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
-	uint64_t light_get_version(RID p_light) const override { return 0; }
-
-	/* PROBE API */
-
-	void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override {}
-	void reflection_probe_set_intensity(RID p_probe, float p_intensity) override {}
-	void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override {}
-	void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override {}
-	void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override {}
-	void reflection_probe_set_max_distance(RID p_probe, float p_distance) override {}
-	void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override {}
-	void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override {}
-	void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override {}
-	void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override {}
-	void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override {}
-	void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override {}
-	void reflection_probe_set_resolution(RID p_probe, int p_resolution) override {}
-	void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override {}
-	float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override { return 0.0; }
-
-	AABB reflection_probe_get_aabb(RID p_probe) const override { return AABB(); }
-	RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override { return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; }
-	uint32_t reflection_probe_get_cull_mask(RID p_probe) const override { return 0; }
-	Vector3 reflection_probe_get_extents(RID p_probe) const override { return Vector3(); }
-	Vector3 reflection_probe_get_origin_offset(RID p_probe) const override { return Vector3(); }
-	float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
-	bool reflection_probe_renders_shadows(RID p_probe) const override { return false; }
-
 	void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
 
 	/* VOXEL GI API */
@@ -149,23 +79,6 @@ public:
 
 	uint32_t voxel_gi_get_version(RID p_voxel_gi) override { return 0; }
 
-	/* LIGHTMAP CAPTURE */
-	RID lightmap_allocate() override { return RID(); }
-	void lightmap_initialize(RID p_rid) override {}
-	void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {}
-	void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {}
-	void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override {}
-	void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override {}
-	PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override { return PackedVector3Array(); }
-	PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override { return PackedColorArray(); }
-	PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override { return PackedInt32Array(); }
-	PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override { return PackedInt32Array(); }
-	AABB lightmap_get_aabb(RID p_lightmap) const override { return AABB(); }
-	void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override {}
-	bool lightmap_is_interior(RID p_lightmap) const override { return false; }
-	void lightmap_set_probe_capture_update_speed(float p_speed) override {}
-	float lightmap_get_probe_capture_update_speed() const override { return 0; }
-
 	/* OCCLUDER */
 
 	void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {}

+ 135 - 0
servers/rendering/dummy/storage/light_storage.h

@@ -0,0 +1,135 @@
+/*************************************************************************/
+/*  light_storage.h                                                      */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef LIGHT_STORAGE_DUMMY_H
+#define LIGHT_STORAGE_DUMMY_H
+
+#include "servers/rendering/storage/light_storage.h"
+
+namespace RendererDummy {
+
+class LightStorage : public RendererLightStorage {
+public:
+	/* Light API */
+
+	virtual RID directional_light_allocate() override { return RID(); }
+	virtual void directional_light_initialize(RID p_rid) override {}
+	virtual RID omni_light_allocate() override { return RID(); }
+	virtual void omni_light_initialize(RID p_rid) override {}
+	virtual RID spot_light_allocate() override { return RID(); }
+	virtual void spot_light_initialize(RID p_rid) override {}
+
+	virtual void light_free(RID p_rid) override {}
+
+	virtual void light_set_color(RID p_light, const Color &p_color) override {}
+	virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {}
+	virtual void light_set_shadow(RID p_light, bool p_enabled) override {}
+	virtual void light_set_projector(RID p_light, RID p_texture) override {}
+	virtual void light_set_negative(RID p_light, bool p_enable) override {}
+	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_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 {}
+
+	virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override {}
+
+	virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override {}
+	virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) override {}
+	virtual bool light_directional_get_blend_splits(RID p_light) const override { return false; }
+	virtual void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) override {}
+	virtual RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const override { return RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; }
+
+	virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override { return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; }
+	virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override { return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; }
+
+	virtual bool light_has_shadow(RID p_light) const override { return false; }
+	virtual bool light_has_projector(RID p_light) const override { return false; }
+
+	virtual RS::LightType light_get_type(RID p_light) const override { return RS::LIGHT_OMNI; }
+	virtual AABB light_get_aabb(RID p_light) const override { return AABB(); }
+	virtual float light_get_param(RID p_light, RS::LightParam p_param) override { return 0.0; }
+	virtual Color light_get_color(RID p_light) override { return Color(); }
+	virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override { return RS::LIGHT_BAKE_DISABLED; }
+	virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
+	virtual uint64_t light_get_version(RID p_light) const override { return 0; }
+
+	/* PROBE API */
+	virtual RID reflection_probe_allocate() override { return RID(); }
+	virtual void reflection_probe_initialize(RID p_rid) override {}
+	virtual void reflection_probe_free(RID p_rid) override {}
+
+	virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override {}
+	virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) override {}
+	virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override {}
+	virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override {}
+	virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override {}
+	virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) override {}
+	virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override {}
+	virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override {}
+	virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override {}
+	virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override {}
+	virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override {}
+	virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override {}
+	virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) override {}
+	virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override {}
+	virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override { return 0.0; }
+
+	virtual AABB reflection_probe_get_aabb(RID p_probe) const override { return AABB(); }
+	virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override { return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; }
+	virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override { return 0; }
+	virtual Vector3 reflection_probe_get_extents(RID p_probe) const override { return Vector3(); }
+	virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override { return Vector3(); }
+	virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
+	virtual bool reflection_probe_renders_shadows(RID p_probe) const override { return false; }
+
+	/* LIGHTMAP CAPTURE */
+	virtual RID lightmap_allocate() override { return RID(); }
+	virtual void lightmap_initialize(RID p_rid) override {}
+	virtual void lightmap_free(RID p_rid) override {}
+
+	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {}
+	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {}
+	virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override {}
+	virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override {}
+	virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override { return PackedVector3Array(); }
+	virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override { return PackedColorArray(); }
+	virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override { return PackedInt32Array(); }
+	virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override { return PackedInt32Array(); }
+	virtual AABB lightmap_get_aabb(RID p_lightmap) const override { return AABB(); }
+	virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override {}
+	virtual bool lightmap_is_interior(RID p_lightmap) const override { return false; }
+	virtual void lightmap_set_probe_capture_update_speed(float p_speed) override {}
+	virtual float lightmap_get_probe_capture_update_speed() const override { return 0; }
+};
+
+} // namespace RendererDummy
+
+#endif // !LIGHT_STORAGE_DUMMY_H

+ 2 - 0
servers/rendering/renderer_compositor.h

@@ -34,6 +34,7 @@
 #include "servers/rendering/renderer_canvas_render.h"
 #include "servers/rendering/renderer_scene.h"
 #include "servers/rendering/renderer_storage.h"
+#include "servers/rendering/storage/light_storage.h"
 #include "servers/rendering/storage/material_storage.h"
 #include "servers/rendering/storage/mesh_storage.h"
 #include "servers/rendering/storage/texture_storage.h"
@@ -73,6 +74,7 @@ protected:
 public:
 	static RendererCompositor *create();
 
+	virtual RendererLightStorage *get_light_storage() = 0;
 	virtual RendererMaterialStorage *get_material_storage() = 0;
 	virtual RendererMeshStorage *get_mesh_storage() = 0;
 	virtual RendererTextureStorage *get_texture_storage() = 0;

+ 10 - 6
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -30,6 +30,7 @@
 
 #include "render_forward_clustered.h"
 #include "core/config/project_settings.h"
+#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
@@ -839,7 +840,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
 		scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);
 
 	} else {
-		if (p_render_data->reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+		if (p_render_data->reflection_probe.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
 			scene_state.ubo.use_ambient_light = false;
 		} else {
 			scene_state.ubo.use_ambient_light = true;
@@ -1230,7 +1231,7 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps
 		to_lm = to_lm.inverse().transposed(); //will transform normals
 		RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
 		scene_state.lightmap_ids[i] = p_lightmaps[i];
-		scene_state.lightmap_has_sh[i] = storage->lightmap_uses_spherical_harmonics(lightmap);
+		scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
 
 		scene_state.lightmaps_used++;
 	}
@@ -1338,7 +1339,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
 		color_only_framebuffer = color_framebuffer;
 		depth_framebuffer = reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
 
-		if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+		if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
 			p_render_data->environment = RID(); //no environment on interiors
 			env = nullptr;
 		}
@@ -2025,14 +2026,16 @@ void RenderForwardClustered::_base_uniforms_changed() {
 }
 
 void RenderForwardClustered::_update_render_base_uniform_set() {
-	if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version()) || base_uniform_set_updated) {
+	RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
+
+	if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version()) || base_uniform_set_updated) {
 		base_uniform_set_updated = false;
 
 		if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
 			RD::get_singleton()->free(render_base_uniform_set);
 		}
 
-		lightmap_texture_array_version = storage->lightmap_array_get_version();
+		lightmap_texture_array_version = light_storage->lightmap_array_get_version();
 
 		Vector<RD::Uniform> uniforms;
 
@@ -2209,6 +2212,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
 
 RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
 	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+	RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
 
 	RenderBufferDataForwardClustered *rb = nullptr;
 	if (p_render_data && p_render_data->render_buffers.is_valid()) {
@@ -2298,7 +2302,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
 		for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
 			if (p_render_data && i < p_render_data->lightmaps->size()) {
 				RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
-				RID texture = storage->lightmap_get_texture(base);
+				RID texture = light_storage->lightmap_get_texture(base);
 				RID rd_texture = texture_storage->texture_get_rd_texture(texture);
 				u.append_id(rd_texture);
 			} else {

+ 9 - 6
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

@@ -30,6 +30,7 @@
 
 #include "render_forward_mobile.h"
 #include "core/config/project_settings.h"
+#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_device.h"
@@ -377,7 +378,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
 		for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
 			if (p_render_data && i < p_render_data->lightmaps->size()) {
 				RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
-				RID texture = storage->lightmap_get_texture(base);
+				RID texture = RendererRD::LightStorage::get_singleton()->lightmap_get_texture(base);
 				RID rd_texture = texture_storage->texture_get_rd_texture(texture);
 				u.append_id(rd_texture);
 			} else {
@@ -465,7 +466,7 @@ void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, c
 		to_lm = to_lm.inverse().transposed(); //will transform normals
 		RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
 		scene_state.lightmap_ids[i] = p_lightmaps[i];
-		scene_state.lightmap_has_sh[i] = storage->lightmap_uses_spherical_harmonics(lightmap);
+		scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
 
 		scene_state.lightmaps_used++;
 	}
@@ -553,7 +554,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 
 		framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
 
-		if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+		if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
 			p_render_data->environment = RID(); //no environment on interiors
 			env = nullptr;
 		}
@@ -1137,14 +1138,16 @@ void RenderForwardMobile::_base_uniforms_changed() {
 }
 
 void RenderForwardMobile::_update_render_base_uniform_set() {
-	if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) {
+	RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
+
+	if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version())) {
 		if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
 			RD::get_singleton()->free(render_base_uniform_set);
 		}
 
 		// This is all loaded into set 0
 
-		lightmap_texture_array_version = storage->lightmap_array_get_version();
+		lightmap_texture_array_version = light_storage->lightmap_array_get_version();
 
 		Vector<RD::Uniform> uniforms;
 
@@ -1667,7 +1670,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
 		scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);
 
 	} else {
-		if (p_render_data->reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+		if (p_render_data->reflection_probe.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
 			scene_state.ubo.use_ambient_light = false;
 		} else {
 			scene_state.ubo.use_ambient_light = true;

+ 2 - 0
servers/rendering/renderer_rd/renderer_compositor_rd.cpp

@@ -155,6 +155,7 @@ void RendererCompositorRD::finalize() {
 	memdelete(scene);
 	memdelete(canvas);
 	memdelete(storage);
+	memdelete(light_storage);
 	memdelete(mesh_storage);
 	memdelete(material_storage);
 	memdelete(texture_storage);
@@ -289,6 +290,7 @@ RendererCompositorRD::RendererCompositorRD() {
 	texture_storage = memnew(RendererRD::TextureStorage);
 	material_storage = memnew(RendererRD::MaterialStorage);
 	mesh_storage = memnew(RendererRD::MeshStorage);
+	light_storage = memnew(RendererRD::LightStorage);
 	storage = memnew(RendererStorageRD);
 	canvas = memnew(RendererCanvasRenderRD(storage));
 

+ 3 - 0
servers/rendering/renderer_rd/renderer_compositor_rd.h

@@ -39,6 +39,7 @@
 #include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
 #include "servers/rendering/renderer_rd/renderer_storage_rd.h"
 #include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
@@ -48,6 +49,7 @@ class RendererCompositorRD : public RendererCompositor {
 protected:
 	UniformSetCacheRD *uniform_set_cache = nullptr;
 	RendererCanvasRenderRD *canvas = nullptr;
+	RendererRD::LightStorage *light_storage;
 	RendererRD::MaterialStorage *material_storage;
 	RendererRD::MeshStorage *mesh_storage;
 	RendererRD::TextureStorage *texture_storage;
@@ -94,6 +96,7 @@ protected:
 	static uint64_t frame;
 
 public:
+	RendererLightStorage *get_light_storage() { return light_storage; };
 	RendererMaterialStorage *get_material_storage() { return material_storage; };
 	RendererMeshStorage *get_mesh_storage() { return mesh_storage; };
 	RendererTextureStorage *get_texture_storage() { return texture_storage; };

+ 31 - 31
servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp

@@ -1459,7 +1459,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re
 			RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->directional_lights->get(j));
 			ERR_CONTINUE(!li);
 
-			if (storage->light_directional_get_sky_mode(li->light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
+			if (RSG::light_storage->light_directional_get_sky_mode(li->light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
 				continue;
 			}
 
@@ -1469,14 +1469,14 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re
 			lights[idx].direction[0] = dir.x;
 			lights[idx].direction[1] = dir.y;
 			lights[idx].direction[2] = dir.z;
-			Color color = storage->light_get_color(li->light);
+			Color color = RSG::light_storage->light_get_color(li->light);
 			color = color.srgb_to_linear();
 			lights[idx].color[0] = color.r;
 			lights[idx].color[1] = color.g;
 			lights[idx].color[2] = color.b;
 			lights[idx].type = RS::LIGHT_DIRECTIONAL;
-			lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
-			lights[idx].has_shadow = storage->light_has_shadow(li->light);
+			lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+			lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light);
 
 			idx++;
 		}
@@ -1493,7 +1493,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re
 			RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->positional_light_instances[j]);
 			ERR_CONTINUE(!li);
 
-			uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light);
+			uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(li->light);
 			if (i > max_sdfgi_cascade) {
 				continue;
 			}
@@ -1514,18 +1514,18 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re
 			lights[idx].position[0] = pos.x;
 			lights[idx].position[1] = pos.y;
 			lights[idx].position[2] = pos.z;
-			Color color = storage->light_get_color(li->light);
+			Color color = RSG::light_storage->light_get_color(li->light);
 			color = color.srgb_to_linear();
 			lights[idx].color[0] = color.r;
 			lights[idx].color[1] = color.g;
 			lights[idx].color[2] = color.b;
-			lights[idx].type = storage->light_get_type(li->light);
-			lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
-			lights[idx].has_shadow = storage->light_has_shadow(li->light);
-			lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
-			lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
-			lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
-			lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+			lights[idx].type = RSG::light_storage->light_get_type(li->light);
+			lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+			lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light);
+			lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
+			lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
+			lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
+			lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
 
 			idx++;
 		}
@@ -1929,7 +1929,7 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32
 				RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_positional_light_cull_result[i][j]);
 				ERR_CONTINUE(!li);
 
-				uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light);
+				uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(li->light);
 				if (p_cascade_indices[i] > max_sdfgi_cascade) {
 					continue;
 				}
@@ -1938,7 +1938,7 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32
 					continue;
 				}
 
-				lights[idx].type = storage->light_get_type(li->light);
+				lights[idx].type = RSG::light_storage->light_get_type(li->light);
 
 				Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
 				if (lights[idx].type == RS::LIGHT_DIRECTIONAL) {
@@ -1953,17 +1953,17 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32
 				lights[idx].position[0] = pos.x;
 				lights[idx].position[1] = pos.y;
 				lights[idx].position[2] = pos.z;
-				Color color = storage->light_get_color(li->light);
+				Color color = RSG::light_storage->light_get_color(li->light);
 				color = color.srgb_to_linear();
 				lights[idx].color[0] = color.r;
 				lights[idx].color[1] = color.g;
 				lights[idx].color[2] = color.b;
-				lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
-				lights[idx].has_shadow = storage->light_has_shadow(li->light);
-				lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
-				lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
-				lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
-				lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+				lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+				lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light);
+				lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
+				lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
+				lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
+				lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
 
 				idx++;
 			}
@@ -2388,22 +2388,22 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
 				RID light_instance = p_light_instances[i];
 				RID light = p_scene_render->light_instance_get_base_light(light_instance);
 
-				l.type = storage->light_get_type(light);
-				if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
+				l.type = RSG::light_storage->light_get_type(light);
+				if (l.type == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
 					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();
-				Color color = storage->light_get_color(light).srgb_to_linear();
+				l.attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
+				l.energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+				l.radius = to_cell.basis.xform(Vector3(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();
+				Color color = RSG::light_storage->light_get_color(light).srgb_to_linear();
 				l.color[0] = color.r;
 				l.color[1] = color.g;
 				l.color[2] = color.b;
 
-				l.cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
-				l.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+				l.cos_spot_angle = Math::cos(Math::deg2rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
+				l.inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
 
 				Transform3D xform = p_scene_render->light_instance_get_base_transform(light_instance);
 
@@ -2418,7 +2418,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
 				l.direction[1] = dir.y;
 				l.direction[2] = dir.z;
 
-				l.has_shadow = storage->light_has_shadow(light);
+				l.has_shadow = RSG::light_storage->light_has_shadow(light);
 			}
 
 			RD::get_singleton()->buffer_update(gi->voxel_gi_lights_uniform, 0, sizeof(VoxelGILight) * light_count, gi->voxel_gi_lights);

+ 83 - 80
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -689,7 +689,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_needs_redraw(RID p_instanc
 		return true;
 	}
 
-	if (storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
+	if (RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
 		return true;
 	}
 
@@ -713,12 +713,12 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
 
 	RD::get_singleton()->draw_command_begin_label("Reflection probe render");
 
-	if (storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->size != 256) {
+	if (RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->size != 256) {
 		WARN_PRINT("ReflectionProbes set to UPDATE_ALWAYS must have an atlas size of 256. Please update the atlas size in the ProjectSettings.");
 		reflection_atlas_set_size(p_reflection_atlas, 256, atlas->count);
 	}
 
-	if (storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->reflections[0].data.layers[0].mipmaps.size() != 8) {
+	if (RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->reflections[0].data.layers[0].mipmaps.size() != 8) {
 		// Invalidate reflection atlas, need to regenerate
 		RD::get_singleton()->free(atlas->reflection);
 		atlas->reflection = RID();
@@ -735,7 +735,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
 
 	if (atlas->reflection.is_null()) {
 		int mipmaps = MIN(sky.roughness_layers, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) + 1);
-		mipmaps = storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS ? 8 : mipmaps; // always use 8 mipmaps with real time filtering
+		mipmaps = RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS ? 8 : mipmaps; // always use 8 mipmaps with real time filtering
 		{
 			//reflection atlas was unused, create:
 			RD::TextureFormat tf;
@@ -759,7 +759,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
 		}
 		atlas->reflections.resize(atlas->count);
 		for (int i = 0; i < atlas->count; i++) {
-			atlas->reflections.write[i].data.update_reflection_data(storage, atlas->size, mipmaps, false, atlas->reflection, i * 6, storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format());
+			atlas->reflections.write[i].data.update_reflection_data(storage, atlas->size, mipmaps, false, atlas->reflection, i * 6, RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format());
 			for (int j = 0; j < 6; j++) {
 				atlas->reflections.write[i].fbs[j] = reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer);
 			}
@@ -827,7 +827,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
 		return false;
 	}
 
-	if (storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
+	if (RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
 		// Using real time reflections, all roughness is done in one step
 		atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(storage, false);
 		rpi->rendering = false;
@@ -1345,7 +1345,7 @@ int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance
 	LightInstance *light_instance = light_instance_owner.get_or_null(p_light_intance);
 	ERR_FAIL_COND_V(!light_instance, 0);
 
-	switch (storage->light_directional_get_shadow_mode(light_instance->light)) {
+	switch (RSG::light_storage->light_directional_get_shadow_mode(light_instance->light)) {
 		case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
 			break; //none
 		case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
@@ -1407,7 +1407,7 @@ RID RendererSceneRenderRD::light_instance_create(RID p_light) {
 
 	light_instance->self = li;
 	light_instance->light = p_light;
-	light_instance->light_type = storage->light_get_type(p_light);
+	light_instance->light_type = RSG::light_storage->light_get_type(p_light);
 	if (light_instance->light_type != RS::LIGHT_DIRECTIONAL) {
 		light_instance->forward_id = _allocate_forward_id(light_instance->light_type == RS::LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT);
 	}
@@ -3191,6 +3191,7 @@ RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_g
 }
 
 void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment) {
+	RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
 	cluster.reflection_count = 0;
 
 	for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) {
@@ -3225,30 +3226,30 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
 
 		Cluster::ReflectionData &reflection_ubo = cluster.reflections[i];
 
-		Vector3 extents = storage->reflection_probe_get_extents(base_probe);
+		Vector3 extents = light_storage->reflection_probe_get_extents(base_probe);
 
-		rpi->cull_mask = storage->reflection_probe_get_cull_mask(base_probe);
+		rpi->cull_mask = light_storage->reflection_probe_get_cull_mask(base_probe);
 
 		reflection_ubo.box_extents[0] = extents.x;
 		reflection_ubo.box_extents[1] = extents.y;
 		reflection_ubo.box_extents[2] = extents.z;
 		reflection_ubo.index = rpi->atlas_index;
 
-		Vector3 origin_offset = storage->reflection_probe_get_origin_offset(base_probe);
+		Vector3 origin_offset = light_storage->reflection_probe_get_origin_offset(base_probe);
 
 		reflection_ubo.box_offset[0] = origin_offset.x;
 		reflection_ubo.box_offset[1] = origin_offset.y;
 		reflection_ubo.box_offset[2] = origin_offset.z;
-		reflection_ubo.mask = storage->reflection_probe_get_cull_mask(base_probe);
+		reflection_ubo.mask = light_storage->reflection_probe_get_cull_mask(base_probe);
 
-		reflection_ubo.intensity = storage->reflection_probe_get_intensity(base_probe);
-		reflection_ubo.ambient_mode = storage->reflection_probe_get_ambient_mode(base_probe);
+		reflection_ubo.intensity = light_storage->reflection_probe_get_intensity(base_probe);
+		reflection_ubo.ambient_mode = light_storage->reflection_probe_get_ambient_mode(base_probe);
 
-		reflection_ubo.exterior = !storage->reflection_probe_is_interior(base_probe);
-		reflection_ubo.box_project = storage->reflection_probe_is_box_projection(base_probe);
+		reflection_ubo.exterior = !light_storage->reflection_probe_is_interior(base_probe);
+		reflection_ubo.box_project = light_storage->reflection_probe_is_box_projection(base_probe);
 
-		Color ambient_linear = storage->reflection_probe_get_ambient_color(base_probe).srgb_to_linear();
-		float interior_ambient_energy = storage->reflection_probe_get_ambient_color_energy(base_probe);
+		Color ambient_linear = light_storage->reflection_probe_get_ambient_color(base_probe).srgb_to_linear();
+		float interior_ambient_energy = light_storage->reflection_probe_get_ambient_color_energy(base_probe);
 		reflection_ubo.ambient[0] = ambient_linear.r * interior_ambient_energy;
 		reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy;
 		reflection_ubo.ambient[2] = ambient_linear.b * interior_ambient_energy;
@@ -3271,6 +3272,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
 
 void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) {
 	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+	RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
 
 	Transform3D inverse_transform = p_camera_transform.affine_inverse();
 
@@ -3293,10 +3295,10 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 
 		ERR_CONTINUE(base.is_null());
 
-		RS::LightType type = storage->light_get_type(base);
+		RS::LightType type = light_storage->light_get_type(base);
 		switch (type) {
 			case RS::LIGHT_DIRECTIONAL: {
-				if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_get_sky_mode(base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
+				if (r_directional_light_count >= cluster.max_directional_lights || light_storage->light_directional_get_sky_mode(base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
 					continue;
 				}
 
@@ -3310,19 +3312,19 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 				light_data.direction[1] = direction.y;
 				light_data.direction[2] = direction.z;
 
-				float sign = storage->light_is_negative(base) ? -1 : 1;
+				float sign = light_storage->light_is_negative(base) ? -1 : 1;
 
-				light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI;
+				light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI;
 
-				Color linear_col = storage->light_get_color(base).srgb_to_linear();
+				Color linear_col = light_storage->light_get_color(base).srgb_to_linear();
 				light_data.color[0] = linear_col.r;
 				light_data.color[1] = linear_col.g;
 				light_data.color[2] = linear_col.b;
 
-				light_data.specular = storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR);
-				light_data.mask = storage->light_get_cull_mask(base);
+				light_data.specular = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR);
+				light_data.mask = light_storage->light_get_cull_mask(base);
 
-				float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+				float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
 
 				light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset
 
@@ -3330,15 +3332,15 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 					WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet.");
 				}
 
-				light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base);
+				light_data.shadow_enabled = p_using_shadows && light_storage->light_has_shadow(base);
 
-				float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+				float angular_diameter = light_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));
-					if (storage->light_has_shadow(base)) {
+					if (light_storage->light_has_shadow(base)) {
 						r_directional_light_soft_shadows = true;
 					}
 				} else {
@@ -3346,10 +3348,10 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 				}
 
 				if (light_data.shadow_enabled) {
-					RS::LightDirectionalShadowMode smode = storage->light_directional_get_shadow_mode(base);
+					RS::LightDirectionalShadowMode smode = light_storage->light_directional_get_shadow_mode(base);
 
 					int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
-					light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && storage->light_directional_get_blend_splits(base);
+					light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light_storage->light_directional_get_blend_splits(base);
 					for (int j = 0; j < 4; j++) {
 						Rect2 atlas_rect = li->shadow_transform[j].atlas_rect;
 						CameraMatrix matrix = li->shadow_transform[j].camera;
@@ -3365,9 +3367,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 						CameraMatrix shadow_mtx = rectm * bias * matrix * modelview;
 						light_data.shadow_split_offsets[j] = split;
 						float bias_scale = li->shadow_transform[j].bias_scale;
-						light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale;
-						light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size;
-						light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale;
+						light_data.shadow_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale;
+						light_data.shadow_normal_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size;
+						light_data.shadow_transmittance_bias[j] = light_storage->light_get_transmittance_bias(base) * bias_scale;
 						light_data.shadow_z_range[j] = li->shadow_transform[j].farplane;
 						light_data.shadow_range_begin[j] = li->shadow_transform[j].range_begin;
 						RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
@@ -3394,14 +3396,14 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 						}
 					}
 
-					float fade_start = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START);
+					float fade_start = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START);
 					light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep
 					light_data.fade_to = -light_data.shadow_split_offsets[3];
-					light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base);
+					light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base);
 
-					light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
+					light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
 					light_data.softshadow_angle = angular_diameter;
-					light_data.bake_mode = storage->light_get_bake_mode(base);
+					light_data.bake_mode = light_storage->light_get_bake_mode(base);
 
 					if (angular_diameter <= 0.0) {
 						light_data.soft_shadow_scale *= directional_shadow_quality_radius_get(); // Only use quality radius for PCF
@@ -3417,9 +3419,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 
 				const real_t distance = camera_plane.distance_to(li->transform.origin);
 
-				if (storage->light_is_distance_fade_enabled(li->light)) {
-					const float fade_begin = storage->light_get_distance_fade_begin(li->light);
-					const float fade_length = storage->light_get_distance_fade_length(li->light);
+				if (light_storage->light_is_distance_fade_enabled(li->light)) {
+					const float fade_begin = light_storage->light_get_distance_fade_begin(li->light);
+					const float fade_length = light_storage->light_get_distance_fade_length(li->light);
 
 					if (distance > fade_begin) {
 						if (distance > fade_begin + fade_length) {
@@ -3440,9 +3442,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 
 				const real_t distance = camera_plane.distance_to(li->transform.origin);
 
-				if (storage->light_is_distance_fade_enabled(li->light)) {
-					const float fade_begin = storage->light_get_distance_fade_begin(li->light);
-					const float fade_length = storage->light_get_distance_fade_length(li->light);
+				if (light_storage->light_is_distance_fade_enabled(li->light)) {
+					const float fade_begin = light_storage->light_get_distance_fade_begin(li->light);
+					const float fade_length = light_storage->light_get_distance_fade_length(li->light);
 
 					if (distance > fade_begin) {
 						if (distance > fade_begin + fade_length) {
@@ -3492,10 +3494,10 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 
 		Transform3D light_transform = li->transform;
 
-		float sign = storage->light_is_negative(base) ? -1 : 1;
-		Color linear_col = storage->light_get_color(base).srgb_to_linear();
+		float sign = light_storage->light_is_negative(base) ? -1 : 1;
+		Color linear_col = light_storage->light_get_color(base).srgb_to_linear();
 
-		light_data.attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION);
+		light_data.attenuation = light_storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION);
 
 		// Reuse fade begin, fade length and distance for shadow LOD determination later.
 		float fade_begin = 0.0;
@@ -3503,9 +3505,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 		real_t distance = 0.0;
 
 		float fade = 1.0;
-		if (storage->light_is_distance_fade_enabled(li->light)) {
-			fade_begin = storage->light_get_distance_fade_begin(li->light);
-			fade_length = storage->light_get_distance_fade_length(li->light);
+		if (light_storage->light_is_distance_fade_enabled(li->light)) {
+			fade_begin = light_storage->light_get_distance_fade_begin(li->light);
+			fade_length = light_storage->light_get_distance_fade_length(li->light);
 			distance = camera_plane.distance_to(li->transform.origin);
 
 			if (distance > fade_begin) {
@@ -3514,15 +3516,15 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 			}
 		}
 
-		float energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade;
+		float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade;
 
 		light_data.color[0] = linear_col.r * energy;
 		light_data.color[1] = linear_col.g * energy;
 		light_data.color[2] = linear_col.b * energy;
-		light_data.specular_amount = storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0;
-		light_data.bake_mode = storage->light_get_bake_mode(base);
+		light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0;
+		light_data.bake_mode = light_storage->light_get_bake_mode(base);
 
-		float radius = MAX(0.001, storage->light_get_param(base, RS::LIGHT_PARAM_RANGE));
+		float radius = MAX(0.001, light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE));
 		light_data.inv_radius = 1.0 / radius;
 
 		Vector3 pos = inverse_transform.xform(light_transform.origin);
@@ -3537,22 +3539,22 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 		light_data.direction[1] = direction.y;
 		light_data.direction[2] = direction.z;
 
-		float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+		float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
 
 		light_data.size = size;
 
-		light_data.inv_spot_attenuation = 1.0f / storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
-		float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);
+		light_data.inv_spot_attenuation = 1.0f / light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+		float spot_angle = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);
 		light_data.cos_spot_angle = Math::cos(Math::deg2rad(spot_angle));
 
-		light_data.mask = storage->light_get_cull_mask(base);
+		light_data.mask = light_storage->light_get_cull_mask(base);
 
 		light_data.atlas_rect[0] = 0;
 		light_data.atlas_rect[1] = 0;
 		light_data.atlas_rect[2] = 0;
 		light_data.atlas_rect[3] = 0;
 
-		RID projector = storage->light_get_projector(base);
+		RID projector = light_storage->light_get_projector(base);
 
 		if (projector.is_valid()) {
 			Rect2 rect = texture_storage->decal_atlas_get_texture_rect(projector);
@@ -3578,8 +3580,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 		const bool needs_shadow = shadow_atlas && shadow_atlas->shadow_owners.has(li->self);
 
 		bool in_shadow_range = true;
-		if (needs_shadow && storage->light_is_distance_fade_enabled(li->light)) {
-			if (distance > storage->light_get_distance_fade_shadow(li->light)) {
+		if (needs_shadow && light_storage->light_is_distance_fade_enabled(li->light)) {
+			if (distance > light_storage->light_get_distance_fade_shadow(li->light)) {
 				// Out of range, don't draw shadows to improve performance.
 				in_shadow_range = false;
 			}
@@ -3591,15 +3593,15 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 			light_data.shadow_enabled = true;
 
 			float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
-			light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;
+			light_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;
 
 			if (type == RS::LIGHT_SPOT) {
-				light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0;
+				light_data.shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0;
 			} else { //omni
-				light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS);
+				light_data.shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS);
 			}
 
-			light_data.transmittance_bias = storage->light_get_transmittance_bias(base);
+			light_data.transmittance_bias = light_storage->light_get_transmittance_bias(base);
 
 			Vector2i omni_offset;
 			Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas, omni_offset);
@@ -3609,8 +3611,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 			light_data.atlas_rect[2] = rect.size.width;
 			light_data.atlas_rect[3] = rect.size.height;
 
-			light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
-			light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base);
+			light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
+			light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base);
 
 			if (type == RS::LIGHT_OMNI) {
 				Transform3D proj = (inverse_transform * light_transform).inverse();
@@ -3647,7 +3649,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 			light_data.shadow_enabled = false;
 		}
 
-		li->cull_mask = storage->light_get_cull_mask(base);
+		li->cull_mask = light_storage->light_get_cull_mask(base);
 
 		if (current_cluster_builder != nullptr) {
 			current_cluster_builder->add_light(type == RS::LIGHT_SPOT ? ClusterBuilderRD::LIGHT_TYPE_SPOT : ClusterBuilderRD::LIGHT_TYPE_OMNI, light_transform, radius, spot_angle);
@@ -4811,6 +4813,7 @@ void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, boo
 
 void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer) {
 	// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
+	RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
 
 	if (p_render_data->render_buffers.is_valid() && p_use_gi) {
 		RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
@@ -4830,9 +4833,9 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 		for (int i = 0; i < render_state.render_shadow_count; i++) {
 			LightInstance *li = light_instance_owner.get_or_null(render_state.render_shadows[i].light);
 
-			if (storage->light_get_type(li->light) == RS::LIGHT_DIRECTIONAL) {
+			if (light_storage->light_get_type(li->light) == RS::LIGHT_DIRECTIONAL) {
 				render_state.directional_shadows.push_back(i);
-			} else if (storage->light_get_type(li->light) == RS::LIGHT_OMNI && storage->light_omni_get_shadow_mode(li->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
+			} else if (light_storage->light_get_type(li->light) == RS::LIGHT_OMNI && light_storage->light_omni_get_shadow_mode(li->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
 				render_state.cube_shadows.push_back(i);
 			} else {
 				render_state.shadows.push_back(i);
@@ -4942,7 +4945,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 	bool using_shadows = true;
 
 	if (p_render_data->reflection_probe.is_valid()) {
-		if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+		if (!RSG::light_storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
 			using_shadows = false;
 		}
 	} else {
@@ -5175,7 +5178,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
 	CameraMatrix light_projection;
 	Transform3D light_transform;
 
-	if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) {
+	if (RSG::light_storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) {
 		//set pssm stuff
 		if (light_instance->last_scene_shadow_pass != scene_pass) {
 			light_instance->directional_rect = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light);
@@ -5183,13 +5186,13 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
 			light_instance->last_scene_shadow_pass = scene_pass;
 		}
 
-		use_pancake = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0;
+		use_pancake = RSG::light_storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0;
 		light_projection = light_instance->shadow_transform[p_pass].camera;
 		light_transform = light_instance->shadow_transform[p_pass].transform;
 
 		atlas_rect = light_instance->directional_rect;
 
-		if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
+		if (RSG::light_storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
 			atlas_rect.size.width /= 2;
 			atlas_rect.size.height /= 2;
 
@@ -5200,7 +5203,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
 			} else if (p_pass == 3) {
 				atlas_rect.position += atlas_rect.size;
 			}
-		} else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
+		} else if (RSG::light_storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
 			atlas_rect.size.height /= 2;
 
 			if (p_pass == 0) {
@@ -5214,7 +5217,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
 		light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size;
 		light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size;
 
-		zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
+		zfar = RSG::light_storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
 
 		render_fb = directional_shadow.fb;
 		render_texture = RID();
@@ -5248,13 +5251,13 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
 		atlas_rect.size.width = shadow_size;
 		atlas_rect.size.height = shadow_size;
 
-		zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
+		zfar = RSG::light_storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
 
-		if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) {
+		if (RSG::light_storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) {
 			bool wrap = (shadow + 1) % shadow_atlas->quadrants[quadrant].subdivision == 0;
 			dual_paraboloid_offset = wrap ? Vector2i(1 - shadow_atlas->quadrants[quadrant].subdivision, 1) : Vector2i(1, 0);
 
-			if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
+			if (RSG::light_storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
 				ShadowCubemap *cubemap = _get_shadow_cubemap(shadow_size / 2);
 
 				render_fb = cubemap->side_fb[p_pass];
@@ -5289,7 +5292,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
 				flip_y = true;
 			}
 
-		} else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) {
+		} else if (RSG::light_storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) {
 			light_projection = light_instance->shadow_transform[0].camera;
 			light_transform = light_instance->shadow_transform[0].transform;
 

+ 7 - 6
servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp

@@ -1086,6 +1086,7 @@ RendererSceneSkyRD::~RendererSceneSkyRD() {
 }
 
 void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
+	RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 	ERR_FAIL_COND(!p_env);
 
@@ -1181,8 +1182,8 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
 
 				ERR_CONTINUE(base.is_null());
 
-				RS::LightType type = storage->light_get_type(base);
-				if (type == RS::LIGHT_DIRECTIONAL && storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) {
+				RS::LightType type = light_storage->light_get_type(base);
+				if (type == RS::LIGHT_DIRECTIONAL && light_storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) {
 					SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count];
 					Transform3D light_transform = li->transform;
 					Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
@@ -1191,17 +1192,17 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
 					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);
+					float sign = light_storage->light_is_negative(base) ? -1 : 1;
+					sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
 
-					Color linear_col = storage->light_get_color(base).srgb_to_linear();
+					Color linear_col = light_storage->light_get_color(base).srgb_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);
+					float angular_diameter = light_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

+ 17 - 737
servers/rendering/renderer_rd/renderer_storage_rd.cpp

@@ -35,6 +35,7 @@
 #include "core/io/resource_loader.h"
 #include "core/math/math_defs.h"
 #include "renderer_compositor_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_server_globals.h"
@@ -1926,520 +1927,7 @@ void RendererStorageRD::visibility_notifier_call(RID p_notifier, bool p_enter, b
 	}
 }
 
-/* LIGHT */
-
-void RendererStorageRD::_light_initialize(RID p_light, RS::LightType p_type) {
-	Light light;
-	light.type = p_type;
-
-	light.param[RS::LIGHT_PARAM_ENERGY] = 1.0;
-	light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0;
-	light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
-	light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
-	light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
-	light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;
-	light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
-	light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;
-	light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
-	light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
-	light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
-	light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
-	light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
-	light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
-	light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
-	light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
-	light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
-	light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1;
-	light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
-
-	light_owner.initialize_rid(p_light, light);
-}
-
-RID RendererStorageRD::directional_light_allocate() {
-	return light_owner.allocate_rid();
-}
-void RendererStorageRD::directional_light_initialize(RID p_light) {
-	_light_initialize(p_light, RS::LIGHT_DIRECTIONAL);
-}
-
-RID RendererStorageRD::omni_light_allocate() {
-	return light_owner.allocate_rid();
-}
-void RendererStorageRD::omni_light_initialize(RID p_light) {
-	_light_initialize(p_light, RS::LIGHT_OMNI);
-}
-
-RID RendererStorageRD::spot_light_allocate() {
-	return light_owner.allocate_rid();
-}
-void RendererStorageRD::spot_light_initialize(RID p_light) {
-	_light_initialize(p_light, RS::LIGHT_SPOT);
-}
-
-void RendererStorageRD::light_set_color(RID p_light, const Color &p_color) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->color = p_color;
-}
-
-void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-	ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX);
-
-	if (light->param[p_param] == p_value) {
-		return;
-	}
-
-	switch (p_param) {
-		case RS::LIGHT_PARAM_RANGE:
-		case RS::LIGHT_PARAM_SPOT_ANGLE:
-		case RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE:
-		case RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET:
-		case RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
-		case RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
-		case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
-		case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
-		case RS::LIGHT_PARAM_SHADOW_BIAS: {
-			light->version++;
-			light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-		} break;
-		case RS::LIGHT_PARAM_SIZE: {
-			if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) {
-				//changing from no size to size and the opposite
-				light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
-			}
-		} break;
-		default: {
-		}
-	}
-
-	light->param[p_param] = p_value;
-}
-
-void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-	light->shadow = p_enabled;
-
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
-	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	if (light->projector == p_texture) {
-		return;
-	}
-
-	if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
-		texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
-	}
-
-	light->projector = p_texture;
-
-	if (light->type != RS::LIGHT_DIRECTIONAL) {
-		if (light->projector.is_valid()) {
-			texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
-		}
-		light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
-	}
-}
-
-void RendererStorageRD::light_set_negative(RID p_light, bool p_enable) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->negative = p_enable;
-}
-
-void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->cull_mask = p_mask;
-
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-void RendererStorageRD::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_COND(!light);
-
-	light->distance_fade = p_enabled;
-	light->distance_fade_begin = p_begin;
-	light->distance_fade_shadow = p_shadow;
-	light->distance_fade_length = p_length;
-}
-
-void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->reverse_cull = p_enabled;
-
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->bake_mode = p_bake_mode;
-
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->max_sdfgi_cascade = p_cascade;
-
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->omni_shadow_mode = p_mode;
-
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-RS::LightOmniShadowMode RendererStorageRD::light_omni_get_shadow_mode(RID p_light) {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE);
-
-	return light->omni_shadow_mode;
-}
-
-void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->directional_shadow_mode = p_mode;
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->directional_blend_splits = p_enable;
-	light->version++;
-	light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
-}
-
-bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, false);
-
-	return light->directional_blend_splits;
-}
-
-void RendererStorageRD::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) {
-	Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND(!light);
-
-	light->directional_sky_mode = p_mode;
-}
-
-RS::LightDirectionalSkyMode RendererStorageRD::light_directional_get_sky_mode(RID p_light) const {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY);
-
-	return light->directional_sky_mode;
-}
-
-RS::LightDirectionalShadowMode RendererStorageRD::light_directional_get_shadow_mode(RID p_light) {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
-
-	return light->directional_shadow_mode;
-}
-
-uint32_t RendererStorageRD::light_get_max_sdfgi_cascade(RID p_light) {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, 0);
-
-	return light->max_sdfgi_cascade;
-}
-
-RS::LightBakeMode RendererStorageRD::light_get_bake_mode(RID p_light) {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, RS::LIGHT_BAKE_DISABLED);
-
-	return light->bake_mode;
-}
-
-uint64_t RendererStorageRD::light_get_version(RID p_light) const {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, 0);
-
-	return light->version;
-}
-
-AABB RendererStorageRD::light_get_aabb(RID p_light) const {
-	const Light *light = light_owner.get_or_null(p_light);
-	ERR_FAIL_COND_V(!light, AABB());
-
-	switch (light->type) {
-		case RS::LIGHT_SPOT: {
-			float len = light->param[RS::LIGHT_PARAM_RANGE];
-			float size = Math::tan(Math::deg2rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len;
-			return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
-		};
-		case RS::LIGHT_OMNI: {
-			float r = light->param[RS::LIGHT_PARAM_RANGE];
-			return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
-		};
-		case RS::LIGHT_DIRECTIONAL: {
-			return AABB();
-		};
-	}
-
-	ERR_FAIL_V(AABB());
-}
-
-/* REFLECTION PROBE */
-
-RID RendererStorageRD::reflection_probe_allocate() {
-	return reflection_probe_owner.allocate_rid();
-}
-void RendererStorageRD::reflection_probe_initialize(RID p_reflection_probe) {
-	reflection_probe_owner.initialize_rid(p_reflection_probe, ReflectionProbe());
-}
-
-void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->update_mode = p_mode;
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-void RendererStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->intensity = p_intensity;
-}
-
-void RendererStorageRD::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->ambient_mode = p_mode;
-}
-
-void RendererStorageRD::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->ambient_color = p_color;
-}
-
-void RendererStorageRD::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->ambient_color_energy = p_energy;
-}
-
-void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->max_distance = p_distance;
-
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	if (reflection_probe->extents == p_extents) {
-		return;
-	}
-	reflection_probe->extents = p_extents;
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->origin_offset = p_offset;
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->interior = p_enable;
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-void RendererStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->box_projection = p_enable;
-}
-
-void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->enable_shadows = p_enable;
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->cull_mask = p_layers;
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-	ERR_FAIL_COND(p_resolution < 32);
-
-	reflection_probe->resolution = p_resolution;
-}
-
-void RendererStorageRD::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {
-	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND(!reflection_probe);
-
-	reflection_probe->mesh_lod_threshold = p_ratio;
-
-	reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
-}
-
-AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, AABB());
-
-	AABB aabb;
-	aabb.position = -reflection_probe->extents;
-	aabb.size = reflection_probe->extents * 2.0;
-
-	return aabb;
-}
-
-RS::ReflectionProbeUpdateMode RendererStorageRD::reflection_probe_get_update_mode(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS);
-
-	return reflection_probe->update_mode;
-}
-
-uint32_t RendererStorageRD::reflection_probe_get_cull_mask(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, 0);
-
-	return reflection_probe->cull_mask;
-}
-
-Vector3 RendererStorageRD::reflection_probe_get_extents(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, Vector3());
-
-	return reflection_probe->extents;
-}
-
-Vector3 RendererStorageRD::reflection_probe_get_origin_offset(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, Vector3());
-
-	return reflection_probe->origin_offset;
-}
-
-bool RendererStorageRD::reflection_probe_renders_shadows(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, false);
-
-	return reflection_probe->enable_shadows;
-}
-
-float RendererStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, 0);
-
-	return reflection_probe->max_distance;
-}
-
-float RendererStorageRD::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, 0);
-
-	return reflection_probe->mesh_lod_threshold;
-}
-
-int RendererStorageRD::reflection_probe_get_resolution(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, 0);
-
-	return reflection_probe->resolution;
-}
-
-float RendererStorageRD::reflection_probe_get_intensity(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, 0);
-
-	return reflection_probe->intensity;
-}
-
-bool RendererStorageRD::reflection_probe_is_interior(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, false);
-
-	return reflection_probe->interior;
-}
-
-bool RendererStorageRD::reflection_probe_is_box_projection(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, false);
-
-	return reflection_probe->box_projection;
-}
-
-RS::ReflectionProbeAmbientMode RendererStorageRD::reflection_probe_get_ambient_mode(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_AMBIENT_DISABLED);
-	return reflection_probe->ambient_mode;
-}
-
-Color RendererStorageRD::reflection_probe_get_ambient_color(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, Color());
-
-	return reflection_probe->ambient_color;
-}
-float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) const {
-	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
-	ERR_FAIL_COND_V(!reflection_probe, 0);
-
-	return reflection_probe->ambient_color_energy;
-}
+/* VOXEL GI */
 
 RID RendererStorageRD::voxel_gi_allocate() {
 	return voxel_gi_owner.allocate_rid();
@@ -2769,185 +2257,6 @@ RID RendererStorageRD::voxel_gi_get_sdf_texture(RID p_voxel_gi) {
 	return voxel_gi->sdf_texture;
 }
 
-/* LIGHTMAP API */
-
-RID RendererStorageRD::lightmap_allocate() {
-	return lightmap_owner.allocate_rid();
-}
-
-void RendererStorageRD::lightmap_initialize(RID p_lightmap) {
-	lightmap_owner.initialize_rid(p_lightmap, Lightmap());
-}
-
-void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
-	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
-
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND(!lm);
-
-	lightmap_array_version++;
-
-	//erase lightmap users
-	if (lm->light_texture.is_valid()) {
-		RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(lm->light_texture);
-		if (t) {
-			t->lightmap_users.erase(p_lightmap);
-		}
-	}
-
-	RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(p_light);
-	lm->light_texture = p_light;
-	lm->uses_spherical_harmonics = p_uses_spherical_haromics;
-
-	RID default_2d_array = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
-	if (!t) {
-		if (using_lightmap_array) {
-			if (lm->array_index >= 0) {
-				lightmap_textures.write[lm->array_index] = default_2d_array;
-				lm->array_index = -1;
-			}
-		}
-
-		return;
-	}
-
-	t->lightmap_users.insert(p_lightmap);
-
-	if (using_lightmap_array) {
-		if (lm->array_index < 0) {
-			//not in array, try to put in array
-			for (int i = 0; i < lightmap_textures.size(); i++) {
-				if (lightmap_textures[i] == default_2d_array) {
-					lm->array_index = i;
-					break;
-				}
-			}
-		}
-		ERR_FAIL_COND_MSG(lm->array_index < 0, "Maximum amount of lightmaps in use (" + itos(lightmap_textures.size()) + ") has been exceeded, lightmap will nod display properly.");
-
-		lightmap_textures.write[lm->array_index] = t->rd_texture;
-	}
-}
-
-void RendererStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND(!lm);
-	lm->bounds = p_bounds;
-}
-
-void RendererStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND(!lm);
-	lm->interior = p_interior;
-}
-
-void RendererStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND(!lm);
-
-	if (p_points.size()) {
-		ERR_FAIL_COND(p_points.size() * 9 != p_point_sh.size());
-		ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0);
-		ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0);
-	}
-
-	lm->points = p_points;
-	lm->bsp_tree = p_bsp_tree;
-	lm->point_sh = p_point_sh;
-	lm->tetrahedra = p_tetrahedra;
-}
-
-PackedVector3Array RendererStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND_V(!lm, PackedVector3Array());
-
-	return lm->points;
-}
-
-PackedColorArray RendererStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND_V(!lm, PackedColorArray());
-	return lm->point_sh;
-}
-
-PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND_V(!lm, PackedInt32Array());
-	return lm->tetrahedra;
-}
-
-PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND_V(!lm, PackedInt32Array());
-	return lm->bsp_tree;
-}
-
-void RendererStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) {
-	lightmap_probe_capture_update_speed = p_speed;
-}
-
-void RendererStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
-	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND(!lm);
-
-	for (int i = 0; i < 9; i++) {
-		r_sh[i] = Color(0, 0, 0, 0);
-	}
-
-	if (!lm->points.size() || !lm->bsp_tree.size() || !lm->tetrahedra.size()) {
-		return;
-	}
-
-	static_assert(sizeof(Lightmap::BSP) == 24);
-
-	const Lightmap::BSP *bsp = (const Lightmap::BSP *)lm->bsp_tree.ptr();
-	int32_t node = 0;
-	while (node >= 0) {
-		if (Plane(bsp[node].plane[0], bsp[node].plane[1], bsp[node].plane[2], bsp[node].plane[3]).is_point_over(p_point)) {
-#ifdef DEBUG_ENABLED
-			ERR_FAIL_COND(bsp[node].over >= 0 && bsp[node].over < node);
-#endif
-
-			node = bsp[node].over;
-		} else {
-#ifdef DEBUG_ENABLED
-			ERR_FAIL_COND(bsp[node].under >= 0 && bsp[node].under < node);
-#endif
-			node = bsp[node].under;
-		}
-	}
-
-	if (node == Lightmap::BSP::EMPTY_LEAF) {
-		return; //nothing could be done
-	}
-
-	node = ABS(node) - 1;
-
-	uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4];
-	Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] };
-	const Color *sh_colors[4]{ &lm->point_sh[tetrahedron[0] * 9], &lm->point_sh[tetrahedron[1] * 9], &lm->point_sh[tetrahedron[2] * 9], &lm->point_sh[tetrahedron[3] * 9] };
-	Color barycentric = Geometry3D::tetrahedron_get_barycentric_coords(points[0], points[1], points[2], points[3], p_point);
-
-	for (int i = 0; i < 4; i++) {
-		float c = CLAMP(barycentric[i], 0.0, 1.0);
-		for (int j = 0; j < 9; j++) {
-			r_sh[j] += sh_colors[i][j] * c;
-		}
-	}
-}
-
-bool RendererStorageRD::lightmap_is_interior(RID p_lightmap) const {
-	const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND_V(!lm, false);
-	return lm->interior;
-}
-
-AABB RendererStorageRD::lightmap_get_aabb(RID p_lightmap) const {
-	const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-	ERR_FAIL_COND_V(!lm, AABB());
-	return lm->bounds;
-}
-
 void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
 	if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_base)) {
 		RendererRD::Mesh *mesh = RendererRD::MeshStorage::get_singleton()->get_mesh(p_base);
@@ -2958,8 +2267,8 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
 		if (multimesh->mesh.is_valid()) {
 			base_update_dependency(multimesh->mesh, p_instance);
 		}
-	} else if (reflection_probe_owner.owns(p_base)) {
-		ReflectionProbe *rp = reflection_probe_owner.get_or_null(p_base);
+	} else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_base)) {
+		RendererRD::ReflectionProbe *rp = RendererRD::LightStorage::get_singleton()->get_reflection_probe(p_base);
 		p_instance->update_dependency(&rp->dependency);
 	} else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_base)) {
 		RendererRD::Decal *decal = RendererRD::TextureStorage::get_singleton()->get_decal(p_base);
@@ -2967,11 +2276,11 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
 	} else if (voxel_gi_owner.owns(p_base)) {
 		VoxelGI *gip = voxel_gi_owner.get_or_null(p_base);
 		p_instance->update_dependency(&gip->dependency);
-	} else if (lightmap_owner.owns(p_base)) {
-		Lightmap *lm = lightmap_owner.get_or_null(p_base);
+	} else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_base)) {
+		RendererRD::Lightmap *lm = RendererRD::LightStorage::get_singleton()->get_lightmap(p_base);
 		p_instance->update_dependency(&lm->dependency);
-	} else if (light_owner.owns(p_base)) {
-		Light *l = light_owner.get_or_null(p_base);
+	} else if (RendererRD::LightStorage::get_singleton()->owns_light(p_base)) {
+		RendererRD::Light *l = RendererRD::LightStorage::get_singleton()->get_light(p_base);
 		p_instance->update_dependency(&l->dependency);
 	} else if (particles_owner.owns(p_base)) {
 		Particles *p = particles_owner.get_or_null(p_base);
@@ -2995,7 +2304,7 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
 	if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
 		return RS::INSTANCE_MULTIMESH;
 	}
-	if (reflection_probe_owner.owns(p_rid)) {
+	if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) {
 		return RS::INSTANCE_REFLECTION_PROBE;
 	}
 	if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
@@ -3004,10 +2313,10 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
 	if (voxel_gi_owner.owns(p_rid)) {
 		return RS::INSTANCE_VOXEL_GI;
 	}
-	if (light_owner.owns(p_rid)) {
+	if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) {
 		return RS::INSTANCE_LIGHT;
 	}
-	if (lightmap_owner.owns(p_rid)) {
+	if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
 		return RS::INSTANCE_LIGHTMAP;
 	}
 	if (particles_owner.owns(p_rid)) {
@@ -3071,10 +2380,8 @@ bool RendererStorageRD::free(RID p_rid) {
 		RendererRD::MeshStorage::get_singleton()->multimesh_free(p_rid);
 	} else if (RendererRD::MeshStorage::get_singleton()->owns_skeleton(p_rid)) {
 		RendererRD::MeshStorage::get_singleton()->skeleton_free(p_rid);
-	} else if (reflection_probe_owner.owns(p_rid)) {
-		ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
-		reflection_probe->dependency.deleted_notify(p_rid);
-		reflection_probe_owner.free(p_rid);
+	} else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) {
+		RendererRD::LightStorage::get_singleton()->reflection_probe_free(p_rid);
 	} else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
 		RendererRD::TextureStorage::get_singleton()->decal_free(p_rid);
 	} else if (voxel_gi_owner.owns(p_rid)) {
@@ -3082,19 +2389,10 @@ bool RendererStorageRD::free(RID p_rid) {
 		VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid);
 		voxel_gi->dependency.deleted_notify(p_rid);
 		voxel_gi_owner.free(p_rid);
-	} else if (lightmap_owner.owns(p_rid)) {
-		lightmap_set_textures(p_rid, RID(), false);
-		Lightmap *lightmap = lightmap_owner.get_or_null(p_rid);
-		lightmap->dependency.deleted_notify(p_rid);
-		lightmap_owner.free(p_rid);
-
-	} else if (light_owner.owns(p_rid)) {
-		light_set_projector(p_rid, RID()); //clear projector
-		// delete the texture
-		Light *light = light_owner.get_or_null(p_rid);
-		light->dependency.deleted_notify(p_rid);
-		light_owner.free(p_rid);
-
+	} else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
+		RendererRD::LightStorage::get_singleton()->lightmap_free(p_rid);
+	} else if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) {
+		RendererRD::LightStorage::get_singleton()->light_free(p_rid);
 	} else if (particles_owner.owns(p_rid)) {
 		update_particles();
 		Particles *particles = particles_owner.get_or_null(p_rid);
@@ -3198,7 +2496,6 @@ RendererStorageRD *RendererStorageRD::base_singleton = nullptr;
 RendererStorageRD::RendererStorageRD() {
 	base_singleton = this;
 
-	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 
 	//default samplers
@@ -3289,23 +2586,6 @@ RendererStorageRD::RendererStorageRD() {
 	//custom sampler
 	sampler_rd_configure_custom(0.0f);
 
-	using_lightmap_array = true; // high end
-	if (using_lightmap_array) {
-		uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
-
-		if (textures_per_stage <= 256) {
-			lightmap_textures.resize(32);
-		} else {
-			lightmap_textures.resize(1024);
-		}
-
-		for (int i = 0; i < lightmap_textures.size(); i++) {
-			lightmap_textures.write[i] = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
-		}
-	}
-
-	lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed");
-
 	/* Particles */
 
 	{

+ 0 - 302
servers/rendering/renderer_rd/renderer_storage_rd.h

@@ -506,57 +506,6 @@ private:
 
 	mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner;
 
-	/* LIGHT */
-
-	struct Light {
-		RS::LightType type;
-		float param[RS::LIGHT_PARAM_MAX];
-		Color color = Color(1, 1, 1, 1);
-		RID projector;
-		bool shadow = false;
-		bool negative = false;
-		bool reverse_cull = false;
-		RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC;
-		uint32_t max_sdfgi_cascade = 2;
-		uint32_t cull_mask = 0xFFFFFFFF;
-		bool distance_fade = false;
-		real_t distance_fade_begin = 40.0;
-		real_t distance_fade_shadow = 50.0;
-		real_t distance_fade_length = 10.0;
-		RS::LightOmniShadowMode omni_shadow_mode = RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
-		RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
-		bool directional_blend_splits = false;
-		RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY;
-		uint64_t version = 0;
-
-		Dependency dependency;
-	};
-
-	mutable RID_Owner<Light, true> light_owner;
-
-	/* REFLECTION PROBE */
-
-	struct ReflectionProbe {
-		RS::ReflectionProbeUpdateMode update_mode = RS::REFLECTION_PROBE_UPDATE_ONCE;
-		int resolution = 256;
-		float intensity = 1.0;
-		RS::ReflectionProbeAmbientMode ambient_mode = RS::REFLECTION_PROBE_AMBIENT_ENVIRONMENT;
-		Color ambient_color;
-		float ambient_color_energy = 1.0;
-		float max_distance = 0;
-		Vector3 extents = Vector3(1, 1, 1);
-		Vector3 origin_offset;
-		bool interior = false;
-		bool box_projection = false;
-		bool enable_shadows = false;
-		uint32_t cull_mask = (1 << 20) - 1;
-		float mesh_lod_threshold = 0.01;
-
-		Dependency dependency;
-	};
-
-	mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner;
-
 	/* VOXEL GI */
 
 	struct VoxelGI {
@@ -593,39 +542,6 @@ private:
 
 	mutable RID_Owner<VoxelGI, true> voxel_gi_owner;
 
-	/* REFLECTION PROBE */
-
-	struct Lightmap {
-		RID light_texture;
-		bool uses_spherical_harmonics = false;
-		bool interior = false;
-		AABB bounds = AABB(Vector3(), Vector3(1, 1, 1));
-		int32_t array_index = -1; //unassigned
-		PackedVector3Array points;
-		PackedColorArray point_sh;
-		PackedInt32Array tetrahedra;
-		PackedInt32Array bsp_tree;
-
-		struct BSP {
-			static const int32_t EMPTY_LEAF = INT32_MIN;
-			float plane[4];
-			int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
-		};
-
-		Dependency dependency;
-	};
-
-	bool using_lightmap_array; //high end uses this
-	/* for high end */
-
-	Vector<RID> lightmap_textures;
-
-	uint64_t lightmap_array_version = 0;
-
-	mutable RID_Owner<Lightmap, true> lightmap_owner;
-
-	float lightmap_probe_capture_update_speed = 4;
-
 	/* EFFECTS */
 
 	EffectsRD *effects = nullptr;
@@ -644,174 +560,6 @@ public:
 
 	void sampler_rd_set_default(float p_mipmap_bias);
 
-	/* Light API */
-
-	void _light_initialize(RID p_rid, RS::LightType p_type);
-
-	RID directional_light_allocate();
-	void directional_light_initialize(RID p_light);
-
-	RID omni_light_allocate();
-	void omni_light_initialize(RID p_light);
-
-	RID spot_light_allocate();
-	void spot_light_initialize(RID p_light);
-
-	void light_set_color(RID p_light, const Color &p_color);
-	void light_set_param(RID p_light, RS::LightParam p_param, float p_value);
-	void light_set_shadow(RID p_light, bool p_enabled);
-	void light_set_projector(RID p_light, RID p_texture);
-	void light_set_negative(RID p_light, bool p_enable);
-	void light_set_cull_mask(RID p_light, uint32_t p_mask);
-	void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length);
-	void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled);
-	void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode);
-	void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade);
-
-	void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode);
-
-	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_mode(RID p_light, RS::LightDirectionalSkyMode p_mode);
-	RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const;
-
-	RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light);
-	RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light);
-
-	_FORCE_INLINE_ RS::LightType light_get_type(RID p_light) const {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
-
-		return light->type;
-	}
-	AABB light_get_aabb(RID p_light) const;
-
-	_FORCE_INLINE_ float light_get_param(RID p_light, RS::LightParam p_param) {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, 0);
-
-		return light->param[p_param];
-	}
-
-	_FORCE_INLINE_ RID light_get_projector(RID p_light) {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, RID());
-
-		return light->projector;
-	}
-
-	_FORCE_INLINE_ Color light_get_color(RID p_light) {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, Color());
-
-		return light->color;
-	}
-
-	_FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, 0);
-
-		return light->cull_mask;
-	}
-
-	_FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) {
-		const Light *light = light_owner.get_or_null(p_light);
-		return light->distance_fade;
-	}
-
-	_FORCE_INLINE_ float light_get_distance_fade_begin(RID p_light) {
-		const Light *light = light_owner.get_or_null(p_light);
-		return light->distance_fade_begin;
-	}
-
-	_FORCE_INLINE_ float light_get_distance_fade_shadow(RID p_light) {
-		const Light *light = light_owner.get_or_null(p_light);
-		return light->distance_fade_shadow;
-	}
-
-	_FORCE_INLINE_ float light_get_distance_fade_length(RID p_light) {
-		const Light *light = light_owner.get_or_null(p_light);
-		return light->distance_fade_length;
-	}
-
-	_FORCE_INLINE_ bool light_has_shadow(RID p_light) const {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
-
-		return light->shadow;
-	}
-
-	_FORCE_INLINE_ bool light_has_projector(RID p_light) const {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
-
-		return light_owner.owns(light->projector);
-	}
-
-	_FORCE_INLINE_ bool light_is_negative(RID p_light) const {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
-
-		return light->negative;
-	}
-
-	_FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, 0.0);
-
-		return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS];
-	}
-
-	_FORCE_INLINE_ float light_get_shadow_volumetric_fog_fade(RID p_light) const {
-		const Light *light = light_owner.get_or_null(p_light);
-		ERR_FAIL_COND_V(!light, 0.0);
-
-		return light->param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE];
-	}
-
-	RS::LightBakeMode light_get_bake_mode(RID p_light);
-	uint32_t light_get_max_sdfgi_cascade(RID p_light);
-	uint64_t light_get_version(RID p_light) const;
-
-	/* PROBE API */
-
-	RID reflection_probe_allocate();
-	void reflection_probe_initialize(RID p_reflection_probe);
-
-	void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode);
-	void reflection_probe_set_intensity(RID p_probe, float p_intensity);
-	void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode);
-	void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color);
-	void reflection_probe_set_ambient_energy(RID p_probe, float p_energy);
-	void reflection_probe_set_max_distance(RID p_probe, float p_distance);
-	void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents);
-	void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset);
-	void reflection_probe_set_as_interior(RID p_probe, bool p_enable);
-	void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable);
-	void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable);
-	void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers);
-	void reflection_probe_set_resolution(RID p_probe, int p_resolution);
-	void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio);
-
-	AABB reflection_probe_get_aabb(RID p_probe) const;
-	RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const;
-	uint32_t reflection_probe_get_cull_mask(RID p_probe) const;
-	Vector3 reflection_probe_get_extents(RID p_probe) const;
-	Vector3 reflection_probe_get_origin_offset(RID p_probe) const;
-	float reflection_probe_get_origin_max_distance(RID p_probe) const;
-	float reflection_probe_get_mesh_lod_threshold(RID p_probe) const;
-
-	int reflection_probe_get_resolution(RID p_probe) const;
-	bool reflection_probe_renders_shadows(RID p_probe) const;
-
-	float reflection_probe_get_intensity(RID p_probe) const;
-	bool reflection_probe_is_interior(RID p_probe) const;
-	bool reflection_probe_is_box_projection(RID p_probe) const;
-	RS::ReflectionProbeAmbientMode reflection_probe_get_ambient_mode(RID p_probe) const;
-	Color reflection_probe_get_ambient_color(RID p_probe) const;
-	float reflection_probe_get_ambient_color_energy(RID p_probe) const;
-
 	void base_update_dependency(RID p_base, DependencyTracker *p_instance);
 
 	/* VOXEL GI API */
@@ -862,56 +610,6 @@ public:
 
 	RID voxel_gi_get_sdf_texture(RID p_voxel_gi);
 
-	/* LIGHTMAP CAPTURE */
-
-	RID lightmap_allocate();
-	void lightmap_initialize(RID p_lightmap);
-
-	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics);
-	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds);
-	virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior);
-	virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree);
-	virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const;
-	virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const;
-	virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const;
-	virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const;
-	virtual AABB lightmap_get_aabb(RID p_lightmap) const;
-	virtual bool lightmap_is_interior(RID p_lightmap) const;
-	virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh);
-	virtual void lightmap_set_probe_capture_update_speed(float p_speed);
-	_FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const {
-		return lightmap_probe_capture_update_speed;
-	}
-	_FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const {
-		const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-		ERR_FAIL_COND_V(!lm, RID());
-		return lm->light_texture;
-	}
-	_FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const {
-		ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays
-		const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-		return lm->array_index;
-	}
-	_FORCE_INLINE_ bool lightmap_uses_spherical_harmonics(RID p_lightmap) const {
-		ERR_FAIL_COND_V(!using_lightmap_array, false); //only for arrays
-		const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
-		return lm->uses_spherical_harmonics;
-	}
-	_FORCE_INLINE_ uint64_t lightmap_array_get_version() const {
-		ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays
-		return lightmap_array_version;
-	}
-
-	_FORCE_INLINE_ int lightmap_array_get_size() const {
-		ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays
-		return lightmap_textures.size();
-	}
-
-	_FORCE_INLINE_ const Vector<RID> &lightmap_array_get_textures() const {
-		ERR_FAIL_COND_V(!using_lightmap_array, lightmap_textures); //only for arrays
-		return lightmap_textures;
-	}
-
 	/* PARTICLES */
 
 	RID particles_allocate();

+ 788 - 0
servers/rendering/renderer_rd/storage_rd/light_storage.cpp

@@ -0,0 +1,788 @@
+/*************************************************************************/
+/*  light_storage.cpp                                                    */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "light_storage.h"
+#include "core/config/project_settings.h"
+#include "texture_storage.h"
+
+using namespace RendererRD;
+
+LightStorage *LightStorage::singleton = nullptr;
+
+LightStorage *LightStorage::get_singleton() {
+	return singleton;
+}
+
+LightStorage::LightStorage() {
+	singleton = this;
+
+	TextureStorage *texture_storage = TextureStorage::get_singleton();
+
+	using_lightmap_array = true; // high end
+	if (using_lightmap_array) {
+		uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
+
+		if (textures_per_stage <= 256) {
+			lightmap_textures.resize(32);
+		} else {
+			lightmap_textures.resize(1024);
+		}
+
+		for (int i = 0; i < lightmap_textures.size(); i++) {
+			lightmap_textures.write[i] = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
+		}
+	}
+
+	lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed");
+}
+
+LightStorage::~LightStorage() {
+	singleton = nullptr;
+}
+
+/* LIGHT */
+
+void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) {
+	Light light;
+	light.type = p_type;
+
+	light.param[RS::LIGHT_PARAM_ENERGY] = 1.0;
+	light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0;
+	light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
+	light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
+	light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
+	light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;
+	light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
+	light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;
+	light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
+	light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
+	light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
+	light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
+	light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
+	light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
+	light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
+	light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
+	light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
+	light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1;
+	light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
+
+	light_owner.initialize_rid(p_light, light);
+}
+
+RID LightStorage::directional_light_allocate() {
+	return light_owner.allocate_rid();
+}
+
+void LightStorage::directional_light_initialize(RID p_light) {
+	_light_initialize(p_light, RS::LIGHT_DIRECTIONAL);
+}
+
+RID LightStorage::omni_light_allocate() {
+	return light_owner.allocate_rid();
+}
+
+void LightStorage::omni_light_initialize(RID p_light) {
+	_light_initialize(p_light, RS::LIGHT_OMNI);
+}
+
+RID LightStorage::spot_light_allocate() {
+	return light_owner.allocate_rid();
+}
+
+void LightStorage::spot_light_initialize(RID p_light) {
+	_light_initialize(p_light, RS::LIGHT_SPOT);
+}
+
+void LightStorage::light_free(RID p_rid) {
+	light_set_projector(p_rid, RID()); //clear projector
+
+	// delete the texture
+	Light *light = light_owner.get_or_null(p_rid);
+	light->dependency.deleted_notify(p_rid);
+	light_owner.free(p_rid);
+}
+
+void LightStorage::light_set_color(RID p_light, const Color &p_color) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->color = p_color;
+}
+
+void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+	ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX);
+
+	if (light->param[p_param] == p_value) {
+		return;
+	}
+
+	switch (p_param) {
+		case RS::LIGHT_PARAM_RANGE:
+		case RS::LIGHT_PARAM_SPOT_ANGLE:
+		case RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE:
+		case RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET:
+		case RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
+		case RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
+		case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
+		case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
+		case RS::LIGHT_PARAM_SHADOW_BIAS: {
+			light->version++;
+			light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+		} break;
+		case RS::LIGHT_PARAM_SIZE: {
+			if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) {
+				//changing from no size to size and the opposite
+				light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+			}
+		} break;
+		default: {
+		}
+	}
+
+	light->param[p_param] = p_value;
+}
+
+void LightStorage::light_set_shadow(RID p_light, bool p_enabled) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+	light->shadow = p_enabled;
+
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+void LightStorage::light_set_projector(RID p_light, RID p_texture) {
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	if (light->projector == p_texture) {
+		return;
+	}
+
+	if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
+		texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
+	}
+
+	light->projector = p_texture;
+
+	if (light->type != RS::LIGHT_DIRECTIONAL) {
+		if (light->projector.is_valid()) {
+			texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
+		}
+		light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+	}
+}
+
+void LightStorage::light_set_negative(RID p_light, bool p_enable) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->negative = p_enable;
+}
+
+void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->cull_mask = p_mask;
+
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+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_COND(!light);
+
+	light->distance_fade = p_enabled;
+	light->distance_fade_begin = p_begin;
+	light->distance_fade_shadow = p_shadow;
+	light->distance_fade_length = p_length;
+}
+
+void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->reverse_cull = p_enabled;
+
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+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_COND(!light);
+
+	light->bake_mode = p_bake_mode;
+
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->max_sdfgi_cascade = p_cascade;
+
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->omni_shadow_mode = p_mode;
+
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE);
+
+	return light->omni_shadow_mode;
+}
+
+void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->directional_shadow_mode = p_mode;
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->directional_blend_splits = p_enable;
+	light->version++;
+	light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+}
+
+bool LightStorage::light_directional_get_blend_splits(RID p_light) const {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, false);
+
+	return light->directional_blend_splits;
+}
+
+void LightStorage::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) {
+	Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->directional_sky_mode = p_mode;
+}
+
+RS::LightDirectionalSkyMode LightStorage::light_directional_get_sky_mode(RID p_light) const {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY);
+
+	return light->directional_sky_mode;
+}
+
+RS::LightDirectionalShadowMode LightStorage::light_directional_get_shadow_mode(RID p_light) {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
+
+	return light->directional_shadow_mode;
+}
+
+uint32_t LightStorage::light_get_max_sdfgi_cascade(RID p_light) {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, 0);
+
+	return light->max_sdfgi_cascade;
+}
+
+RS::LightBakeMode LightStorage::light_get_bake_mode(RID p_light) {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, RS::LIGHT_BAKE_DISABLED);
+
+	return light->bake_mode;
+}
+
+uint64_t LightStorage::light_get_version(RID p_light) const {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, 0);
+
+	return light->version;
+}
+
+AABB LightStorage::light_get_aabb(RID p_light) const {
+	const Light *light = light_owner.get_or_null(p_light);
+	ERR_FAIL_COND_V(!light, AABB());
+
+	switch (light->type) {
+		case RS::LIGHT_SPOT: {
+			float len = light->param[RS::LIGHT_PARAM_RANGE];
+			float size = Math::tan(Math::deg2rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len;
+			return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
+		};
+		case RS::LIGHT_OMNI: {
+			float r = light->param[RS::LIGHT_PARAM_RANGE];
+			return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
+		};
+		case RS::LIGHT_DIRECTIONAL: {
+			return AABB();
+		};
+	}
+
+	ERR_FAIL_V(AABB());
+}
+
+/* REFLECTION PROBE */
+
+RID LightStorage::reflection_probe_allocate() {
+	return reflection_probe_owner.allocate_rid();
+}
+
+void LightStorage::reflection_probe_initialize(RID p_reflection_probe) {
+	reflection_probe_owner.initialize_rid(p_reflection_probe, ReflectionProbe());
+}
+
+void LightStorage::reflection_probe_free(RID p_rid) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
+	reflection_probe->dependency.deleted_notify(p_rid);
+	reflection_probe_owner.free(p_rid);
+};
+
+void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->update_mode = p_mode;
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->intensity = p_intensity;
+}
+
+void LightStorage::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->ambient_mode = p_mode;
+}
+
+void LightStorage::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->ambient_color = p_color;
+}
+
+void LightStorage::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->ambient_color_energy = p_energy;
+}
+
+void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->max_distance = p_distance;
+
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	if (reflection_probe->extents == p_extents) {
+		return;
+	}
+	reflection_probe->extents = p_extents;
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->origin_offset = p_offset;
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->interior = p_enable;
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->box_projection = p_enable;
+}
+
+void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->enable_shadows = p_enable;
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->cull_mask = p_layers;
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+	ERR_FAIL_COND(p_resolution < 32);
+
+	reflection_probe->resolution = p_resolution;
+}
+
+void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {
+	ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND(!reflection_probe);
+
+	reflection_probe->mesh_lod_threshold = p_ratio;
+
+	reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, AABB());
+
+	AABB aabb;
+	aabb.position = -reflection_probe->extents;
+	aabb.size = reflection_probe->extents * 2.0;
+
+	return aabb;
+}
+
+RS::ReflectionProbeUpdateMode LightStorage::reflection_probe_get_update_mode(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS);
+
+	return reflection_probe->update_mode;
+}
+
+uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, 0);
+
+	return reflection_probe->cull_mask;
+}
+
+Vector3 LightStorage::reflection_probe_get_extents(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, Vector3());
+
+	return reflection_probe->extents;
+}
+
+Vector3 LightStorage::reflection_probe_get_origin_offset(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, Vector3());
+
+	return reflection_probe->origin_offset;
+}
+
+bool LightStorage::reflection_probe_renders_shadows(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, false);
+
+	return reflection_probe->enable_shadows;
+}
+
+float LightStorage::reflection_probe_get_origin_max_distance(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, 0);
+
+	return reflection_probe->max_distance;
+}
+
+float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, 0);
+
+	return reflection_probe->mesh_lod_threshold;
+}
+
+int LightStorage::reflection_probe_get_resolution(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, 0);
+
+	return reflection_probe->resolution;
+}
+
+float LightStorage::reflection_probe_get_intensity(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, 0);
+
+	return reflection_probe->intensity;
+}
+
+bool LightStorage::reflection_probe_is_interior(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, false);
+
+	return reflection_probe->interior;
+}
+
+bool LightStorage::reflection_probe_is_box_projection(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, false);
+
+	return reflection_probe->box_projection;
+}
+
+RS::ReflectionProbeAmbientMode LightStorage::reflection_probe_get_ambient_mode(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_AMBIENT_DISABLED);
+	return reflection_probe->ambient_mode;
+}
+
+Color LightStorage::reflection_probe_get_ambient_color(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, Color());
+
+	return reflection_probe->ambient_color;
+}
+float LightStorage::reflection_probe_get_ambient_color_energy(RID p_probe) const {
+	const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+	ERR_FAIL_COND_V(!reflection_probe, 0);
+
+	return reflection_probe->ambient_color_energy;
+}
+
+/* LIGHTMAP API */
+
+RID LightStorage::lightmap_allocate() {
+	return lightmap_owner.allocate_rid();
+}
+
+void LightStorage::lightmap_initialize(RID p_lightmap) {
+	lightmap_owner.initialize_rid(p_lightmap, Lightmap());
+}
+
+void LightStorage::lightmap_free(RID p_rid) {
+	lightmap_set_textures(p_rid, RID(), false);
+	Lightmap *lightmap = lightmap_owner.get_or_null(p_rid);
+	lightmap->dependency.deleted_notify(p_rid);
+	lightmap_owner.free(p_rid);
+}
+
+void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND(!lm);
+
+	lightmap_array_version++;
+
+	//erase lightmap users
+	if (lm->light_texture.is_valid()) {
+		RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(lm->light_texture);
+		if (t) {
+			t->lightmap_users.erase(p_lightmap);
+		}
+	}
+
+	RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(p_light);
+	lm->light_texture = p_light;
+	lm->uses_spherical_harmonics = p_uses_spherical_haromics;
+
+	RID default_2d_array = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
+	if (!t) {
+		if (using_lightmap_array) {
+			if (lm->array_index >= 0) {
+				lightmap_textures.write[lm->array_index] = default_2d_array;
+				lm->array_index = -1;
+			}
+		}
+
+		return;
+	}
+
+	t->lightmap_users.insert(p_lightmap);
+
+	if (using_lightmap_array) {
+		if (lm->array_index < 0) {
+			//not in array, try to put in array
+			for (int i = 0; i < lightmap_textures.size(); i++) {
+				if (lightmap_textures[i] == default_2d_array) {
+					lm->array_index = i;
+					break;
+				}
+			}
+		}
+		ERR_FAIL_COND_MSG(lm->array_index < 0, "Maximum amount of lightmaps in use (" + itos(lightmap_textures.size()) + ") has been exceeded, lightmap will nod display properly.");
+
+		lightmap_textures.write[lm->array_index] = t->rd_texture;
+	}
+}
+
+void LightStorage::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND(!lm);
+	lm->bounds = p_bounds;
+}
+
+void LightStorage::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND(!lm);
+	lm->interior = p_interior;
+}
+
+void LightStorage::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND(!lm);
+
+	if (p_points.size()) {
+		ERR_FAIL_COND(p_points.size() * 9 != p_point_sh.size());
+		ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0);
+		ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0);
+	}
+
+	lm->points = p_points;
+	lm->bsp_tree = p_bsp_tree;
+	lm->point_sh = p_point_sh;
+	lm->tetrahedra = p_tetrahedra;
+}
+
+PackedVector3Array LightStorage::lightmap_get_probe_capture_points(RID p_lightmap) const {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND_V(!lm, PackedVector3Array());
+
+	return lm->points;
+}
+
+PackedColorArray LightStorage::lightmap_get_probe_capture_sh(RID p_lightmap) const {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND_V(!lm, PackedColorArray());
+	return lm->point_sh;
+}
+
+PackedInt32Array LightStorage::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND_V(!lm, PackedInt32Array());
+	return lm->tetrahedra;
+}
+
+PackedInt32Array LightStorage::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND_V(!lm, PackedInt32Array());
+	return lm->bsp_tree;
+}
+
+void LightStorage::lightmap_set_probe_capture_update_speed(float p_speed) {
+	lightmap_probe_capture_update_speed = p_speed;
+}
+
+void LightStorage::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
+	Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND(!lm);
+
+	for (int i = 0; i < 9; i++) {
+		r_sh[i] = Color(0, 0, 0, 0);
+	}
+
+	if (!lm->points.size() || !lm->bsp_tree.size() || !lm->tetrahedra.size()) {
+		return;
+	}
+
+	static_assert(sizeof(Lightmap::BSP) == 24);
+
+	const Lightmap::BSP *bsp = (const Lightmap::BSP *)lm->bsp_tree.ptr();
+	int32_t node = 0;
+	while (node >= 0) {
+		if (Plane(bsp[node].plane[0], bsp[node].plane[1], bsp[node].plane[2], bsp[node].plane[3]).is_point_over(p_point)) {
+#ifdef DEBUG_ENABLED
+			ERR_FAIL_COND(bsp[node].over >= 0 && bsp[node].over < node);
+#endif
+
+			node = bsp[node].over;
+		} else {
+#ifdef DEBUG_ENABLED
+			ERR_FAIL_COND(bsp[node].under >= 0 && bsp[node].under < node);
+#endif
+			node = bsp[node].under;
+		}
+	}
+
+	if (node == Lightmap::BSP::EMPTY_LEAF) {
+		return; //nothing could be done
+	}
+
+	node = ABS(node) - 1;
+
+	uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4];
+	Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] };
+	const Color *sh_colors[4]{ &lm->point_sh[tetrahedron[0] * 9], &lm->point_sh[tetrahedron[1] * 9], &lm->point_sh[tetrahedron[2] * 9], &lm->point_sh[tetrahedron[3] * 9] };
+	Color barycentric = Geometry3D::tetrahedron_get_barycentric_coords(points[0], points[1], points[2], points[3], p_point);
+
+	for (int i = 0; i < 4; i++) {
+		float c = CLAMP(barycentric[i], 0.0, 1.0);
+		for (int j = 0; j < 9; j++) {
+			r_sh[j] += sh_colors[i][j] * c;
+		}
+	}
+}
+
+bool LightStorage::lightmap_is_interior(RID p_lightmap) const {
+	const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND_V(!lm, false);
+	return lm->interior;
+}
+
+AABB LightStorage::lightmap_get_aabb(RID p_lightmap) const {
+	const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+	ERR_FAIL_COND_V(!lm, AABB());
+	return lm->bounds;
+}

+ 370 - 0
servers/rendering/renderer_rd/storage_rd/light_storage.h

@@ -0,0 +1,370 @@
+/*************************************************************************/
+/*  light_storage.h                                                      */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef LIGHT_STORAGE_RD_H
+#define LIGHT_STORAGE_RD_H
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/self_list.h"
+#include "servers/rendering/storage/light_storage.h"
+
+namespace RendererRD {
+
+/* LIGHT */
+
+struct Light {
+	RS::LightType type;
+	float param[RS::LIGHT_PARAM_MAX];
+	Color color = Color(1, 1, 1, 1);
+	RID projector;
+	bool shadow = false;
+	bool negative = false;
+	bool reverse_cull = false;
+	RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC;
+	uint32_t max_sdfgi_cascade = 2;
+	uint32_t cull_mask = 0xFFFFFFFF;
+	bool distance_fade = false;
+	real_t distance_fade_begin = 40.0;
+	real_t distance_fade_shadow = 50.0;
+	real_t distance_fade_length = 10.0;
+	RS::LightOmniShadowMode omni_shadow_mode = RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
+	RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
+	bool directional_blend_splits = false;
+	RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY;
+	uint64_t version = 0;
+
+	RendererStorage::Dependency dependency;
+};
+
+/* REFLECTION PROBE */
+
+struct ReflectionProbe {
+	RS::ReflectionProbeUpdateMode update_mode = RS::REFLECTION_PROBE_UPDATE_ONCE;
+	int resolution = 256;
+	float intensity = 1.0;
+	RS::ReflectionProbeAmbientMode ambient_mode = RS::REFLECTION_PROBE_AMBIENT_ENVIRONMENT;
+	Color ambient_color;
+	float ambient_color_energy = 1.0;
+	float max_distance = 0;
+	Vector3 extents = Vector3(1, 1, 1);
+	Vector3 origin_offset;
+	bool interior = false;
+	bool box_projection = false;
+	bool enable_shadows = false;
+	uint32_t cull_mask = (1 << 20) - 1;
+	float mesh_lod_threshold = 0.01;
+
+	RendererStorage::Dependency dependency;
+};
+
+/* LIGHTMAP */
+
+struct Lightmap {
+	RID light_texture;
+	bool uses_spherical_harmonics = false;
+	bool interior = false;
+	AABB bounds = AABB(Vector3(), Vector3(1, 1, 1));
+	int32_t array_index = -1; //unassigned
+	PackedVector3Array points;
+	PackedColorArray point_sh;
+	PackedInt32Array tetrahedra;
+	PackedInt32Array bsp_tree;
+
+	struct BSP {
+		static const int32_t EMPTY_LEAF = INT32_MIN;
+		float plane[4];
+		int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
+	};
+
+	RendererStorage::Dependency dependency;
+};
+
+class LightStorage : public RendererLightStorage {
+private:
+	static LightStorage *singleton;
+
+	/* LIGHT */
+	mutable RID_Owner<Light, true> light_owner;
+
+	/* REFLECTION PROBE */
+	mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner;
+
+	/* LIGHTMAP */
+
+	bool using_lightmap_array;
+	Vector<RID> lightmap_textures;
+	uint64_t lightmap_array_version = 0;
+	float lightmap_probe_capture_update_speed = 4;
+
+	mutable RID_Owner<Lightmap, true> lightmap_owner;
+
+public:
+	static LightStorage *get_singleton();
+
+	LightStorage();
+	virtual ~LightStorage();
+
+	/* LIGHT */
+
+	Light *get_light(RID p_rid) { return light_owner.get_or_null(p_rid); };
+	bool owns_light(RID p_rid) { return light_owner.owns(p_rid); };
+
+	void _light_initialize(RID p_rid, RS::LightType p_type);
+
+	virtual RID directional_light_allocate() override;
+	virtual void directional_light_initialize(RID p_light) override;
+
+	virtual RID omni_light_allocate() override;
+	virtual void omni_light_initialize(RID p_light) override;
+
+	virtual RID spot_light_allocate() override;
+	virtual void spot_light_initialize(RID p_light) override;
+
+	virtual void light_free(RID p_rid) override;
+
+	virtual void light_set_color(RID p_light, const Color &p_color) override;
+	virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override;
+	virtual void light_set_shadow(RID p_light, bool p_enabled) override;
+	virtual void light_set_projector(RID p_light, RID p_texture) override;
+	virtual void light_set_negative(RID p_light, bool p_enable) override;
+	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_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;
+
+	virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override;
+
+	virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override;
+	virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) override;
+	virtual bool light_directional_get_blend_splits(RID p_light) const override;
+	virtual void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) override;
+	virtual RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const override;
+
+	virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override;
+	virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override;
+
+	virtual RS::LightType light_get_type(RID p_light) const override {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
+
+		return light->type;
+	}
+	virtual AABB light_get_aabb(RID p_light) const override;
+
+	virtual float light_get_param(RID p_light, RS::LightParam p_param) override {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, 0);
+
+		return light->param[p_param];
+	}
+
+	_FORCE_INLINE_ RID light_get_projector(RID p_light) {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, RID());
+
+		return light->projector;
+	}
+
+	virtual Color light_get_color(RID p_light) override {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, Color());
+
+		return light->color;
+	}
+
+	_FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, 0);
+
+		return light->cull_mask;
+	}
+
+	_FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) {
+		const Light *light = light_owner.get_or_null(p_light);
+		return light->distance_fade;
+	}
+
+	_FORCE_INLINE_ float light_get_distance_fade_begin(RID p_light) {
+		const Light *light = light_owner.get_or_null(p_light);
+		return light->distance_fade_begin;
+	}
+
+	_FORCE_INLINE_ float light_get_distance_fade_shadow(RID p_light) {
+		const Light *light = light_owner.get_or_null(p_light);
+		return light->distance_fade_shadow;
+	}
+
+	_FORCE_INLINE_ float light_get_distance_fade_length(RID p_light) {
+		const Light *light = light_owner.get_or_null(p_light);
+		return light->distance_fade_length;
+	}
+
+	virtual bool light_has_shadow(RID p_light) const override {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
+
+		return light->shadow;
+	}
+
+	virtual bool light_has_projector(RID p_light) const override {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
+
+		return light_owner.owns(light->projector);
+	}
+
+	_FORCE_INLINE_ bool light_is_negative(RID p_light) const {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
+
+		return light->negative;
+	}
+
+	_FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, 0.0);
+
+		return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS];
+	}
+
+	_FORCE_INLINE_ float light_get_shadow_volumetric_fog_fade(RID p_light) const {
+		const Light *light = light_owner.get_or_null(p_light);
+		ERR_FAIL_COND_V(!light, 0.0);
+
+		return light->param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE];
+	}
+
+	virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override;
+	virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override;
+	virtual uint64_t light_get_version(RID p_light) const override;
+
+	/* REFLECTION PROBE */
+
+	ReflectionProbe *get_reflection_probe(RID p_rid) { return reflection_probe_owner.get_or_null(p_rid); };
+	bool owns_reflection_probe(RID p_rid) { return reflection_probe_owner.owns(p_rid); };
+
+	virtual RID reflection_probe_allocate() override;
+	virtual void reflection_probe_initialize(RID p_reflection_probe) override;
+	virtual void reflection_probe_free(RID p_rid) override;
+
+	virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override;
+	virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) override;
+	virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override;
+	virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override;
+	virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override;
+	virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) override;
+	virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override;
+	virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override;
+	virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override;
+	virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override;
+	virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override;
+	virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override;
+	virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) override;
+	virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override;
+
+	virtual AABB reflection_probe_get_aabb(RID p_probe) const override;
+	virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
+	virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override;
+	virtual Vector3 reflection_probe_get_extents(RID p_probe) const override;
+	virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override;
+	virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override;
+	virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override;
+
+	int reflection_probe_get_resolution(RID p_probe) const;
+	virtual bool reflection_probe_renders_shadows(RID p_probe) const override;
+
+	float reflection_probe_get_intensity(RID p_probe) const;
+	bool reflection_probe_is_interior(RID p_probe) const;
+	bool reflection_probe_is_box_projection(RID p_probe) const;
+	RS::ReflectionProbeAmbientMode reflection_probe_get_ambient_mode(RID p_probe) const;
+	Color reflection_probe_get_ambient_color(RID p_probe) const;
+	float reflection_probe_get_ambient_color_energy(RID p_probe) const;
+
+	/* LIGHTMAP */
+
+	Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); };
+	bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); };
+
+	virtual RID lightmap_allocate() override;
+	virtual void lightmap_initialize(RID p_lightmap) override;
+	virtual void lightmap_free(RID p_rid) override;
+
+	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override;
+	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override;
+	virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override;
+	virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override;
+	virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override;
+	virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override;
+	virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override;
+	virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override;
+	virtual AABB lightmap_get_aabb(RID p_lightmap) const override;
+	virtual bool lightmap_is_interior(RID p_lightmap) const override;
+	virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override;
+	virtual void lightmap_set_probe_capture_update_speed(float p_speed) override;
+
+	virtual float lightmap_get_probe_capture_update_speed() const override {
+		return lightmap_probe_capture_update_speed;
+	}
+	_FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const {
+		const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+		ERR_FAIL_COND_V(!lm, RID());
+		return lm->light_texture;
+	}
+	_FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const {
+		ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays
+		const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+		return lm->array_index;
+	}
+	_FORCE_INLINE_ bool lightmap_uses_spherical_harmonics(RID p_lightmap) const {
+		ERR_FAIL_COND_V(!using_lightmap_array, false); //only for arrays
+		const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
+		return lm->uses_spherical_harmonics;
+	}
+	_FORCE_INLINE_ uint64_t lightmap_array_get_version() const {
+		ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays
+		return lightmap_array_version;
+	}
+
+	_FORCE_INLINE_ int lightmap_array_get_size() const {
+		ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays
+		return lightmap_textures.size();
+	}
+
+	_FORCE_INLINE_ const Vector<RID> &lightmap_array_get_textures() const {
+		ERR_FAIL_COND_V(!using_lightmap_array, lightmap_textures); //only for arrays
+		return lightmap_textures;
+	}
+};
+
+} // namespace RendererRD
+
+#endif // !LIGHT_STORAGE_RD_H

+ 81 - 81
servers/rendering/renderer_scene_cull.cpp

@@ -521,7 +521,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
 			case RS::INSTANCE_LIGHT: {
 				InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
 
-				if (scenario && instance->visible && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+				if (scenario && instance->visible && RSG::light_storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
 					scenario->dynamic_lights.erase(light->instance);
 				}
 
@@ -619,7 +619,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
 			case RS::INSTANCE_LIGHT: {
 				InstanceLightData *light = memnew(InstanceLightData);
 
-				if (scenario && RSG::storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) {
+				if (scenario && RSG::light_storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) {
 					light->D = scenario->directional_lights.push_back(instance);
 				}
 
@@ -801,7 +801,7 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) {
 			case RS::INSTANCE_LIGHT: {
 				InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
 
-				if (RSG::storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) {
+				if (RSG::light_storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) {
 					light->D = scenario->directional_lights.push_back(instance);
 				}
 			} break;
@@ -930,7 +930,7 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
 
 	if (instance->base_type == RS::INSTANCE_LIGHT) {
 		InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
-		if (instance->scenario && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+		if (instance->scenario && RSG::light_storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
 			if (p_visible) {
 				instance->scenario->dynamic_lights.push_back(light->instance);
 			} else {
@@ -1490,8 +1490,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
 		scene_render->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb));
 		light->shadow_dirty = true;
 
-		RS::LightBakeMode bake_mode = RSG::storage->light_get_bake_mode(p_instance->base);
-		if (RSG::storage->light_get_type(p_instance->base) != RS::LIGHT_DIRECTIONAL && bake_mode != light->bake_mode) {
+		RS::LightBakeMode bake_mode = RSG::light_storage->light_get_bake_mode(p_instance->base);
+		if (RSG::light_storage->light_get_type(p_instance->base) != RS::LIGHT_DIRECTIONAL && bake_mode != light->bake_mode) {
 			if (p_instance->visible && p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
 				p_instance->scenario->dynamic_lights.erase(light->instance);
 			}
@@ -1503,7 +1503,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
 			}
 		}
 
-		uint32_t max_sdfgi_cascade = RSG::storage->light_get_max_sdfgi_cascade(p_instance->base);
+		uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(p_instance->base);
 		if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
 			light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
 		}
@@ -1646,8 +1646,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
 			case RS::INSTANCE_LIGHT: {
 				InstanceLightData *light_data = static_cast<InstanceLightData *>(p_instance->base_data);
 				idata.instance_data_rid = light_data->instance.get_id();
-				light_data->uses_projector = RSG::storage->light_has_projector(p_instance->base);
-				light_data->uses_softshadow = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE) > CMP_EPSILON;
+				light_data->uses_projector = RSG::light_storage->light_has_projector(p_instance->base);
+				light_data->uses_softshadow = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE) > CMP_EPSILON;
 
 			} break;
 			case RS::INSTANCE_REFLECTION_PROBE: {
@@ -1740,7 +1740,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
 		pair.pair_mask |= RS::INSTANCE_GEOMETRY_MASK;
 		pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
 
-		if (RSG::storage->light_get_bake_mode(p_instance->base) == RS::LIGHT_BAKE_DYNAMIC) {
+		if (RSG::light_storage->light_get_bake_mode(p_instance->base) == RS::LIGHT_BAKE_DYNAMIC) {
 			pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI);
 			pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
 		}
@@ -1879,11 +1879,11 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
 			new_aabb = RSG::storage->visibility_notifier_get_aabb(p_instance->base);
 		} break;
 		case RenderingServer::INSTANCE_LIGHT: {
-			new_aabb = RSG::storage->light_get_aabb(p_instance->base);
+			new_aabb = RSG::light_storage->light_get_aabb(p_instance->base);
 
 		} break;
 		case RenderingServer::INSTANCE_REFLECTION_PROBE: {
-			new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base);
+			new_aabb = RSG::light_storage->reflection_probe_get_aabb(p_instance->base);
 
 		} break;
 		case RenderingServer::INSTANCE_DECAL: {
@@ -1895,7 +1895,7 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
 
 		} break;
 		case RenderingServer::INSTANCE_LIGHTMAP: {
-			new_aabb = RSG::storage->lightmap_get_aabb(p_instance->base);
+			new_aabb = RSG::light_storage->lightmap_get_aabb(p_instance->base);
 
 		} break;
 		default: {
@@ -1923,7 +1923,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance)
 	for (Set<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) {
 		Instance *lightmap = E->get();
 
-		bool interior = RSG::storage->lightmap_is_interior(lightmap->base);
+		bool interior = RSG::light_storage->lightmap_is_interior(lightmap->base);
 
 		if (inside && !interior) {
 			continue; //we are inside, ignore exteriors
@@ -1934,13 +1934,13 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance)
 
 		Vector3 lm_pos = to_bounds.xform(center);
 
-		AABB bounds = RSG::storage->lightmap_get_aabb(lightmap->base);
+		AABB bounds = RSG::light_storage->lightmap_get_aabb(lightmap->base);
 		if (!bounds.has_point(lm_pos)) {
 			continue; //not in this lightmap
 		}
 
 		Color sh[9];
-		RSG::storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh);
+		RSG::light_storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh);
 
 		//rotate it
 		Basis rot = lightmap->transform.basis.orthonormalized();
@@ -1997,19 +1997,19 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in
 	light_transform.orthonormalize(); //scale does not count on lights
 
 	real_t max_distance = p_cam_projection.get_z_far();
-	real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
+	real_t shadow_max = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
 	if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
 		max_distance = MIN(shadow_max, max_distance);
 	}
 	max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001);
 	real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
 
-	real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
+	real_t pancake_size = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
 
 	real_t range = max_distance - min_distance;
 
 	int splits = 0;
-	switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) {
+	switch (RSG::light_storage->light_directional_get_shadow_mode(p_instance->base)) {
 		case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
 			splits = 1;
 			break;
@@ -2025,14 +2025,14 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in
 
 	distances[0] = min_distance;
 	for (int i = 0; i < splits; i++) {
-		distances[i + 1] = min_distance + RSG::storage->light_get_param(p_instance->base, RS::LightParam(RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range;
+		distances[i + 1] = min_distance + RSG::light_storage->light_get_param(p_instance->base, RS::LightParam(RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range;
 	};
 
 	distances[splits] = max_distance;
 
 	real_t texture_size = scene_render->get_directional_light_shadow_size(light->instance);
 
-	bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base);
+	bool overlap = RSG::light_storage->light_directional_get_blend_splits(p_instance->base);
 
 	cull.shadow_count = p_shadow_index + 1;
 	cull.shadows[p_shadow_index].cascade_count = splits;
@@ -2139,7 +2139,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in
 			z_min_cam = z_vec.dot(center) - radius;
 
 			{
-				float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
+				float soft_shadow_angle = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
 
 				if (soft_shadow_angle > 0.0) {
 					float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
@@ -2215,11 +2215,11 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
 
 	bool animated_material_found = false;
 
-	switch (RSG::storage->light_get_type(p_instance->base)) {
+	switch (RSG::light_storage->light_get_type(p_instance->base)) {
 		case RS::LIGHT_DIRECTIONAL: {
 		} break;
 		case RS::LIGHT_OMNI: {
-			RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base);
+			RS::LightOmniShadowMode shadow_mode = RSG::light_storage->light_omni_get_shadow_mode(p_instance->base);
 
 			if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !scene_render->light_instances_can_render_shadow_cube()) {
 				if (max_shadows_used + 2 > MAX_UPDATE_SHADOWS) {
@@ -2229,7 +2229,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
 					//using this one ensures that raster deferred will have it
 					RENDER_TIMESTAMP("Cull OmniLight3D Shadow Paraboloid, Half " + itos(i));
 
-					real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+					real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
 
 					real_t z = i == 0 ? -1 : 1;
 					Vector<Plane> planes;
@@ -2290,7 +2290,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
 					return true;
 				}
 
-				real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+				real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
 				CameraMatrix cm;
 				cm.set_perspective(90, 1, radius * 0.005f, radius);
 
@@ -2374,8 +2374,8 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
 				return true;
 			}
 
-			real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
-			real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+			real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+			real_t angle = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
 
 			CameraMatrix cm;
 			cm.set_perspective(angle * 2.0, 1.0, 0.005f * radius, radius);
@@ -2623,7 +2623,7 @@ void RendererSceneCull::_scene_cull_threaded(uint32_t p_thread, CullData *cull_d
 
 void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cull_result, uint64_t p_from, uint64_t p_to) {
 	uint64_t frame_number = RSG::rasterizer->get_frame_number();
-	float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
+	float lightmap_probe_update_speed = RSG::light_storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
 
 	uint32_t sdfgi_last_light_index = 0xFFFFFFFF;
 	uint32_t sdfgi_last_light_cascade = 0xFFFFFFFF;
@@ -2654,7 +2654,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 				if (base_type == RS::INSTANCE_LIGHT) {
 					cull_result.lights.push_back(idata.instance);
 					cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid));
-					if (cull_data.shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) {
+					if (cull_data.shadow_atlas.is_valid() && RSG::light_storage->light_has_shadow(idata.base_rid)) {
 						scene_render->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later
 					}
 
@@ -2948,7 +2948,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
 			//check shadow..
 
 			if (light) {
-				if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->base) && !(RSG::storage->light_get_type(E->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_get_sky_mode(E->base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY)) {
+				if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::light_storage->light_has_shadow(E->base) && !(RSG::light_storage->light_get_type(E->base) == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(E->base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY)) {
 					lights_with_shadow.push_back(E);
 				}
 				//add to list
@@ -3070,7 +3070,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
 		for (uint32_t i = 0; i < (uint32_t)scene_cull_result.lights.size(); i++) {
 			Instance *ins = scene_cull_result.lights[i];
 
-			if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) {
+			if (!p_shadow_atlas.is_valid() || !RSG::light_storage->light_has_shadow(ins->base)) {
 				continue;
 			}
 
@@ -3087,9 +3087,9 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
 				// near plane half width and height
 				Vector2 vp_half_extents = p_camera_data->main_projection.get_viewport_half_extents();
 
-				switch (RSG::storage->light_get_type(ins->base)) {
+				switch (RSG::light_storage->light_get_type(ins->base)) {
 					case RS::LIGHT_OMNI: {
-						float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
+						float radius = RSG::light_storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
 
 						//get two points parallel to near plane
 						Vector3 points[2] = {
@@ -3112,8 +3112,8 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
 						coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
 					} break;
 					case RS::LIGHT_SPOT: {
-						float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
-						float angle = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+						float radius = RSG::light_storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
+						float angle = RSG::light_storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE);
 
 						float w = radius * Math::sin(Math::deg2rad(angle));
 						float d = radius * Math::cos(Math::deg2rad(angle));
@@ -3303,11 +3303,11 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
 			Vector3(0, -1, 0)
 		};
 
-		Vector3 extents = RSG::storage->reflection_probe_get_extents(p_instance->base);
-		Vector3 origin_offset = RSG::storage->reflection_probe_get_origin_offset(p_instance->base);
-		float max_distance = RSG::storage->reflection_probe_get_origin_max_distance(p_instance->base);
+		Vector3 extents = RSG::light_storage->reflection_probe_get_extents(p_instance->base);
+		Vector3 origin_offset = RSG::light_storage->reflection_probe_get_origin_offset(p_instance->base);
+		float max_distance = RSG::light_storage->reflection_probe_get_origin_max_distance(p_instance->base);
 		float size = scene_render->reflection_atlas_get_size(scenario->reflection_atlas);
-		float mesh_lod_threshold = RSG::storage->reflection_probe_get_mesh_lod_threshold(p_instance->base) / size;
+		float mesh_lod_threshold = RSG::light_storage->reflection_probe_get_mesh_lod_threshold(p_instance->base) / size;
 
 		Vector3 edge = view_normals[p_step] * extents;
 		float distance = ABS(view_normals[p_step].dot(edge) - view_normals[p_step].dot(origin_offset)); //distance from origin offset to actual view distance limit
@@ -3325,7 +3325,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
 
 		RID shadow_atlas;
 
-		bool use_shadows = RSG::storage->reflection_probe_renders_shadows(p_instance->base);
+		bool use_shadows = RSG::light_storage->reflection_probe_renders_shadows(p_instance->base);
 		if (use_shadows) {
 			shadow_atlas = scenario->reflection_probe_shadow_atlas;
 		}
@@ -3341,7 +3341,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
 		RendererSceneRender::CameraData camera_data;
 		camera_data.set_camera(xform, cm, false, false);
 
-		_render_scene(&camera_data, RID(), environment, RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
+		_render_scene(&camera_data, RID(), environment, RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
 
 	} else {
 		//do roughness postprocess step until it believes it's done
@@ -3363,7 +3363,7 @@ void RendererSceneCull::render_probes() {
 		SelfList<InstanceReflectionProbeData> *next = ref_probe->next();
 		RID base = ref_probe->self()->owner->base;
 
-		switch (RSG::storage->reflection_probe_get_update_mode(base)) {
+		switch (RSG::light_storage->reflection_probe_get_update_mode(base)) {
 			case RS::REFLECTION_PROBE_UPDATE_ONCE: {
 				if (busy) { //already rendering something
 					break;
@@ -3432,16 +3432,16 @@ void RendererSceneCull::render_probes() {
 
 					if (
 							instance_caches[idx] != instance_light->instance ||
-							cache->has_shadow != RSG::storage->light_has_shadow(instance->base) ||
-							cache->type != RSG::storage->light_get_type(instance->base) ||
+							cache->has_shadow != RSG::light_storage->light_has_shadow(instance->base) ||
+							cache->type != RSG::light_storage->light_get_type(instance->base) ||
 							cache->transform != instance->transform ||
-							cache->color != RSG::storage->light_get_color(instance->base) ||
-							cache->energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
-							cache->bake_energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
-							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->color != RSG::light_storage->light_get_color(instance->base) ||
+							cache->energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
+							cache->bake_energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
+							cache->radius != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
+							cache->attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
+							cache->spot_angle != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
+							cache->spot_attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION)) {
 						cache_dirty = true;
 					}
 				}
@@ -3463,17 +3463,17 @@ void RendererSceneCull::render_probes() {
 
 					if (
 							instance_caches[idx] != instance_light->instance ||
-							cache->has_shadow != RSG::storage->light_has_shadow(instance->base) ||
-							cache->type != RSG::storage->light_get_type(instance->base) ||
+							cache->has_shadow != RSG::light_storage->light_has_shadow(instance->base) ||
+							cache->type != RSG::light_storage->light_get_type(instance->base) ||
 							cache->transform != instance->transform ||
-							cache->color != RSG::storage->light_get_color(instance->base) ||
-							cache->energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
-							cache->bake_energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
-							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->sky_mode != RSG::storage->light_directional_get_sky_mode(instance->base)) {
+							cache->color != RSG::light_storage->light_get_color(instance->base) ||
+							cache->energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
+							cache->bake_energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
+							cache->radius != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
+							cache->attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
+							cache->spot_angle != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
+							cache->spot_attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION) ||
+							cache->sky_mode != RSG::light_storage->light_directional_get_sky_mode(instance->base)) {
 						cache_dirty = true;
 					}
 				}
@@ -3509,16 +3509,16 @@ void RendererSceneCull::render_probes() {
 					InstanceVoxelGIData::LightCache *cache = &caches[idx];
 
 					instance_caches[idx] = instance_light->instance;
-					cache->has_shadow = RSG::storage->light_has_shadow(instance->base);
-					cache->type = RSG::storage->light_get_type(instance->base);
+					cache->has_shadow = RSG::light_storage->light_has_shadow(instance->base);
+					cache->type = RSG::light_storage->light_get_type(instance->base);
 					cache->transform = instance->transform;
-					cache->color = RSG::storage->light_get_color(instance->base);
-					cache->energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
-					cache->bake_energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
-					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->color = RSG::light_storage->light_get_color(instance->base);
+					cache->energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
+					cache->bake_energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+					cache->radius = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
+					cache->attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
+					cache->spot_angle = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+					cache->spot_attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
 
 					idx++;
 				}
@@ -3531,17 +3531,17 @@ void RendererSceneCull::render_probes() {
 					InstanceVoxelGIData::LightCache *cache = &caches[idx];
 
 					instance_caches[idx] = instance_light->instance;
-					cache->has_shadow = RSG::storage->light_has_shadow(instance->base);
-					cache->type = RSG::storage->light_get_type(instance->base);
+					cache->has_shadow = RSG::light_storage->light_has_shadow(instance->base);
+					cache->type = RSG::light_storage->light_get_type(instance->base);
 					cache->transform = instance->transform;
-					cache->color = RSG::storage->light_get_color(instance->base);
-					cache->energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
-					cache->bake_energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
-					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->sky_mode = RSG::storage->light_directional_get_sky_mode(instance->base);
+					cache->color = RSG::light_storage->light_get_color(instance->base);
+					cache->energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
+					cache->bake_energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+					cache->radius = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
+					cache->attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
+					cache->spot_angle = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+					cache->spot_attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+					cache->sky_mode = RSG::light_storage->light_directional_get_sky_mode(instance->base);
 
 					idx++;
 				}

+ 0 - 93
servers/rendering/renderer_storage.h

@@ -119,80 +119,6 @@ public:
 		Set<Dependency *> dependencies;
 	};
 
-	/* Light API */
-
-	virtual RID directional_light_allocate() = 0;
-	virtual void directional_light_initialize(RID p_rid) = 0;
-
-	virtual RID omni_light_allocate() = 0;
-	virtual void omni_light_initialize(RID p_rid) = 0;
-
-	virtual RID spot_light_allocate() = 0;
-	virtual void spot_light_initialize(RID p_rid) = 0;
-
-	virtual void light_set_color(RID p_light, const Color &p_color) = 0;
-	virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0;
-	virtual void light_set_shadow(RID p_light, bool p_enabled) = 0;
-	virtual void light_set_projector(RID p_light, RID p_texture) = 0;
-	virtual void light_set_negative(RID p_light, bool p_enable) = 0;
-	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_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;
-
-	virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) = 0;
-
-	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_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) = 0;
-	virtual RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const = 0;
-
-	virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0;
-	virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0;
-
-	virtual bool light_has_shadow(RID p_light) const = 0;
-
-	virtual bool light_has_projector(RID p_light) const = 0;
-
-	virtual RS::LightType light_get_type(RID p_light) const = 0;
-	virtual AABB light_get_aabb(RID p_light) const = 0;
-	virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0;
-	virtual Color light_get_color(RID p_light) = 0;
-	virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0;
-	virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0;
-	virtual uint64_t light_get_version(RID p_light) const = 0;
-
-	/* PROBE API */
-
-	virtual RID reflection_probe_allocate() = 0;
-	virtual void reflection_probe_initialize(RID p_rid) = 0;
-
-	virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0;
-	virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
-	virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) = 0;
-	virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) = 0;
-	virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) = 0;
-	virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) = 0;
-	virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) = 0;
-	virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) = 0;
-	virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) = 0;
-	virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) = 0;
-	virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0;
-	virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0;
-	virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
-	virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) = 0;
-
-	virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0;
-	virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0;
-	virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0;
-	virtual Vector3 reflection_probe_get_extents(RID p_probe) const = 0;
-	virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const = 0;
-	virtual float reflection_probe_get_origin_max_distance(RID p_probe) const = 0;
-	virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0;
-	virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const = 0;
-
 	virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
 
 	/* VOXEL GI API */
@@ -237,25 +163,6 @@ public:
 
 	virtual uint32_t voxel_gi_get_version(RID p_probe) = 0;
 
-	/* LIGHTMAP  */
-
-	virtual RID lightmap_allocate() = 0;
-	virtual void lightmap_initialize(RID p_rid) = 0;
-
-	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0;
-	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0;
-	virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0;
-	virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0;
-	virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0;
-	virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0;
-	virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0;
-	virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0;
-	virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0;
-	virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0;
-	virtual bool lightmap_is_interior(RID p_lightmap) const = 0;
-	virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0;
-	virtual float lightmap_get_probe_capture_update_speed() const = 0;
-
 	/* PARTICLES */
 
 	virtual RID particles_allocate() = 0;

+ 1 - 0
servers/rendering/rendering_server_default.cpp

@@ -398,6 +398,7 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
 	RendererSceneCull *sr = memnew(RendererSceneCull);
 	RSG::scene = sr;
 	RSG::rasterizer = RendererCompositor::create();
+	RSG::light_storage = RSG::rasterizer->get_light_storage();
 	RSG::material_storage = RSG::rasterizer->get_material_storage();
 	RSG::mesh_storage = RSG::rasterizer->get_mesh_storage();
 	RSG::texture_storage = RSG::rasterizer->get_texture_storage();

+ 16 - 16
servers/rendering/rendering_server_default.h

@@ -351,8 +351,8 @@ public:
 #undef ServerName
 #undef server_name
 
-#define ServerName RendererStorage
-#define server_name RSG::storage
+#define ServerName RendererLightStorage
+#define server_name RSG::light_storage
 
 	FUNCRIDSPLIT(directional_light)
 	FUNCRIDSPLIT(omni_light)
@@ -394,6 +394,20 @@ public:
 	FUNC2(reflection_probe_set_resolution, RID, int)
 	FUNC2(reflection_probe_set_mesh_lod_threshold, RID, float)
 
+	/* LIGHTMAP */
+
+	FUNCRIDSPLIT(lightmap)
+
+	FUNC3(lightmap_set_textures, RID, RID, bool)
+	FUNC2(lightmap_set_probe_bounds, RID, const AABB &)
+	FUNC2(lightmap_set_probe_interior, RID, bool)
+	FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &)
+	FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID)
+	FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID)
+	FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID)
+	FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
+	FUNC1(lightmap_set_probe_capture_update_speed, float)
+
 	/* DECAL API */
 
 #undef ServerName
@@ -443,20 +457,6 @@ public:
 	FUNC2(voxel_gi_set_interior, RID, bool)
 	FUNC2(voxel_gi_set_use_two_bounces, RID, bool)
 
-	/* LIGHTMAP */
-
-	FUNCRIDSPLIT(lightmap)
-
-	FUNC3(lightmap_set_textures, RID, RID, bool)
-	FUNC2(lightmap_set_probe_bounds, RID, const AABB &)
-	FUNC2(lightmap_set_probe_interior, RID, bool)
-	FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &)
-	FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID)
-	FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID)
-	FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID)
-	FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
-	FUNC1(lightmap_set_probe_capture_update_speed, float)
-
 	/* PARTICLES */
 
 	FUNCRIDSPLIT(particles)

+ 1 - 0
servers/rendering/rendering_server_globals.cpp

@@ -32,6 +32,7 @@
 
 bool RenderingServerGlobals::threaded = false;
 
+RendererLightStorage *RenderingServerGlobals::light_storage = nullptr;
 RendererMaterialStorage *RenderingServerGlobals::material_storage = nullptr;
 RendererMeshStorage *RenderingServerGlobals::mesh_storage = nullptr;
 RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;

+ 2 - 0
servers/rendering/rendering_server_globals.h

@@ -34,6 +34,7 @@
 #include "servers/rendering/renderer_canvas_cull.h"
 #include "servers/rendering/renderer_canvas_render.h"
 #include "servers/rendering/renderer_scene.h"
+#include "servers/rendering/storage/light_storage.h"
 #include "servers/rendering/storage/material_storage.h"
 #include "servers/rendering/storage/mesh_storage.h"
 #include "servers/rendering/storage/texture_storage.h"
@@ -46,6 +47,7 @@ class RenderingServerGlobals {
 public:
 	static bool threaded;
 
+	static RendererLightStorage *light_storage;
 	static RendererMaterialStorage *material_storage;
 	static RendererMeshStorage *mesh_storage;
 	static RendererTextureStorage *texture_storage;

+ 139 - 0
servers/rendering/storage/light_storage.h

@@ -0,0 +1,139 @@
+/*************************************************************************/
+/*  light_storage.h                                                      */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef LIGHT_STORAGE_H
+#define LIGHT_STORAGE_H
+
+#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering_server.h"
+
+class RendererLightStorage {
+public:
+	virtual ~RendererLightStorage() {}
+
+	/* Light API */
+
+	virtual RID directional_light_allocate() = 0;
+	virtual void directional_light_initialize(RID p_rid) = 0;
+
+	virtual RID omni_light_allocate() = 0;
+	virtual void omni_light_initialize(RID p_rid) = 0;
+
+	virtual RID spot_light_allocate() = 0;
+	virtual void spot_light_initialize(RID p_rid) = 0;
+
+	virtual void light_free(RID p_rid) = 0;
+
+	virtual void light_set_color(RID p_light, const Color &p_color) = 0;
+	virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0;
+	virtual void light_set_shadow(RID p_light, bool p_enabled) = 0;
+	virtual void light_set_projector(RID p_light, RID p_texture) = 0;
+	virtual void light_set_negative(RID p_light, bool p_enable) = 0;
+	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_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;
+
+	virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) = 0;
+
+	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_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) = 0;
+	virtual RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const = 0;
+
+	virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0;
+	virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0;
+
+	virtual bool light_has_shadow(RID p_light) const = 0;
+
+	virtual bool light_has_projector(RID p_light) const = 0;
+
+	virtual RS::LightType light_get_type(RID p_light) const = 0;
+	virtual AABB light_get_aabb(RID p_light) const = 0;
+	virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0;
+	virtual Color light_get_color(RID p_light) = 0;
+	virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0;
+	virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0;
+	virtual uint64_t light_get_version(RID p_light) const = 0;
+
+	/* PROBE API */
+
+	virtual RID reflection_probe_allocate() = 0;
+	virtual void reflection_probe_initialize(RID p_rid) = 0;
+	virtual void reflection_probe_free(RID p_rid) = 0;
+
+	virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0;
+	virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
+	virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) = 0;
+	virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) = 0;
+	virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) = 0;
+	virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) = 0;
+	virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) = 0;
+	virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) = 0;
+	virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) = 0;
+	virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) = 0;
+	virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0;
+	virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0;
+	virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
+	virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) = 0;
+
+	virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0;
+	virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0;
+	virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0;
+	virtual Vector3 reflection_probe_get_extents(RID p_probe) const = 0;
+	virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const = 0;
+	virtual float reflection_probe_get_origin_max_distance(RID p_probe) const = 0;
+	virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0;
+	virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const = 0;
+
+	/* LIGHTMAP  */
+
+	virtual RID lightmap_allocate() = 0;
+	virtual void lightmap_initialize(RID p_rid) = 0;
+	virtual void lightmap_free(RID p_rid) = 0;
+
+	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0;
+	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0;
+	virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0;
+	virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0;
+	virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0;
+	virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0;
+	virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0;
+	virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0;
+	virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0;
+	virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0;
+	virtual bool lightmap_is_interior(RID p_lightmap) const = 0;
+	virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0;
+	virtual float lightmap_get_probe_capture_update_speed() const = 0;
+};
+
+#endif // !LIGHT_STORAGE_H