Browse Source

Move Sky(RD) into environment
Move Fog logic from render scene render to fog

Bastiaan Olij 3 years ago
parent
commit
bad5c659a4

+ 1061 - 0
servers/rendering/renderer_rd/environment/fog.cpp

@@ -30,6 +30,11 @@
 
 #include "fog.h"
 
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
+#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
+#include "servers/rendering/rendering_server_default.h"
+
 using namespace RendererRD;
 
 Fog *Fog::singleton = nullptr;
@@ -126,3 +131,1059 @@ Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const {
 	ERR_FAIL_COND_V(!fog_volume, Vector3());
 	return fog_volume->extents;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// Fog material
+
+bool Fog::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+	uniform_set_updated = true;
+
+	return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, Fog::get_singleton()->volumetric_fog.shader.version_get_shader(shader_data->version, 0), VolumetricFogShader::FogSet::FOG_SET_MATERIAL);
+}
+
+Fog::FogMaterialData::~FogMaterialData() {
+	free_parameters_uniform_set(uniform_set);
+}
+
+RendererRD::ShaderData *Fog::_create_fog_shader_func() {
+	FogShaderData *shader_data = memnew(FogShaderData);
+	return shader_data;
+}
+
+RendererRD::ShaderData *Fog::_create_fog_shader_funcs() {
+	return Fog::get_singleton()->_create_fog_shader_func();
+};
+
+RendererRD::MaterialData *Fog::_create_fog_material_func(FogShaderData *p_shader) {
+	FogMaterialData *material_data = memnew(FogMaterialData);
+	material_data->shader_data = p_shader;
+	//update will happen later anyway so do nothing.
+	return material_data;
+}
+
+RendererRD::MaterialData *Fog::_create_fog_material_funcs(RendererRD::ShaderData *p_shader) {
+	return Fog::get_singleton()->_create_fog_material_func(static_cast<FogShaderData *>(p_shader));
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// FOG VOLUMES INSTANCE
+
+RID Fog::fog_volume_instance_create(RID p_fog_volume) {
+	FogVolumeInstance fvi;
+	fvi.volume = p_fog_volume;
+	return fog_volume_instance_owner.make_rid(fvi);
+}
+
+void Fog::fog_instance_free(RID p_rid) {
+	fog_volume_instance_owner.free(p_rid);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Volumetric Fog Shader
+
+void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array) {
+	MaterialStorage *material_storage = MaterialStorage::get_singleton();
+
+	{
+		// Initialize local fog shader
+		Vector<String> volumetric_fog_modes;
+		volumetric_fog_modes.push_back("");
+		volumetric_fog.shader.initialize(volumetric_fog_modes);
+
+		material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_shader_funcs);
+		material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_material_funcs);
+		volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO));
+	}
+
+	{
+		ShaderCompiler::DefaultIdentifierActions actions;
+
+		actions.renames["TIME"] = "scene_params.time";
+		actions.renames["PI"] = _MKSTR(Math_PI);
+		actions.renames["TAU"] = _MKSTR(Math_TAU);
+		actions.renames["E"] = _MKSTR(Math_E);
+		actions.renames["WORLD_POSITION"] = "world.xyz";
+		actions.renames["OBJECT_POSITION"] = "params.position";
+		actions.renames["UVW"] = "uvw";
+		actions.renames["EXTENTS"] = "params.extents";
+		actions.renames["ALBEDO"] = "albedo";
+		actions.renames["DENSITY"] = "density";
+		actions.renames["EMISSION"] = "emission";
+		actions.renames["SDF"] = "sdf";
+
+		actions.usage_defines["SDF"] = "#define SDF_USED\n";
+		actions.usage_defines["DENSITY"] = "#define DENSITY_USED\n";
+		actions.usage_defines["ALBEDO"] = "#define ALBEDO_USED\n";
+		actions.usage_defines["EMISSION"] = "#define EMISSION_USED\n";
+
+		actions.sampler_array_name = "material_samplers";
+		actions.base_texture_binding_index = 1;
+		actions.texture_layout_set = VolumetricFogShader::FogSet::FOG_SET_MATERIAL;
+		actions.base_uniform_string = "material.";
+
+		actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
+		actions.default_repeat = ShaderLanguage::REPEAT_DISABLE;
+		actions.global_buffer_array_variable = "global_variables.data";
+
+		volumetric_fog.compiler.initialize(actions);
+	}
+
+	{
+		// default material and shader for fog shader
+		volumetric_fog.default_shader = material_storage->shader_allocate();
+		material_storage->shader_initialize(volumetric_fog.default_shader);
+		material_storage->shader_set_code(volumetric_fog.default_shader, R"(
+// Default fog shader.
+
+shader_type fog;
+
+void fog() {
+DENSITY = 1.0;
+ALBEDO = vec3(1.0);
+}
+)");
+		volumetric_fog.default_material = material_storage->material_allocate();
+		material_storage->material_initialize(volumetric_fog.default_material);
+		material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader);
+
+		FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::SHADER_TYPE_FOG));
+		volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, 0);
+
+		Vector<RD::Uniform> uniforms;
+
+		{
+			Vector<RID> ids;
+			ids.resize(12);
+			RID *ids_ptr = ids.ptrw();
+			ids_ptr[0] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+			ids_ptr[1] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+			ids_ptr[2] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+			ids_ptr[3] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+			ids_ptr[4] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+			ids_ptr[5] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+			ids_ptr[6] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+			ids_ptr[7] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+			ids_ptr[8] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+			ids_ptr[9] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+			ids_ptr[10] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+			ids_ptr[11] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+
+			RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids);
+			uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+			u.binding = 2;
+			u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer());
+			uniforms.push_back(u);
+		}
+
+		volumetric_fog.base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_BASE);
+	}
+	{
+		String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(p_max_directional_lights) + "\n";
+		defines += "\n#define MAX_SKY_LOD " + itos(p_roughness_layers - 1) + ".0\n";
+		if (p_is_using_radiance_cubemap_array) {
+			defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
+		}
+		Vector<String> volumetric_fog_modes;
+		volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n");
+		volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n#define ENABLE_SDFGI\n");
+		volumetric_fog_modes.push_back("\n#define MODE_FILTER\n");
+		volumetric_fog_modes.push_back("\n#define MODE_FOG\n");
+		volumetric_fog_modes.push_back("\n#define MODE_COPY\n");
+
+		volumetric_fog.process_shader.initialize(volumetric_fog_modes, defines);
+		volumetric_fog.process_shader_version = volumetric_fog.process_shader.version_create();
+		for (int i = 0; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) {
+			volumetric_fog.process_pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, i));
+		}
+		volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO));
+	}
+}
+
+void Fog::free_fog_shader() {
+	MaterialStorage *material_storage = MaterialStorage::get_singleton();
+
+	volumetric_fog.process_shader.version_free(volumetric_fog.process_shader_version);
+	RD::get_singleton()->free(volumetric_fog.volume_ubo);
+	RD::get_singleton()->free(volumetric_fog.params_ubo);
+	material_storage->shader_free(volumetric_fog.default_shader);
+	material_storage->material_free(volumetric_fog.default_material);
+}
+
+void Fog::FogShaderData::set_path_hint(const String &p_path) {
+	path = p_path;
+}
+
+void Fog::FogShaderData::set_code(const String &p_code) {
+	//compile
+
+	code = p_code;
+	valid = false;
+	ubo_size = 0;
+	uniforms.clear();
+
+	if (code.is_empty()) {
+		return; //just invalid, but no error
+	}
+
+	ShaderCompiler::GeneratedCode gen_code;
+	ShaderCompiler::IdentifierActions actions;
+	actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE;
+
+	uses_time = false;
+
+	actions.usage_flag_pointers["TIME"] = &uses_time;
+
+	actions.uniforms = &uniforms;
+
+	Fog *fog_singleton = Fog::get_singleton();
+
+	Error err = fog_singleton->volumetric_fog.compiler.compile(RS::SHADER_FOG, code, &actions, path, gen_code);
+	ERR_FAIL_COND_MSG(err != OK, "Fog shader compilation failed.");
+
+	if (version.is_null()) {
+		version = fog_singleton->volumetric_fog.shader.version_create();
+	}
+
+	fog_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines);
+	ERR_FAIL_COND(!fog_singleton->volumetric_fog.shader.version_is_valid(version));
+
+	ubo_size = gen_code.uniform_total_size;
+	ubo_offsets = gen_code.uniform_offsets;
+	texture_uniforms = gen_code.texture_uniforms;
+
+	pipeline = RD::get_singleton()->compute_pipeline_create(fog_singleton->volumetric_fog.shader.version_get_shader(version, 0));
+
+	valid = true;
+}
+
+void Fog::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
+	if (!p_texture.is_valid()) {
+		if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) {
+			default_texture_params[p_name].erase(p_index);
+
+			if (default_texture_params[p_name].is_empty()) {
+				default_texture_params.erase(p_name);
+			}
+		}
+	} else {
+		if (!default_texture_params.has(p_name)) {
+			default_texture_params[p_name] = HashMap<int, RID>();
+		}
+		default_texture_params[p_name][p_index] = p_texture;
+	}
+}
+
+void Fog::FogShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+	RBMap<int, StringName> order;
+
+	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
+		if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+			continue;
+		}
+
+		if (E.value.texture_order >= 0) {
+			order[E.value.texture_order + 100000] = E.key;
+		} else {
+			order[E.value.order] = E.key;
+		}
+	}
+
+	for (const KeyValue<int, StringName> &E : order) {
+		PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
+		pi.name = E.value;
+		p_param_list->push_back(pi);
+	}
+}
+
+void Fog::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
+	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
+		if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+			continue;
+		}
+
+		RendererMaterialStorage::InstanceShaderParam p;
+		p.info = ShaderLanguage::uniform_to_property_info(E.value);
+		p.info.name = E.key; //supply name
+		p.index = E.value.instance_index;
+		p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint);
+		p_param_list->push_back(p);
+	}
+}
+
+bool Fog::FogShaderData::is_param_texture(const StringName &p_param) const {
+	if (!uniforms.has(p_param)) {
+		return false;
+	}
+
+	return uniforms[p_param].texture_order >= 0;
+}
+
+bool Fog::FogShaderData::is_animated() const {
+	return false;
+}
+
+bool Fog::FogShaderData::casts_shadows() const {
+	return false;
+}
+
+Variant Fog::FogShaderData::get_default_parameter(const StringName &p_parameter) const {
+	if (uniforms.has(p_parameter)) {
+		ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
+		Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
+		return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
+	}
+	return Variant();
+}
+
+RS::ShaderNativeSourceCode Fog::FogShaderData::get_native_source_code() const {
+	Fog *fog_singleton = Fog::get_singleton();
+
+	return fog_singleton->volumetric_fog.shader.version_get_native_source_code(version);
+}
+
+Fog::FogShaderData::~FogShaderData() {
+	Fog *fog_singleton = Fog::get_singleton();
+	ERR_FAIL_COND(!fog_singleton);
+	//pipeline variants will clear themselves if shader is gone
+	if (version.is_valid()) {
+		fog_singleton->volumetric_fog.shader.version_free(version);
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Volumetric Fog
+
+Fog::VolumetricFog::VolumetricFog(const Vector3i &fog_size, RID p_sky_shader) {
+	width = fog_size.x;
+	height = fog_size.y;
+	depth = fog_size.z;
+
+	RD::TextureFormat tf;
+	tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+	tf.width = fog_size.x;
+	tf.height = fog_size.y;
+	tf.depth = fog_size.z;
+	tf.texture_type = RD::TEXTURE_TYPE_3D;
+	tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+
+	light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+	RD::get_singleton()->set_resource_name(light_density_map, "Fog light-density map");
+
+	tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+
+	prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+	RD::get_singleton()->set_resource_name(prev_light_density_map, "Fog previous light-density map");
+	RD::get_singleton()->texture_clear(prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
+
+	tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+
+	fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+	RD::get_singleton()->set_resource_name(fog_map, "Fog map");
+
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+	Vector<uint8_t> dm;
+	dm.resize(fog_size.x * fog_size.y * fog_size.z * 4);
+	dm.fill(0);
+
+	density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
+	RD::get_singleton()->set_resource_name(density_map, "Fog density map");
+	light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
+	RD::get_singleton()->set_resource_name(light_map, "Fog light map");
+	emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);
+	RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");
+#else
+	tf.format = RD::DATA_FORMAT_R32_UINT;
+	tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+	density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+	RD::get_singleton()->set_resource_name(density_map, "Fog density map");
+	RD::get_singleton()->texture_clear(density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
+	light_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+	RD::get_singleton()->set_resource_name(light_map, "Fog light map");
+	RD::get_singleton()->texture_clear(light_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
+	emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+	RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");
+	RD::get_singleton()->texture_clear(emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
+#endif
+
+	Vector<RD::Uniform> uniforms;
+	{
+		RD::Uniform u;
+		u.binding = 0;
+		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+		u.append_id(fog_map);
+		uniforms.push_back(u);
+	}
+
+	sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_sky_shader, RendererRD::SkyRD::SKY_SET_FOG);
+}
+
+Fog::VolumetricFog::~VolumetricFog() {
+	RD::get_singleton()->free(prev_light_density_map);
+	RD::get_singleton()->free(light_density_map);
+	RD::get_singleton()->free(fog_map);
+	RD::get_singleton()->free(density_map);
+	RD::get_singleton()->free(light_map);
+	RD::get_singleton()->free(emissive_map);
+
+	if (fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog_uniform_set)) {
+		RD::get_singleton()->free(fog_uniform_set);
+	}
+	if (process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set_density)) {
+		RD::get_singleton()->free(process_uniform_set_density);
+	}
+	if (process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set)) {
+		RD::get_singleton()->free(process_uniform_set);
+	}
+	if (process_uniform_set2.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set2)) {
+		RD::get_singleton()->free(process_uniform_set2);
+	}
+	if (sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_uniform_set)) {
+		RD::get_singleton()->free(sdfgi_uniform_set);
+	}
+	if (sky_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_uniform_set)) {
+		RD::get_singleton()->free(sky_uniform_set);
+	}
+}
+
+Vector3i Fog::_point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform) {
+	Vector3 view_position = p_cam_transform.affine_inverse().xform(p_point);
+	view_position.z = MIN(view_position.z, -0.01); // Clamp to the front of camera
+	Vector3 fog_position = Vector3(0, 0, 0);
+
+	view_position.y = -view_position.y;
+	fog_position.z = -view_position.z / fog_end;
+	fog_position.x = (view_position.x / (2 * (fog_near_size.x * (1.0 - fog_position.z) + fog_far_size.x * fog_position.z))) + 0.5;
+	fog_position.y = (view_position.y / (2 * (fog_near_size.y * (1.0 - fog_position.z) + fog_far_size.y * fog_position.z))) + 0.5;
+	fog_position.z = Math::pow(float(fog_position.z), float(1.0 / volumetric_fog_detail_spread));
+	fog_position = fog_position * fog_size - Vector3(0.5, 0.5, 0.5);
+
+	fog_position.x = CLAMP(fog_position.x, 0.0, fog_size.x);
+	fog_position.y = CLAMP(fog_position.y, 0.0, fog_size.y);
+	fog_position.z = CLAMP(fog_position.z, 0.0, fog_size.z);
+
+	return Vector3i(fog_position);
+}
+
+void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) {
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
+
+	RENDER_TIMESTAMP("> Volumetric Fog");
+	RD::get_singleton()->draw_command_begin_label("Volumetric Fog");
+
+	if (p_fog_volumes.size() > 0) {
+		RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes");
+
+		RENDER_TIMESTAMP("Render FogVolumes");
+
+		VolumetricFogShader::VolumeUBO params;
+
+		Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents();
+		Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents();
+		float z_near = p_cam_projection.get_z_near();
+		float z_far = p_cam_projection.get_z_far();
+		float fog_end = p_settings.env->volumetric_fog_length;
+
+		Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near));
+		Vector2 fog_near_size;
+		if (p_cam_projection.is_orthogonal()) {
+			fog_near_size = fog_far_size;
+		} else {
+			fog_near_size = Vector2();
+		}
+
+		params.fog_frustum_size_begin[0] = fog_near_size.x;
+		params.fog_frustum_size_begin[1] = fog_near_size.y;
+
+		params.fog_frustum_size_end[0] = fog_far_size.x;
+		params.fog_frustum_size_end[1] = fog_far_size.y;
+
+		params.fog_frustum_end = fog_end;
+		params.z_near = z_near;
+		params.z_far = z_far;
+		params.time = p_settings.time;
+
+		params.fog_volume_size[0] = p_settings.vfog->width;
+		params.fog_volume_size[1] = p_settings.vfog->height;
+		params.fog_volume_size[2] = p_settings.vfog->depth;
+
+		params.use_temporal_reprojection = p_settings.env->volumetric_fog_temporal_reprojection;
+		params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
+		params.detail_spread = p_settings.env->volumetric_fog_detail_spread;
+		params.temporal_blend = p_settings.env->volumetric_fog_temporal_reprojection_amount;
+
+		Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
+		RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);
+		RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform);
+
+		RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), &params, RD::BARRIER_MASK_COMPUTE);
+
+		if (p_settings.vfog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->fog_uniform_set)) {
+			Vector<RD::Uniform> uniforms;
+
+			{
+				RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
+				u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
+				u.binding = 1;
+				u.append_id(p_settings.vfog->emissive_map);
+				uniforms.push_back(u);
+			}
+
+			{
+				RD::Uniform u;
+				u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+				u.binding = 2;
+				u.append_id(volumetric_fog.volume_ubo);
+				uniforms.push_back(u);
+			}
+
+			{
+				RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
+				u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
+				u.binding = 3;
+				u.append_id(p_settings.vfog->density_map);
+				uniforms.push_back(u);
+			}
+
+			{
+				RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
+				u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
+				u.binding = 4;
+				u.append_id(p_settings.vfog->light_map);
+				uniforms.push_back(u);
+			}
+
+			p_settings.vfog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS);
+		}
+
+		RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+		bool any_uses_time = false;
+
+		for (int i = 0; i < (int)p_fog_volumes.size(); i++) {
+			FogVolumeInstance *fog_volume_instance = fog_volume_instance_owner.get_or_null(p_fog_volumes[i]);
+			ERR_FAIL_COND(!fog_volume_instance);
+			RID fog_volume = fog_volume_instance->volume;
+
+			RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume);
+
+			FogMaterialData *material = nullptr;
+
+			if (fog_material.is_valid()) {
+				material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG));
+				if (!material || !material->shader_data->valid) {
+					material = nullptr;
+				}
+			}
+
+			if (!material) {
+				fog_material = volumetric_fog.default_material;
+				material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG));
+			}
+
+			ERR_FAIL_COND(!material);
+
+			FogShaderData *shader_data = material->shader_data;
+
+			ERR_FAIL_COND(!shader_data);
+
+			any_uses_time |= shader_data->uses_time;
+
+			Vector3i min = Vector3i();
+			Vector3i max = Vector3i();
+			Vector3i kernel_size = Vector3i();
+
+			Vector3 position = fog_volume_instance->transform.get_origin();
+			RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume);
+			Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume);
+
+			if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {
+				// Local fog volume.
+				Vector3i points[8];
+				Vector3 fog_size = Vector3(p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth);
+				points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+				points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+				points[2] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+				points[3] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+				points[4] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+				points[5] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+				points[6] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+				points[7] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform);
+
+				min = Vector3i(int32_t(p_settings.vfog->width) - 1, int32_t(p_settings.vfog->height) - 1, int32_t(p_settings.vfog->depth) - 1);
+				max = Vector3i(1, 1, 1);
+
+				for (int j = 0; j < 8; j++) {
+					min = Vector3i(MIN(min.x, points[j].x), MIN(min.y, points[j].y), MIN(min.z, points[j].z));
+					max = Vector3i(MAX(max.x, points[j].x), MAX(max.y, points[j].y), MAX(max.z, points[j].z));
+				}
+
+				kernel_size = max - min;
+			} else {
+				// Volume type global runs on all cells
+				extents = Vector3(p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth);
+				min = Vector3i(0, 0, 0);
+				kernel_size = Vector3i(int32_t(p_settings.vfog->width), int32_t(p_settings.vfog->height), int32_t(p_settings.vfog->depth));
+			}
+
+			if (kernel_size.x == 0 || kernel_size.y == 0 || kernel_size.z == 0) {
+				continue;
+			}
+
+			VolumetricFogShader::FogPushConstant push_constant;
+			push_constant.position[0] = position.x;
+			push_constant.position[1] = position.y;
+			push_constant.position[2] = position.z;
+			push_constant.extents[0] = extents.x;
+			push_constant.extents[1] = extents.y;
+			push_constant.extents[2] = extents.z;
+			push_constant.corner[0] = min.x;
+			push_constant.corner[1] = min.y;
+			push_constant.corner[2] = min.z;
+			push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume));
+			RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), push_constant.transform);
+
+			RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline);
+
+			RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS);
+			RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::FogPushConstant));
+			RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE);
+			if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set.
+				RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL);
+			}
+
+			RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z);
+		}
+		if (any_uses_time || p_settings.env->volumetric_fog_temporal_reprojection) {
+			RenderingServerDefault::redraw_request();
+		}
+
+		RD::get_singleton()->draw_command_end_label();
+
+		RD::get_singleton()->compute_list_end();
+	}
+
+	if (p_settings.vfog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->process_uniform_set_density)) {
+		//re create uniform set if needed
+		Vector<RD::Uniform> uniforms;
+		Vector<RD::Uniform> copy_uniforms;
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 1;
+			if (p_settings.shadow_atlas_depth.is_null()) {
+				u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK));
+			} else {
+				u.append_id(p_settings.shadow_atlas_depth);
+			}
+
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 2;
+			if (p_settings.directional_shadow_depth.is_valid()) {
+				u.append_id(p_settings.directional_shadow_depth);
+			} else {
+				u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK));
+			}
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+			u.binding = 3;
+			u.append_id(p_settings.omni_light_buffer);
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+			u.binding = 4;
+			u.append_id(p_settings.spot_light_buffer);
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+			u.binding = 5;
+			u.append_id(p_settings.directional_light_buffer);
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+			u.binding = 6;
+			u.append_id(p_settings.cluster_builder->get_cluster_buffer());
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+			u.binding = 7;
+			u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+			u.binding = 8;
+			u.append_id(p_settings.vfog->light_density_map);
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+			u.binding = 9;
+			u.append_id(p_settings.vfog->fog_map);
+			uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+			u.binding = 9;
+			u.append_id(p_settings.vfog->prev_light_density_map);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+			u.binding = 10;
+			u.append_id(p_settings.shadow_sampler);
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+			u.binding = 11;
+			u.append_id(p_settings.voxel_gl_buffer);
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 12;
+			for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) {
+				u.append_id(p_settings.rbgi->voxel_gi_textures[i]);
+			}
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+			u.binding = 13;
+			u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+			u.binding = 14;
+			u.append_id(volumetric_fog.params_ubo);
+			uniforms.push_back(u);
+			copy_uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 15;
+			u.append_id(p_settings.vfog->prev_light_density_map);
+			uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
+			u.binding = 16;
+			u.append_id(p_settings.vfog->density_map);
+			uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
+			u.binding = 17;
+			u.append_id(p_settings.vfog->light_map);
+			uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+#else
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+#endif
+			u.binding = 18;
+			u.append_id(p_settings.vfog->emissive_map);
+			uniforms.push_back(u);
+		}
+
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 19;
+			RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_cubemap_array ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
+			RID sky_texture = p_settings.env->sky.is_valid() ? p_settings.sky->sky_get_radiance_texture_rd(p_settings.env->sky) : RID();
+			u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture);
+			uniforms.push_back(u);
+		}
+
+		p_settings.vfog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0);
+
+		p_settings.vfog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
+
+		RID aux7 = uniforms.write[7].get_id(0);
+		RID aux8 = uniforms.write[8].get_id(0);
+
+		uniforms.write[7].set_id(0, aux8);
+		uniforms.write[8].set_id(0, aux7);
+
+		p_settings.vfog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
+
+		uniforms.remove_at(8);
+		uniforms.write[7].set_id(0, aux7);
+		p_settings.vfog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0);
+	}
+
+	bool using_sdfgi = p_settings.env->volumetric_fog_gi_inject > 0.0001 && p_settings.env->sdfgi_enabled && (p_settings.sdfgi != nullptr);
+
+	if (using_sdfgi) {
+		if (p_settings.vfog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->sdfgi_uniform_set)) {
+			Vector<RD::Uniform> uniforms;
+
+			{
+				RD::Uniform u;
+				u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+				u.binding = 0;
+				u.append_id(p_settings.gi->sdfgi_ubo);
+				uniforms.push_back(u);
+			}
+
+			{
+				RD::Uniform u;
+				u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+				u.binding = 1;
+				u.append_id(p_settings.sdfgi->ambient_texture);
+				uniforms.push_back(u);
+			}
+
+			{
+				RD::Uniform u;
+				u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+				u.binding = 2;
+				u.append_id(p_settings.sdfgi->occlusion_texture);
+				uniforms.push_back(u);
+			}
+
+			p_settings.vfog->sdfgi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI), 1);
+		}
+	}
+
+	p_settings.vfog->length = p_settings.env->volumetric_fog_length;
+	p_settings.vfog->spread = p_settings.env->volumetric_fog_detail_spread;
+
+	VolumetricFogShader::ParamsUBO params;
+
+	Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents();
+	Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents();
+	float z_near = p_cam_projection.get_z_near();
+	float z_far = p_cam_projection.get_z_far();
+	float fog_end = p_settings.env->volumetric_fog_length;
+
+	Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near));
+	Vector2 fog_near_size;
+	if (p_cam_projection.is_orthogonal()) {
+		fog_near_size = fog_far_size;
+	} else {
+		fog_near_size = Vector2();
+	}
+
+	params.fog_frustum_size_begin[0] = fog_near_size.x;
+	params.fog_frustum_size_begin[1] = fog_near_size.y;
+
+	params.fog_frustum_size_end[0] = fog_far_size.x;
+	params.fog_frustum_size_end[1] = fog_far_size.y;
+
+	params.ambient_inject = p_settings.env->volumetric_fog_ambient_inject * p_settings.env->ambient_light_energy;
+	params.z_far = z_far;
+
+	params.fog_frustum_end = fog_end;
+
+	Color ambient_color = p_settings.env->ambient_light.srgb_to_linear();
+	params.ambient_color[0] = ambient_color.r;
+	params.ambient_color[1] = ambient_color.g;
+	params.ambient_color[2] = ambient_color.b;
+	params.sky_contribution = p_settings.env->ambient_sky_contribution;
+
+	params.fog_volume_size[0] = p_settings.vfog->width;
+	params.fog_volume_size[1] = p_settings.vfog->height;
+	params.fog_volume_size[2] = p_settings.vfog->depth;
+
+	params.directional_light_count = p_directional_light_count;
+
+	Color emission = p_settings.env->volumetric_fog_emission.srgb_to_linear();
+	params.base_emission[0] = emission.r * p_settings.env->volumetric_fog_emission_energy;
+	params.base_emission[1] = emission.g * p_settings.env->volumetric_fog_emission_energy;
+	params.base_emission[2] = emission.b * p_settings.env->volumetric_fog_emission_energy;
+	params.base_density = p_settings.env->volumetric_fog_density;
+
+	Color base_scattering = p_settings.env->volumetric_fog_scattering.srgb_to_linear();
+	params.base_scattering[0] = base_scattering.r;
+	params.base_scattering[1] = base_scattering.g;
+	params.base_scattering[2] = base_scattering.b;
+	params.phase_g = p_settings.env->volumetric_fog_anisotropy;
+
+	params.detail_spread = p_settings.env->volumetric_fog_detail_spread;
+	params.gi_inject = p_settings.env->volumetric_fog_gi_inject;
+
+	params.cam_rotation[0] = p_cam_transform.basis[0][0];
+	params.cam_rotation[1] = p_cam_transform.basis[1][0];
+	params.cam_rotation[2] = p_cam_transform.basis[2][0];
+	params.cam_rotation[3] = 0;
+	params.cam_rotation[4] = p_cam_transform.basis[0][1];
+	params.cam_rotation[5] = p_cam_transform.basis[1][1];
+	params.cam_rotation[6] = p_cam_transform.basis[2][1];
+	params.cam_rotation[7] = 0;
+	params.cam_rotation[8] = p_cam_transform.basis[0][2];
+	params.cam_rotation[9] = p_cam_transform.basis[1][2];
+	params.cam_rotation[10] = p_cam_transform.basis[2][2];
+	params.cam_rotation[11] = 0;
+	params.filter_axis = 0;
+	params.max_voxel_gi_instances = p_settings.env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0;
+	params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
+
+	Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
+	RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);
+
+	params.use_temporal_reprojection = p_settings.env->volumetric_fog_temporal_reprojection;
+	params.temporal_blend = p_settings.env->volumetric_fog_temporal_reprojection_amount;
+
+	{
+		uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size();
+		params.cluster_shift = get_shift_from_power_of_2(cluster_size);
+
+		uint32_t cluster_screen_width = (p_settings.rb_size.x - 1) / cluster_size + 1;
+		uint32_t cluster_screen_height = (p_settings.rb_size.y - 1) / cluster_size + 1;
+		params.max_cluster_element_count_div_32 = p_settings.max_cluster_elements / 32;
+		params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32);
+		params.cluster_width = cluster_screen_width;
+
+		params.screen_size[0] = p_settings.rb_size.x;
+		params.screen_size[1] = p_settings.rb_size.y;
+	}
+
+	Basis sky_transform = p_settings.env->sky_orientation;
+	sky_transform = sky_transform.inverse() * p_cam_transform.basis;
+	RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform);
+
+	RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog");
+
+	RENDER_TIMESTAMP("Render Fog");
+	RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), &params, RD::BARRIER_MASK_COMPUTE);
+
+	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]);
+
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set_density, 0);
+
+	if (using_sdfgi) {
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->sdfgi_uniform_set, 1);
+	}
+	RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth);
+	RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+	// Copy fog to history buffer
+	if (p_settings.env->volumetric_fog_temporal_reprojection) {
+		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]);
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->copy_uniform_set, 0);
+		RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth);
+		RD::get_singleton()->compute_list_add_barrier(compute_list);
+	}
+	RD::get_singleton()->draw_command_end_label();
+
+	if (p_settings.volumetric_fog_filter_active) {
+		RD::get_singleton()->draw_command_begin_label("Filter Fog");
+
+		RENDER_TIMESTAMP("Filter Fog");
+
+		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set, 0);
+		RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth);
+
+		RD::get_singleton()->compute_list_end();
+		//need restart for buffer update
+
+		params.filter_axis = 1;
+		RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), &params);
+
+		compute_list = RD::get_singleton()->compute_list_begin();
+		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set2, 0);
+		RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth);
+
+		RD::get_singleton()->compute_list_add_barrier(compute_list);
+		RD::get_singleton()->draw_command_end_label();
+	}
+
+	RENDER_TIMESTAMP("Integrate Fog");
+	RD::get_singleton()->draw_command_begin_label("Integrate Fog");
+
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set, 0);
+	RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, 1);
+
+	RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER);
+
+	RENDER_TIMESTAMP("< Volumetric Fog");
+	RD::get_singleton()->draw_command_end_label();
+	RD::get_singleton()->draw_command_end_label();
+}

