Path: blob/master/servers/rendering/renderer_rd/environment/fog.cpp
20897 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_octmap_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_octmap_array) {305defines += "\n#define USE_RADIANCE_OCTMAP_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].create_compute_pipeline(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();335for (int i = 0; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) {336volumetric_fog.process_pipelines[i].free();337}338if (volumetric_fog.process_shader_version.is_valid()) {339volumetric_fog.process_shader.version_free(volumetric_fog.process_shader_version);340}341if (volumetric_fog.volume_ubo.is_valid()) {342RD::get_singleton()->free_rid(volumetric_fog.volume_ubo);343}344if (volumetric_fog.params_ubo.is_valid()) {345RD::get_singleton()->free_rid(volumetric_fog.params_ubo);346}347if (volumetric_fog.default_shader.is_valid()) {348material_storage->shader_free(volumetric_fog.default_shader);349}350if (volumetric_fog.default_material.is_valid()) {351material_storage->material_free(volumetric_fog.default_material);352}353}354355void Fog::FogShaderData::set_code(const String &p_code) {356//compile357358code = p_code;359valid = false;360ubo_size = 0;361uniforms.clear();362363if (code.is_empty()) {364return; //just invalid, but no error365}366367ShaderCompiler::GeneratedCode gen_code;368ShaderCompiler::IdentifierActions actions;369actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE;370371uses_time = false;372373actions.usage_flag_pointers["TIME"] = &uses_time;374375actions.uniforms = &uniforms;376377Fog *fog_singleton = Fog::get_singleton();378379Error err = fog_singleton->volumetric_fog.compiler.compile(RS::SHADER_FOG, code, &actions, path, gen_code);380ERR_FAIL_COND_MSG(err != OK, "Fog shader compilation failed.");381382if (version.is_null()) {383version = fog_singleton->volumetric_fog.shader.version_create();384} else {385pipeline.free();386}387388fog_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);389ERR_FAIL_COND(!fog_singleton->volumetric_fog.shader.version_is_valid(version));390391ubo_size = gen_code.uniform_total_size;392ubo_offsets = gen_code.uniform_offsets;393texture_uniforms = gen_code.texture_uniforms;394395pipeline.create_compute_pipeline(fog_singleton->volumetric_fog.shader.version_get_shader(version, _get_fog_variant()));396397valid = true;398}399400bool Fog::FogShaderData::is_animated() const {401return false;402}403404bool Fog::FogShaderData::casts_shadows() const {405return false;406}407408RS::ShaderNativeSourceCode Fog::FogShaderData::get_native_source_code() const {409Fog *fog_singleton = Fog::get_singleton();410411return fog_singleton->volumetric_fog.shader.version_get_native_source_code(version);412}413414Pair<ShaderRD *, RID> Fog::FogShaderData::get_native_shader_and_version() const {415Fog *fog_singleton = Fog::get_singleton();416return { &fog_singleton->volumetric_fog.shader, version };417}418419Fog::FogShaderData::~FogShaderData() {420pipeline.free();421422Fog *fog_singleton = Fog::get_singleton();423ERR_FAIL_NULL(fog_singleton);424if (version.is_valid()) {425fog_singleton->volumetric_fog.shader.version_free(version);426}427}428429////////////////////////////////////////////////////////////////////////////////430// Volumetric Fog431432bool Fog::VolumetricFog::sync_gi_dependent_sets_validity(bool p_ensure_freed) {433bool null = gi_dependent_sets.process_uniform_set_density.is_null();434bool valid = !null && RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set_density);435436#ifdef DEV_ENABLED437// It's all-or-nothing, or something else has changed that requires dev attention.438DEV_ASSERT(null == gi_dependent_sets.process_uniform_set.is_null());439DEV_ASSERT(null == gi_dependent_sets.process_uniform_set2.is_null());440DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set));441DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set2));442#endif443444if (valid) {445if (p_ensure_freed) {446RD::get_singleton()->free_rid(gi_dependent_sets.process_uniform_set_density);447RD::get_singleton()->free_rid(gi_dependent_sets.process_uniform_set);448RD::get_singleton()->free_rid(gi_dependent_sets.process_uniform_set2);449valid = false;450}451}452453if (!valid && !null) {454gi_dependent_sets = {};455}456457return valid;458}459460void Fog::VolumetricFog::init(const Vector3i &fog_size, RID p_sky_shader) {461width = fog_size.x;462height = fog_size.y;463depth = fog_size.z;464atomic_type = RD::get_singleton()->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT) ? RD::UNIFORM_TYPE_IMAGE : RD::UNIFORM_TYPE_STORAGE_BUFFER;465466RD::TextureFormat tf;467tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;468tf.width = fog_size.x;469tf.height = fog_size.y;470tf.depth = fog_size.z;471tf.texture_type = RD::TEXTURE_TYPE_3D;472tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;473474light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());475RD::get_singleton()->set_resource_name(light_density_map, "Fog light-density map");476477tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;478479prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());480RD::get_singleton()->set_resource_name(prev_light_density_map, "Fog previous light-density map");481RD::get_singleton()->texture_clear(prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);482483tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;484485fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());486RD::get_singleton()->set_resource_name(fog_map, "Fog map");487488if (atomic_type == RD::UNIFORM_TYPE_STORAGE_BUFFER) {489Vector<uint8_t> dm;490dm.resize_initialized(fog_size.x * fog_size.y * fog_size.z * 4);491492density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);493RD::get_singleton()->set_resource_name(density_map, "Fog density map");494light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);495RD::get_singleton()->set_resource_name(light_map, "Fog light map");496emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm);497RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");498} else {499tf.format = RD::DATA_FORMAT_R32_UINT;500tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_ATOMIC_BIT;501density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());502RD::get_singleton()->set_resource_name(density_map, "Fog density map");503RD::get_singleton()->texture_clear(density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);504light_map = RD::get_singleton()->texture_create(tf, RD::TextureView());505RD::get_singleton()->set_resource_name(light_map, "Fog light map");506RD::get_singleton()->texture_clear(light_map, Color(0, 0, 0, 0), 0, 1, 0, 1);507emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView());508RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map");509RD::get_singleton()->texture_clear(emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1);510}511512Vector<RD::Uniform> uniforms;513{514RD::Uniform u;515u.binding = 0;516u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;517u.append_id(fog_map);518uniforms.push_back(u);519}520521sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_sky_shader, RendererRD::SkyRD::SKY_SET_FOG);522}523524Fog::VolumetricFog::~VolumetricFog() {525RD::get_singleton()->free_rid(prev_light_density_map);526RD::get_singleton()->free_rid(light_density_map);527RD::get_singleton()->free_rid(fog_map);528RD::get_singleton()->free_rid(density_map);529RD::get_singleton()->free_rid(light_map);530RD::get_singleton()->free_rid(emissive_map);531532if (fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog_uniform_set)) {533RD::get_singleton()->free_rid(fog_uniform_set);534}535if (copy_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(copy_uniform_set)) {536RD::get_singleton()->free_rid(copy_uniform_set);537}538539sync_gi_dependent_sets_validity(true);540541if (sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_uniform_set)) {542RD::get_singleton()->free_rid(sdfgi_uniform_set);543}544if (sky_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_uniform_set)) {545RD::get_singleton()->free_rid(sky_uniform_set);546}547}548549Vector3i 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) {550Vector3 view_position = p_cam_transform.affine_inverse().xform(p_point);551view_position.z = MIN(view_position.z, -0.01); // Clamp to the front of camera552Vector3 fog_position = Vector3(0, 0, 0);553554view_position.y = -view_position.y;555fog_position.z = -view_position.z / fog_end;556fog_position.x = (view_position.x / (2 * (fog_near_size.x * (1.0 - fog_position.z) + fog_far_size.x * fog_position.z))) + 0.5;557fog_position.y = (view_position.y / (2 * (fog_near_size.y * (1.0 - fog_position.z) + fog_far_size.y * fog_position.z))) + 0.5;558fog_position.z = Math::pow(float(fog_position.z), float(1.0 / volumetric_fog_detail_spread));559fog_position = fog_position * fog_size - Vector3(0.5, 0.5, 0.5);560561fog_position = fog_position.clamp(Vector3(), fog_size);562563return Vector3i(fog_position);564}565566void 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) {567RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();568RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();569570RENDER_TIMESTAMP("> Volumetric Fog");571RD::get_singleton()->draw_command_begin_label("Volumetric Fog");572573Ref<VolumetricFog> fog = p_settings.vfog;574575if (p_fog_volumes.size() > 0) {576RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes");577578RENDER_TIMESTAMP("Render FogVolumes");579580VolumetricFogShader::VolumeUBO params;581582Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents();583Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents();584float z_near = p_cam_projection.get_z_near();585float z_far = p_cam_projection.get_z_far();586float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env);587588Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near));589Vector2 fog_near_size;590if (p_cam_projection.is_orthogonal()) {591fog_near_size = fog_far_size;592} else {593fog_near_size = frustum_near_size.maxf(0.001);594}595596params.fog_frustum_size_begin[0] = fog_near_size.x;597params.fog_frustum_size_begin[1] = fog_near_size.y;598599params.fog_frustum_size_end[0] = fog_far_size.x;600params.fog_frustum_size_end[1] = fog_far_size.y;601602params.fog_frustum_end = fog_end;603params.z_near = z_near;604params.z_far = z_far;605params.time = p_settings.time;606607params.fog_volume_size[0] = fog->width;608params.fog_volume_size[1] = fog->height;609params.fog_volume_size[2] = fog->depth;610611params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env);612params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;613params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);614params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env);615616Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;617RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);618RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform);619620RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms);621622if (fog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->fog_uniform_set)) {623Vector<RD::Uniform> uniforms;624625{626RD::Uniform u;627u.uniform_type = fog->atomic_type;628u.binding = 1;629u.append_id(fog->emissive_map);630uniforms.push_back(u);631}632633{634RD::Uniform u;635u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;636u.binding = 2;637u.append_id(volumetric_fog.volume_ubo);638uniforms.push_back(u);639}640641{642RD::Uniform u;643u.uniform_type = fog->atomic_type;644u.binding = 3;645u.append_id(fog->density_map);646uniforms.push_back(u);647}648649{650RD::Uniform u;651u.uniform_type = fog->atomic_type;652u.binding = 4;653u.append_id(fog->light_map);654uniforms.push_back(u);655}656657fog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS);658}659660RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();661bool any_uses_time = false;662Vector3 cam_position = p_cam_transform.get_origin();663664for (int i = 0; i < (int)p_fog_volumes.size(); i++) {665FogVolumeInstance *fog_volume_instance = fog_volume_instance_owner.get_or_null(p_fog_volumes[i]);666ERR_FAIL_NULL(fog_volume_instance);667RID fog_volume = fog_volume_instance->volume;668669RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume);670671FogMaterialData *material = nullptr;672673if (fog_material.is_valid()) {674material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG));675if (!material || !material->shader_data->valid) {676material = nullptr;677}678}679680if (!material) {681fog_material = volumetric_fog.default_material;682material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::MaterialStorage::SHADER_TYPE_FOG));683}684685ERR_FAIL_NULL(material);686687FogShaderData *shader_data = material->shader_data;688689ERR_FAIL_NULL(shader_data);690691any_uses_time |= shader_data->uses_time;692693Vector3i froxel_min;694Vector3i froxel_max;695Vector3i kernel_size;696697Vector3 fog_position = fog_volume_instance->transform.get_origin();698RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume);699Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_size(fog_volume) / 2;700701if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {702// Local fog volume.703Vector3 fog_size = Vector3(fog->width, fog->height, fog->depth);704float volumetric_fog_detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);705Vector3 corners[8]{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)),709fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)),710fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)),711fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)),712fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)),713fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z))714};715Vector3i froxels[8];716Vector3 corner_min = corners[0];717Vector3 corner_max = corners[0];718for (int j = 0; j < 8; j++) {719froxels[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);720corner_min = corner_min.min(corners[j]);721corner_max = corner_max.max(corners[j]);722}723724froxel_min = Vector3i(int32_t(fog->width) - 1, int32_t(fog->height) - 1, int32_t(fog->depth) - 1);725froxel_max = Vector3i(1, 1, 1);726727// Tracking just the corners of the fog volume can result in missing some fog:728// when the camera's near plane is inside the fog, we must always consider the entire screen729Vector3 near_plane_corner(frustum_near_size.x, frustum_near_size.y, z_near);730float expand = near_plane_corner.length();731if (cam_position.x > (corner_min.x - expand) && cam_position.x < (corner_max.x + expand) &&732cam_position.y > (corner_min.y - expand) && cam_position.y < (corner_max.y + expand) &&733cam_position.z > (corner_min.z - expand) && cam_position.z < (corner_max.z + expand)) {734froxel_min.x = 0;735froxel_min.y = 0;736froxel_min.z = 0;737froxel_max.x = int32_t(fog->width);738froxel_max.y = int32_t(fog->height);739for (int j = 0; j < 8; j++) {740froxel_max.z = MAX(froxel_max.z, froxels[j].z);741}742} else {743// Camera is guaranteed to be outside the fog volume744for (int j = 0; j < 8; j++) {745froxel_min = froxel_min.min(froxels[j]);746froxel_max = froxel_max.max(froxels[j]);747}748}749750kernel_size = froxel_max - froxel_min;751} else {752// Volume type global runs on all cells753extents = Vector3(fog->width, fog->height, fog->depth);754froxel_min = Vector3i(0, 0, 0);755kernel_size = Vector3i(int32_t(fog->width), int32_t(fog->height), int32_t(fog->depth));756}757758if (kernel_size.x == 0 || kernel_size.y == 0 || kernel_size.z == 0) {759continue;760}761762VolumetricFogShader::FogPushConstant push_constant;763push_constant.position[0] = fog_position.x;764push_constant.position[1] = fog_position.y;765push_constant.position[2] = fog_position.z;766push_constant.size[0] = extents.x * 2;767push_constant.size[1] = extents.y * 2;768push_constant.size[2] = extents.z * 2;769push_constant.corner[0] = froxel_min.x;770push_constant.corner[1] = froxel_min.y;771push_constant.corner[2] = froxel_min.z;772push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume));773RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), push_constant.transform);774775RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline.get_rid());776777RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS);778RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::FogPushConstant));779RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE);780if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set.781RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL);782material->set_as_used();783}784785RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z);786}787if (any_uses_time || RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) {788RenderingServerDefault::redraw_request();789}790791RD::get_singleton()->draw_command_end_label();792793RD::get_singleton()->compute_list_end();794}795796bool gi_dependent_sets_valid = fog->sync_gi_dependent_sets_validity();797if (!fog->copy_uniform_set.is_null() && !RD::get_singleton()->uniform_set_is_valid(fog->copy_uniform_set)) {798fog->copy_uniform_set = RID();799}800if (!gi_dependent_sets_valid || fog->copy_uniform_set.is_null()) {801//re create uniform set if needed802Vector<RD::Uniform> uniforms;803Vector<RD::Uniform> copy_uniforms;804805{806RD::Uniform u;807u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;808u.binding = 1;809if (p_settings.shadow_atlas_depth.is_null()) {810u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK));811} else {812u.append_id(p_settings.shadow_atlas_depth);813}814815uniforms.push_back(u);816copy_uniforms.push_back(u);817}818819{820RD::Uniform u;821u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;822u.binding = 2;823if (p_settings.directional_shadow_depth.is_valid()) {824u.append_id(p_settings.directional_shadow_depth);825} else {826u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK));827}828uniforms.push_back(u);829copy_uniforms.push_back(u);830}831832{833RD::Uniform u;834u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;835u.binding = 3;836u.append_id(p_settings.omni_light_buffer);837uniforms.push_back(u);838copy_uniforms.push_back(u);839}840{841RD::Uniform u;842u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;843u.binding = 4;844u.append_id(p_settings.spot_light_buffer);845uniforms.push_back(u);846copy_uniforms.push_back(u);847}848849{850RD::Uniform u;851u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;852u.binding = 5;853u.append_id(p_settings.directional_light_buffer);854uniforms.push_back(u);855copy_uniforms.push_back(u);856}857858{859RD::Uniform u;860u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;861u.binding = 6;862u.append_id(p_settings.cluster_builder->get_cluster_buffer());863uniforms.push_back(u);864copy_uniforms.push_back(u);865}866867{868RD::Uniform u;869u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;870u.binding = 7;871u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));872uniforms.push_back(u);873copy_uniforms.push_back(u);874}875876{877RD::Uniform u;878u.uniform_type = RD::UNIFORM_TYPE_IMAGE;879u.binding = 8;880u.append_id(fog->light_density_map);881uniforms.push_back(u);882copy_uniforms.push_back(u);883}884885{886RD::Uniform u;887u.uniform_type = RD::UNIFORM_TYPE_IMAGE;888u.binding = 9;889u.append_id(fog->fog_map);890uniforms.push_back(u);891}892893{894RD::Uniform u;895u.uniform_type = RD::UNIFORM_TYPE_IMAGE;896u.binding = 9;897u.append_id(fog->prev_light_density_map);898copy_uniforms.push_back(u);899}900901{902RD::Uniform u;903u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;904u.binding = 10;905u.append_id(p_settings.shadow_sampler);906uniforms.push_back(u);907copy_uniforms.push_back(u);908}909910{911RD::Uniform u;912u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;913u.binding = 11;914u.append_id(p_settings.voxel_gi_buffer);915uniforms.push_back(u);916copy_uniforms.push_back(u);917}918919{920RD::Uniform u;921u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;922u.binding = 12;923for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) {924u.append_id(p_settings.rbgi->voxel_gi_textures[i]);925}926uniforms.push_back(u);927copy_uniforms.push_back(u);928}929{930RD::Uniform u;931u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;932u.binding = 13;933u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));934uniforms.push_back(u);935copy_uniforms.push_back(u);936}937{938RD::Uniform u;939u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;940u.binding = 14;941u.append_id(volumetric_fog.params_ubo);942uniforms.push_back(u);943copy_uniforms.push_back(u);944}945{946RD::Uniform u;947u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;948u.binding = 15;949u.append_id(fog->prev_light_density_map);950uniforms.push_back(u);951}952{953RD::Uniform u;954u.uniform_type = fog->atomic_type;955u.binding = 16;956u.append_id(fog->density_map);957uniforms.push_back(u);958}959{960RD::Uniform u;961u.uniform_type = fog->atomic_type;962u.binding = 17;963u.append_id(fog->light_map);964uniforms.push_back(u);965}966967{968RD::Uniform u;969u.uniform_type = fog->atomic_type;970u.binding = 18;971u.append_id(fog->emissive_map);972uniforms.push_back(u);973}974975{976RD::Uniform u;977u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;978u.binding = 19;979RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_octmap_array ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);980RID 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();981u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture);982uniforms.push_back(u);983}984985if (fog->copy_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog->copy_uniform_set)) {986RD::get_singleton()->free_rid(fog->copy_uniform_set);987}988fog->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);989990if (!gi_dependent_sets_valid) {991fog->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);992993RID aux7 = uniforms.write[7].get_id(0);994RID aux8 = uniforms.write[8].get_id(0);995996uniforms.write[7].set_id(0, aux8);997uniforms.write[8].set_id(0, aux7);998999fog->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);10001001uniforms.remove_at(8);1002uniforms.write[7].set_id(0, aux7);1003fog->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);1004}1005}10061007bool 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());10081009if (using_sdfgi) {1010if (fog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->sdfgi_uniform_set)) {1011Vector<RD::Uniform> uniforms;10121013{1014RD::Uniform u;1015u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1016u.binding = 0;1017u.append_id(p_settings.gi->sdfgi_ubo);1018uniforms.push_back(u);1019}10201021{1022RD::Uniform u;1023u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1024u.binding = 1;1025u.append_id(p_settings.sdfgi->ambient_texture);1026uniforms.push_back(u);1027}10281029{1030RD::Uniform u;1031u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1032u.binding = 2;1033u.append_id(p_settings.sdfgi->occlusion_texture);1034uniforms.push_back(u);1035}10361037fog->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);1038}1039}10401041fog->length = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env);1042fog->spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);10431044VolumetricFogShader::ParamsUBO params;10451046Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents();1047Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents();1048float z_near = p_cam_projection.get_z_near();1049float z_far = p_cam_projection.get_z_far();1050float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env);10511052Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near));1053Vector2 fog_near_size;1054if (p_cam_projection.is_orthogonal()) {1055fog_near_size = fog_far_size;1056} else {1057fog_near_size = frustum_near_size.maxf(0.001);1058}10591060params.fog_frustum_size_begin[0] = fog_near_size.x;1061params.fog_frustum_size_begin[1] = fog_near_size.y;10621063params.fog_frustum_size_end[0] = fog_far_size.x;1064params.fog_frustum_size_end[1] = fog_far_size.y;10651066params.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);1067params.z_far = z_far;10681069params.fog_frustum_end = fog_end;10701071Color ambient_color = RendererSceneRenderRD::get_singleton()->environment_get_ambient_light(p_settings.env).srgb_to_linear();1072params.ambient_color[0] = ambient_color.r;1073params.ambient_color[1] = ambient_color.g;1074params.ambient_color[2] = ambient_color.b;1075params.sky_contribution = RendererSceneRenderRD::get_singleton()->environment_get_ambient_sky_contribution(p_settings.env);10761077params.fog_volume_size[0] = fog->width;1078params.fog_volume_size[1] = fog->height;1079params.fog_volume_size[2] = fog->depth;10801081params.directional_light_count = p_directional_light_count;10821083Color emission = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission(p_settings.env).srgb_to_linear();1084params.base_emission[0] = emission.r * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env);1085params.base_emission[1] = emission.g * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env);1086params.base_emission[2] = emission.b * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env);1087params.base_density = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_density(p_settings.env);10881089Color base_scattering = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_scattering(p_settings.env).srgb_to_linear();1090params.base_scattering[0] = base_scattering.r;1091params.base_scattering[1] = base_scattering.g;1092params.base_scattering[2] = base_scattering.b;1093params.phase_g = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_anisotropy(p_settings.env);10941095params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);1096params.gi_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env);10971098params.cam_rotation[0] = p_cam_transform.basis[0][0];1099params.cam_rotation[1] = p_cam_transform.basis[1][0];1100params.cam_rotation[2] = p_cam_transform.basis[2][0];1101params.cam_rotation[3] = 0;1102params.cam_rotation[4] = p_cam_transform.basis[0][1];1103params.cam_rotation[5] = p_cam_transform.basis[1][1];1104params.cam_rotation[6] = p_cam_transform.basis[2][1];1105params.cam_rotation[7] = 0;1106params.cam_rotation[8] = p_cam_transform.basis[0][2];1107params.cam_rotation[9] = p_cam_transform.basis[1][2];1108params.cam_rotation[10] = p_cam_transform.basis[2][2];1109params.cam_rotation[11] = 0;1110params.filter_axis = 0;1111params.max_voxel_gi_instances = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.001 ? p_voxel_gi_count : 0;1112params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;11131114Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;1115RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);11161117params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env);1118params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env);11191120RID sky_rid = RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env);1121if (sky_rid.is_valid()) {1122float uv_border_size = p_settings.sky->sky_get_uv_border_size(sky_rid);1123params.sky_border_size[0] = uv_border_size;1124params.sky_border_size[1] = 1.0f - uv_border_size * 2.0f;1125}11261127{1128uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size();1129params.cluster_shift = get_shift_from_power_of_2(cluster_size);11301131uint32_t cluster_screen_width = Math::division_round_up((uint32_t)p_settings.rb_size.x, cluster_size);1132uint32_t cluster_screen_height = Math::division_round_up((uint32_t)p_settings.rb_size.y, cluster_size);1133params.max_cluster_element_count_div_32 = p_settings.max_cluster_elements / 32;1134params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32);1135params.cluster_width = cluster_screen_width;11361137params.screen_size[0] = p_settings.rb_size.x;1138params.screen_size[1] = p_settings.rb_size.y;1139}11401141Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_settings.env);1142sky_transform = sky_transform.inverse() * p_cam_transform.basis;1143RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform);11441145RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog");11461147RENDER_TIMESTAMP("Render Fog");1148RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms);11491150RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();11511152RD::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].get_rid());11531154RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set_density, 0);11551156if (using_sdfgi) {1157RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->sdfgi_uniform_set, 1);1158}1159RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);1160RD::get_singleton()->compute_list_add_barrier(compute_list);11611162// Copy fog to history buffer1163if (RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) {1164RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY].get_rid());1165RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->copy_uniform_set, 0);1166RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);1167RD::get_singleton()->compute_list_add_barrier(compute_list);1168}1169RD::get_singleton()->draw_command_end_label();11701171if (p_settings.volumetric_fog_filter_active) {1172RD::get_singleton()->draw_command_begin_label("Filter Fog");11731174RENDER_TIMESTAMP("Filter Fog");11751176RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER].get_rid());1177RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0);1178RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);11791180RD::get_singleton()->compute_list_end();1181//need restart for buffer update11821183params.filter_axis = 1;1184RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms);11851186compute_list = RD::get_singleton()->compute_list_begin();1187RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER].get_rid());1188RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set2, 0);1189RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);11901191RD::get_singleton()->compute_list_add_barrier(compute_list);1192RD::get_singleton()->draw_command_end_label();1193}11941195RENDER_TIMESTAMP("Integrate Fog");1196RD::get_singleton()->draw_command_begin_label("Integrate Fog");11971198RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG].get_rid());1199RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0);1200RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, 1);12011202RD::get_singleton()->compute_list_end();12031204RENDER_TIMESTAMP("< Volumetric Fog");1205RD::get_singleton()->draw_command_end_label();1206RD::get_singleton()->draw_command_end_label();1207}120812091210