diff options
Diffstat (limited to 'servers/rendering/renderer_rd')
22 files changed, 1745 insertions, 1922 deletions
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 2a6c96480e..987c1dbb52 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -30,6 +30,11 @@ #include "fog.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" +#include "servers/rendering/rendering_server_default.h" + using namespace RendererRD; Fog *Fog::singleton = nullptr; @@ -126,3 +131,1074 @@ Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const { ERR_FAIL_COND_V(!fog_volume, Vector3()); return fog_volume->extents; } + +//////////////////////////////////////////////////////////////////////////////// +// Fog material + +bool Fog::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { + uniform_set_updated = true; + + return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, Fog::get_singleton()->volumetric_fog.shader.version_get_shader(shader_data->version, 0), VolumetricFogShader::FogSet::FOG_SET_MATERIAL); +} + +Fog::FogMaterialData::~FogMaterialData() { + free_parameters_uniform_set(uniform_set); +} + +RendererRD::ShaderData *Fog::_create_fog_shader_func() { + FogShaderData *shader_data = memnew(FogShaderData); + return shader_data; +} + +RendererRD::ShaderData *Fog::_create_fog_shader_funcs() { + return Fog::get_singleton()->_create_fog_shader_func(); +}; + +RendererRD::MaterialData *Fog::_create_fog_material_func(FogShaderData *p_shader) { + FogMaterialData *material_data = memnew(FogMaterialData); + material_data->shader_data = p_shader; + //update will happen later anyway so do nothing. + return material_data; +} + +RendererRD::MaterialData *Fog::_create_fog_material_funcs(RendererRD::ShaderData *p_shader) { + return Fog::get_singleton()->_create_fog_material_func(static_cast<FogShaderData *>(p_shader)); +}; + +//////////////////////////////////////////////////////////////////////////////// +// FOG VOLUMES INSTANCE + +RID Fog::fog_volume_instance_create(RID p_fog_volume) { + FogVolumeInstance fvi; + fvi.volume = p_fog_volume; + return fog_volume_instance_owner.make_rid(fvi); +} + +void Fog::fog_instance_free(RID p_rid) { + fog_volume_instance_owner.free(p_rid); +} + +//////////////////////////////////////////////////////////////////////////////// +// Volumetric Fog Shader + +void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array) { + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + + { + // Initialize local fog shader + Vector<String> volumetric_fog_modes; + volumetric_fog_modes.push_back(""); + volumetric_fog.shader.initialize(volumetric_fog_modes); + + material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_shader_funcs); + material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_material_funcs); + volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO)); + } + + { + ShaderCompiler::DefaultIdentifierActions actions; + + actions.renames["TIME"] = "scene_params.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); + actions.renames["WORLD_POSITION"] = "world.xyz"; + actions.renames["OBJECT_POSITION"] = "params.position"; + actions.renames["UVW"] = "uvw"; + actions.renames["EXTENTS"] = "params.extents"; + actions.renames["ALBEDO"] = "albedo"; + actions.renames["DENSITY"] = "density"; + actions.renames["EMISSION"] = "emission"; + actions.renames["SDF"] = "sdf"; + + actions.usage_defines["SDF"] = "#define SDF_USED\n"; + actions.usage_defines["DENSITY"] = "#define DENSITY_USED\n"; + actions.usage_defines["ALBEDO"] = "#define ALBEDO_USED\n"; + actions.usage_defines["EMISSION"] = "#define EMISSION_USED\n"; + + actions.sampler_array_name = "material_samplers"; + actions.base_texture_binding_index = 1; + actions.texture_layout_set = VolumetricFogShader::FogSet::FOG_SET_MATERIAL; + actions.base_uniform_string = "material."; + + actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; + actions.default_repeat = ShaderLanguage::REPEAT_DISABLE; + actions.global_buffer_array_variable = "global_variables.data"; + + volumetric_fog.compiler.initialize(actions); + } + + { + // default material and shader for fog shader + volumetric_fog.default_shader = material_storage->shader_allocate(); + material_storage->shader_initialize(volumetric_fog.default_shader); + material_storage->shader_set_code(volumetric_fog.default_shader, R"( +// Default fog shader. + +shader_type fog; + +void fog() { +DENSITY = 1.0; +ALBEDO = vec3(1.0); +} +)"); + volumetric_fog.default_material = material_storage->material_allocate(); + material_storage->material_initialize(volumetric_fog.default_material); + material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader); + + FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::SHADER_TYPE_FOG)); + volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, 0); + + Vector<RD::Uniform> uniforms; + + { + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); + ids_ptr[0] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[1] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[2] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[3] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[4] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[5] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[6] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[7] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[8] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[9] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[10] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[11] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 2; + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + uniforms.push_back(u); + } + + volumetric_fog.base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_BASE); + } + { + String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(p_max_directional_lights) + "\n"; + defines += "\n#define MAX_SKY_LOD " + itos(p_roughness_layers - 1) + ".0\n"; + if (p_is_using_radiance_cubemap_array) { + defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n"; + } + Vector<String> volumetric_fog_modes; + volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n"); + volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n#define ENABLE_SDFGI\n"); + volumetric_fog_modes.push_back("\n#define MODE_FILTER\n"); + volumetric_fog_modes.push_back("\n#define MODE_FOG\n"); + volumetric_fog_modes.push_back("\n#define MODE_COPY\n"); + + volumetric_fog.process_shader.initialize(volumetric_fog_modes, defines); + volumetric_fog.process_shader_version = volumetric_fog.process_shader.version_create(); + for (int i = 0; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) { + volumetric_fog.process_pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, i)); + } + volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO)); + } +} + +void Fog::free_fog_shader() { + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + + volumetric_fog.process_shader.version_free(volumetric_fog.process_shader_version); + RD::get_singleton()->free(volumetric_fog.volume_ubo); + RD::get_singleton()->free(volumetric_fog.params_ubo); + material_storage->shader_free(volumetric_fog.default_shader); + material_storage->material_free(volumetric_fog.default_material); +} + +void Fog::FogShaderData::set_path_hint(const String &p_path) { + path = p_path; +} + +void Fog::FogShaderData::set_code(const String &p_code) { + //compile + + code = p_code; + valid = false; + ubo_size = 0; + uniforms.clear(); + + if (code.is_empty()) { + return; //just invalid, but no error + } + + ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE; + + uses_time = false; + + actions.usage_flag_pointers["TIME"] = &uses_time; + + actions.uniforms = &uniforms; + + Fog *fog_singleton = Fog::get_singleton(); + + Error err = fog_singleton->volumetric_fog.compiler.compile(RS::SHADER_FOG, code, &actions, path, gen_code); + ERR_FAIL_COND_MSG(err != OK, "Fog shader compilation failed."); + + if (version.is_null()) { + version = fog_singleton->volumetric_fog.shader.version_create(); + } + + fog_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines); + ERR_FAIL_COND(!fog_singleton->volumetric_fog.shader.version_is_valid(version)); + + ubo_size = gen_code.uniform_total_size; + ubo_offsets = gen_code.uniform_offsets; + texture_uniforms = gen_code.texture_uniforms; + + pipeline = RD::get_singleton()->compute_pipeline_create(fog_singleton->volumetric_fog.shader.version_get_shader(version, 0)); + + valid = true; +} + +void Fog::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { + if (!p_texture.is_valid()) { + if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { + default_texture_params[p_name].erase(p_index); + + if (default_texture_params[p_name].is_empty()) { + default_texture_params.erase(p_name); + } + } + } else { + if (!default_texture_params.has(p_name)) { + default_texture_params[p_name] = HashMap<int, RID>(); + } + default_texture_params[p_name][p_index] = p_texture; + } +} + +void Fog::FogShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { + RBMap<int, StringName> order; + + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; + } else { + order[E.value.order] = E.key; + } + } + + String last_group; + for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; + p_param_list->push_back(pi); + } +} + +void Fog::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RendererMaterialStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); + p_param_list->push_back(p); + } +} + +bool Fog::FogShaderData::is_param_texture(const StringName &p_param) const { + if (!uniforms.has(p_param)) { + return false; + } + + return uniforms[p_param].texture_order >= 0; +} + +bool Fog::FogShaderData::is_animated() const { + return false; +} + +bool Fog::FogShaderData::casts_shadows() const { + return false; +} + +Variant Fog::FogShaderData::get_default_parameter(const StringName &p_parameter) const { + if (uniforms.has(p_parameter)) { + ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; + Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); + } + return Variant(); +} + +RS::ShaderNativeSourceCode Fog::FogShaderData::get_native_source_code() const { + Fog *fog_singleton = Fog::get_singleton(); + + return fog_singleton->volumetric_fog.shader.version_get_native_source_code(version); +} + +Fog::FogShaderData::~FogShaderData() { + Fog *fog_singleton = Fog::get_singleton(); + ERR_FAIL_COND(!fog_singleton); + //pipeline variants will clear themselves if shader is gone + if (version.is_valid()) { + fog_singleton->volumetric_fog.shader.version_free(version); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Volumetric Fog + +Fog::VolumetricFog::VolumetricFog(const Vector3i &fog_size, RID p_sky_shader) { + width = fog_size.x; + height = fog_size.y; + depth = fog_size.z; + + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.width = fog_size.x; + tf.height = fog_size.y; + tf.depth = fog_size.z; + tf.texture_type = RD::TEXTURE_TYPE_3D; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(light_density_map, "Fog light-density map"); + + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + + prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(prev_light_density_map, "Fog previous light-density map"); + RD::get_singleton()->texture_clear(prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1); + + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + + fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(fog_map, "Fog map"); + +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + Vector<uint8_t> dm; + dm.resize(fog_size.x * fog_size.y * fog_size.z * 4); + dm.fill(0); + + density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); + RD::get_singleton()->set_resource_name(density_map, "Fog density map"); + light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); + RD::get_singleton()->set_resource_name(light_map, "Fog light map"); + emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); + RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map"); +#else + tf.format = RD::DATA_FORMAT_R32_UINT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(density_map, "Fog density map"); + RD::get_singleton()->texture_clear(density_map, Color(0, 0, 0, 0), 0, 1, 0, 1); + light_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(light_map, "Fog light map"); + RD::get_singleton()->texture_clear(light_map, Color(0, 0, 0, 0), 0, 1, 0, 1); + emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map"); + RD::get_singleton()->texture_clear(emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1); +#endif + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.append_id(fog_map); + uniforms.push_back(u); + } + + sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_sky_shader, RendererRD::SkyRD::SKY_SET_FOG); +} + +Fog::VolumetricFog::~VolumetricFog() { + RD::get_singleton()->free(prev_light_density_map); + RD::get_singleton()->free(light_density_map); + RD::get_singleton()->free(fog_map); + RD::get_singleton()->free(density_map); + RD::get_singleton()->free(light_map); + RD::get_singleton()->free(emissive_map); + + if (fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog_uniform_set)) { + RD::get_singleton()->free(fog_uniform_set); + } + if (process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set_density)) { + RD::get_singleton()->free(process_uniform_set_density); + } + if (process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set)) { + RD::get_singleton()->free(process_uniform_set); + } + if (process_uniform_set2.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set2)) { + RD::get_singleton()->free(process_uniform_set2); + } + if (sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_uniform_set)) { + RD::get_singleton()->free(sdfgi_uniform_set); + } + if (sky_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_uniform_set)) { + RD::get_singleton()->free(sky_uniform_set); + } +} + +Vector3i Fog::_point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform) { + Vector3 view_position = p_cam_transform.affine_inverse().xform(p_point); + view_position.z = MIN(view_position.z, -0.01); // Clamp to the front of camera + Vector3 fog_position = Vector3(0, 0, 0); + + view_position.y = -view_position.y; + fog_position.z = -view_position.z / fog_end; + fog_position.x = (view_position.x / (2 * (fog_near_size.x * (1.0 - fog_position.z) + fog_far_size.x * fog_position.z))) + 0.5; + fog_position.y = (view_position.y / (2 * (fog_near_size.y * (1.0 - fog_position.z) + fog_far_size.y * fog_position.z))) + 0.5; + fog_position.z = Math::pow(float(fog_position.z), float(1.0 / volumetric_fog_detail_spread)); + fog_position = fog_position * fog_size - Vector3(0.5, 0.5, 0.5); + + fog_position.x = CLAMP(fog_position.x, 0.0, fog_size.x); + fog_position.y = CLAMP(fog_position.y, 0.0, fog_size.y); + fog_position.z = CLAMP(fog_position.z, 0.0, fog_size.z); + + return Vector3i(fog_position); +} + +void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + + RENDER_TIMESTAMP("> Volumetric Fog"); + RD::get_singleton()->draw_command_begin_label("Volumetric Fog"); + + if (p_fog_volumes.size() > 0) { + RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes"); + + RENDER_TIMESTAMP("Render FogVolumes"); + + VolumetricFogShader::VolumeUBO params; + + Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); + Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); + float z_near = p_cam_projection.get_z_near(); + float z_far = p_cam_projection.get_z_far(); + float fog_end = p_settings.env->volumetric_fog_length; + + Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); + Vector2 fog_near_size; + if (p_cam_projection.is_orthogonal()) { + fog_near_size = fog_far_size; + } else { + fog_near_size = Vector2(); + } + + params.fog_frustum_size_begin[0] = fog_near_size.x; + params.fog_frustum_size_begin[1] = fog_near_size.y; + + params.fog_frustum_size_end[0] = fog_far_size.x; + params.fog_frustum_size_end[1] = fog_far_size.y; + + params.fog_frustum_end = fog_end; + params.z_near = z_near; + params.z_far = z_far; + params.time = p_settings.time; + + params.fog_volume_size[0] = p_settings.vfog->width; + params.fog_volume_size[1] = p_settings.vfog->height; + params.fog_volume_size[2] = p_settings.vfog->depth; + + params.use_temporal_reprojection = p_settings.env->volumetric_fog_temporal_reprojection; + params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; + params.detail_spread = p_settings.env->volumetric_fog_detail_spread; + params.temporal_blend = p_settings.env->volumetric_fog_temporal_reprojection_amount; + + Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; + RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); + RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform); + + RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms, RD::BARRIER_MASK_COMPUTE); + + if (p_settings.vfog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->fog_uniform_set)) { + Vector<RD::Uniform> uniforms; + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 1; + u.append_id(p_settings.vfog->emissive_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 2; + u.append_id(volumetric_fog.volume_ubo); + uniforms.push_back(u); + } + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 3; + u.append_id(p_settings.vfog->density_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 4; + u.append_id(p_settings.vfog->light_map); + uniforms.push_back(u); + } + + p_settings.vfog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); + } + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + bool any_uses_time = false; + + for (int i = 0; i < (int)p_fog_volumes.size(); i++) { + FogVolumeInstance *fog_volume_instance = fog_volume_instance_owner.get_or_null(p_fog_volumes[i]); + ERR_FAIL_COND(!fog_volume_instance); + RID fog_volume = fog_volume_instance->volume; + + RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume); + + FogMaterialData *material = nullptr; + + if (fog_material.is_valid()) { + material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); + if (!material || !material->shader_data->valid) { + material = nullptr; + } + } + + if (!material) { + fog_material = volumetric_fog.default_material; + material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); + } + + ERR_FAIL_COND(!material); + + FogShaderData *shader_data = material->shader_data; + + ERR_FAIL_COND(!shader_data); + + any_uses_time |= shader_data->uses_time; + + Vector3i min = Vector3i(); + Vector3i max = Vector3i(); + Vector3i kernel_size = Vector3i(); + + Vector3 position = fog_volume_instance->transform.get_origin(); + RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); + Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume); + + if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) { + // Local fog volume. + Vector3i points[8]; + Vector3 fog_size = Vector3(p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[2] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[3] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[4] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[5] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[6] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[7] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, p_settings.env->volumetric_fog_detail_spread, fog_size, p_cam_transform); + + min = Vector3i(int32_t(p_settings.vfog->width) - 1, int32_t(p_settings.vfog->height) - 1, int32_t(p_settings.vfog->depth) - 1); + max = Vector3i(1, 1, 1); + + for (int j = 0; j < 8; j++) { + min = Vector3i(MIN(min.x, points[j].x), MIN(min.y, points[j].y), MIN(min.z, points[j].z)); + max = Vector3i(MAX(max.x, points[j].x), MAX(max.y, points[j].y), MAX(max.z, points[j].z)); + } + + kernel_size = max - min; + } else { + // Volume type global runs on all cells + extents = Vector3(p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + min = Vector3i(0, 0, 0); + kernel_size = Vector3i(int32_t(p_settings.vfog->width), int32_t(p_settings.vfog->height), int32_t(p_settings.vfog->depth)); + } + + if (kernel_size.x == 0 || kernel_size.y == 0 || kernel_size.z == 0) { + continue; + } + + VolumetricFogShader::FogPushConstant push_constant; + push_constant.position[0] = position.x; + push_constant.position[1] = position.y; + push_constant.position[2] = position.z; + push_constant.extents[0] = extents.x; + push_constant.extents[1] = extents.y; + push_constant.extents[2] = extents.z; + push_constant.corner[0] = min.x; + push_constant.corner[1] = min.y; + push_constant.corner[2] = min.z; + push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume)); + RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), push_constant.transform); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::FogPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE); + if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set. + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL); + } + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); + } + if (any_uses_time || p_settings.env->volumetric_fog_temporal_reprojection) { + RenderingServerDefault::redraw_request(); + } + + RD::get_singleton()->draw_command_end_label(); + + RD::get_singleton()->compute_list_end(); + } + + if (p_settings.vfog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->process_uniform_set_density)) { + //re create uniform set if needed + Vector<RD::Uniform> uniforms; + Vector<RD::Uniform> copy_uniforms; + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 1; + if (p_settings.shadow_atlas_depth.is_null()) { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); + } else { + u.append_id(p_settings.shadow_atlas_depth); + } + + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 2; + if (p_settings.directional_shadow_depth.is_valid()) { + u.append_id(p_settings.directional_shadow_depth); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); + } + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 3; + u.append_id(p_settings.omni_light_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 4; + u.append_id(p_settings.spot_light_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 5; + u.append_id(p_settings.directional_light_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 6; + u.append_id(p_settings.cluster_builder->get_cluster_buffer()); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 7; + u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 8; + u.append_id(p_settings.vfog->light_density_map); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 9; + u.append_id(p_settings.vfog->fog_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 9; + u.append_id(p_settings.vfog->prev_light_density_map); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 10; + u.append_id(p_settings.shadow_sampler); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 11; + u.append_id(p_settings.voxel_gl_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 12; + for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) { + u.append_id(p_settings.rbgi->voxel_gi_textures[i]); + } + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 13; + u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 14; + u.append_id(volumetric_fog.params_ubo); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 15; + u.append_id(p_settings.vfog->prev_light_density_map); + uniforms.push_back(u); + } + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 16; + u.append_id(p_settings.vfog->density_map); + uniforms.push_back(u); + } + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 17; + u.append_id(p_settings.vfog->light_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 18; + u.append_id(p_settings.vfog->emissive_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 19; + RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_cubemap_array ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + RID sky_texture = p_settings.env->sky.is_valid() ? p_settings.sky->sky_get_radiance_texture_rd(p_settings.env->sky) : RID(); + u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); + uniforms.push_back(u); + } + + p_settings.vfog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0); + + p_settings.vfog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); + + RID aux7 = uniforms.write[7].get_id(0); + RID aux8 = uniforms.write[8].get_id(0); + + uniforms.write[7].set_id(0, aux8); + uniforms.write[8].set_id(0, aux7); + + p_settings.vfog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); + + uniforms.remove_at(8); + uniforms.write[7].set_id(0, aux7); + p_settings.vfog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); + } + + bool using_sdfgi = p_settings.env->volumetric_fog_gi_inject > 0.0001 && p_settings.env->sdfgi_enabled && (p_settings.sdfgi != nullptr); + + if (using_sdfgi) { + if (p_settings.vfog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->sdfgi_uniform_set)) { + Vector<RD::Uniform> uniforms; + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 0; + u.append_id(p_settings.gi->sdfgi_ubo); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 1; + u.append_id(p_settings.sdfgi->ambient_texture); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 2; + u.append_id(p_settings.sdfgi->occlusion_texture); + uniforms.push_back(u); + } + + p_settings.vfog->sdfgi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI), 1); + } + } + + p_settings.vfog->length = p_settings.env->volumetric_fog_length; + p_settings.vfog->spread = p_settings.env->volumetric_fog_detail_spread; + + VolumetricFogShader::ParamsUBO params; + + Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); + Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); + float z_near = p_cam_projection.get_z_near(); + float z_far = p_cam_projection.get_z_far(); + float fog_end = p_settings.env->volumetric_fog_length; + + Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); + Vector2 fog_near_size; + if (p_cam_projection.is_orthogonal()) { + fog_near_size = fog_far_size; + } else { + fog_near_size = Vector2(); + } + + params.fog_frustum_size_begin[0] = fog_near_size.x; + params.fog_frustum_size_begin[1] = fog_near_size.y; + + params.fog_frustum_size_end[0] = fog_far_size.x; + params.fog_frustum_size_end[1] = fog_far_size.y; + + params.ambient_inject = p_settings.env->volumetric_fog_ambient_inject * p_settings.env->ambient_light_energy; + params.z_far = z_far; + + params.fog_frustum_end = fog_end; + + Color ambient_color = p_settings.env->ambient_light.srgb_to_linear(); + params.ambient_color[0] = ambient_color.r; + params.ambient_color[1] = ambient_color.g; + params.ambient_color[2] = ambient_color.b; + params.sky_contribution = p_settings.env->ambient_sky_contribution; + + params.fog_volume_size[0] = p_settings.vfog->width; + params.fog_volume_size[1] = p_settings.vfog->height; + params.fog_volume_size[2] = p_settings.vfog->depth; + + params.directional_light_count = p_directional_light_count; + + Color emission = p_settings.env->volumetric_fog_emission.srgb_to_linear(); + params.base_emission[0] = emission.r * p_settings.env->volumetric_fog_emission_energy; + params.base_emission[1] = emission.g * p_settings.env->volumetric_fog_emission_energy; + params.base_emission[2] = emission.b * p_settings.env->volumetric_fog_emission_energy; + params.base_density = p_settings.env->volumetric_fog_density; + + Color base_scattering = p_settings.env->volumetric_fog_scattering.srgb_to_linear(); + params.base_scattering[0] = base_scattering.r; + params.base_scattering[1] = base_scattering.g; + params.base_scattering[2] = base_scattering.b; + params.phase_g = p_settings.env->volumetric_fog_anisotropy; + + params.detail_spread = p_settings.env->volumetric_fog_detail_spread; + params.gi_inject = p_settings.env->volumetric_fog_gi_inject; + + params.cam_rotation[0] = p_cam_transform.basis[0][0]; + params.cam_rotation[1] = p_cam_transform.basis[1][0]; + params.cam_rotation[2] = p_cam_transform.basis[2][0]; + params.cam_rotation[3] = 0; + params.cam_rotation[4] = p_cam_transform.basis[0][1]; + params.cam_rotation[5] = p_cam_transform.basis[1][1]; + params.cam_rotation[6] = p_cam_transform.basis[2][1]; + params.cam_rotation[7] = 0; + params.cam_rotation[8] = p_cam_transform.basis[0][2]; + params.cam_rotation[9] = p_cam_transform.basis[1][2]; + params.cam_rotation[10] = p_cam_transform.basis[2][2]; + params.cam_rotation[11] = 0; + params.filter_axis = 0; + params.max_voxel_gi_instances = p_settings.env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0; + params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; + + Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; + RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); + + params.use_temporal_reprojection = p_settings.env->volumetric_fog_temporal_reprojection; + params.temporal_blend = p_settings.env->volumetric_fog_temporal_reprojection_amount; + + { + uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size(); + params.cluster_shift = get_shift_from_power_of_2(cluster_size); + + uint32_t cluster_screen_width = (p_settings.rb_size.x - 1) / cluster_size + 1; + uint32_t cluster_screen_height = (p_settings.rb_size.y - 1) / cluster_size + 1; + params.max_cluster_element_count_div_32 = p_settings.max_cluster_elements / 32; + params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32); + params.cluster_width = cluster_screen_width; + + params.screen_size[0] = p_settings.rb_size.x; + params.screen_size[1] = p_settings.rb_size.y; + } + + Basis sky_transform = p_settings.env->sky_orientation; + sky_transform = sky_transform.inverse() * p_cam_transform.basis; + RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform); + + RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog"); + + RENDER_TIMESTAMP("Render Fog"); + RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶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]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set_density, 0); + + if (using_sdfgi) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->sdfgi_uniform_set, 1); + } + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + // Copy fog to history buffer + if (p_settings.env->volumetric_fog_temporal_reprojection) { + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->copy_uniform_set, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + RD::get_singleton()->compute_list_add_barrier(compute_list); + } + RD::get_singleton()->draw_command_end_label(); + + if (p_settings.volumetric_fog_filter_active) { + RD::get_singleton()->draw_command_begin_label("Filter Fog"); + + RENDER_TIMESTAMP("Filter Fog"); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + + RD::get_singleton()->compute_list_end(); + //need restart for buffer update + + params.filter_axis = 1; + RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶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]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set2, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + + RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->draw_command_end_label(); + } + + RENDER_TIMESTAMP("Integrate Fog"); + RD::get_singleton()->draw_command_begin_label("Integrate Fog"); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, 1); + + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER); + + RENDER_TIMESTAMP("< Volumetric Fog"); + RD::get_singleton()->draw_command_end_label(); + RD::get_singleton()->draw_command_end_label(); +} diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h index 24a3fa798c..61a5d80d20 100644 --- a/servers/rendering/renderer_rd/environment/fog.h +++ b/servers/rendering/renderer_rd/environment/fog.h @@ -34,12 +34,19 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "servers/rendering/environment/renderer_fog.h" +#include "servers/rendering/renderer_rd/cluster_builder_rd.h" +#include "servers/rendering/renderer_rd/environment/gi.h" +#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" +#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl.gen.h" #include "servers/rendering/storage/utilities.h" namespace RendererRD { class Fog : public RendererFog { public: + /* FOG VOLUMES */ + struct FogVolume { RID material; Vector3 extents = Vector3(1, 1, 1); @@ -49,10 +56,179 @@ public: Dependency dependency; }; + struct FogVolumeInstance { + RID volume; + Transform3D transform; + bool active = false; + }; + private: static Fog *singleton; mutable RID_Owner<FogVolume, true> fog_volume_owner; + mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner; + + /* Volumetric Fog */ + struct VolumetricFogShader { + enum FogSet { + FOG_SET_BASE, + FOG_SET_UNIFORMS, + FOG_SET_MATERIAL, + FOG_SET_MAX, + }; + + struct FogPushConstant { + float position[3]; + float pad; + + float extents[3]; + float pad2; + + int32_t corner[3]; + uint32_t shape; + + float transform[16]; + }; + + struct VolumeUBO { + float fog_frustum_size_begin[2]; + float fog_frustum_size_end[2]; + + float fog_frustum_end; + float z_near; + float z_far; + float time; + + int32_t fog_volume_size[3]; + uint32_t directional_light_count; + + uint32_t use_temporal_reprojection; + uint32_t temporal_frame; + float detail_spread; + float temporal_blend; + + float to_prev_view[16]; + float transform[16]; + }; + + ShaderCompiler compiler; + VolumetricFogShaderRD shader; + RID volume_ubo; + + RID default_shader; + RID default_material; + RID default_shader_rd; + + RID base_uniform_set; + + RID params_ubo; + + enum { + VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY, + VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI, + VOLUMETRIC_FOG_PROCESS_SHADER_FILTER, + VOLUMETRIC_FOG_PROCESS_SHADER_FOG, + VOLUMETRIC_FOG_PROCESS_SHADER_COPY, + VOLUMETRIC_FOG_PROCESS_SHADER_MAX, + }; + + struct ParamsUBO { + float fog_frustum_size_begin[2]; + float fog_frustum_size_end[2]; + + float fog_frustum_end; + float ambient_inject; + float z_far; + uint32_t filter_axis; + + float ambient_color[3]; + float sky_contribution; + + int32_t fog_volume_size[3]; + uint32_t directional_light_count; + + float base_emission[3]; + float base_density; + + float base_scattering[3]; + float phase_g; + + float detail_spread; + float gi_inject; + uint32_t max_voxel_gi_instances; + uint32_t cluster_type_size; + + float screen_size[2]; + uint32_t cluster_shift; + uint32_t cluster_width; + + uint32_t max_cluster_element_count_div_32; + uint32_t use_temporal_reprojection; + uint32_t temporal_frame; + float temporal_blend; + + float cam_rotation[12]; + float to_prev_view[16]; + float radiance_inverse_xform[12]; + }; + + VolumetricFogProcessShaderRD process_shader; + + RID process_shader_version; + RID process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX]; + + } volumetric_fog; + + Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform); + + struct FogShaderData : public RendererRD::ShaderData { + bool valid = false; + RID version; + + RID pipeline; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; + + Vector<uint32_t> ubo_offsets; + uint32_t ubo_size = 0; + + String path; + String code; + HashMap<StringName, HashMap<int, RID>> default_texture_params; + + bool uses_time = false; + + virtual void set_path_hint(const String &p_hint); + virtual void set_code(const String &p_Code); + virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; + virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_animated() const; + virtual bool casts_shadows() const; + virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + + FogShaderData() {} + virtual ~FogShaderData(); + }; + + struct FogMaterialData : public RendererRD::MaterialData { + FogShaderData *shader_data = nullptr; + RID uniform_set; + bool uniform_set_updated; + + virtual void set_render_priority(int p_priority) {} + virtual void set_next_pass(RID p_pass) {} + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual ~FogMaterialData(); + }; + + RendererRD::ShaderData *_create_fog_shader_func(); + static RendererRD::ShaderData *_create_fog_shader_funcs(); + + RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader); + static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader); public: static Fog *get_singleton() { return singleton; } @@ -76,6 +252,76 @@ public: RID fog_volume_get_material(RID p_fog_volume) const; virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override; Vector3 fog_volume_get_extents(RID p_fog_volume) const; + + /* FOG VOLUMES INSTANCE */ + + FogVolumeInstance *get_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.get_or_null(p_rid); }; + bool owns_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.owns(p_rid); }; + + RID fog_volume_instance_create(RID p_fog_volume); + void fog_instance_free(RID p_rid); + + /* Volumetric FOG */ + struct VolumetricFog { + enum { + MAX_TEMPORAL_FRAMES = 16 + }; + + uint32_t width = 0; + uint32_t height = 0; + uint32_t depth = 0; + + float length; + float spread; + + RID light_density_map; + RID prev_light_density_map; + RID fog_map; + RID density_map; + RID light_map; + RID emissive_map; + + RID fog_uniform_set; + RID copy_uniform_set; + RID process_uniform_set_density; + RID process_uniform_set; + RID process_uniform_set2; + RID sdfgi_uniform_set; + RID sky_uniform_set; + + int last_shadow_filter = -1; + + VolumetricFog(const Vector3i &fog_size, RID p_sky_shader); + ~VolumetricFog(); + }; + + void init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array); + void free_fog_shader(); + + struct VolumetricFogSettings { + Vector2i rb_size; + double time; + bool is_using_radiance_cubemap_array; + uint32_t max_cluster_elements; + bool volumetric_fog_filter_active; + RID shadow_sampler; + RID voxel_gl_buffer; + RID shadow_atlas_depth; + RID omni_light_buffer; + RID spot_light_buffer; + RID directional_shadow_depth; + RID directional_light_buffer; + + // Objects related to our render buffer + VolumetricFog *vfog; + ClusterBuilderRD *cluster_builder; + GI *gi; + GI::SDFGI *sdfgi; + GI::RenderBuffersGI *rbgi; + RendererSceneEnvironmentRD *env; + SkyRD *sky; + }; + void volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); }; } // namespace RendererRD diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index c37284f72a..cb120a1b49 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -1268,7 +1268,7 @@ void GI::SDFGI::update_light() { RD::get_singleton()->draw_command_end_label(); } -void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) { +void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, SkyRD::Sky *p_sky) { RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes"); SDFGIShader::IntegratePushConstant push_constant; @@ -1947,7 +1947,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r } } -void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { //print_line("rendering region " + itos(p_region)); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... @@ -2428,7 +2428,7 @@ void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_co //////////////////////////////////////////////////////////////////////////////// // VoxelGIInstance -void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); uint32_t data_version = gi->voxel_gi_get_data_version(probe); @@ -2951,10 +2951,10 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID //this could probably be better parallelized in compute.. for (int i = 0; i < (int)p_dynamic_objects.size(); i++) { - RendererSceneRender::GeometryInstance *instance = p_dynamic_objects[i]; + RenderGeometryInstance *instance = p_dynamic_objects[i]; //transform aabb to voxel_gi - AABB aabb = (to_probe_xform * p_scene_render->geometry_instance_get_transform(instance)).xform(p_scene_render->geometry_instance_get_aabb(instance)); + AABB aabb = (to_probe_xform * instance->get_transform()).xform(instance->get_aabb()); //this needs to wrap to grid resolution to avoid jitter //also extend margin a bit just in case @@ -3233,7 +3233,7 @@ GI::~GI() { singleton = nullptr; } -void GI::init(RendererSceneSkyRD *p_sky) { +void GI::init(SkyRD *p_sky) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -3960,7 +3960,7 @@ bool GI::voxel_gi_needs_update(RID p_probe) const { return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe); } -void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); ERR_FAIL_COND(!voxel_gi); diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h index 517fa86ce3..30e695120e 100644 --- a/servers/rendering/renderer_rd/environment/gi.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -35,8 +35,8 @@ #include "core/templates/rid_owner.h" #include "servers/rendering/environment/renderer_gi.h" #include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_rd/environment/sky.h" #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" #include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h" @@ -471,7 +471,7 @@ public: Transform3D transform; - void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; @@ -618,7 +618,7 @@ public: void erase(); void update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position); void update_light(); - void update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky); + void update_probes(RendererSceneEnvironmentRD *p_env, RendererRD::SkyRD::Sky *p_sky); void store_probes(); int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const; void update_cascades(); @@ -627,7 +627,7 @@ public: void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); - void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); + void render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); }; @@ -769,7 +769,7 @@ public: GI(); ~GI(); - void init(RendererSceneSkyRD *p_sky); + void init(RendererRD::SkyRD *p_sky); void free(); SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); @@ -780,7 +780,7 @@ public: RID voxel_gi_instance_create(RID p_base); void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); bool voxel_gi_needs_update(RID p_probe) const; - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 33c21f5b04..2b140696b4 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene_sky_rd.cpp */ +/* sky.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,25 +28,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "renderer_scene_sky_rd.h" +#include "sky.h" #include "core/config/project_settings.h" #include "core/math/math_defs.h" -#include "renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/effects/copy_effects.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_globals.h" +using namespace RendererRD; + //////////////////////////////////////////////////////////////////////////////// // SKY SHADER -void RendererSceneSkyRD::SkyShaderData::set_path_hint(const String &p_path) { +void SkyRD::SkyShaderData::set_path_hint(const String &p_path) { path = p_path; } -void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { +void SkyRD::SkyShaderData::set_code(const String &p_code) { //compile code = p_code; @@ -145,7 +147,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { valid = true; } -void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -162,7 +164,7 @@ void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringNa } } -void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void SkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -176,15 +178,29 @@ void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_par order[E.value.order] = E.key; } } - + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); } } -void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { +void SkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; @@ -199,7 +215,7 @@ void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererMat } } -bool RendererSceneSkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const { +bool SkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -207,15 +223,15 @@ bool RendererSceneSkyRD::SkyShaderData::is_param_texture(const StringName &p_par return uniforms[p_param].texture_order >= 0; } -bool RendererSceneSkyRD::SkyShaderData::is_animated() const { +bool SkyRD::SkyShaderData::is_animated() const { return false; } -bool RendererSceneSkyRD::SkyShaderData::casts_shadows() const { +bool SkyRD::SkyShaderData::casts_shadows() const { return false; } -Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { +Variant SkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; @@ -224,13 +240,13 @@ Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringNam return Variant(); } -RS::ShaderNativeSourceCode RendererSceneSkyRD::SkyShaderData::get_native_source_code() const { +RS::ShaderNativeSourceCode SkyRD::SkyShaderData::get_native_source_code() const { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); return scene_singleton->sky.sky_shader.shader.version_get_native_source_code(version); } -RendererSceneSkyRD::SkyShaderData::~SkyShaderData() { +SkyRD::SkyShaderData::~SkyShaderData() { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); ERR_FAIL_COND(!scene_singleton); //pipeline variants will clear themselves if shader is gone @@ -242,7 +258,7 @@ RendererSceneSkyRD::SkyShaderData::~SkyShaderData() { //////////////////////////////////////////////////////////////////////////////// // Sky material -bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool SkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); uniform_set_updated = true; @@ -250,7 +266,7 @@ bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const HashMap<String return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL); } -RendererSceneSkyRD::SkyMaterialData::~SkyMaterialData() { +SkyRD::SkyMaterialData::~SkyMaterialData() { free_parameters_uniform_set(uniform_set); } @@ -272,7 +288,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } -void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) { +void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) { SkyPushConstant sky_push_constant; memset(&sky_push_constant, 0, sizeof(SkyPushConstant)); @@ -323,7 +339,7 @@ void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_ //////////////////////////////////////////////////////////////////////////////// // ReflectionData -void RendererSceneSkyRD::ReflectionData::clear_reflection_data() { +void SkyRD::ReflectionData::clear_reflection_data() { layers.clear(); radiance_base_cubemap = RID(); if (downsampled_radiance_cubemap.is_valid()) { @@ -334,7 +350,7 @@ void RendererSceneSkyRD::ReflectionData::clear_reflection_data() { coefficient_buffer = RID(); } -void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) { +void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) { //recreate radiance and all data int mipmaps = p_mipmaps; @@ -403,21 +419,22 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, 1, RD::TEXTURE_SLICE_CUBEMAP); RD::get_singleton()->set_resource_name(radiance_base_cubemap, "radiance base cubemap"); + RD::TextureFormat tf; tf.format = p_texture_format; - tf.width = 64; // Always 64x64 - tf.height = 64; + tf.width = p_low_quality ? 64 : p_size >> 1; // Always 64x64 when using REALTIME. + tf.height = p_low_quality ? 64 : p_size >> 1; tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.array_layers = 6; - tf.mipmaps = 7; + tf.mipmaps = p_low_quality ? 7 : mipmaps - 1; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView()); RD::get_singleton()->set_resource_name(downsampled_radiance_cubemap, "downsampled radiance cubemap"); { - uint32_t mmw = 64; - uint32_t mmh = 64; - downsampled_layer.mipmaps.resize(7); + uint32_t mmw = tf.width; + uint32_t mmh = tf.height; + downsampled_layer.mipmaps.resize(tf.mipmaps); for (int j = 0; j < downsampled_layer.mipmaps.size(); j++) { ReflectionData::DownsampleLayer::Mipmap &mm = downsampled_layer.mipmaps.write[j]; mm.size.width = mmw; @@ -442,7 +459,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int } } -void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { +void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); @@ -500,7 +517,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_us } } -void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { +void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); @@ -569,7 +586,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(boo RD::get_singleton()->draw_command_end_label(); // Filter radiance } -void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) { +void SkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); @@ -594,9 +611,9 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, } //////////////////////////////////////////////////////////////////////////////// -// RendererSceneSkyRD::Sky +// SkyRD::Sky -void RendererSceneSkyRD::Sky::free() { +void SkyRD::Sky::free() { if (radiance.is_valid()) { RD::get_singleton()->free(radiance); radiance = RID(); @@ -624,7 +641,7 @@ void RendererSceneSkyRD::Sky::free() { } } -RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) { +RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) { @@ -685,7 +702,7 @@ RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_ return texture_uniform_sets[p_version]; } -bool RendererSceneSkyRD::Sky::set_radiance_size(int p_radiance_size) { +bool SkyRD::Sky::set_radiance_size(int p_radiance_size) { ERR_FAIL_COND_V(p_radiance_size < 32 || p_radiance_size > 2048, false); if (radiance_size == p_radiance_size) { return false; @@ -706,7 +723,7 @@ bool RendererSceneSkyRD::Sky::set_radiance_size(int p_radiance_size) { return true; } -bool RendererSceneSkyRD::Sky::set_mode(RS::SkyMode p_mode) { +bool SkyRD::Sky::set_mode(RS::SkyMode p_mode) { if (mode == p_mode) { return false; } @@ -727,7 +744,7 @@ bool RendererSceneSkyRD::Sky::set_mode(RS::SkyMode p_mode) { return true; } -bool RendererSceneSkyRD::Sky::set_material(RID p_material) { +bool SkyRD::Sky::set_material(RID p_material) { if (material == p_material) { return false; } @@ -736,7 +753,7 @@ bool RendererSceneSkyRD::Sky::set_material(RID p_material) { return true; } -Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) { +Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) { if (radiance.is_valid()) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); @@ -770,37 +787,37 @@ Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(float p_energy, int p_roughnes } //////////////////////////////////////////////////////////////////////////////// -// RendererSceneSkyRD +// SkyRD -RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_func() { +RendererRD::ShaderData *SkyRD::_create_sky_shader_func() { SkyShaderData *shader_data = memnew(SkyShaderData); return shader_data; } -RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_funcs() { +RendererRD::ShaderData *SkyRD::_create_sky_shader_funcs() { // !BAS! Why isn't _create_sky_shader_func not just static too? return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_shader_func(); }; -RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_func(SkyShaderData *p_shader) { +RendererRD::MaterialData *SkyRD::_create_sky_material_func(SkyShaderData *p_shader) { SkyMaterialData *material_data = memnew(SkyMaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. return material_data; } -RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) { +RendererRD::MaterialData *SkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) { // !BAS! same here, we could just make _create_sky_material_func static? return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_material_func(static_cast<SkyShaderData *>(p_shader)); }; -RendererSceneSkyRD::RendererSceneSkyRD() { +SkyRD::SkyRD() { roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers"); sky_ggx_samples_quality = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples"); sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections"); } -void RendererSceneSkyRD::init() { +void SkyRD::init() { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -1055,11 +1072,11 @@ void sky() { } } -void RendererSceneSkyRD::set_texture_format(RD::DataFormat p_texture_format) { +void SkyRD::set_texture_format(RD::DataFormat p_texture_format) { texture_format = p_texture_format; } -RendererSceneSkyRD::~RendererSceneSkyRD() { +SkyRD::~SkyRD() { // cleanup anything created in init... RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -1089,7 +1106,7 @@ RendererSceneSkyRD::~RendererSceneSkyRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency } -void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { +void SkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1301,7 +1318,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } -void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1470,7 +1487,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const Project } } -void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) { +void SkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1577,7 +1594,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont RD::get_singleton()->draw_list_end(); } -void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1662,7 +1679,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u } } -void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1741,7 +1758,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier); } -void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) { +void SkyRD::invalidate_sky(Sky *p_sky) { if (!p_sky->dirty) { p_sky->dirty = true; p_sky->dirty_list = dirty_sky_list; @@ -1749,7 +1766,7 @@ void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) { } } -void RendererSceneSkyRD::update_dirty_skys() { +void SkyRD::update_dirty_skys() { Sky *sky = dirty_sky_list; while (sky) { @@ -1853,26 +1870,26 @@ void RendererSceneSkyRD::update_dirty_skys() { dirty_sky_list = nullptr; } -RID RendererSceneSkyRD::sky_get_material(RID p_sky) const { +RID SkyRD::sky_get_material(RID p_sky) const { Sky *sky = get_sky(p_sky); ERR_FAIL_COND_V(!sky, RID()); return sky->material; } -RID RendererSceneSkyRD::allocate_sky_rid() { +RID SkyRD::allocate_sky_rid() { return sky_owner.allocate_rid(); } -void RendererSceneSkyRD::initialize_sky_rid(RID p_rid) { +void SkyRD::initialize_sky_rid(RID p_rid) { sky_owner.initialize_rid(p_rid, Sky()); } -RendererSceneSkyRD::Sky *RendererSceneSkyRD::get_sky(RID p_sky) const { +SkyRD::Sky *SkyRD::get_sky(RID p_sky) const { return sky_owner.get_or_null(p_sky); } -void RendererSceneSkyRD::free_sky(RID p_sky) { +void SkyRD::free_sky(RID p_sky) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1880,7 +1897,7 @@ void RendererSceneSkyRD::free_sky(RID p_sky) { sky_owner.free(p_sky); } -void RendererSceneSkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { +void SkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1889,7 +1906,7 @@ void RendererSceneSkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { } } -void RendererSceneSkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { +void SkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1898,7 +1915,7 @@ void RendererSceneSkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { } } -void RendererSceneSkyRD::sky_set_material(RID p_sky, RID p_material) { +void SkyRD::sky_set_material(RID p_sky, RID p_material) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1907,7 +1924,7 @@ void RendererSceneSkyRD::sky_set_material(RID p_sky, RID p_material) { } } -Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { +Ref<Image> SkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND_V(!sky, Ref<Image>()); @@ -1916,7 +1933,7 @@ Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool return sky->bake_panorama(p_energy, p_bake_irradiance ? roughness_layers : 0, p_size); } -RID RendererSceneSkyRD::sky_get_radiance_texture_rd(RID p_sky) const { +RID SkyRD::sky_get_radiance_texture_rd(RID p_sky) const { Sky *sky = get_sky(p_sky); ERR_FAIL_COND_V(!sky, RID()); diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/environment/sky.h index dd63dc95ae..c3962f20b7 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene_sky_rd.h */ +/* sky.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERER_SCENE_SKY_RD_H -#define RENDERER_SCENE_SKY_RD_H +#ifndef SKY_RD_H +#define SKY_RD_H #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/sky.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -44,7 +44,9 @@ // Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound class RendererSceneRenderRD; -class RendererSceneSkyRD { +namespace RendererRD { + +class SkyRD { public: enum SkySet { SKY_SET_UNIFORMS, @@ -290,10 +292,10 @@ public: RendererRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader); static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader); - RendererSceneSkyRD(); + SkyRD(); void init(); void set_texture_format(RD::DataFormat p_texture_format); - ~RendererSceneSkyRD(); + ~SkyRD(); void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); void update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); @@ -318,4 +320,6 @@ public: RID sky_get_radiance_texture_rd(RID p_sky) const; }; -#endif // RENDERER_SCENE_SKY_RD_H +} // namespace RendererRD + +#endif // SKY_RD_H diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index d92f37e21e..872a27fda1 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -775,7 +775,7 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis void RenderForwardClustered::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) { uint32_t render_total = p_params->element_count; - uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count(); uint32_t render_from = p_thread * render_total / total_threads; uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads); _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to); @@ -787,9 +787,10 @@ void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_p if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardClustered::_render_list_thread_function, p_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardClustered::_render_list_thread_function, p_params, thread_draw_lists.size(), -1, true, SNAME("ForwardClusteredRenderList")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); RD::get_singleton()->draw_list_end(p_params->barrier); } else { //single threaded @@ -1872,7 +1873,7 @@ void RenderForwardClustered::_render_shadow_begin() { scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -1962,7 +1963,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -2001,7 +2002,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -2050,7 +2051,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); RD::get_singleton()->draw_command_begin_label("Render UV2"); @@ -2120,7 +2121,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { +void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { RENDER_TIMESTAMP("Render SDFGI"); RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel"); @@ -2791,24 +2792,23 @@ RID RenderForwardClustered::_render_buffers_get_velocity_texture(RID p_render_bu RenderForwardClustered *RenderForwardClustered::singleton = nullptr; -void RenderForwardClustered::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RenderForwardClustered::GeometryInstanceForwardClustered::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + GeometryInstanceSurfaceDataCache *surf = surface_caches; while (surf) { GeometryInstanceSurfaceDataCache *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RenderForwardClustered::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); + RenderForwardClustered::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); } void RenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -2976,7 +2976,7 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw } } -void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); @@ -3135,7 +3135,7 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata); @@ -3149,10 +3149,10 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D } } void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } -RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -3165,155 +3165,47 @@ RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed; ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RenderForwardClustered::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) { uint64_t frame = RSG::rasterizer->get_frame_number(); - if (frame != ginstance->prev_transform_change_frame) { - ginstance->prev_transform = ginstance->transform; - ginstance->prev_transform_change_frame = frame; - ginstance->prev_transform_dirty = true; + if (frame != prev_transform_change_frame) { + prev_transform = transform; + prev_transform_change_frame = frame; + prev_transform_dirty = true; } - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - - ginstance->lod_model_scale = max_scale; -} -void RenderForwardClustered::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} -void RenderForwardClustered::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->fade_near = p_enable_near; - ginstance->fade_near_begin = p_near_begin; - ginstance->fade_near_end = p_near_end; - ginstance->fade_far = p_enable_far; - ginstance->fade_far_begin = p_far_begin; - ginstance->fade_far_end = p_far_end; + RenderGeometryInstanceBase::set_transform(p_transform, p_aabb, p_transformed_aabbb); } -void RenderForwardClustered::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->parent_fade_alpha = p_alpha; -} +void RenderForwardClustered::GeometryInstanceForwardClustered::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { + lightmap_instance = p_lightmap_instance; + lightmap_uv_scale = p_lightmap_uv_scale; + lightmap_slice_index = p_lightmap_slice_index; -void RenderForwardClustered::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->force_alpha = CLAMP(1.0 - p_transparency, 0, 1); + _mark_dirty(); } -void RenderForwardClustered::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_dynamic_gi = p_enable; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lightmap_instance = p_lightmap_instance; - ginstance->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->lightmap_slice_index = p_lightmap_slice_index; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_lightmap_capture(const Color *p_sh9) { if (p_sh9) { - if (ginstance->lightmap_sh == nullptr) { - ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc(); + if (lightmap_sh == nullptr) { + lightmap_sh = RenderForwardClustered::get_singleton()->geometry_instance_lightmap_sh.alloc(); } - memcpy(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9); + memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9); } else { - if (ginstance->lightmap_sh != nullptr) { - geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); - ginstance->lightmap_sh = nullptr; + if (lightmap_sh != nullptr) { + RenderForwardClustered::get_singleton()->geometry_instance_lightmap_sh.free(lightmap_sh); + lightmap_sh = nullptr; } } - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); + _mark_dirty(); } -void RenderForwardClustered::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardClustered::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; -} - -void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RenderForwardClustered::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); if (ginstance->lightmap_sh != nullptr) { @@ -3332,47 +3224,25 @@ void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry uint32_t RenderForwardClustered::geometry_instance_get_pair_mask() { return (1 << RS::INSTANCE_VOXEL_GI); } -void RenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { -} -void RenderForwardClustered::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { -} -void RenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { -} -Transform3D RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform3D()); - return ginstance->transform; -} - -AABB RenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); - ERR_FAIL_COND_V(!ginstance, AABB()); - return ginstance->data->aabb; -} - -void RenderForwardClustered::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { if (p_voxel_gi_instance_count > 0) { - ginstance->voxel_gi_instances[0] = p_voxel_gi_instances[0]; + voxel_gi_instances[0] = p_voxel_gi_instances[0]; } else { - ginstance->voxel_gi_instances[0] = RID(); + voxel_gi_instances[0] = RID(); } if (p_voxel_gi_instance_count > 1) { - ginstance->voxel_gi_instances[1] = p_voxel_gi_instances[1]; + voxel_gi_instances[1] = p_voxel_gi_instances[1]; } else { - ginstance->voxel_gi_instances[1] = RID(); + voxel_gi_instances[1] = RID(); } } -void RenderForwardClustered::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->using_projectors = p_projector; - ginstance->using_softshadows = p_softshadow; - _geometry_instance_mark_dirty(ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) { + using_projectors = p_projector; + using_softshadows = p_softshadow; + _mark_dirty(); } void RenderForwardClustered::_update_shader_quality_settings() { diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 2bdf48c72f..7e71406af8 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -427,7 +427,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { HashMap<Size2i, RID> sdfgi_framebuffer_size_cache; struct GeometryInstanceData; - struct GeometryInstanceForwardClustered; + class GeometryInstanceForwardClustered; struct GeometryInstanceLightmapSH { Color sh[9]; @@ -487,73 +487,48 @@ class RenderForwardClustered : public RendererSceneRenderRD { GeometryInstanceForwardClustered *owner = nullptr; }; - struct GeometryInstanceForwardClustered : public GeometryInstance { + class GeometryInstanceForwardClustered : public RenderGeometryInstanceBase { + public: + // lightmap + RID lightmap_instance; + Rect2 lightmap_uv_scale; + uint32_t lightmap_slice_index; + GeometryInstanceLightmapSH *lightmap_sh = nullptr; + //used during rendering - bool mirror = false; - bool non_uniform_scale = false; - float lod_bias = 0.0; - float lod_model_scale = 1.0; - AABB transformed_aabb; //needed for LOD - float depth = 0; + uint32_t gi_offset_cache = 0; - uint32_t flags_cache = 0; bool store_transform_cache = true; - int32_t shader_parameters_offset = -1; - uint32_t lightmap_slice_index; - Rect2 lightmap_uv_scale; - uint32_t layer_mask = 1; RID transforms_uniform_set; uint32_t instance_count = 0; uint32_t trail_steps = 1; - RID mesh_instance; bool can_sdfgi = false; bool using_projectors = false; bool using_softshadows = false; - bool fade_near = false; - float fade_near_begin = 0; - float fade_near_end = 0; - bool fade_far = false; - float fade_far_begin = 0; - float fade_far_end = 0; - float force_alpha = 1.0; - float parent_fade_alpha = 1.0; //used during setup - uint32_t base_flags = 0; uint64_t prev_transform_change_frame = 0xFFFFFFFF; bool prev_transform_dirty = true; - Transform3D transform; Transform3D prev_transform; RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE]; - RID lightmap_instance; - GeometryInstanceLightmapSH *lightmap_sh = nullptr; GeometryInstanceSurfaceDataCache *surface_caches = nullptr; SelfList<GeometryInstanceForwardClustered> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; - - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; + GeometryInstanceForwardClustered() : + dirty_list_element(this) {} - bool use_dynamic_gi = false; - bool use_baked_light = true; - bool cast_double_sided_shadows = false; - bool mirror = false; - bool dirty_dependencies = false; + virtual void _mark_dirty() override; - DependencyTracker dependency_tracker; - }; + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - Data *data = nullptr; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override {} + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - GeometryInstanceForwardClustered() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override; }; static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); @@ -568,8 +543,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); /* Render List */ @@ -640,52 +614,27 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override; public: + static RenderForwardClustered *get_singleton() { return singleton; } + _FORCE_INLINE_ virtual void update_uniform_sets() override { base_uniform_set_updated = true; _update_render_base_uniform_set(); } - virtual GeometryInstance *geometry_instance_create(RID p_base) override; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; - - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override; + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; virtual uint32_t geometry_instance_get_pair_mask() override; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; virtual bool free(RID p_rid) override; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index a559241846..6f4a7f6a84 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -407,7 +407,22 @@ void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); @@ -667,7 +682,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index a07955d2d1..67c7d12517 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -758,9 +758,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_begin_split(framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardMobile::_render_list_thread_function, &render_list_params); + + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderList")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { //single threaded RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); @@ -822,10 +825,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_switch_to_next_pass_split(thread_draw_lists.size(), thread_draw_lists.ptr()); render_list_params.subpass = RD::get_singleton()->draw_list_get_current_pass(); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardMobile::_render_list_thread_function, &render_list_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { //single threaded RD::DrawListID draw_list = RD::get_singleton()->draw_list_switch_to_next_pass(); @@ -859,9 +864,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_begin_split(framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardMobile::_render_list_thread_function, &render_list_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL); } else { //single threaded @@ -900,7 +907,7 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -994,7 +1001,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { /* */ -void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -1040,7 +1047,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c RD::get_singleton()->draw_command_end_label(); } -void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); RD::get_singleton()->draw_command_begin_label("Render UV2"); @@ -1107,11 +1114,11 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in RD::get_singleton()->draw_command_end_label(); } -void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { +void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { // we don't do GI in low end.. } -void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1771,7 +1778,7 @@ void RenderForwardMobile::_render_list(RenderingDevice::DrawListID p_draw_list, void RenderForwardMobile::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) { uint32_t render_total = p_params->element_count; - uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count(); uint32_t render_from = p_thread * render_total / total_threads; uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads); _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to); @@ -1783,9 +1790,11 @@ void RenderForwardMobile::_render_list_with_threads(RenderListParameters *p_para if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardMobile::_render_list_thread_function, p_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, p_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + RD::get_singleton()->draw_list_end(p_params->barrier); } else { //single threaded @@ -2047,7 +2056,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr /* Geometry instance */ -RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -2057,165 +2066,36 @@ RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_cr ginstance->data->base = p_base; ginstance->data->base_type = type; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RenderForwardMobile::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - - ginstance->lod_model_scale = max_scale; -} - -void RenderForwardMobile::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; -} - -void RenderForwardMobile::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} - -void RenderForwardMobile::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { -} +void RenderForwardMobile::GeometryInstanceForwardMobile::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { + lightmap_instance = p_lightmap_instance; + lightmap_uv_scale = p_lightmap_uv_scale; + lightmap_slice_index = p_lightmap_slice_index; -void RenderForwardMobile::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { + _mark_dirty(); } -void RenderForwardMobile::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { -} - -void RenderForwardMobile::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - // !BAS! do we support this in mobile? - // GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - // ERR_FAIL_COND(!ginstance); - // ginstance->data->use_dynamic_gi = p_enable; - // _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lightmap_instance = p_lightmap_instance; - ginstance->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->lightmap_slice_index = p_lightmap_slice_index; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardMobile::GeometryInstanceForwardMobile::set_lightmap_capture(const Color *p_sh9) { if (p_sh9) { - if (ginstance->lightmap_sh == nullptr) { - ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc(); + if (lightmap_sh == nullptr) { + lightmap_sh = RenderForwardMobile::get_singleton()->geometry_instance_lightmap_sh.alloc(); } - memcpy(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9); + memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9); } else { - if (ginstance->lightmap_sh != nullptr) { - geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); - ginstance->lightmap_sh = nullptr; + if (lightmap_sh != nullptr) { + RenderForwardMobile::get_singleton()->geometry_instance_lightmap_sh.free(lightmap_sh); + lightmap_sh = nullptr; } } - _geometry_instance_mark_dirty(ginstance); + _mark_dirty(); } -void RenderForwardMobile::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - -Transform3D RenderForwardMobile::geometry_instance_get_transform(GeometryInstance *p_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform3D()); - return ginstance->transform; -} - -AABB RenderForwardMobile::geometry_instance_get_aabb(GeometryInstance *p_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance); - ERR_FAIL_COND_V(!ginstance, AABB()); - return ginstance->data->aabb; -} - -void RenderForwardMobile::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RenderForwardMobile::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); if (ginstance->lightmap_sh != nullptr) { @@ -2235,26 +2115,23 @@ uint32_t RenderForwardMobile::geometry_instance_get_pair_mask() { return ((1 << RS::INSTANCE_LIGHT) + (1 << RS::INSTANCE_REFLECTION_PROBE) + (1 << RS::INSTANCE_DECAL)); } -void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->omni_light_count = 0; - ginstance->spot_light_count = 0; +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) { + omni_light_count = 0; + spot_light_count = 0; for (uint32_t i = 0; i < p_light_instance_count; i++) { - RS::LightType type = light_instance_get_type(p_light_instances[i]); + RS::LightType type = RenderForwardMobile::get_singleton()->light_instance_get_type(p_light_instances[i]); switch (type) { case RS::LIGHT_OMNI: { - if (ginstance->omni_light_count < (uint32_t)MAX_RDL_CULL) { - ginstance->omni_lights[ginstance->omni_light_count] = light_instance_get_forward_id(p_light_instances[i]); - ginstance->omni_light_count++; + if (omni_light_count < (uint32_t)MAX_RDL_CULL) { + omni_lights[omni_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]); + omni_light_count++; } } break; case RS::LIGHT_SPOT: { - if (ginstance->spot_light_count < (uint32_t)MAX_RDL_CULL) { - ginstance->spot_lights[ginstance->spot_light_count] = light_instance_get_forward_id(p_light_instances[i]); - ginstance->spot_light_count++; + if (spot_light_count < (uint32_t)MAX_RDL_CULL) { + spot_lights[spot_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]); + spot_light_count++; } } break; default: @@ -2263,56 +2140,42 @@ void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstanc } } -void RenderForwardMobile::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL; - for (uint32_t i = 0; i < ginstance->reflection_probe_count; i++) { - ginstance->reflection_probes[i] = reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]); +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { + reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL; + for (uint32_t i = 0; i < reflection_probe_count; i++) { + reflection_probes[i] = RenderForwardMobile::get_singleton()->reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]); } } -void RenderForwardMobile::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL; - for (uint32_t i = 0; i < ginstance->decals_count; i++) { - ginstance->decals[i] = decal_instance_get_forward_id(p_decal_instances[i]); +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) { + decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL; + for (uint32_t i = 0; i < decals_count; i++) { + decals[i] = RenderForwardMobile::get_singleton()->decal_instance_get_forward_id(p_decal_instances[i]); } } -void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { - // We do not have this here! +void RenderForwardMobile::GeometryInstanceForwardMobile::set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) { + use_projector = p_projector; + use_soft_shadow = p_softshadow; } -void RenderForwardMobile::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->use_projector = p_projector; - ginstance->use_soft_shadow = p_softshadow; -} - -void RenderForwardMobile::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RenderForwardMobile::GeometryInstanceForwardMobile::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + GeometryInstanceSurfaceDataCache *surf = surface_caches; while (surf) { GeometryInstanceSurfaceDataCache *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RenderForwardMobile::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); + RenderForwardMobile::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); } void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -2478,7 +2341,7 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward } } -void RenderForwardMobile::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); @@ -2632,7 +2495,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata); @@ -2646,7 +2509,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe } } void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } /* misc */ diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 5b1109512a..4a7112eb81 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -160,7 +160,7 @@ protected: // PASS_MODE_SDF, }; - struct GeometryInstanceForwardMobile; + class GeometryInstanceForwardMobile; struct GeometryInstanceSurfaceDataCache; struct RenderElementInfo; @@ -212,14 +212,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -518,14 +518,8 @@ protected: GeometryInstanceForwardMobile *owner = nullptr; }; - // !BAS! GeometryInstanceForwardClustered and GeometryInstanceForwardMobile will likely have a lot of overlap - // may need to think about making this its own class like GeometryInstanceRD? - - struct GeometryInstanceForwardMobile : public GeometryInstance { - // setup - uint32_t base_flags = 0; - uint32_t flags_cache = 0; - + class GeometryInstanceForwardMobile : public RenderGeometryInstanceBase { + public: // this structure maps to our push constant in our shader and is populated right before our draw call struct PushConstant { float transform[16]; @@ -543,28 +537,18 @@ protected: // PushConstant push_constant; // we populate this from our instance data //used during rendering - uint32_t layer_mask = 1; RID transforms_uniform_set; - float depth = 0; - bool mirror = false; bool use_projector = false; bool use_soft_shadow = false; - Transform3D transform; bool store_transform_cache = true; // if true we copy our transform into our PushConstant, if false we use our transforms UBO and clear our PushConstants transform - bool non_uniform_scale = false; - AABB transformed_aabb; //needed for LOD - float lod_bias = 0.0; - float lod_model_scale = 1.0; - int32_t shader_parameters_offset = -1; uint32_t instance_count = 0; uint32_t trail_steps = 1; - RID mesh_instance; // lightmap uint32_t gi_offset_cache = 0; // !BAS! Should rename this to lightmap_offset_cache, in forward clustered this was shared between gi and lightmap - uint32_t lightmap_slice_index; - Rect2 lightmap_uv_scale; RID lightmap_instance; + Rect2 lightmap_uv_scale; + uint32_t lightmap_slice_index; GeometryInstanceLightmapSH *lightmap_sh = nullptr; // culled light info @@ -582,30 +566,20 @@ protected: // do we use this? SelfList<GeometryInstanceForwardMobile> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; - - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; - - bool use_baked_light = true; - bool cast_double_sided_shadows = false; - // bool mirror = false; // !BAS! Does not seem used, we already have this in the main struct + GeometryInstanceForwardMobile() : + dirty_list_element(this) {} - bool dirty_dependencies = false; + virtual void _mark_dirty() override; - DependencyTracker dependency_tracker; - }; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - Data *data = nullptr; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override; + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override; + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - GeometryInstanceForwardMobile() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override; }; _FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance); @@ -613,6 +587,8 @@ protected: void _update_shader_quality_settings() override; public: + static RenderForwardMobile *get_singleton() { return singleton; } + virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override; static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); @@ -627,41 +603,13 @@ public: void _geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); - virtual GeometryInstance *geometry_instance_create(RID p_base) override; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; - - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override; + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; virtual uint32_t geometry_instance_get_pair_mask() override; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; virtual bool free(RID p_rid) override; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index afe4eac0b3..ba8ee62b3f 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -364,7 +364,22 @@ void SceneShaderForwardMobile::ShaderData::get_param_list(List<PropertyInfo> *p_ } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); @@ -569,7 +584,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index cf749854e2..a58cdd5066 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -528,7 +528,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend } if (rect->flags & CANVAS_RECT_TRANSPOSE) { - dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform + push_constant.flags |= FLAGS_TRANSPOSE_RECT; } if (rect->flags & CANVAS_RECT_CLIP_UV) { @@ -2185,7 +2185,22 @@ void RendererCanvasRenderRD::CanvasShaderData::get_param_list(List<PropertyInfo> } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 1d3a5585e1..564c26bfe4 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -32,7 +32,6 @@ #define RENDERER_COMPOSITOR_RD_H #include "core/os/os.h" -#include "core/templates/thread_work_pool.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/effects_rd.h" #include "servers/rendering/renderer_rd/environment/fog.h" diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 937a0cec70..4e43acaf57 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -558,29 +558,28 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba //////////////////////////////////////////////////////////// RID RendererSceneRenderRD::fog_volume_instance_create(RID p_fog_volume) { - FogVolumeInstance fvi; - fvi.volume = p_fog_volume; - return fog_volume_instance_owner.make_rid(fvi); + return RendererRD::Fog::get_singleton()->fog_volume_instance_create(p_fog_volume); } + void RendererSceneRenderRD::fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND(!fvi); fvi->transform = p_transform; } void RendererSceneRenderRD::fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND(!fvi); fvi->active = p_active; } RID RendererSceneRenderRD::fog_volume_instance_get_volume(RID p_fog_volume_instance) const { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND_V(!fvi, RID()); return fvi->volume; } Vector3 RendererSceneRenderRD::fog_volume_instance_get_position(RID p_fog_volume_instance) const { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND_V(!fvi, Vector3()); return fvi->transform.get_origin(); @@ -1526,7 +1525,7 @@ bool RendererSceneRenderRD::voxel_gi_needs_update(RID p_probe) const { return gi.voxel_gi_needs_update(p_probe); } -void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) { +void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { if (!is_dynamic_gi_supported()) { return; } @@ -3689,242 +3688,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const //////////////////////////////////////////////////////////////////////////////// // FOG SHADER -void RendererSceneRenderRD::FogShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - -void RendererSceneRenderRD::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; - - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - - Error err = scene_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 = scene_singleton->volumetric_fog.shader.version_create(); - } - - scene_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(!scene_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(scene_singleton->volumetric_fog.shader.version_get_shader(version, 0)); - - valid = true; -} - -void RendererSceneRenderRD::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void RendererSceneRenderRD::FogShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - RBMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - for (const KeyValue<int, StringName> &E : order) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void RendererSceneRenderRD::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool RendererSceneRenderRD::FogShaderData::is_param_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - -bool RendererSceneRenderRD::FogShaderData::is_animated() const { - return false; -} - -bool RendererSceneRenderRD::FogShaderData::casts_shadows() const { - return false; -} - -Variant RendererSceneRenderRD::FogShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - -RS::ShaderNativeSourceCode RendererSceneRenderRD::FogShaderData::get_native_source_code() const { - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - - return scene_singleton->volumetric_fog.shader.version_get_native_source_code(version); -} - -RendererSceneRenderRD::FogShaderData::~FogShaderData() { - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - ERR_FAIL_COND(!scene_singleton); - //pipeline variants will clear themselves if shader is gone - if (version.is_valid()) { - scene_singleton->volumetric_fog.shader.version_free(version); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Fog material - -bool RendererSceneRenderRD::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - - uniform_set_updated = true; - - return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->volumetric_fog.shader.version_get_shader(shader_data->version, 0), VolumetricFogShader::FogSet::FOG_SET_MATERIAL); -} - -RendererSceneRenderRD::FogMaterialData::~FogMaterialData() { - free_parameters_uniform_set(uniform_set); -} - -RendererRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_func() { - FogShaderData *shader_data = memnew(FogShaderData); - return shader_data; -} - -RendererRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_funcs() { - return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->_create_fog_shader_func(); -}; - -RendererRD::MaterialData *RendererSceneRenderRD::_create_fog_material_func(FogShaderData *p_shader) { - FogMaterialData *material_data = memnew(FogMaterialData); - material_data->shader_data = p_shader; - //update will happen later anyway so do nothing. - return material_data; -} - -RendererRD::MaterialData *RendererSceneRenderRD::_create_fog_material_funcs(RendererRD::ShaderData *p_shader) { - return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->_create_fog_material_func(static_cast<FogShaderData *>(p_shader)); -}; - -//////////////////////////////////////////////////////////////////////////////// -// Volumetric Fog - -void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { - ERR_FAIL_COND(!rb->volumetric_fog); - - RD::get_singleton()->free(rb->volumetric_fog->prev_light_density_map); - RD::get_singleton()->free(rb->volumetric_fog->light_density_map); - RD::get_singleton()->free(rb->volumetric_fog->fog_map); - RD::get_singleton()->free(rb->volumetric_fog->density_map); - RD::get_singleton()->free(rb->volumetric_fog->light_map); - RD::get_singleton()->free(rb->volumetric_fog->emissive_map); - - if (rb->volumetric_fog->fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set); - } - if (rb->volumetric_fog->process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) { - RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set_density); - } - if (rb->volumetric_fog->process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set); - } - if (rb->volumetric_fog->process_uniform_set2.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set2)) { - RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set2); - } - if (rb->volumetric_fog->sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->sdfgi_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->sdfgi_uniform_set); - } - if (rb->volumetric_fog->sky_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->sky_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->sky_uniform_set); - } - - memdelete(rb->volumetric_fog); - - rb->volumetric_fog = nullptr; -} - -Vector3i RendererSceneRenderRD::_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 RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) { - RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3937,7 +3701,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e if (rb->volumetric_fog) { //validate if (!env || !env->volumetric_fog_enabled || rb->volumetric_fog->width != target_width || rb->volumetric_fog->height != target_height || rb->volumetric_fog->depth != volumetric_fog_depth) { - _volumetric_fog_erase(rb); + memdelete(rb->volumetric_fog); + rb->volumetric_fog = nullptr; } } @@ -3946,684 +3711,38 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e return; } - RENDER_TIMESTAMP("> Volumetric Fog"); - RD::get_singleton()->draw_command_begin_label("Volumetric Fog"); - if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) { //required volumetric fog but not existing, create - rb->volumetric_fog = memnew(VolumetricFog); - rb->volumetric_fog->width = target_width; - rb->volumetric_fog->height = target_height; - rb->volumetric_fog->depth = volumetric_fog_depth; - - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.width = target_width; - tf.height = target_height; - tf.depth = volumetric_fog_depth; - tf.texture_type = RD::TEXTURE_TYPE_3D; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - - rb->volumetric_fog->light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->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; - - rb->volumetric_fog->prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->prev_light_density_map, "Fog previous light-density map"); - RD::get_singleton()->texture_clear(rb->volumetric_fog->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; - - rb->volumetric_fog->fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->fog_map, "Fog map"); - -#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) - Vector<uint8_t> dm; - dm.resize(target_width * target_height * volumetric_fog_depth * 4); - dm.fill(0); - - rb->volumetric_fog->density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->density_map, "Fog density map"); - rb->volumetric_fog->light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->light_map, "Fog light map"); - rb->volumetric_fog->emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->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; - rb->volumetric_fog->density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->density_map, "Fog density map"); - RD::get_singleton()->texture_clear(rb->volumetric_fog->density_map, Color(0, 0, 0, 0), 0, 1, 0, 1); - rb->volumetric_fog->light_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->light_map, "Fog light map"); - RD::get_singleton()->texture_clear(rb->volumetric_fog->light_map, Color(0, 0, 0, 0), 0, 1, 0, 1); - rb->volumetric_fog->emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->emissive_map, "Fog emissive map"); - RD::get_singleton()->texture_clear(rb->volumetric_fog->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(rb->volumetric_fog->fog_map); - uniforms.push_back(u); - } - - rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky.sky_shader.default_shader_rd, RendererSceneSkyRD::SKY_SET_FOG); - } - - if (p_fog_volumes.size() > 0) { - RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes"); - - RENDER_TIMESTAMP("Render FogVolumes"); - - VolumetricFogShader::VolumeUBO params; - - Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); - Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); - float z_near = p_cam_projection.get_z_near(); - float z_far = p_cam_projection.get_z_far(); - float fog_end = env->volumetric_fog_length; - - Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); - Vector2 fog_near_size; - if (p_cam_projection.is_orthogonal()) { - fog_near_size = fog_far_size; - } else { - fog_near_size = Vector2(); - } - - params.fog_frustum_size_begin[0] = fog_near_size.x; - params.fog_frustum_size_begin[1] = fog_near_size.y; - - params.fog_frustum_size_end[0] = fog_far_size.x; - params.fog_frustum_size_end[1] = fog_far_size.y; - - params.fog_frustum_end = fog_end; - params.z_near = z_near; - params.z_far = z_far; - params.time = time; - - params.fog_volume_size[0] = rb->volumetric_fog->width; - params.fog_volume_size[1] = rb->volumetric_fog->height; - params.fog_volume_size[2] = rb->volumetric_fog->depth; - - params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection; - params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; - params.detail_spread = env->volumetric_fog_detail_spread; - params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount; - - Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; - RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); - RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform); - - RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms, RD::BARRIER_MASK_COMPUTE); - - if (rb->volumetric_fog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) { - Vector<RD::Uniform> uniforms; - - { - RD::Uniform u; -#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 1; - u.append_id(rb->volumetric_fog->emissive_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 2; - u.append_id(volumetric_fog.volume_ubo); - uniforms.push_back(u); - } - - { - RD::Uniform u; -#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 3; - u.append_id(rb->volumetric_fog->density_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; -#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 4; - u.append_id(rb->volumetric_fog->light_map); - uniforms.push_back(u); - } - - rb->volumetric_fog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); - } - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - bool any_uses_time = false; - - for (int i = 0; i < (int)p_fog_volumes.size(); i++) { - FogVolumeInstance *fog_volume_instance = fog_volume_instance_owner.get_or_null(p_fog_volumes[i]); - ERR_FAIL_COND(!fog_volume_instance); - RID fog_volume = fog_volume_instance->volume; - - RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume); - - FogMaterialData *material = nullptr; - - if (fog_material.is_valid()) { - material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); - if (!material || !material->shader_data->valid) { - material = nullptr; - } - } - - if (!material) { - fog_material = volumetric_fog.default_material; - material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); - } - - ERR_FAIL_COND(!material); - - FogShaderData *shader_data = material->shader_data; - - ERR_FAIL_COND(!shader_data); - - any_uses_time |= shader_data->uses_time; - - Vector3i min = Vector3i(); - Vector3i max = Vector3i(); - Vector3i kernel_size = Vector3i(); - - Vector3 position = fog_volume_instance->transform.get_origin(); - RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); - Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume); - - if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) { - // Local fog volume. - Vector3i points[8]; - 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 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, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - - min = Vector3i(int32_t(rb->volumetric_fog->width) - 1, int32_t(rb->volumetric_fog->height) - 1, int32_t(rb->volumetric_fog->depth) - 1); - max = Vector3i(1, 1, 1); - - for (int j = 0; j < 8; j++) { - min = Vector3i(MIN(min.x, points[j].x), MIN(min.y, points[j].y), MIN(min.z, points[j].z)); - max = Vector3i(MAX(max.x, points[j].x), MAX(max.y, points[j].y), MAX(max.z, points[j].z)); - } - - kernel_size = max - min; - } else { - // Volume type global runs on all cells - extents = Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); - min = Vector3i(0, 0, 0); - kernel_size = Vector3i(int32_t(rb->volumetric_fog->width), int32_t(rb->volumetric_fog->height), int32_t(rb->volumetric_fog->depth)); - } - - if (kernel_size.x == 0 || kernel_size.y == 0 || kernel_size.z == 0) { - continue; - } - - volumetric_fog.push_constant.position[0] = position.x; - volumetric_fog.push_constant.position[1] = position.y; - volumetric_fog.push_constant.position[2] = position.z; - volumetric_fog.push_constant.extents[0] = extents.x; - volumetric_fog.push_constant.extents[1] = extents.y; - volumetric_fog.push_constant.extents[2] = extents.z; - volumetric_fog.push_constant.corner[0] = min.x; - volumetric_fog.push_constant.corner[1] = min.y; - volumetric_fog.push_constant.corner[2] = min.z; - volumetric_fog.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(), volumetric_fog.push_constant.transform); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &volumetric_fog.push_constant, sizeof(VolumetricFogShader::FogPushConstant)); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE); - if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set. - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL); - } - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); - } - if (any_uses_time || env->volumetric_fog_temporal_reprojection) { - RenderingServerDefault::redraw_request(); - } - - RD::get_singleton()->draw_command_end_label(); - - RD::get_singleton()->compute_list_end(); + rb->volumetric_fog = memnew(RendererRD::Fog::VolumetricFog(Vector3i(target_width, target_height, volumetric_fog_depth), sky.sky_shader.default_shader_rd)); } - if (rb->volumetric_fog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) { - //re create uniform set if needed - Vector<RD::Uniform> uniforms; - Vector<RD::Uniform> copy_uniforms; - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); - if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); - } else { - u.append_id(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 (directional_shadow.depth.is_valid()) { - u.append_id(directional_shadow.depth); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); - } - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 3; - u.append_id(get_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(get_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(get_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(rb->cluster_builder->get_cluster_buffer()); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 7; - u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 8; - u.append_id(rb->volumetric_fog->light_density_map); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; - u.append_id(rb->volumetric_fog->fog_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; - u.append_id(rb->volumetric_fog->prev_light_density_map); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 10; - u.append_id(shadow_sampler); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 11; - u.append_id(render_buffers_get_voxel_gi_buffer(p_render_buffers)); - 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(rb->rbgi.voxel_gi_textures[i]); - } - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 13; - u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 14; - u.append_id(volumetric_fog.params_ubo); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 15; - u.append_id(rb->volumetric_fog->prev_light_density_map); - uniforms.push_back(u); - } - { - RD::Uniform u; -#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 16; - u.append_id(rb->volumetric_fog->density_map); - uniforms.push_back(u); - } - { - RD::Uniform u; -#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 17; - u.append_id(rb->volumetric_fog->light_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; -#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 18; - u.append_id(rb->volumetric_fog->emissive_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 19; - RID radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); - RID sky_texture = env->sky.is_valid() ? sky.sky_get_radiance_texture_rd(env->sky) : RID(); - u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); - uniforms.push_back(u); - } - - rb->volumetric_fog->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); - - rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); - - RID aux7 = uniforms.write[7].get_id(0); - RID aux8 = uniforms.write[8].get_id(0); - - uniforms.write[7].set_id(0, aux8); - uniforms.write[8].set_id(0, aux7); - - rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); - - uniforms.remove_at(8); - uniforms.write[7].set_id(0, aux7); - rb->volumetric_fog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); - } - - bool using_sdfgi = env->volumetric_fog_gi_inject > 0.0001 && env->sdfgi_enabled && (rb->sdfgi != nullptr); - - if (using_sdfgi) { - if (rb->volumetric_fog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->sdfgi_uniform_set)) { - Vector<RD::Uniform> uniforms; - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 0; - u.append_id(gi.sdfgi_ubo); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - u.append_id(rb->sdfgi->ambient_texture); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 2; - u.append_id(rb->sdfgi->occlusion_texture); - uniforms.push_back(u); - } - - rb->volumetric_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); - } - } - - rb->volumetric_fog->length = env->volumetric_fog_length; - rb->volumetric_fog->spread = env->volumetric_fog_detail_spread; - - VolumetricFogShader::ParamsUBO params; - - Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); - Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); - float z_near = p_cam_projection.get_z_near(); - float z_far = p_cam_projection.get_z_far(); - float fog_end = env->volumetric_fog_length; - - Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); - Vector2 fog_near_size; - if (p_cam_projection.is_orthogonal()) { - fog_near_size = fog_far_size; - } else { - fog_near_size = Vector2(); - } - - params.fog_frustum_size_begin[0] = fog_near_size.x; - params.fog_frustum_size_begin[1] = fog_near_size.y; - - params.fog_frustum_size_end[0] = fog_far_size.x; - params.fog_frustum_size_end[1] = fog_far_size.y; - - params.ambient_inject = env->volumetric_fog_ambient_inject * env->ambient_light_energy; - params.z_far = z_far; - - params.fog_frustum_end = fog_end; - - Color ambient_color = env->ambient_light.srgb_to_linear(); - params.ambient_color[0] = ambient_color.r; - params.ambient_color[1] = ambient_color.g; - params.ambient_color[2] = ambient_color.b; - params.sky_contribution = env->ambient_sky_contribution; - - params.fog_volume_size[0] = rb->volumetric_fog->width; - params.fog_volume_size[1] = rb->volumetric_fog->height; - params.fog_volume_size[2] = rb->volumetric_fog->depth; - - params.directional_light_count = p_directional_light_count; - - Color emission = env->volumetric_fog_emission.srgb_to_linear(); - params.base_emission[0] = emission.r * env->volumetric_fog_emission_energy; - params.base_emission[1] = emission.g * env->volumetric_fog_emission_energy; - params.base_emission[2] = emission.b * env->volumetric_fog_emission_energy; - params.base_density = env->volumetric_fog_density; - - Color base_scattering = env->volumetric_fog_scattering.srgb_to_linear(); - params.base_scattering[0] = base_scattering.r; - params.base_scattering[1] = base_scattering.g; - params.base_scattering[2] = base_scattering.b; - params.phase_g = env->volumetric_fog_anisotropy; - - params.detail_spread = env->volumetric_fog_detail_spread; - params.gi_inject = env->volumetric_fog_gi_inject; - - params.cam_rotation[0] = p_cam_transform.basis[0][0]; - params.cam_rotation[1] = p_cam_transform.basis[1][0]; - params.cam_rotation[2] = p_cam_transform.basis[2][0]; - params.cam_rotation[3] = 0; - params.cam_rotation[4] = p_cam_transform.basis[0][1]; - params.cam_rotation[5] = p_cam_transform.basis[1][1]; - params.cam_rotation[6] = p_cam_transform.basis[2][1]; - params.cam_rotation[7] = 0; - params.cam_rotation[8] = p_cam_transform.basis[0][2]; - params.cam_rotation[9] = p_cam_transform.basis[1][2]; - params.cam_rotation[10] = p_cam_transform.basis[2][2]; - params.cam_rotation[11] = 0; - params.filter_axis = 0; - params.max_voxel_gi_instances = env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0; - params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; - - Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; - RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); - - params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection; - params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount; - - { - uint32_t cluster_size = rb->cluster_builder->get_cluster_size(); - params.cluster_shift = get_shift_from_power_of_2(cluster_size); - - uint32_t cluster_screen_width = (rb->width - 1) / cluster_size + 1; - uint32_t cluster_screen_height = (rb->height - 1) / cluster_size + 1; - params.max_cluster_element_count_div_32 = 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] = rb->width; - params.screen_size[1] = rb->height; - } - - Basis sky_transform = env->sky_orientation; - sky_transform = sky_transform.inverse() * p_cam_transform.basis; - RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform); - - RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog"); - - RENDER_TIMESTAMP("Render Fog"); - RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶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]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set_density, 0); - - if (using_sdfgi) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1); - } - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); - RD::get_singleton()->compute_list_add_barrier(compute_list); - - // Copy fog to history buffer - if (env->volumetric_fog_temporal_reprojection) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->copy_uniform_set, 0); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); - RD::get_singleton()->compute_list_add_barrier(compute_list); - } - RD::get_singleton()->draw_command_end_label(); - - if (volumetric_fog_filter_active) { - RD::get_singleton()->draw_command_begin_label("Filter Fog"); - - RENDER_TIMESTAMP("Filter Fog"); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set, 0); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); - - RD::get_singleton()->compute_list_end(); - //need restart for buffer update - - params.filter_axis = 1; - RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms); + if (rb->volumetric_fog) { + RendererRD::Fog::VolumetricFogSettings settings; + settings.rb_size = Vector2i(rb->width, rb->height); + settings.time = time; + settings.is_using_radiance_cubemap_array = is_using_radiance_cubemap_array(); + settings.max_cluster_elements = max_cluster_elements; + settings.volumetric_fog_filter_active = volumetric_fog_filter_active; + + settings.shadow_sampler = shadow_sampler; + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); + settings.shadow_atlas_depth = shadow_atlas ? shadow_atlas->depth : RID(); + settings.voxel_gl_buffer = render_buffers_get_voxel_gi_buffer(p_render_buffers); + settings.omni_light_buffer = get_omni_light_buffer(); + settings.spot_light_buffer = get_spot_light_buffer(); + settings.directional_shadow_depth = directional_shadow.depth; + settings.directional_light_buffer = get_directional_light_buffer(); - compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set2, 0); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); + settings.vfog = rb->volumetric_fog; + settings.cluster_builder = rb->cluster_builder; + settings.rbgi = &rb->rbgi; + settings.sdfgi = rb->sdfgi; + settings.env = env; + settings.sky = &sky; + settings.gi = &gi; - RD::get_singleton()->compute_list_add_barrier(compute_list); - RD::get_singleton()->draw_command_end_label(); + RendererRD::Fog::get_singleton()->volumetric_fog_update(settings, p_cam_projection, p_cam_transform, p_prev_cam_inv_transform, p_shadow_atlas, p_directional_light_count, p_use_directional_shadows, p_positional_light_count, p_voxel_gi_count, p_fog_volumes); } - - RENDER_TIMESTAMP("Integrate Fog"); - RD::get_singleton()->draw_command_begin_label("Integrate Fog"); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set, 0); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, 1); - - RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER); - - RENDER_TIMESTAMP("< Volumetric Fog"); - RD::get_singleton()->draw_command_end_label(); - RD::get_singleton()->draw_command_end_label(); } bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { @@ -4828,7 +3947,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } } -void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); // getting this here now so we can direct call a bunch of things more easily @@ -5023,7 +4142,7 @@ void RendererSceneRenderRD::_debug_draw_cluster(RID p_render_buffers) { } } -void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { +void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { LightInstance *light_instance = light_instance_owner.get_or_null(p_light); ERR_FAIL_COND(!light_instance); @@ -5195,11 +4314,11 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } } -void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { _render_material(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_instances, p_framebuffer, p_region); } -void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { +void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) { RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider)); @@ -5229,7 +4348,8 @@ bool RendererSceneRenderRD::free(RID p_rid) { rb->sdfgi = nullptr; } if (rb->volumetric_fog) { - _volumetric_fog_erase(rb); + memdelete(rb->volumetric_fog); + rb->volumetric_fog = nullptr; } if (rb->cluster_builder) { memdelete(rb->cluster_builder); @@ -5304,8 +4424,8 @@ bool RendererSceneRenderRD::free(RID p_rid) { } else if (shadow_atlas_owner.owns(p_rid)) { shadow_atlas_set_size(p_rid, 0); shadow_atlas_owner.free(p_rid); - } else if (fog_volume_instance_owner.owns(p_rid)) { - fog_volume_instance_owner.free(p_rid); + } else if (RendererRD::Fog::get_singleton()->owns_fog_volume_instance(p_rid)) { + RendererRD::Fog::get_singleton()->fog_instance_free(p_rid); } else { return false; } @@ -5377,7 +4497,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto //RID sampled_light; - GeometryInstance *gi = geometry_instance_create(p_base); + RenderGeometryInstance *gi = geometry_instance_create(p_base); uint32_t sc = RSG::mesh_storage->mesh_get_surface_count(p_base); Vector<RID> materials; @@ -5389,7 +4509,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto } } - geometry_instance_set_surface_materials(gi, materials); + gi->set_surface_materials(materials); if (cull_argument.size() == 0) { cull_argument.push_back(nullptr); @@ -5499,8 +4619,6 @@ RendererSceneRenderRD::RendererSceneRenderRD() { } void RendererSceneRenderRD::init() { - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - max_cluster_elements = get_max_elements(); directional_shadow.size = GLOBAL_GET("rendering/shadows/directional_shadow/size"); @@ -5551,124 +4669,7 @@ void RendererSceneRenderRD::init() { } if (is_volumetric_supported()) { - { - // Initialize local fog shader - Vector<String> volumetric_fog_modes; - volumetric_fog_modes.push_back(""); - volumetric_fog.shader.initialize(volumetric_fog_modes); - - material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_shader_funcs); - material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_material_funcs); - volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO)); - } - - { - ShaderCompiler::DefaultIdentifierActions actions; - - actions.renames["TIME"] = "scene_params.time"; - actions.renames["PI"] = _MKSTR(Math_PI); - actions.renames["TAU"] = _MKSTR(Math_TAU); - actions.renames["E"] = _MKSTR(Math_E); - actions.renames["WORLD_POSITION"] = "world.xyz"; - actions.renames["OBJECT_POSITION"] = "params.position"; - actions.renames["UVW"] = "uvw"; - actions.renames["EXTENTS"] = "params.extents"; - actions.renames["ALBEDO"] = "albedo"; - actions.renames["DENSITY"] = "density"; - actions.renames["EMISSION"] = "emission"; - actions.renames["SDF"] = "sdf"; - - actions.usage_defines["SDF"] = "#define SDF_USED\n"; - actions.usage_defines["DENSITY"] = "#define DENSITY_USED\n"; - actions.usage_defines["ALBEDO"] = "#define ALBEDO_USED\n"; - actions.usage_defines["EMISSION"] = "#define EMISSION_USED\n"; - - actions.sampler_array_name = "material_samplers"; - actions.base_texture_binding_index = 1; - actions.texture_layout_set = VolumetricFogShader::FogSet::FOG_SET_MATERIAL; - actions.base_uniform_string = "material."; - - actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; - actions.default_repeat = ShaderLanguage::REPEAT_DISABLE; - actions.global_buffer_array_variable = "global_variables.data"; - - volumetric_fog.compiler.initialize(actions); - } - - { - // default material and shader for fog shader - volumetric_fog.default_shader = material_storage->shader_allocate(); - material_storage->shader_initialize(volumetric_fog.default_shader); - material_storage->shader_set_code(volumetric_fog.default_shader, R"( -// Default fog shader. - -shader_type fog; - -void fog() { - DENSITY = 1.0; - ALBEDO = vec3(1.0); -} -)"); - volumetric_fog.default_material = material_storage->material_allocate(); - material_storage->material_initialize(volumetric_fog.default_material); - material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader); - - FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::SHADER_TYPE_FOG)); - volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, 0); - - Vector<RD::Uniform> uniforms; - - { - Vector<RID> ids; - ids.resize(12); - RID *ids_ptr = ids.ptrw(); - ids_ptr[0] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[1] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[2] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[3] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[4] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[5] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[6] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[7] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[8] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[9] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[10] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[11] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - - RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 2; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); - uniforms.push_back(u); - } - - volumetric_fog.base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_BASE); - } - { - String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n"; - defines += "\n#define MAX_SKY_LOD " + itos(get_roughness_layers() - 1) + ".0\n"; - if (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)); - } + RendererRD::Fog::get_singleton()->init_fog_shader(cluster.max_directional_lights, get_roughness_layers(), is_using_radiance_cubemap_array()); } { @@ -5721,8 +4722,6 @@ void fog() { } RendererSceneRenderRD::~RendererSceneRenderRD() { - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - if (bokeh_dof) { memdelete(bokeh_dof); } @@ -5752,11 +4751,7 @@ RendererSceneRenderRD::~RendererSceneRenderRD() { } if (is_volumetric_supported()) { - 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); + RendererRD::Fog::get_singleton()->free_fog_shader(); } memdelete_arr(directional_penumbra_shadow_kernel); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 0e15c9155d..8b2c159660 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -40,11 +40,10 @@ #include "servers/rendering/renderer_rd/effects/ss_effects.h" #include "servers/rendering/renderer_rd/effects/tone_mapper.h" #include "servers/rendering/renderer_rd/effects/vrs.h" +#include "servers/rendering/renderer_rd/environment/fog.h" #include "servers/rendering/renderer_rd/environment/gi.h" +#include "servers/rendering/renderer_rd/environment/sky.h" #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" -#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h" #include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -70,7 +69,7 @@ struct RenderDataRD { float z_near = 0.0; float z_far = 0.0; - const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr; + const PagedArray<RenderGeometryInstance *> *instances = nullptr; const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; const PagedArray<RID> *voxel_gi_instances = nullptr; @@ -99,7 +98,7 @@ struct RenderDataRD { }; class RendererSceneRenderRD : public RendererSceneRender { - friend RendererSceneSkyRD; + friend RendererRD::SkyRD; friend RendererRD::GI; protected: @@ -123,14 +122,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0; virtual void _render_shadow_begin() = 0; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; virtual void _render_shadow_process() = 0; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; - virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) = 0; void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void _debug_draw_cluster(RID p_render_buffers); @@ -162,12 +161,12 @@ protected: void _disable_clear_request(const RenderDataRD *p_render_data); // needed for a single argument calls (material and uv2) - PagedArrayPool<GeometryInstance *> cull_argument_pool; - PagedArray<GeometryInstance *> cull_argument; //need this to exist + PagedArrayPool<RenderGeometryInstance *> cull_argument_pool; + PagedArray<RenderGeometryInstance *> cull_argument; //need this to exist RendererRD::SSEffects *ss_effects = nullptr; RendererRD::GI gi; - RendererSceneSkyRD sky; + RendererRD::SkyRD sky; RendererSceneEnvironmentRD *get_environment(RID p_environment) { if (p_environment.is_valid()) { @@ -212,7 +211,7 @@ private: struct Reflection { RID owner; - RendererSceneSkyRD::ReflectionData data; + RendererRD::SkyRD::ReflectionData data; RID fbs[6]; }; @@ -407,16 +406,6 @@ private: mutable RID_Owner<LightInstance> light_instance_owner; - /* FOG VOLUMES */ - - struct FogVolumeInstance { - RID volume; - Transform3D transform; - bool active = false; - }; - - mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner; - /* ENVIRONMENT */ RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM; @@ -471,8 +460,6 @@ private: ClusterBuilderSharedDataRD cluster_builder_shared; ClusterBuilderRD *current_cluster_builder = nullptr; - struct VolumetricFog; - struct RenderBuffers { RenderBufferData *data = nullptr; int internal_width = 0; @@ -508,8 +495,8 @@ private: Vector<View> views; RendererRD::GI::SDFGI *sdfgi = nullptr; - VolumetricFog *volumetric_fog = nullptr; RendererRD::GI::RenderBuffersGI rbgi; + RendererRD::Fog::VolumetricFog *volumetric_fog = nullptr; ClusterBuilderRD *cluster_builder = nullptr; @@ -749,204 +736,6 @@ private: bool depth_prepass_used; // this does not seem used anywhere... } render_state; - struct VolumetricFog { - enum { - MAX_TEMPORAL_FRAMES = 16 - }; - - uint32_t width = 0; - uint32_t height = 0; - uint32_t depth = 0; - - float length; - float spread; - - RID light_density_map; - RID prev_light_density_map; - RID fog_map; - RID density_map; - RID light_map; - RID emissive_map; - - RID fog_uniform_set; - RID copy_uniform_set; - RID process_uniform_set_density; - RID process_uniform_set; - RID process_uniform_set2; - RID sdfgi_uniform_set; - RID sky_uniform_set; - - int last_shadow_filter = -1; - }; - - struct VolumetricFogShader { - enum FogSet { - FOG_SET_BASE, - FOG_SET_UNIFORMS, - FOG_SET_MATERIAL, - FOG_SET_MAX, - }; - - struct FogPushConstant { - float position[3]; - float pad; - - float extents[3]; - float pad2; - - int32_t corner[3]; - uint32_t shape; - - float transform[16]; - }; - - struct VolumeUBO { - float fog_frustum_size_begin[2]; - float fog_frustum_size_end[2]; - - float fog_frustum_end; - float z_near; - float z_far; - float time; - - int32_t fog_volume_size[3]; - uint32_t directional_light_count; - - uint32_t use_temporal_reprojection; - uint32_t temporal_frame; - float detail_spread; - float temporal_blend; - - float to_prev_view[16]; - float transform[16]; - }; - - ShaderCompiler compiler; - VolumetricFogShaderRD shader; - FogPushConstant push_constant; - RID volume_ubo; - - RID default_shader; - RID default_material; - RID default_shader_rd; - - RID base_uniform_set; - - RID params_ubo; - - enum { - VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY, - VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI, - VOLUMETRIC_FOG_PROCESS_SHADER_FILTER, - VOLUMETRIC_FOG_PROCESS_SHADER_FOG, - VOLUMETRIC_FOG_PROCESS_SHADER_COPY, - VOLUMETRIC_FOG_PROCESS_SHADER_MAX, - }; - - struct ParamsUBO { - float fog_frustum_size_begin[2]; - float fog_frustum_size_end[2]; - - float fog_frustum_end; - float ambient_inject; - float z_far; - uint32_t filter_axis; - - float ambient_color[3]; - float sky_contribution; - - int32_t fog_volume_size[3]; - uint32_t directional_light_count; - - float base_emission[3]; - float base_density; - - float base_scattering[3]; - float phase_g; - - float detail_spread; - float gi_inject; - uint32_t max_voxel_gi_instances; - uint32_t cluster_type_size; - - float screen_size[2]; - uint32_t cluster_shift; - uint32_t cluster_width; - - uint32_t max_cluster_element_count_div_32; - uint32_t use_temporal_reprojection; - uint32_t temporal_frame; - float temporal_blend; - - float cam_rotation[12]; - float to_prev_view[16]; - float radiance_inverse_xform[12]; - }; - - VolumetricFogProcessShaderRD process_shader; - - RID process_shader_version; - RID process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX]; - - } volumetric_fog; - - uint32_t volumetric_fog_depth = 128; - uint32_t volumetric_fog_size = 128; - bool volumetric_fog_filter_active = true; - - Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform); - void _volumetric_fog_erase(RenderBuffers *rb); - void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); - - struct FogShaderData : public RendererRD::ShaderData { - bool valid = false; - RID version; - - RID pipeline; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; - - Vector<uint32_t> ubo_offsets; - uint32_t ubo_size = 0; - - String path; - String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; - - bool uses_time = false; - - virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; - virtual bool is_animated() const; - virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; - virtual RS::ShaderNativeSourceCode get_native_source_code() const; - - FogShaderData() {} - virtual ~FogShaderData(); - }; - - struct FogMaterialData : public RendererRD::MaterialData { - FogShaderData *shader_data = nullptr; - RID uniform_set; - bool uniform_set_updated; - - virtual void set_render_priority(int p_priority) {} - virtual void set_next_pass(RID p_pass) {} - virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); - virtual ~FogMaterialData(); - }; - - RendererRD::ShaderData *_create_fog_shader_func(); - static RendererRD::ShaderData *_create_fog_shader_funcs(); - - RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader); - static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader); - RID shadow_sampler; uint64_t scene_pass = 0; @@ -961,12 +750,17 @@ private: uint32_t max_cluster_elements = 512; - void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); -public: - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0; + /* Volumetric Fog */ + uint32_t volumetric_fog_size = 128; + uint32_t volumetric_fog_depth = 128; + bool volumetric_fog_filter_active = true; + + void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); + +public: /* GI */ RendererRD::GI *get_gi() { return &gi; } @@ -1363,7 +1157,7 @@ public: virtual RID voxel_gi_instance_create(RID p_base) override; virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override; virtual bool voxel_gi_needs_update(RID p_probe) const override; - virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override; + virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override; virtual void voxel_gi_set_quality(RS::VoxelGIQuality p_quality) override { gi.voxel_gi_quality = p_quality; } /* render buffers */ @@ -1406,11 +1200,11 @@ public: virtual void update_uniform_sets(){}; - virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; + virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; - virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override; virtual void set_scene_pass(uint64_t p_pass) override { scene_pass = p_pass; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 176465234e..c9b6d09d4c 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -476,7 +476,9 @@ void ShaderRD::_compile_version(Version *p_version) { #if 1 - RendererThreadPool::singleton->thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &ShaderRD::_compile_variant, p_version, variant_defines.size(), -1, true, SNAME("ShaderCompilation")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + #else for (int i = 0; i < variant_defines.size(); i++) { _compile_variant(i, p_version); diff --git a/servers/rendering/renderer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index 5b4594da99..5b4594da99 100644 --- a/servers/rendering/renderer_rd/shaders/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl index eee609fb48..fb3c725b1f 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl @@ -21,8 +21,8 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; #define DENSITY_SCALE 1024.0 -#include "cluster_data_inc.glsl" -#include "light_data_inc.glsl" +#include "../cluster_data_inc.glsl" +#include "../light_data_inc.glsl" #define M_PI 3.14159265359 diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index fdbd7d3e35..e74cfad65c 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -19,8 +19,8 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #endif -#include "cluster_data_inc.glsl" -#include "light_data_inc.glsl" +#include "../cluster_data_inc.glsl" +#include "../light_data_inc.glsl" #define M_PI 3.14159265359 diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index ea4bd6ab0b..75977c5bc9 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -1612,7 +1612,22 @@ void ParticlesStorage::ParticlesShaderData::get_param_list(List<PropertyInfo> *p } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 1a5a3dd023..1eb4a283ca 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -191,8 +191,8 @@ struct Decal { float upper_fade = 0.3; float lower_fade = 0.3; bool distance_fade = false; - float distance_fade_begin = 10; - float distance_fade_length = 1; + float distance_fade_begin = 40.0; + float distance_fade_length = 10.0; float normal_fade = 0.0; Dependency dependency; |