+ 246 - 0
servers/rendering/renderer_rd/environment/fog.h

@@ -34,12 +34,19 @@
 #include "core/templates/local_vector.h"
 #include "core/templates/rid_owner.h"
 #include "servers/rendering/environment/renderer_fog.h"
+#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
+#include "servers/rendering/renderer_rd/environment/gi.h"
+#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
+#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl.gen.h"
 #include "servers/rendering/storage/utilities.h"
 
 namespace RendererRD {
 
 class Fog : public RendererFog {
 public:
+	/* FOG VOLUMES */
+
 	struct FogVolume {
 		RID material;
 		Vector3 extents = Vector3(1, 1, 1);
@@ -49,10 +56,179 @@ public:
 		Dependency dependency;
 	};
 
+	struct FogVolumeInstance {
+		RID volume;
+		Transform3D transform;
+		bool active = false;
+	};
+
 private:
 	static Fog *singleton;
 
 	mutable RID_Owner<FogVolume, true> fog_volume_owner;
+	mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner;
+
+	/* Volumetric Fog */
+	struct VolumetricFogShader {
+		enum FogSet {
+			FOG_SET_BASE,
+			FOG_SET_UNIFORMS,
+			FOG_SET_MATERIAL,
+			FOG_SET_MAX,
+		};
+
+		struct FogPushConstant {
+			float position[3];
+			float pad;
+
+			float extents[3];
+			float pad2;
+
+			int32_t corner[3];
+			uint32_t shape;
+
+			float transform[16];
+		};
+
+		struct VolumeUBO {
+			float fog_frustum_size_begin[2];
+			float fog_frustum_size_end[2];
+
+			float fog_frustum_end;
+			float z_near;
+			float z_far;
+			float time;
+
+			int32_t fog_volume_size[3];
+			uint32_t directional_light_count;
+
+			uint32_t use_temporal_reprojection;
+			uint32_t temporal_frame;
+			float detail_spread;
+			float temporal_blend;
+
+			float to_prev_view[16];
+			float transform[16];
+		};
+
+		ShaderCompiler compiler;
+		VolumetricFogShaderRD shader;
+		RID volume_ubo;
+
+		RID default_shader;
+		RID default_material;
+		RID default_shader_rd;
+
+		RID base_uniform_set;
+
+		RID params_ubo;
+
+		enum {
+			VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY,
+			VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI,
+			VOLUMETRIC_FOG_PROCESS_SHADER_FILTER,
+			VOLUMETRIC_FOG_PROCESS_SHADER_FOG,
+			VOLUMETRIC_FOG_PROCESS_SHADER_COPY,
+			VOLUMETRIC_FOG_PROCESS_SHADER_MAX,
+		};
+
+		struct ParamsUBO {
+			float fog_frustum_size_begin[2];
+			float fog_frustum_size_end[2];
+
+			float fog_frustum_end;
+			float ambient_inject;
+			float z_far;
+			uint32_t filter_axis;
+
+			float ambient_color[3];
+			float sky_contribution;
+
+			int32_t fog_volume_size[3];
+			uint32_t directional_light_count;
+
+			float base_emission[3];
+			float base_density;
+
+			float base_scattering[3];
+			float phase_g;
+
+			float detail_spread;
+			float gi_inject;
+			uint32_t max_voxel_gi_instances;
+			uint32_t cluster_type_size;
+
+			float screen_size[2];
+			uint32_t cluster_shift;
+			uint32_t cluster_width;
+
+			uint32_t max_cluster_element_count_div_32;
+			uint32_t use_temporal_reprojection;
+			uint32_t temporal_frame;
+			float temporal_blend;
+
+			float cam_rotation[12];
+			float to_prev_view[16];
+			float radiance_inverse_xform[12];
+		};
+
+		VolumetricFogProcessShaderRD process_shader;
+
+		RID process_shader_version;
+		RID process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX];
+
+	} volumetric_fog;
+
+	Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform);
+
+	struct FogShaderData : public RendererRD::ShaderData {
+		bool valid = false;
+		RID version;
+
+		RID pipeline;
+		HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+		Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
+
+		Vector<uint32_t> ubo_offsets;
+		uint32_t ubo_size = 0;
+
+		String path;
+		String code;
+		HashMap<StringName, HashMap<int, RID>> default_texture_params;
+
+		bool uses_time = false;
+
+		virtual void set_path_hint(const String &p_hint);
+		virtual void set_code(const String &p_Code);
+		virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index);
+		virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+		virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const;
+		virtual bool is_param_texture(const StringName &p_param) const;
+		virtual bool is_animated() const;
+		virtual bool casts_shadows() const;
+		virtual Variant get_default_parameter(const StringName &p_parameter) const;
+		virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+
+		FogShaderData() {}
+		virtual ~FogShaderData();
+	};
+
+	struct FogMaterialData : public RendererRD::MaterialData {
+		FogShaderData *shader_data = nullptr;
+		RID uniform_set;
+		bool uniform_set_updated;
+
+		virtual void set_render_priority(int p_priority) {}
+		virtual void set_next_pass(RID p_pass) {}
+		virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+		virtual ~FogMaterialData();
+	};
+
+	RendererRD::ShaderData *_create_fog_shader_func();
+	static RendererRD::ShaderData *_create_fog_shader_funcs();
+
+	RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader);
+	static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader);
 
 public:
 	static Fog *get_singleton() { return singleton; }
