| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  fog.cpp                                                               */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* 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.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "fog.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | #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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | using namespace RendererRD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Fog *Fog::singleton = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Fog::Fog() { | 
					
						
							|  |  |  | 	singleton = this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Fog::~Fog() { | 
					
						
							|  |  |  | 	singleton = nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* FOG VOLUMES */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RID Fog::fog_volume_allocate() { | 
					
						
							|  |  |  | 	return fog_volume_owner.allocate_rid(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Fog::fog_volume_initialize(RID p_rid) { | 
					
						
							|  |  |  | 	fog_volume_owner.initialize_rid(p_rid, FogVolume()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 19:44:48 +10:00
										 |  |  | void Fog::fog_volume_free(RID p_rid) { | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid); | 
					
						
							|  |  |  | 	fog_volume->dependency.deleted_notify(p_rid); | 
					
						
							|  |  |  | 	fog_volume_owner.free(p_rid); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 19:44:48 +10:00
										 |  |  | Dependency *Fog::fog_volume_get_dependency(RID p_fog_volume) const { | 
					
						
							|  |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_NULL_V(fog_volume, nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return &fog_volume->dependency; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) { | 
					
						
							|  |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!fog_volume); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_shape == fog_volume->shape) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fog_volume->shape = p_shape; | 
					
						
							|  |  |  | 	fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | void Fog::fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) { | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!fog_volume); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | 	fog_volume->size = p_size; | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | 	fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Fog::fog_volume_set_material(RID p_fog_volume, RID p_material) { | 
					
						
							|  |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!fog_volume); | 
					
						
							|  |  |  | 	fog_volume->material = p_material; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RID Fog::fog_volume_get_material(RID p_fog_volume) const { | 
					
						
							|  |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!fog_volume, RID()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return fog_volume->material; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RS::FogVolumeShape Fog::fog_volume_get_shape(RID p_fog_volume) const { | 
					
						
							|  |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!fog_volume, RS::FOG_VOLUME_SHAPE_BOX); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return fog_volume->shape; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const { | 
					
						
							|  |  |  | 	FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!fog_volume, AABB()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (fog_volume->shape) { | 
					
						
							|  |  |  | 		case RS::FOG_VOLUME_SHAPE_ELLIPSOID: | 
					
						
							|  |  |  | 		case RS::FOG_VOLUME_SHAPE_CONE: | 
					
						
							|  |  |  | 		case RS::FOG_VOLUME_SHAPE_CYLINDER: | 
					
						
							|  |  |  | 		case RS::FOG_VOLUME_SHAPE_BOX: { | 
					
						
							|  |  |  | 			AABB aabb; | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | 			aabb.position = -fog_volume->size / 2; | 
					
						
							|  |  |  | 			aabb.size = fog_volume->size; | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | 			return aabb; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		default: { | 
					
						
							|  |  |  | 			// Need some size otherwise will get culled
 | 
					
						
							|  |  |  | 			return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | Vector3 Fog::fog_volume_get_size(RID p_fog_volume) const { | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | 	const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!fog_volume, Vector3()); | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | 	return fog_volume->size; | 
					
						
							| 
									
										
										
										
											2022-06-21 10:08:33 +10:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | ////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // 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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-30 15:15:11 -07:00
										 |  |  | 	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, true); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Fog::FogMaterialData::~FogMaterialData() { | 
					
						
							|  |  |  | 	free_parameters_uniform_set(uniform_set); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | RendererRD::MaterialStorage::ShaderData *Fog::_create_fog_shader_func() { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	FogShaderData *shader_data = memnew(FogShaderData); | 
					
						
							|  |  |  | 	return shader_data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | RendererRD::MaterialStorage::ShaderData *Fog::_create_fog_shader_funcs() { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	return Fog::get_singleton()->_create_fog_shader_func(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | RendererRD::MaterialStorage::MaterialData *Fog::_create_fog_material_func(FogShaderData *p_shader) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	FogMaterialData *material_data = memnew(FogMaterialData); | 
					
						
							|  |  |  | 	material_data->shader_data = p_shader; | 
					
						
							|  |  |  | 	//update will happen later anyway so do nothing.
 | 
					
						
							|  |  |  | 	return material_data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | RendererRD::MaterialStorage::MaterialData *Fog::_create_fog_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | 		material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_shader_funcs); | 
					
						
							|  |  |  | 		material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_material_funcs); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		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"; | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | 		actions.renames["SIZE"] = "params.size"; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | 		FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG)); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		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; | 
					
						
							| 
									
										
										
										
											2022-04-03 18:56:43 +02:00
										 |  |  | 			u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			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_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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Fog::FogShaderData::is_animated() const { | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Fog::FogShaderData::casts_shadows() const { | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-28 12:49:11 +02:00
										 |  |  | bool Fog::VolumetricFog::sync_gi_dependent_sets_validity(bool p_ensure_freed) { | 
					
						
							|  |  |  | 	bool null = gi_dependent_sets.copy_uniform_set.is_null(); | 
					
						
							|  |  |  | 	bool valid = !null && RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.copy_uniform_set); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEV_ENABLED
 | 
					
						
							|  |  |  | 	// It's all-or-nothing, or something else has changed that requires dev attention.
 | 
					
						
							|  |  |  | 	DEV_ASSERT(null == gi_dependent_sets.process_uniform_set_density.is_null()); | 
					
						
							|  |  |  | 	DEV_ASSERT(null == gi_dependent_sets.process_uniform_set.is_null()); | 
					
						
							|  |  |  | 	DEV_ASSERT(null == gi_dependent_sets.process_uniform_set2.is_null()); | 
					
						
							|  |  |  | 	DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set_density)); | 
					
						
							|  |  |  | 	DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set)); | 
					
						
							|  |  |  | 	DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set2)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (valid) { | 
					
						
							|  |  |  | 		if (p_ensure_freed) { | 
					
						
							|  |  |  | 			RD::get_singleton()->free(gi_dependent_sets.copy_uniform_set); | 
					
						
							|  |  |  | 			RD::get_singleton()->free(gi_dependent_sets.process_uniform_set_density); | 
					
						
							|  |  |  | 			RD::get_singleton()->free(gi_dependent_sets.process_uniform_set); | 
					
						
							|  |  |  | 			RD::get_singleton()->free(gi_dependent_sets.process_uniform_set2); | 
					
						
							|  |  |  | 			valid = false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!valid && !null) { | 
					
						
							|  |  |  | 		gi_dependent_sets = {}; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return valid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | void Fog::VolumetricFog::init(const Vector3i &fog_size, RID p_sky_shader) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	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"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 17:51:31 +03:00
										 |  |  | #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-28 12:49:11 +02:00
										 |  |  | 	sync_gi_dependent_sets_validity(true); | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	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"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 	Ref<VolumetricFog> fog = p_settings.vfog; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	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(); | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 		float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 		params.fog_volume_size[0] = fog->width; | 
					
						
							|  |  |  | 		params.fog_volume_size[1] = fog->height; | 
					
						
							|  |  |  | 		params.fog_volume_size[2] = fog->depth; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 		params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 		params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); | 
					
						
							|  |  |  | 		params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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), ¶ms, RD::BARRIER_MASK_COMPUTE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 		if (fog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->fog_uniform_set)) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			Vector<RD::Uniform> uniforms; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				RD::Uniform u; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:51:31 +03:00
										 |  |  | #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 				u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 				u.binding = 1; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 				u.append_id(fog->emissive_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				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; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:51:31 +03:00
										 |  |  | #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 				u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 				u.binding = 3; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 				u.append_id(fog->density_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				uniforms.push_back(u); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				RD::Uniform u; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:51:31 +03:00
										 |  |  | #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 				u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 				u.binding = 4; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 				u.append_id(fog->light_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				uniforms.push_back(u); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			fog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		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()) { | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | 				material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG)); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				if (!material || !material->shader_data->valid) { | 
					
						
							|  |  |  | 					material = nullptr; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!material) { | 
					
						
							|  |  |  | 				fog_material = volumetric_fog.default_material; | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | 				material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG)); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ERR_FAIL_COND(!material); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			FogShaderData *shader_data = material->shader_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ERR_FAIL_COND(!shader_data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			any_uses_time |= shader_data->uses_time; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-14 18:21:06 +01:00
										 |  |  | 			Vector3i min; | 
					
						
							|  |  |  | 			Vector3i max; | 
					
						
							|  |  |  | 			Vector3i kernel_size; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			Vector3 position = fog_volume_instance->transform.get_origin(); | 
					
						
							|  |  |  | 			RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | 			Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_size(fog_volume) / 2; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) { | 
					
						
							|  |  |  | 				// Local fog volume.
 | 
					
						
							|  |  |  | 				Vector3i points[8]; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 				Vector3 fog_size = Vector3(fog->width, fog->height, fog->depth); | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 				float volumetric_fog_detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); | 
					
						
							|  |  |  | 				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, 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, 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, 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, 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, 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, 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, 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, volumetric_fog_detail_spread, fog_size, p_cam_transform); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 				min = Vector3i(int32_t(fog->width) - 1, int32_t(fog->height) - 1, int32_t(fog->depth) - 1); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				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
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 				extents = Vector3(fog->width, fog->height, fog->depth); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 				min = Vector3i(0, 0, 0); | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 				kernel_size = Vector3i(int32_t(fog->width), int32_t(fog->height), int32_t(fog->depth)); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			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; | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  | 			push_constant.size[0] = extents.x * 2; | 
					
						
							|  |  |  | 			push_constant.size[1] = extents.y * 2; | 
					
						
							|  |  |  | 			push_constant.size[2] = extents.z * 2; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			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); | 
					
						
							| 
									
										
										
										
											2022-12-15 16:07:00 -08:00
										 |  |  | 				material->set_as_used(); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 		if (any_uses_time || RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			RenderingServerDefault::redraw_request(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		RD::get_singleton()->draw_command_end_label(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		RD::get_singleton()->compute_list_end(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-28 12:49:11 +02:00
										 |  |  | 	if (!fog->sync_gi_dependent_sets_validity()) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		//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()) { | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | 				u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK)); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			} 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 { | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | 				u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK)); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			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; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(fog->light_density_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			uniforms.push_back(u); | 
					
						
							|  |  |  | 			copy_uniforms.push_back(u); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			RD::Uniform u; | 
					
						
							|  |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | 			u.binding = 9; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(fog->fog_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			uniforms.push_back(u); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			RD::Uniform u; | 
					
						
							|  |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | 			u.binding = 9; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(fog->prev_light_density_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			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; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(p_settings.voxel_gi_buffer); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			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; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(fog->prev_light_density_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			uniforms.push_back(u); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			RD::Uniform u; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:51:31 +03:00
										 |  |  | #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 			u.binding = 16; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(fog->density_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			uniforms.push_back(u); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			RD::Uniform u; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:51:31 +03:00
										 |  |  | #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 			u.binding = 17; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(fog->light_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			uniforms.push_back(u); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			RD::Uniform u; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:51:31 +03:00
										 |  |  | #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_IMAGE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 			u.binding = 18; | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			u.append_id(fog->emissive_map); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			uniforms.push_back(u); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			RD::Uniform u; | 
					
						
							|  |  |  | 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; | 
					
						
							|  |  |  | 			u.binding = 19; | 
					
						
							| 
									
										
										
										
											2022-08-01 11:59:14 +10:00
										 |  |  | 			RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_cubemap_array ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 			RID sky_texture = RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env).is_valid() ? p_settings.sky->sky_get_radiance_texture_rd(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env)) : RID(); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); | 
					
						
							|  |  |  | 			uniforms.push_back(u); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 		fog->gi_dependent_sets.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); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 		fog->gi_dependent_sets.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); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 		fog->gi_dependent_sets.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); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		uniforms.remove_at(8); | 
					
						
							|  |  |  | 		uniforms.write[7].set_id(0, aux7); | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 		fog->gi_dependent_sets.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); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 	bool using_sdfgi = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.0001 && RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_enabled(p_settings.env) && (p_settings.sdfgi.is_valid()); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (using_sdfgi) { | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 		if (fog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->sdfgi_uniform_set)) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 			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); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 			fog->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); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 	fog->length = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); | 
					
						
							|  |  |  | 	fog->spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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(); | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	params.ambient_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_ambient_inject(p_settings.env) * RendererSceneRenderRD::get_singleton()->environment_get_ambient_light_energy(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	params.z_far = z_far; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	params.fog_frustum_end = fog_end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	Color ambient_color = RendererSceneRenderRD::get_singleton()->environment_get_ambient_light(p_settings.env).srgb_to_linear(); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	params.ambient_color[0] = ambient_color.r; | 
					
						
							|  |  |  | 	params.ambient_color[1] = ambient_color.g; | 
					
						
							|  |  |  | 	params.ambient_color[2] = ambient_color.b; | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	params.sky_contribution = RendererSceneRenderRD::get_singleton()->environment_get_ambient_sky_contribution(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 	params.fog_volume_size[0] = fog->width; | 
					
						
							|  |  |  | 	params.fog_volume_size[1] = fog->height; | 
					
						
							|  |  |  | 	params.fog_volume_size[2] = fog->depth; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	params.directional_light_count = p_directional_light_count; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	Color emission = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission(p_settings.env).srgb_to_linear(); | 
					
						
							|  |  |  | 	params.base_emission[0] = emission.r * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); | 
					
						
							|  |  |  | 	params.base_emission[1] = emission.g * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); | 
					
						
							|  |  |  | 	params.base_emission[2] = emission.b * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); | 
					
						
							|  |  |  | 	params.base_density = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_density(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	Color base_scattering = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_scattering(p_settings.env).srgb_to_linear(); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	params.base_scattering[0] = base_scattering.r; | 
					
						
							|  |  |  | 	params.base_scattering[1] = base_scattering.g; | 
					
						
							|  |  |  | 	params.base_scattering[2] = base_scattering.b; | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	params.phase_g = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_anisotropy(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); | 
					
						
							|  |  |  | 	params.gi_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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; | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	params.max_voxel_gi_instances = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.001 ? p_voxel_gi_count : 0; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env); | 
					
						
							|  |  |  | 	params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_settings.env); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	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), ¶ms, 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]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set_density, 0); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (using_sdfgi) { | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->sdfgi_uniform_set, 1); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 	RD::get_singleton()->compute_list_add_barrier(compute_list); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Copy fog to history buffer
 | 
					
						
							| 
									
										
										
										
											2022-07-27 16:14:23 +10:00
										 |  |  | 	if (RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) { | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]); | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.copy_uniform_set, 0); | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 		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]); | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0); | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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), ¶ms); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		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]); | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set2, 0); | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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]); | 
					
						
							| 
									
										
										
										
											2023-04-26 10:18:27 +02:00
										 |  |  | 	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0); | 
					
						
							| 
									
										
										
										
											2022-08-04 18:40:39 +10:00
										 |  |  | 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, 1); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:17:58 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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(); | 
					
						
							|  |  |  | } |