Path: blob/master/servers/rendering/renderer_rd/environment/fog.cpp
10279 views
/**************************************************************************/1/* fog.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "fog.h"3132#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"33#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"34#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"35#include "servers/rendering/rendering_server_default.h"3637using namespace RendererRD;3839Fog *Fog::singleton = nullptr;4041Fog::Fog() {42singleton = this;43}4445Fog::~Fog() {46singleton = nullptr;47}4849int Fog::_get_fog_shader_group() {50RenderingDevice *rd = RD::get_singleton();51bool use_32_bit_atomics = rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT);52bool use_vulkan_memory_model = rd->has_feature(RD::SUPPORTS_VULKAN_MEMORY_MODEL);53if (use_vulkan_memory_model) {54return use_32_bit_atomics ? VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL : VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL_NO_ATOMICS;55} else {56return use_32_bit_atomics ? VolumetricFogShader::SHADER_GROUP_BASE : VolumetricFogShader::SHADER_GROUP_NO_ATOMICS;57}58}5960int Fog::_get_fog_variant() {61RenderingDevice *rd = RD::get_singleton();62bool use_32_bit_atomics = rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT);63bool use_vulkan_memory_model = rd->has_feature(RD::SUPPORTS_VULKAN_MEMORY_MODEL);64return (use_vulkan_memory_model ? 2 : 0) + (use_32_bit_atomics ? 0 : 1);65}6667int Fog::_get_fog_process_variant(int p_idx) {68RenderingDevice *rd = RD::get_singleton();69bool use_32_bit_atomics = rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT);70bool use_vulkan_memory_model = rd->has_feature(RD::SUPPORTS_VULKAN_MEMORY_MODEL);71return (use_vulkan_memory_model ? (VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX * 2) : 0) + (use_32_bit_atomics ? 0 : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX) + p_idx;72}7374/* FOG VOLUMES */7576RID Fog::fog_volume_allocate() {77return fog_volume_owner.allocate_rid();78}7980void Fog::fog_volume_initialize(RID p_rid) {81fog_volume_owner.initialize_rid(p_rid, FogVolume());82}8384void Fog::fog_volume_free(RID p_rid) {85FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);86fog_volume->dependency.deleted_notify(p_rid);87fog_volume_owner.free(p_rid);88}8990Dependency *Fog::fog_volume_get_dependency(RID p_fog_volume) const {91FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);92ERR_FAIL_NULL_V(fog_volume, nullptr);9394return &fog_volume->dependency;95}9697void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {98FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);99ERR_FAIL_NULL(fog_volume);100101if (p_shape == fog_volume->shape) {102return;103}104105fog_volume->shape = p_shape;106fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);107}108109void Fog::fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) {110FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);111ERR_FAIL_NULL(fog_volume);112113fog_volume->size = p_size;114fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);115}116117void Fog::fog_volume_set_material(RID p_fog_volume, RID p_material) {118FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);119ERR_FAIL_NULL(fog_volume);120fog_volume->material = p_material;121}122123RID Fog::fog_volume_get_material(RID p_fog_volume) const {124FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);125ERR_FAIL_NULL_V(fog_volume, RID());126127return fog_volume->material;128}129130RS::FogVolumeShape Fog::fog_volume_get_shape(RID p_fog_volume) const {131FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);132ERR_FAIL_NULL_V(fog_volume, RS::FOG_VOLUME_SHAPE_BOX);133134return fog_volume->shape;135}136137AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const {138FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);139ERR_FAIL_NULL_V(fog_volume, AABB());140141switch (fog_volume->shape) {142case RS::FOG_VOLUME_SHAPE_ELLIPSOID:143case RS::FOG_VOLUME_SHAPE_CONE:144case RS::FOG_VOLUME_SHAPE_CYLINDER:145case RS::FOG_VOLUME_SHAPE_BOX: {146AABB aabb;147aabb.position = -fog_volume->size / 2;148aabb.size = fog_volume->size;149return aabb;150}151default: {152// Need some size otherwise will get culled153return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));154}155}156}157158Vector3 Fog::fog_volume_get_size(RID p_fog_volume) const {159const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);160ERR_FAIL_NULL_V(fog_volume, Vector3());161return fog_volume->size;162}163164////////////////////////////////////////////////////////////////////////////////165// Fog material166167bool Fog::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {168uniform_set_updated = true;169170return 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, _get_fog_variant()), VolumetricFogShader::FogSet::FOG_SET_MATERIAL, true, true);171}172173Fog::FogMaterialData::~FogMaterialData() {174free_parameters_uniform_set(uniform_set);175}176177RendererRD::MaterialStorage::ShaderData *Fog::_create_fog_shader_func() {178FogShaderData *shader_data = memnew(FogShaderData);179return shader_data;180}181182RendererRD::MaterialStorage::ShaderData *Fog::_create_fog_shader_funcs() {183return Fog::get_singleton()->_create_fog_shader_func();184}185186RendererRD::MaterialStorage::MaterialData *Fog::_create_fog_material_func(FogShaderData *p_shader) {187FogMaterialData *material_data = memnew(FogMaterialData);188material_data->shader_data = p_shader;189//update will happen later anyway so do nothing.190return material_data;191}192193RendererRD::MaterialStorage::MaterialData *Fog::_create_fog_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader) {194return Fog::get_singleton()->_create_fog_material_func(static_cast<FogShaderData *>(p_shader));195}196197////////////////////////////////////////////////////////////////////////////////198// FOG VOLUMES INSTANCE199200RID Fog::fog_volume_instance_create(RID p_fog_volume) {201FogVolumeInstance fvi;202fvi.volume = p_fog_volume;203return fog_volume_instance_owner.make_rid(fvi);204}205206void Fog::fog_instance_free(RID p_rid) {207fog_volume_instance_owner.free(p_rid);208}209210////////////////////////////////////////////////////////////////////////////////211// Volumetric Fog Shader212213void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array) {214MaterialStorage *material_storage = MaterialStorage::get_singleton();215216{217String defines = "#define SAMPLERS_BINDING_FIRST_INDEX " + itos(SAMPLERS_BINDING_FIRST_INDEX) + "\n";218// Initialize local fog shader219Vector<ShaderRD::VariantDefine> volumetric_fog_modes;220volumetric_fog_modes.push_back(ShaderRD::VariantDefine(VolumetricFogShader::SHADER_GROUP_BASE, "", false));221volumetric_fog_modes.push_back(ShaderRD::VariantDefine(VolumetricFogShader::SHADER_GROUP_NO_ATOMICS, "#define NO_IMAGE_ATOMICS\n", false));222volumetric_fog_modes.push_back(ShaderRD::VariantDefine(VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL, "#define USE_VULKAN_MEMORY_MODEL\n", false));223volumetric_fog_modes.push_back(ShaderRD::VariantDefine(VolumetricFogShader::SHADER_GROUP_VULKAN_MEMORY_MODEL_NO_ATOMICS, "#define USE_VULKAN_MEMORY_MODEL\n#define NO_IMAGE_ATOMICS\n", false));224225volumetric_fog.shader.initialize(volumetric_fog_modes, defines);226volumetric_fog.shader.enable_group(_get_fog_shader_group());227228material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_shader_funcs);229material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_material_funcs);230volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO));231}232233{234ShaderCompiler::DefaultIdentifierActions actions;235236actions.renames["TIME"] = "scene_params.time";237actions.renames["PI"] = String::num(Math::PI);238actions.renames["TAU"] = String::num(Math::TAU);239actions.renames["E"] = String::num(Math::E);240actions.renames["WORLD_POSITION"] = "world.xyz";241actions.renames["OBJECT_POSITION"] = "params.position";242actions.renames["UVW"] = "uvw";243actions.renames["SIZE"] = "params.size";244actions.renames["ALBEDO"] = "albedo";245actions.renames["DENSITY"] = "density";246actions.renames["EMISSION"] = "emission";247actions.renames["SDF"] = "sdf";248249actions.usage_defines["SDF"] = "#define SDF_USED\n";250actions.usage_defines["DENSITY"] = "#define DENSITY_USED\n";251actions.usage_defines["ALBEDO"] = "#define ALBEDO_USED\n";252actions.usage_defines["EMISSION"] = "#define EMISSION_USED\n";253254actions.base_texture_binding_index = 1;255actions.texture_layout_set = VolumetricFogShader::FogSet::FOG_SET_MATERIAL;256actions.base_uniform_string = "material.";257258actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;259actions.default_repeat = ShaderLanguage::REPEAT_DISABLE;260actions.global_buffer_array_variable = "global_shader_uniforms.data";261262volumetric_fog.compiler.initialize(actions);263}264265{266// default material and shader for fog shader267volumetric_fog.default_shader = material_storage->shader_allocate();268material_storage->shader_initialize(volumetric_fog.default_shader);269material_storage->shader_set_code(volumetric_fog.default_shader, R"(270// Default fog shader.271272shader_type fog;273274void fog() {275DENSITY = 1.0;276ALBEDO = vec3(1.0);277}278)");279volumetric_fog.default_material = material_storage->material_allocate();280material_storage->material_initialize(volumetric_fog.default_material);281material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader);282283FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG));284volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, _get_fog_variant());285286Vector<RD::Uniform> uniforms;287288{289RD::Uniform u;290u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;291u.binding = 2;292u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer());293uniforms.push_back(u);294}295296material_storage->samplers_rd_get_default().append_uniforms(uniforms, SAMPLERS_BINDING_FIRST_INDEX);297298volumetric_fog.base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_BASE);299}300301{302String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(p_max_directional_lights) + "\n";303defines += "\n#define MAX_SKY_LOD " + itos(p_roughness_layers - 1) + ".0\n";304if (p_is_using_radiance_cubemap_array) {305defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";306}307Vector<ShaderRD::VariantDefine> volumetric_fog_modes;308int shader_group = 0;309for (int vk_memory_model = 0; vk_memory_model < 2; vk_memory_model++) {310for (int no_atomics = 0; no_atomics < 2; no_atomics++) {311String base_define = vk_memory_model ? "\n#define USE_VULKAN_MEMORY_MODEL" : "";312base_define += no_atomics ? "\n#define NO_IMAGE_ATOMICS" : "";313volumetric_fog_modes.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_DENSITY\n", false));314volumetric_fog_modes.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_DENSITY\n#define ENABLE_SDFGI\n", false));315volumetric_fog_modes.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_FILTER\n", false));316volumetric_fog_modes.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_FOG\n", false));317volumetric_fog_modes.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_COPY\n", false));318shader_group++;319}320}321322volumetric_fog.process_shader.initialize(volumetric_fog_modes, defines);323volumetric_fog.process_shader.enable_group(_get_fog_shader_group());324325volumetric_fog.process_shader_version = volumetric_fog.process_shader.version_create();326for (int i = 0; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) {327volumetric_fog.process_pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, _get_fog_process_variant(i)));328}329volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO));330}331}332333void Fog::free_fog_shader() {334MaterialStorage *material_storage = MaterialStorage::get_singleton();335336if (volumetric_fog.process_shader_version.is_valid()) {337volumetric_fog.process_shader.version_free(volumetric_fog.process_shader_version);338}339if (volumetric_fog.volume_ubo.is_valid()) {340RD::get_singleton()->free(volumetric_fog.volume_ubo);341}342if (volumetric_fog.params_ubo.is_valid()) {343RD::get_singleton()->free(volumetric_fog.params_ubo);344}345if (volumetric_fog.default_shader.is_valid()) {346material_storage->shader_free(volumetric_fog.default_shader);347}348if (volumetric_fog.default_material.is_valid()) {349material_storage->material_free(volumetric_fog.default_material);350}351}352353void Fog::FogShaderData::set_code(const String &p_code) {354//compile355356code = p_code;357valid = false;358ubo_size = 0;359uniforms.clear();360361if (code.is_empty()) {362return; //just invalid, but no error363}364365ShaderCompiler::GeneratedCode gen_code;366ShaderCompiler::IdentifierActions actions;367actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE;368369uses_time = false;370371actions.usage_flag_pointers["TIME"] = &uses_time;372373actions.uniforms = &uniforms;374375Fog *fog_singleton = Fog::get_singleton();376377Error err = fog_singleton->volumetric_fog.compiler.compile(RS::SHADER_FOG, code, &actions, path, gen_code);378ERR_FAIL_COND_MSG(err != OK, "Fog shader compilation failed.");379380if (version.is_null()) {381version = fog_singleton->volumetric_fog.shader.version_create();382}383384fog_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);385ERR_FAIL_COND(!fog_singleton->volumetric_fog.shader.version_is_valid(version));386387ubo_size = gen_code.uniform_total_size;388ubo_offsets = gen_code.uniform_offsets;389texture_uniforms = gen_code.texture_uniforms;390391pipeline = RD::get_singleton()->compute_pipeline_create(fog_singleton->volumetric_fog.shader.version_get_shader(version, _get_fog_variant()));392393valid = true;394}395396bool Fog::FogShaderData::is_animated() const {397return false;398}399400bool Fog::FogShaderData::casts_shadows() const {401return false;402}403404RS::ShaderNativeSourceCode Fog::FogShaderData::get_native_source_code() const {405Fog *fog_singleton = Fog::get_singleton();406407return fog_singleton->volumetric_fog.shader.version_get_native_source_code(version);408}409410Pair<ShaderRD *, RID> Fog::FogShaderData::get_native_shader_and_version() const {411Fog *fog_singleton = Fog::get_singleton();412return { &fog_singleton->volumetric_fog.shader, version };413}414415Fog::FogShaderData::~FogShaderData() {416Fog *fog_singleton = Fog::get_singleton();417ERR_FAIL_NULL(fog_singleton);418//pipeline variants will clear themselves if shader is gone419if (version.is_valid()) {420fog_singleton->volumetric_fog.shader.version_free(version);421}422}423424////////////////////////////////////////////////////////////////////////////////425// Volumetric Fog426427bool Fog::VolumetricFog::sync_gi_dependent_sets_validity(bool p_ensure_freed) {428bool null = gi_dependent_sets.process_uniform_set_density.is_null();429bool valid = !null && RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set_density);430431#ifdef DEV_ENABLED432// It's all-or-nothing, or something else has changed that requires dev attention.433DEV_ASSERT(null == gi_dependent_sets.process_uniform_set.is_null());434DEV_ASSERT(null == gi_dependent_sets.process_uniform_set2.is_null());435DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set));436DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set2));437#endif438439if (valid) {440if (p_ensure_freed) {441RD::get_singleton()->free(gi_dependent_sets.process_uniform_set_density);442RD::get_singleton()->free(gi_dependent_sets.process_uniform_set);443RD::get_singleton()->free(gi_dependent_sets.process_uniform_set2);444valid = false;445}446}447448if (!valid && !null) {449gi_dependent_sets = {};450}451452return valid;453}454455void Fog::VolumetricFog::init(const Vector3i &fog_size, RID p_sky_shader) {456width = fog_size.x;457height = fog_size.y;458depth = fog_size.z;459atomic_type = RD::get_singleton()->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT) ? RD::UNIFORM_TYPE_IMAGE : RD::UNIFORM_TYPE_STORAGE_BUFFER;460461RD::TextureFormat tf;462tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;463tf.width = fog_size.x;464tf.height = fog_size.y;465tf.depth = fog_size.z;466tf.texture_type = RD::TEXTURE_TYPE_3D;467tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;468469light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());470RD::get_singleton()->set_resource_name(light_density_map, "Fog light-density map");471472tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;473474prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());475RD::get_singleton()->set_resource_name(prev_light_density_map, "Fog previous light-density map");476RD::get_singleton()->texture_clear(prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);477478tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;479480fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());481RD::get_singleton()->set_resource_name(fog_map, "Fog map");482483if (atomic_type == RD::UNIFORM_TYPE_STORAGE_BUFFER) {484Vector<uint8_t> dm;485dm.resize_initialized(fog_size.x * fog_size.y * fog_size.z * 4);486487density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);488RD::get_singleton()->set_resource_name(density_map, "Fog density map");489light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);490RD::get_singleton()->set_resource_name(light_map, "Fog light map");491emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);492RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");493} else {494tf.format = RD::DATA_FORMAT_R32_UINT;495tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_ATOMIC_BIT;496density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());497RD::get_singleton()->set_resource_name(density_map, "Fog density map");498RD::get_singleton()->texture_clear(density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);499light_map = RD::get_singleton()->texture_create(tf, RD::TextureView());500RD::get_singleton()->set_resource_name(light_map, "Fog light map");501RD::get_singleton()->texture_clear(light_map, Color(0, 0, 0, 0), 0, 1, 0, 1);502emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView());503RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");504RD::get_singleton()->texture_clear(emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1);505}506507Vector<RD::Uniform> uniforms;508{509RD::Uniform u;510u.binding = 0;511u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;512u.append_id(fog_map);513uniforms.push_back(u);514}515516sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_sky_shader, RendererRD::SkyRD::SKY_SET_FOG);517}518519Fog::VolumetricFog::~VolumetricFog() {520RD::get_singleton()->free(prev_light_density_map);521RD::get_singleton()->free(light_density_map);522RD::get_singleton()->free(fog_map);523RD::get_singleton()->free(density_map);524RD::get_singleton()->free(light_map);525RD::get_singleton()->free(emissive_map);526527if (fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog_uniform_set)) {528RD::get_singleton()->free(fog_uniform_set);529}530if (copy_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(copy_uniform_set)) {531RD::get_singleton()->free(copy_uniform_set);532}533534sync_gi_dependent_sets_validity(true);535536if (sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_uniform_set)) {537RD::get_singleton()->free(sdfgi_uniform_set);538}539if (sky_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_uniform_set)) {540RD::get_singleton()->free(sky_uniform_set);541}542}543544Vector3i 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) {545Vector3 view_position = p_cam_transform.affine_inverse().xform(p_point);546view_position.z = MIN(view_position.z, -0.01); // Clamp to the front of camera547Vector3 fog_position = Vector3(0, 0, 0);548549view_position.y = -view_position.y;550fog_position.z = -view_position.z / fog_end;551fog_position.x = (view_position.x / (2 * (fog_near_size.x * (1.0 - fog_position.z) + fog_far_size.x * fog_position.z))) + 0.5;552fog_position.y = (view_position.y / (2 * (fog_near_size.y * (1.0 - fog_position.z) + fog_far_size.y * fog_position.z))) + 0.5;553fog_position.z = Math::pow(float(fog_position.z), float(1.0 / volumetric_fog_detail_spread));554fog_position = fog_position * fog_size - Vector3(0.5, 0.5, 0.5);555556fog_position = fog_position.clamp(Vector3(), fog_size);557558return Vector3i(fog_position);559}560561void 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) {562RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();563RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();564565RENDER_TIMESTAMP("> Volumetric Fog");566RD::get_singleton()->draw_command_begin_label("Volumetric Fog");567568Ref<VolumetricFog> fog = p_settings.vfog;569570if (p_fog_volumes.size() > 0) {571RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes");572573RENDER_TIMESTAMP("Render FogVolumes");574575VolumetricFogShader::VolumeUBO params;576577Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents();578Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents();579float z_near = p_cam_projection.get_z_near();580float z_far = p_cam_projection.get_z_far();581float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env);582583Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near));584Vector2 fog_near_size;585if (p_cam_projection.is_orthogonal()) {586fog_near_size = fog_far_size;587} else {588fog_near_size = frustum_near_size.maxf(0.001);589}590591params.fog_frustum_size_begin[0] = fog_near_size.x;592params.fog_frustum_size_begin[1] = fog_near_size.y;593594params.fog_frustum_size_end[0] = fog_far_size.x;595params.fog_frustum_size_end[1] = fog_far_size.y;596597params.fog_frustum_end = fog_end;598params.z_near = z_near;599params.z_far = z_far;600params.time = p_settings.time;601602params.fog_volume_size[0] = fog->width;603params.fog_volume_size[1] = fog->height;604params.fog_volume_size[2] = fog->depth;605606params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env);607params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;608params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);609params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env);610611Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;612RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);613RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform);614615RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms);616617if (fog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->fog_uniform_set)) {618Vector<RD::Uniform> uniforms;619620{621RD::Uniform u;622u.uniform_type = fog->atomic_type;623u.binding = 1;624u.append_id(fog->emissive_map);625uniforms.push_back(u);626}627628{629RD::Uniform u;630u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;631u.binding = 2;632u.append_id(volumetric_fog.volume_ubo);633uniforms.push_back(u);634}635636{637RD::Uniform u;638u.uniform_type = fog->atomic_type;639u.binding = 3;640u.append_id(fog->density_map);641uniforms.push_back(u);642}643644{645RD::Uniform u;646u.uniform_type = fog->atomic_type;647u.binding = 4;648u.append_id(fog->light_map);649uniforms.push_back(u);650}651652fog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS);653}654655RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();656bool any_uses_time = false;657Vector3 cam_position = p_cam_transform.get_origin();658659for (int i = 0; i < (int)p_fog_volumes.size(); i++) {660FogVolumeInstance *fog_volume_instance = fog_volume_instance_owner.get_or_null(p_fog_volumes[i]);661ERR_FAIL_NULL(fog_volume_instance);662RID fog_volume = fog_volume_instance->volume;663664RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume);665666FogMaterialData *material = nullptr;667668if (fog_material.is_valid()) {669material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG));670if (!material || !material->shader_data->valid) {671material = nullptr;672}673}674675if (!material) {676fog_material = volumetric_fog.default_material;677material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG));678}679680ERR_FAIL_NULL(material);681682FogShaderData *shader_data = material->shader_data;683684ERR_FAIL_NULL(shader_data);685686any_uses_time |= shader_data->uses_time;687688Vector3i froxel_min;689Vector3i froxel_max;690Vector3i kernel_size;691692Vector3 fog_position = fog_volume_instance->transform.get_origin();693RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume);694Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_size(fog_volume) / 2;695696if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {697// Local fog volume.698Vector3 fog_size = Vector3(fog->width, fog->height, fog->depth);699float volumetric_fog_detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);700Vector3 corners[8]{701fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)),702fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)),703fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)),704fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)),705fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)),706fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)),707fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)),708fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z))709};710Vector3i froxels[8];711Vector3 corner_min = corners[0];712Vector3 corner_max = corners[0];713for (int j = 0; j < 8; j++) {714froxels[j] = _point_get_position_in_froxel_volume(corners[j], fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);715corner_min = corner_min.min(corners[j]);716corner_max = corner_max.max(corners[j]);717}718719froxel_min = Vector3i(int32_t(fog->width) - 1, int32_t(fog->height) - 1, int32_t(fog->depth) - 1);720froxel_max = Vector3i(1, 1, 1);721722// Tracking just the corners of the fog volume can result in missing some fog:723// when the camera's near plane is inside the fog, we must always consider the entire screen724Vector3 near_plane_corner(frustum_near_size.x, frustum_near_size.y, z_near);725float expand = near_plane_corner.length();726if (cam_position.x > (corner_min.x - expand) && cam_position.x < (corner_max.x + expand) &&727cam_position.y > (corner_min.y - expand) && cam_position.y < (corner_max.y + expand) &&728cam_position.z > (corner_min.z - expand) && cam_position.z < (corner_max.z + expand)) {729froxel_min.x = 0;730froxel_min.y = 0;731froxel_min.z = 0;732froxel_max.x = int32_t(fog->width);733froxel_max.y = int32_t(fog->height);734for (int j = 0; j < 8; j++) {735froxel_max.z = MAX(froxel_max.z, froxels[j].z);736}737} else {738// Camera is guaranteed to be outside the fog volume739for (int j = 0; j < 8; j++) {740froxel_min = froxel_min.min(froxels[j]);741froxel_max = froxel_max.max(froxels[j]);742}743}744745kernel_size = froxel_max - froxel_min;746} else {747// Volume type global runs on all cells748extents = Vector3(fog->width, fog->height, fog->depth);749froxel_min = Vector3i(0, 0, 0);750kernel_size = Vector3i(int32_t(fog->width), int32_t(fog->height), int32_t(fog->depth));751}752753if (kernel_size.x == 0 || kernel_size.y == 0 || kernel_size.z == 0) {754continue;755}756757VolumetricFogShader::FogPushConstant push_constant;758push_constant.position[0] = fog_position.x;759push_constant.position[1] = fog_position.y;760push_constant.position[2] = fog_position.z;761push_constant.size[0] = extents.x * 2;762push_constant.size[1] = extents.y * 2;763push_constant.size[2] = extents.z * 2;764push_constant.corner[0] = froxel_min.x;765push_constant.corner[1] = froxel_min.y;766push_constant.corner[2] = froxel_min.z;767push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume));768RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), push_constant.transform);769770RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline);771772RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS);773RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::FogPushConstant));774RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE);775if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set.776RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL);777material->set_as_used();778}779780RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z);781}782if (any_uses_time || RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) {783RenderingServerDefault::redraw_request();784}785786RD::get_singleton()->draw_command_end_label();787788RD::get_singleton()->compute_list_end();789}790791bool gi_dependent_sets_valid = fog->sync_gi_dependent_sets_validity();792if (!fog->copy_uniform_set.is_null() && !RD::get_singleton()->uniform_set_is_valid(fog->copy_uniform_set)) {793fog->copy_uniform_set = RID();794}795if (!gi_dependent_sets_valid || fog->copy_uniform_set.is_null()) {796//re create uniform set if needed797Vector<RD::Uniform> uniforms;798Vector<RD::Uniform> copy_uniforms;799800{801RD::Uniform u;802u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;803u.binding = 1;804if (p_settings.shadow_atlas_depth.is_null()) {805u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK));806} else {807u.append_id(p_settings.shadow_atlas_depth);808}809810uniforms.push_back(u);811copy_uniforms.push_back(u);812}813814{815RD::Uniform u;816u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;817u.binding = 2;818if (p_settings.directional_shadow_depth.is_valid()) {819u.append_id(p_settings.directional_shadow_depth);820} else {821u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK));822}823uniforms.push_back(u);824copy_uniforms.push_back(u);825}826827{828RD::Uniform u;829u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;830u.binding = 3;831u.append_id(p_settings.omni_light_buffer);832uniforms.push_back(u);833copy_uniforms.push_back(u);834}835{836RD::Uniform u;837u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;838u.binding = 4;839u.append_id(p_settings.spot_light_buffer);840uniforms.push_back(u);841copy_uniforms.push_back(u);842}843844{845RD::Uniform u;846u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;847u.binding = 5;848u.append_id(p_settings.directional_light_buffer);849uniforms.push_back(u);850copy_uniforms.push_back(u);851}852853{854RD::Uniform u;855u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;856u.binding = 6;857u.append_id(p_settings.cluster_builder->get_cluster_buffer());858uniforms.push_back(u);859copy_uniforms.push_back(u);860}861862{863RD::Uniform u;864u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;865u.binding = 7;866u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));867uniforms.push_back(u);868copy_uniforms.push_back(u);869}870871{872RD::Uniform u;873u.uniform_type = RD::UNIFORM_TYPE_IMAGE;874u.binding = 8;875u.append_id(fog->light_density_map);876uniforms.push_back(u);877copy_uniforms.push_back(u);878}879880{881RD::Uniform u;882u.uniform_type = RD::UNIFORM_TYPE_IMAGE;883u.binding = 9;884u.append_id(fog->fog_map);885uniforms.push_back(u);886}887888{889RD::Uniform u;890u.uniform_type = RD::UNIFORM_TYPE_IMAGE;891u.binding = 9;892u.append_id(fog->prev_light_density_map);893copy_uniforms.push_back(u);894}895896{897RD::Uniform u;898u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;899u.binding = 10;900u.append_id(p_settings.shadow_sampler);901uniforms.push_back(u);902copy_uniforms.push_back(u);903}904905{906RD::Uniform u;907u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;908u.binding = 11;909u.append_id(p_settings.voxel_gi_buffer);910uniforms.push_back(u);911copy_uniforms.push_back(u);912}913914{915RD::Uniform u;916u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;917u.binding = 12;918for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) {919u.append_id(p_settings.rbgi->voxel_gi_textures[i]);920}921uniforms.push_back(u);922copy_uniforms.push_back(u);923}924{925RD::Uniform u;926u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;927u.binding = 13;928u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));929uniforms.push_back(u);930copy_uniforms.push_back(u);931}932{933RD::Uniform u;934u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;935u.binding = 14;936u.append_id(volumetric_fog.params_ubo);937uniforms.push_back(u);938copy_uniforms.push_back(u);939}940{941RD::Uniform u;942u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;943u.binding = 15;944u.append_id(fog->prev_light_density_map);945uniforms.push_back(u);946}947{948RD::Uniform u;949u.uniform_type = fog->atomic_type;950u.binding = 16;951u.append_id(fog->density_map);952uniforms.push_back(u);953}954{955RD::Uniform u;956u.uniform_type = fog->atomic_type;957u.binding = 17;958u.append_id(fog->light_map);959uniforms.push_back(u);960}961962{963RD::Uniform u;964u.uniform_type = fog->atomic_type;965u.binding = 18;966u.append_id(fog->emissive_map);967uniforms.push_back(u);968}969970{971RD::Uniform u;972u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;973u.binding = 19;974RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_cubemap_array ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);975RID sky_texture = RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env).is_valid() ? p_settings.sky->sky_get_radiance_texture_rd(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env)) : RID();976u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture);977uniforms.push_back(u);978}979980if (fog->copy_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog->copy_uniform_set)) {981RD::get_singleton()->free(fog->copy_uniform_set);982}983fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, _get_fog_process_variant(VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY)), 0);984985if (!gi_dependent_sets_valid) {986fog->gi_dependent_sets.process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, _get_fog_process_variant(VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG)), 0);987988RID aux7 = uniforms.write[7].get_id(0);989RID aux8 = uniforms.write[8].get_id(0);990991uniforms.write[7].set_id(0, aux8);992uniforms.write[8].set_id(0, aux7);993994fog->gi_dependent_sets.process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, _get_fog_process_variant(VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG)), 0);995996uniforms.remove_at(8);997uniforms.write[7].set_id(0, aux7);998fog->gi_dependent_sets.process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, _get_fog_process_variant(VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY)), 0);999}1000}10011002bool using_sdfgi = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.0001 && RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_enabled(p_settings.env) && (p_settings.sdfgi.is_valid());10031004if (using_sdfgi) {1005if (fog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->sdfgi_uniform_set)) {1006Vector<RD::Uniform> uniforms;10071008{1009RD::Uniform u;1010u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1011u.binding = 0;1012u.append_id(p_settings.gi->sdfgi_ubo);1013uniforms.push_back(u);1014}10151016{1017RD::Uniform u;1018u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1019u.binding = 1;1020u.append_id(p_settings.sdfgi->ambient_texture);1021uniforms.push_back(u);1022}10231024{1025RD::Uniform u;1026u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1027u.binding = 2;1028u.append_id(p_settings.sdfgi->occlusion_texture);1029uniforms.push_back(u);1030}10311032fog->sdfgi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, _get_fog_process_variant(VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI)), 1);1033}1034}10351036fog->length = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env);1037fog->spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);10381039VolumetricFogShader::ParamsUBO params;10401041Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents();1042Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents();1043float z_near = p_cam_projection.get_z_near();1044float z_far = p_cam_projection.get_z_far();1045float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env);10461047Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near));1048Vector2 fog_near_size;1049if (p_cam_projection.is_orthogonal()) {1050fog_near_size = fog_far_size;1051} else {1052fog_near_size = frustum_near_size.maxf(0.001);1053}10541055params.fog_frustum_size_begin[0] = fog_near_size.x;1056params.fog_frustum_size_begin[1] = fog_near_size.y;10571058params.fog_frustum_size_end[0] = fog_far_size.x;1059params.fog_frustum_size_end[1] = fog_far_size.y;10601061params.ambient_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_ambient_inject(p_settings.env) * RendererSceneRenderRD::get_singleton()->environment_get_ambient_light_energy(p_settings.env);1062params.z_far = z_far;10631064params.fog_frustum_end = fog_end;10651066Color ambient_color = RendererSceneRenderRD::get_singleton()->environment_get_ambient_light(p_settings.env).srgb_to_linear();1067params.ambient_color[0] = ambient_color.r;1068params.ambient_color[1] = ambient_color.g;1069params.ambient_color[2] = ambient_color.b;1070params.sky_contribution = RendererSceneRenderRD::get_singleton()->environment_get_ambient_sky_contribution(p_settings.env);10711072params.fog_volume_size[0] = fog->width;1073params.fog_volume_size[1] = fog->height;1074params.fog_volume_size[2] = fog->depth;10751076params.directional_light_count = p_directional_light_count;10771078Color emission = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission(p_settings.env).srgb_to_linear();1079params.base_emission[0] = emission.r * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env);1080params.base_emission[1] = emission.g * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env);1081params.base_emission[2] = emission.b * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env);1082params.base_density = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_density(p_settings.env);10831084Color base_scattering = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_scattering(p_settings.env).srgb_to_linear();1085params.base_scattering[0] = base_scattering.r;1086params.base_scattering[1] = base_scattering.g;1087params.base_scattering[2] = base_scattering.b;1088params.phase_g = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_anisotropy(p_settings.env);10891090params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);1091params.gi_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env);10921093params.cam_rotation[0] = p_cam_transform.basis[0][0];1094params.cam_rotation[1] = p_cam_transform.basis[1][0];1095params.cam_rotation[2] = p_cam_transform.basis[2][0];1096params.cam_rotation[3] = 0;1097params.cam_rotation[4] = p_cam_transform.basis[0][1];1098params.cam_rotation[5] = p_cam_transform.basis[1][1];1099params.cam_rotation[6] = p_cam_transform.basis[2][1];1100params.cam_rotation[7] = 0;1101params.cam_rotation[8] = p_cam_transform.basis[0][2];1102params.cam_rotation[9] = p_cam_transform.basis[1][2];1103params.cam_rotation[10] = p_cam_transform.basis[2][2];1104params.cam_rotation[11] = 0;1105params.filter_axis = 0;1106params.max_voxel_gi_instances = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.001 ? p_voxel_gi_count : 0;1107params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;11081109Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;1110RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);11111112params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env);1113params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env);11141115{1116uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size();1117params.cluster_shift = get_shift_from_power_of_2(cluster_size);11181119uint32_t cluster_screen_width = Math::division_round_up((uint32_t)p_settings.rb_size.x, cluster_size);1120uint32_t cluster_screen_height = Math::division_round_up((uint32_t)p_settings.rb_size.y, cluster_size);1121params.max_cluster_element_count_div_32 = p_settings.max_cluster_elements / 32;1122params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32);1123params.cluster_width = cluster_screen_width;11241125params.screen_size[0] = p_settings.rb_size.x;1126params.screen_size[1] = p_settings.rb_size.y;1127}11281129Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_settings.env);1130sky_transform = sky_transform.inverse() * p_cam_transform.basis;1131RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform);11321133RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog");11341135RENDER_TIMESTAMP("Render Fog");1136RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms);11371138RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();11391140RD::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]);11411142RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set_density, 0);11431144if (using_sdfgi) {1145RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->sdfgi_uniform_set, 1);1146}1147RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);1148RD::get_singleton()->compute_list_add_barrier(compute_list);11491150// Copy fog to history buffer1151if (RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) {1152RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]);1153RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->copy_uniform_set, 0);1154RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);1155RD::get_singleton()->compute_list_add_barrier(compute_list);1156}1157RD::get_singleton()->draw_command_end_label();11581159if (p_settings.volumetric_fog_filter_active) {1160RD::get_singleton()->draw_command_begin_label("Filter Fog");11611162RENDER_TIMESTAMP("Filter Fog");11631164RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);1165RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0);1166RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);11671168RD::get_singleton()->compute_list_end();1169//need restart for buffer update11701171params.filter_axis = 1;1172RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms);11731174compute_list = RD::get_singleton()->compute_list_begin();1175RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);1176RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set2, 0);1177RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);11781179RD::get_singleton()->compute_list_add_barrier(compute_list);1180RD::get_singleton()->draw_command_end_label();1181}11821183RENDER_TIMESTAMP("Integrate Fog");1184RD::get_singleton()->draw_command_begin_label("Integrate Fog");11851186RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]);1187RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0);1188RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, 1);11891190RD::get_singleton()->compute_list_end();11911192RENDER_TIMESTAMP("< Volumetric Fog");1193RD::get_singleton()->draw_command_end_label();1194RD::get_singleton()->draw_command_end_label();1195}119611971198