@@ -76,6 +252,76 @@ public:
 	RID fog_volume_get_material(RID p_fog_volume) const;
 	virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;
 	Vector3 fog_volume_get_extents(RID p_fog_volume) const;
+
+	/* FOG VOLUMES INSTANCE */
+
+	FogVolumeInstance *get_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.get_or_null(p_rid); };
+	bool owns_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.owns(p_rid); };
+
+	RID fog_volume_instance_create(RID p_fog_volume);
+	void fog_instance_free(RID p_rid);
+
+	/* Volumetric FOG */
+	struct VolumetricFog {
+		enum {
+			MAX_TEMPORAL_FRAMES = 16
+		};
+
+		uint32_t width = 0;
+		uint32_t height = 0;
+		uint32_t depth = 0;
+
+		float length;
+		float spread;
+
+		RID light_density_map;
+		RID prev_light_density_map;
+		RID fog_map;
+		RID density_map;
+		RID light_map;
+		RID emissive_map;
+
+		RID fog_uniform_set;
+		RID copy_uniform_set;
+		RID process_uniform_set_density;
+		RID process_uniform_set;
+		RID process_uniform_set2;
+		RID sdfgi_uniform_set;
+		RID sky_uniform_set;
+
+		int last_shadow_filter = -1;
+
+		VolumetricFog(const Vector3i &fog_size, RID p_sky_shader);
+		~VolumetricFog();
+	};
+
+	void init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array);
+	void free_fog_shader();
+
+	struct VolumetricFogSettings {
+		Vector2i rb_size;
+		double time;
+		bool is_using_radiance_cubemap_array;
+		uint32_t max_cluster_elements;
+		bool volumetric_fog_filter_active;
+		RID shadow_sampler;
+		RID voxel_gl_buffer;
+		RID shadow_atlas_depth;
+		RID omni_light_buffer;
+		RID spot_light_buffer;
+		RID directional_shadow_depth;
+		RID directional_light_buffer;
+
+		// Objects related to our render buffer
+		VolumetricFog *vfog;
+		ClusterBuilderRD *cluster_builder;
+		GI *gi;
+		GI::SDFGI *sdfgi;
+		GI::RenderBuffersGI *rbgi;
+		RendererSceneEnvironmentRD *env;
+		SkyRD *sky;
+	};
+	void volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
 };
 
 } // namespace RendererRD

+ 2 - 2
servers/rendering/renderer_rd/environment/gi.cpp

@@ -1268,7 +1268,7 @@ void GI::SDFGI::update_light() {
 	RD::get_singleton()->draw_command_end_label();
 }
 
-void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) {
+void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, SkyRD::Sky *p_sky) {
 	RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes");
 
 	SDFGIShader::IntegratePushConstant push_constant;
@@ -3233,7 +3233,7 @@ GI::~GI() {
 	singleton = nullptr;
 }
 
-void GI::init(RendererSceneSkyRD *p_sky) {
+void GI::init(SkyRD *p_sky) {
 	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 

+ 3 - 3
servers/rendering/renderer_rd/environment/gi.h

@@ -35,8 +35,8 @@
 #include "core/templates/rid_owner.h"
 #include "servers/rendering/environment/renderer_gi.h"
 #include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/environment/sky.h"
 #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
-#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
 #include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h"
@@ -618,7 +618,7 @@ public:
 		void erase();
 		void update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position);
 		void update_light();
-		void update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky);
+		void update_probes(RendererSceneEnvironmentRD *p_env, RendererRD::SkyRD::Sky *p_sky);
 		void store_probes();
 		int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const;
 		void update_cascades();
@@ -769,7 +769,7 @@ public:
 	GI();
 	~GI();
 
-	void init(RendererSceneSkyRD *p_sky);
+	void init(RendererRD::SkyRD *p_sky);
 	void free();
 
 	SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size);

+ 57 - 55
servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp → servers/rendering/renderer_rd/environment/sky.cpp

@@ -1,5 +1,5 @@
 /*************************************************************************/
-/*  renderer_scene_sky_rd.cpp                                            */
+/*  sky.cpp                                                              */
 /*************************************************************************/
 /*                       This file is part of:                           */
 /*                           GODOT ENGINE                                */
@@ -28,25 +28,27 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 
-#include "renderer_scene_sky_rd.h"
+#include "sky.h"
 #include "core/config/project_settings.h"
 #include "core/math/math_defs.h"
-#include "renderer_scene_render_rd.h"
 #include "servers/rendering/renderer_rd/effects/copy_effects.h"
 #include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
 #include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_server_default.h"
 #include "servers/rendering/rendering_server_globals.h"
 
+using namespace RendererRD;
+
 ////////////////////////////////////////////////////////////////////////////////
 // SKY SHADER
 
-void RendererSceneSkyRD::SkyShaderData::set_path_hint(const String &p_path) {
+void SkyRD::SkyShaderData::set_path_hint(const String &p_path) {
 	path = p_path;
 }
 
-void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
+void SkyRD::SkyShaderData::set_code(const String &p_code) {
 	//compile
 
 	code = p_code;
@@ -145,7 +147,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
 	valid = true;
 }
 
-void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
+void SkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
 	if (!p_texture.is_valid()) {
 		if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) {
 			default_texture_params[p_name].erase(p_index);
@@ -162,7 +164,7 @@ void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringNa
 	}
 }
 
-void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void SkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
 	HashMap<int, StringName> order;
 
 	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
@@ -184,7 +186,7 @@ void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_par
 	}
 }
 
-void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
+void SkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
 	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
 		if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
 			continue;
@@ -199,7 +201,7 @@ void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererMat
 	}
 }
 
-bool RendererSceneSkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
+bool SkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
 	if (!uniforms.has(p_param)) {
 		return false;
 	}
@@ -207,15 +209,15 @@ bool RendererSceneSkyRD::SkyShaderData::is_param_texture(const StringName &p_par
 	return uniforms[p_param].texture_order >= 0;
 }
 
-bool RendererSceneSkyRD::SkyShaderData::is_animated() const {
+bool SkyRD::SkyShaderData::is_animated() const {
 	return false;
 }
 
-bool RendererSceneSkyRD::SkyShaderData::casts_shadows() const {
+bool SkyRD::SkyShaderData::casts_shadows() const {
 	return false;
 }
 
-Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
+Variant SkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
 	if (uniforms.has(p_parameter)) {
 		ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
 		Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
@@ -224,13 +226,13 @@ Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringNam
 	return Variant();
 }
 
-RS::ShaderNativeSourceCode RendererSceneSkyRD::SkyShaderData::get_native_source_code() const {
+RS::ShaderNativeSourceCode SkyRD::SkyShaderData::get_native_source_code() const {
 	RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton);
 
 	return scene_singleton->sky.sky_shader.shader.version_get_native_source_code(version);
 }
 
-RendererSceneSkyRD::SkyShaderData::~SkyShaderData() {
+SkyRD::SkyShaderData::~SkyShaderData() {
 	RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton);
 	ERR_FAIL_COND(!scene_singleton);
 	//pipeline variants will clear themselves if shader is gone
@@ -242,7 +244,7 @@ RendererSceneSkyRD::SkyShaderData::~SkyShaderData() {
 ////////////////////////////////////////////////////////////////////////////////
 // Sky material
 
-bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool SkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
 	RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton);
 
 	uniform_set_updated = true;
@@ -250,7 +252,7 @@ bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const HashMap<String
 	return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
 }
 
-RendererSceneSkyRD::SkyMaterialData::~SkyMaterialData() {
+SkyRD::SkyMaterialData::~SkyMaterialData() {
 	free_parameters_uniform_set(uniform_set);
 }
 
@@ -272,7 +274,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar
 	p_array[11] = 0;
 }
 
-void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) {
+void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) {
 	SkyPushConstant sky_push_constant;
 
 	memset(&sky_push_constant, 0, sizeof(SkyPushConstant));
@@ -323,7 +325,7 @@ void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_
 ////////////////////////////////////////////////////////////////////////////////
 // ReflectionData
 
-void RendererSceneSkyRD::ReflectionData::clear_reflection_data() {
+void SkyRD::ReflectionData::clear_reflection_data() {
 	layers.clear();
 	radiance_base_cubemap = RID();
 	if (downsampled_radiance_cubemap.is_valid()) {
@@ -334,7 +336,7 @@ void RendererSceneSkyRD::ReflectionData::clear_reflection_data() {
 	coefficient_buffer = RID();
 }
 
-void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) {
+void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) {
 	//recreate radiance and all data
 
 	int mipmaps = p_mipmaps;
@@ -442,7 +444,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int
 	}
 }
 
-void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) {
+void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) {
 	RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
 	ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
 	bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
@@ -500,7 +502,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_us
 	}
 }
 
-void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
+void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
 	RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
 	ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
 	bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
@@ -569,7 +571,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(boo
 	RD::get_singleton()->draw_command_end_label(); // Filter radiance
 }
 
-void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) {
+void SkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) {
 	RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
 	ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
 	bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
@@ -594,9 +596,9 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// RendererSceneSkyRD::Sky
+// SkyRD::Sky
 
-void RendererSceneSkyRD::Sky::free() {
+void SkyRD::Sky::free() {
 	if (radiance.is_valid()) {
 		RD::get_singleton()->free(radiance);
 		radiance = RID();
@@ -624,7 +626,7 @@ void RendererSceneSkyRD::Sky::free() {
 	}
 }
 
-RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) {
+RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) {
 	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 
 	if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) {
@@ -685,7 +687,7 @@ RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_
 	return texture_uniform_sets[p_version];
 }
 
-bool RendererSceneSkyRD::Sky::set_radiance_size(int p_radiance_size) {
+bool SkyRD::Sky::set_radiance_size(int p_radiance_size) {
 	ERR_FAIL_COND_V(p_radiance_size < 32 || p_radiance_size > 2048, false);
 	if (radiance_size == p_radiance_size) {
 		return false;
@@ -706,7 +708,7 @@ bool RendererSceneSkyRD::Sky::set_radiance_size(int p_radiance_size) {
 	return true;
 }
 
-bool RendererSceneSkyRD::Sky::set_mode(RS::SkyMode p_mode) {
+bool SkyRD::Sky::set_mode(RS::SkyMode p_mode) {
 	if (mode == p_mode) {
 		return false;
 	}
@@ -727,7 +729,7 @@ bool RendererSceneSkyRD::Sky::set_mode(RS::SkyMode p_mode) {
 	return true;
 }
 
-bool RendererSceneSkyRD::Sky::set_material(RID p_material) {
+bool SkyRD::Sky::set_material(RID p_material) {
 	if (material == p_material) {
 		return false;
 	}
@@ -736,7 +738,7 @@ bool RendererSceneSkyRD::Sky::set_material(RID p_material) {
 	return true;
 }
 
-Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) {
+Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) {
 	if (radiance.is_valid()) {
 		RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
 
@@ -770,37 +772,37 @@ Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(float p_energy, int p_roughnes
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// RendererSceneSkyRD
+// SkyRD
 
-RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_func() {
+RendererRD::ShaderData *SkyRD::_create_sky_shader_func() {
 	SkyShaderData *shader_data = memnew(SkyShaderData);
 	return shader_data;
 }
 
-RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_funcs() {
+RendererRD::ShaderData *SkyRD::_create_sky_shader_funcs() {
 	// !BAS! Why isn't _create_sky_shader_func not just static too?
 	return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_shader_func();
 };
 
-RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_func(SkyShaderData *p_shader) {
+RendererRD::MaterialData *SkyRD::_create_sky_material_func(SkyShaderData *p_shader) {
 	SkyMaterialData *material_data = memnew(SkyMaterialData);
 	material_data->shader_data = p_shader;
 	//update will happen later anyway so do nothing.
 	return material_data;
 }
 
-RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) {
+RendererRD::MaterialData *SkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) {
 	// !BAS! same here, we could just make _create_sky_material_func static?
 	return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
 };
 
-RendererSceneSkyRD::RendererSceneSkyRD() {
+SkyRD::SkyRD() {
 	roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers");
 	sky_ggx_samples_quality = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples");
 	sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections");
 }
 
-void RendererSceneSkyRD::init() {
+void SkyRD::init() {
 	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 
@@ -1055,11 +1057,11 @@ void sky() {
 	}
 }
 
-void RendererSceneSkyRD::set_texture_format(RD::DataFormat p_texture_format) {
+void SkyRD::set_texture_format(RD::DataFormat p_texture_format) {
 	texture_format = p_texture_format;
 }
 
-RendererSceneSkyRD::~RendererSceneSkyRD() {
+SkyRD::~SkyRD() {
 	// cleanup anything created in init...
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 
@@ -1089,7 +1091,7 @@ RendererSceneSkyRD::~RendererSceneSkyRD() {
 	RD::get_singleton()->free(index_buffer); //array gets freed as dependency
 }
 
-void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
+void SkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &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);
@@ -1301,7 +1303,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
 	RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo);
 }
 
-void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
+void SkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 	ERR_FAIL_COND(!p_env);
 
@@ -1470,7 +1472,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const Project
 	}
 }
 
-void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) {
+void SkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) {
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 	ERR_FAIL_COND(!p_env);
 
@@ -1577,7 +1579,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
 	RD::get_singleton()->draw_list_end();
 }
 
-void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
+void SkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 	ERR_FAIL_COND(!p_env);
 
@@ -1662,7 +1664,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
 	}
 }
 
-void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
+void SkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 	ERR_FAIL_COND(!p_env);
 
@@ -1741,7 +1743,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme
 	_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
 }
 
-void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) {
+void SkyRD::invalidate_sky(Sky *p_sky) {
 	if (!p_sky->dirty) {
 		p_sky->dirty = true;
 		p_sky->dirty_list = dirty_sky_list;
@@ -1749,7 +1751,7 @@ void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) {
 	}
 }
 
-void RendererSceneSkyRD::update_dirty_skys() {
+void SkyRD::update_dirty_skys() {
 	Sky *sky = dirty_sky_list;
 
 	while (sky) {
@@ -1853,26 +1855,26 @@ void RendererSceneSkyRD::update_dirty_skys() {
 	dirty_sky_list = nullptr;
 }
 
-RID RendererSceneSkyRD::sky_get_material(RID p_sky) const {
+RID SkyRD::sky_get_material(RID p_sky) const {
 	Sky *sky = get_sky(p_sky);
 	ERR_FAIL_COND_V(!sky, RID());
 
 	return sky->material;
 }
 
-RID RendererSceneSkyRD::allocate_sky_rid() {
+RID SkyRD::allocate_sky_rid() {
 	return sky_owner.allocate_rid();
 }
 
-void RendererSceneSkyRD::initialize_sky_rid(RID p_rid) {
+void SkyRD::initialize_sky_rid(RID p_rid) {
 	sky_owner.initialize_rid(p_rid, Sky());
 }
 
-RendererSceneSkyRD::Sky *RendererSceneSkyRD::get_sky(RID p_sky) const {
+SkyRD::Sky *SkyRD::get_sky(RID p_sky) const {
 	return sky_owner.get_or_null(p_sky);
 }
 
-void RendererSceneSkyRD::free_sky(RID p_sky) {
+void SkyRD::free_sky(RID p_sky) {
 	Sky *sky = get_sky(p_sky);
 	ERR_FAIL_COND(!sky);
 
@@ -1880,7 +1882,7 @@ void RendererSceneSkyRD::free_sky(RID p_sky) {
 	sky_owner.free(p_sky);
 }
 
-void RendererSceneSkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
+void SkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
 	Sky *sky = get_sky(p_sky);
 	ERR_FAIL_COND(!sky);
 
@@ -1889,7 +1891,7 @@ void RendererSceneSkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
 	}
 }
 
-void RendererSceneSkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
+void SkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
 	Sky *sky = get_sky(p_sky);
 	ERR_FAIL_COND(!sky);
 
@@ -1898,7 +1900,7 @@ void RendererSceneSkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
 	}
 }
 
-void RendererSceneSkyRD::sky_set_material(RID p_sky, RID p_material) {
+void SkyRD::sky_set_material(RID p_sky, RID p_material) {
 	Sky *sky = get_sky(p_sky);
 	ERR_FAIL_COND(!sky);
 
@@ -1907,7 +1909,7 @@ void RendererSceneSkyRD::sky_set_material(RID p_sky, RID p_material) {
 	}
 }
 
-Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
+Ref<Image> SkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
 	Sky *sky = get_sky(p_sky);
 	ERR_FAIL_COND_V(!sky, Ref<Image>());
 
@@ -1916,7 +1918,7 @@ Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool
 	return sky->bake_panorama(p_energy, p_bake_irradiance ? roughness_layers : 0, p_size);
 }
 
-RID RendererSceneSkyRD::sky_get_radiance_texture_rd(RID p_sky) const {
+RID SkyRD::sky_get_radiance_texture_rd(RID p_sky) const {
 	Sky *sky = get_sky(p_sky);
 	ERR_FAIL_COND_V(!sky, RID());
 

+ 12 - 8
servers/rendering/renderer_rd/renderer_scene_sky_rd.h → servers/rendering/renderer_rd/environment/sky.h

@@ -1,5 +1,5 @@
 /*************************************************************************/
-/*  renderer_scene_sky_rd.h                                              */
+/*  sky.h                                                                */
 /*************************************************************************/
 /*                       This file is part of:                           */
 /*                           GODOT ENGINE                                */
@@ -28,14 +28,14 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 
-#ifndef RENDERER_SCENE_SKY_RD_H
-#define RENDERER_SCENE_SKY_RD_H
+#ifndef SKY_RD_H
+#define SKY_RD_H
 
 #include "core/templates/rid_owner.h"
 #include "servers/rendering/renderer_compositor.h"
 #include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
 #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
-#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/sky.glsl.gen.h"
 #include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
 #include "servers/rendering/renderer_scene_render.h"
 #include "servers/rendering/rendering_device.h"
@@ -44,7 +44,9 @@
 // Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
 class RendererSceneRenderRD;
 
-class RendererSceneSkyRD {
+namespace RendererRD {
+
+class SkyRD {
 public:
 	enum SkySet {
 		SKY_SET_UNIFORMS,
@@ -290,10 +292,10 @@ public:
 	RendererRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
 	static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader);
 
-	RendererSceneSkyRD();
+	SkyRD();
 	void init();
 	void set_texture_format(RD::DataFormat p_texture_format);
-	~RendererSceneSkyRD();
+	~SkyRD();
 
 	void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
 	void update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
@@ -318,4 +320,6 @@ public:
 	RID sky_get_radiance_texture_rd(RID p_sky) const;
 };
 
-#endif // RENDERER_SCENE_SKY_RD_H
+} // namespace RendererRD
+
+#endif // SKY_RD_H

File diff suppressed because it is too large
+ 35 - 915
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp


+ 14 - 217
servers/rendering/renderer_rd/renderer_scene_render_rd.h

@@ -40,11 +40,10 @@
 #include "servers/rendering/renderer_rd/effects/ss_effects.h"
 #include "servers/rendering/renderer_rd/effects/tone_mapper.h"
 #include "servers/rendering/renderer_rd/effects/vrs.h"
+#include "servers/rendering/renderer_rd/environment/fog.h"
 #include "servers/rendering/renderer_rd/environment/gi.h"
+#include "servers/rendering/renderer_rd/environment/sky.h"
 #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
-#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
-#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h"
 #include "servers/rendering/renderer_scene.h"
 #include "servers/rendering/renderer_scene_render.h"
 #include "servers/rendering/rendering_device.h"
@@ -99,7 +98,7 @@ struct RenderDataRD {
 };
 
 class RendererSceneRenderRD : public RendererSceneRender {
-	friend RendererSceneSkyRD;
+	friend RendererRD::SkyRD;
 	friend RendererRD::GI;
 
 protected:
@@ -167,7 +166,7 @@ protected:
 
 	RendererRD::SSEffects *ss_effects = nullptr;
 	RendererRD::GI gi;
-	RendererSceneSkyRD sky;
+	RendererRD::SkyRD sky;
 
 	RendererSceneEnvironmentRD *get_environment(RID p_environment) {
 		if (p_environment.is_valid()) {
@@ -212,7 +211,7 @@ private:
 
 		struct Reflection {
 			RID owner;
-			RendererSceneSkyRD::ReflectionData data;
+			RendererRD::SkyRD::ReflectionData data;
 			RID fbs[6];
 		};
 
@@ -407,16 +406,6 @@ private:
 
 	mutable RID_Owner<LightInstance> light_instance_owner;
 
-	/* FOG VOLUMES */
-
-	struct FogVolumeInstance {
-		RID volume;
-		Transform3D transform;
-		bool active = false;
-	};
-
-	mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner;
-
 	/* ENVIRONMENT */
 
 	RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
@@ -471,8 +460,6 @@ private:
 	ClusterBuilderSharedDataRD cluster_builder_shared;
 	ClusterBuilderRD *current_cluster_builder = nullptr;
 
-	struct VolumetricFog;
-
 	struct RenderBuffers {
 		RenderBufferData *data = nullptr;
 		int internal_width = 0;
@@ -508,8 +495,8 @@ private:
 		Vector<View> views;
 
 		RendererRD::GI::SDFGI *sdfgi = nullptr;
-		VolumetricFog *volumetric_fog = nullptr;
 		RendererRD::GI::RenderBuffersGI rbgi;
+		RendererRD::Fog::VolumetricFog *volumetric_fog = nullptr;
 
 		ClusterBuilderRD *cluster_builder = nullptr;
 
@@ -749,204 +736,6 @@ private:
 		bool depth_prepass_used; // this does not seem used anywhere...
 	} render_state;
 
-	struct VolumetricFog {
-		enum {
-			MAX_TEMPORAL_FRAMES = 16
-		};
-
-		uint32_t width = 0;
-		uint32_t height = 0;
-		uint32_t depth = 0;
-
-		float length;
-		float spread;
-
-		RID light_density_map;
-		RID prev_light_density_map;
-		RID fog_map;
-		RID density_map;
-		RID light_map;
-		RID emissive_map;
-
-		RID fog_uniform_set;
-		RID copy_uniform_set;
-		RID process_uniform_set_density;
-		RID process_uniform_set;
-		RID process_uniform_set2;
-		RID sdfgi_uniform_set;
-		RID sky_uniform_set;
-
-		int last_shadow_filter = -1;
-	};
-
-	struct VolumetricFogShader {
-		enum FogSet {
-			FOG_SET_BASE,
-			FOG_SET_UNIFORMS,
-			FOG_SET_MATERIAL,
-			FOG_SET_MAX,
-		};
-
-		struct FogPushConstant {
-			float position[3];
-			float pad;
-
-			float extents[3];
-			float pad2;
-
-			int32_t corner[3];
-			uint32_t shape;
-
-			float transform[16];
-		};
-
-		struct VolumeUBO {
-			float fog_frustum_size_begin[2];
-			float fog_frustum_size_end[2];
-
-			float fog_frustum_end;
-			float z_near;
-			float z_far;
-			float time;
-
-			int32_t fog_volume_size[3];
-			uint32_t directional_light_count;
-
-			uint32_t use_temporal_reprojection;
-			uint32_t temporal_frame;
-			float detail_spread;
-			float temporal_blend;
-
-			float to_prev_view[16];
-			float transform[16];
-		};
-
-		ShaderCompiler compiler;
-		VolumetricFogShaderRD shader;
-		FogPushConstant push_constant;
-		RID volume_ubo;
-
-		RID default_shader;
-		RID default_material;
-		RID default_shader_rd;
-
-		RID base_uniform_set;
-
-		RID params_ubo;
-
-		enum {
-			VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY,
-			VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI,
-			VOLUMETRIC_FOG_PROCESS_SHADER_FILTER,
-			VOLUMETRIC_FOG_PROCESS_SHADER_FOG,
-			VOLUMETRIC_FOG_PROCESS_SHADER_COPY,
-			VOLUMETRIC_FOG_PROCESS_SHADER_MAX,
-		};
-
-		struct ParamsUBO {
-			float fog_frustum_size_begin[2];
-			float fog_frustum_size_end[2];
-
-			float fog_frustum_end;
-			float ambient_inject;
-			float z_far;
-			uint32_t filter_axis;
-
-			float ambient_color[3];
-			float sky_contribution;
-
-			int32_t fog_volume_size[3];
-			uint32_t directional_light_count;
-
-			float base_emission[3];
-			float base_density;
-
-			float base_scattering[3];
-			float phase_g;
-
-			float detail_spread;
-			float gi_inject;
-			uint32_t max_voxel_gi_instances;
-			uint32_t cluster_type_size;
-
-			float screen_size[2];
-			uint32_t cluster_shift;
-			uint32_t cluster_width;
-
-			uint32_t max_cluster_element_count_div_32;
-			uint32_t use_temporal_reprojection;
-			uint32_t temporal_frame;
-			float temporal_blend;
-
-			float cam_rotation[12];
-			float to_prev_view[16];
-			float radiance_inverse_xform[12];
-		};
-
-		VolumetricFogProcessShaderRD process_shader;
-
-		RID process_shader_version;
-		RID process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX];
-
-	} volumetric_fog;
-
-	uint32_t volumetric_fog_depth = 128;
-	uint32_t volumetric_fog_size = 128;
-	bool volumetric_fog_filter_active = true;
-
-	Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform);
-	void _volumetric_fog_erase(RenderBuffers *rb);
-	void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
-
-	struct FogShaderData : public RendererRD::ShaderData {
-		bool valid = false;
-		RID version;
-
-		RID pipeline;
-		HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
-		Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
-
-		Vector<uint32_t> ubo_offsets;
-		uint32_t ubo_size = 0;
-
-		String path;
-		String code;
-		HashMap<StringName, HashMap<int, RID>> default_texture_params;
-
-		bool uses_time = false;
-
-		virtual void set_code(const String &p_Code);
-		virtual void set_path_hint(const String &p_hint);
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index);
-		virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
-		virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const;
-		virtual bool is_param_texture(const StringName &p_param) const;
-		virtual bool is_animated() const;
-		virtual bool casts_shadows() const;
-		virtual Variant get_default_parameter(const StringName &p_parameter) const;
-		virtual RS::ShaderNativeSourceCode get_native_source_code() const;
-
-		FogShaderData() {}
-		virtual ~FogShaderData();
-	};
-
-	struct FogMaterialData : public RendererRD::MaterialData {
-		FogShaderData *shader_data = nullptr;
-		RID uniform_set;
-		bool uniform_set_updated;
-
-		virtual void set_render_priority(int p_priority) {}
-		virtual void set_next_pass(RID p_pass) {}
-		virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
-		virtual ~FogMaterialData();
-	};
-
-	RendererRD::ShaderData *_create_fog_shader_func();
-	static RendererRD::ShaderData *_create_fog_shader_funcs();
-
-	RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader);
-	static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader);
-
 	RID shadow_sampler;
 
 	uint64_t scene_pass = 0;
@@ -963,6 +752,14 @@ private:
 
 	void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr);
 
+	/* Volumetric Fog */
+
+	uint32_t volumetric_fog_size = 128;
+	uint32_t volumetric_fog_depth = 128;
+	bool volumetric_fog_filter_active = true;
+
+	void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
+
 public:
 	virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
 	virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0;

+ 0 - 0
servers/rendering/renderer_rd/shaders/sky.glsl → servers/rendering/renderer_rd/shaders/environment/sky.glsl


+ 2 - 2
servers/rendering/renderer_rd/shaders/volumetric_fog.glsl → servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl

@@ -21,8 +21,8 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
 
 #define DENSITY_SCALE 1024.0
 
-#include "cluster_data_inc.glsl"
-#include "light_data_inc.glsl"
+#include "../cluster_data_inc.glsl"
+#include "../light_data_inc.glsl"
 
 #define M_PI 3.14159265359
 

+ 2 - 2
servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl → servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl

@@ -19,8 +19,8 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 #endif
 
-#include "cluster_data_inc.glsl"
-#include "light_data_inc.glsl"
+#include "../cluster_data_inc.glsl"
+#include "../light_data_inc.glsl"
 
 #define M_PI 3.14159265359
 

Some files were not shown because too many files changed in this diff