Path: blob/master/servers/rendering/renderer_rd/environment/fog.h
21403 views
/**************************************************************************/1/* fog.h */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#pragma once3132#include "core/templates/local_vector.h"33#include "core/templates/rid_owner.h"34#include "servers/rendering/environment/renderer_fog.h"35#include "servers/rendering/renderer_rd/cluster_builder_rd.h"36#include "servers/rendering/renderer_rd/environment/gi.h"37#include "servers/rendering/renderer_rd/pipeline_deferred_rd.h"38#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl.gen.h"39#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl.gen.h"40#include "servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h"41#include "servers/rendering/storage/utilities.h"4243#define RB_SCOPE_FOG SNAME("Fog")4445namespace RendererRD {4647class Fog : public RendererFog {48private:49static Fog *singleton;5051static int _get_fog_shader_group();52static int _get_fog_variant();53static int _get_fog_process_variant(int p_idx);5455/* FOG VOLUMES */5657struct FogVolume {58RID material;59Vector3 size = Vector3(2, 2, 2);6061RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;6263Dependency dependency;64};6566mutable RID_Owner<FogVolume, true> fog_volume_owner;6768struct FogVolumeInstance {69RID volume;70Transform3D transform;71bool active = false;72};7374mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner;7576const int SAMPLERS_BINDING_FIRST_INDEX = 3;7778/* Volumetric Fog */79struct VolumetricFogShader {80enum ShaderGroup {81SHADER_GROUP_BASE,82SHADER_GROUP_NO_ATOMICS,83SHADER_GROUP_VULKAN_MEMORY_MODEL,84SHADER_GROUP_VULKAN_MEMORY_MODEL_NO_ATOMICS,85};8687enum FogSet {88FOG_SET_BASE,89FOG_SET_UNIFORMS,90FOG_SET_MATERIAL,91FOG_SET_MAX,92};9394struct FogPushConstant {95float position[3];96float pad;9798float size[3];99float pad2;100101int32_t corner[3];102uint32_t shape;103104float transform[16];105};106107struct VolumeUBO {108float fog_frustum_size_begin[2];109float fog_frustum_size_end[2];110111float fog_frustum_end;112float z_near;113float z_far;114float time;115116int32_t fog_volume_size[3];117uint32_t directional_light_count;118119uint32_t use_temporal_reprojection;120uint32_t temporal_frame;121float detail_spread;122float temporal_blend;123124float to_prev_view[16];125float transform[16];126};127128ShaderCompiler compiler;129VolumetricFogShaderRD shader;130RID volume_ubo;131132RID default_shader;133RID default_material;134RID default_shader_rd;135136RID base_uniform_set;137138RID params_ubo;139140enum {141VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY,142VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI,143VOLUMETRIC_FOG_PROCESS_SHADER_FILTER,144VOLUMETRIC_FOG_PROCESS_SHADER_FOG,145VOLUMETRIC_FOG_PROCESS_SHADER_COPY,146VOLUMETRIC_FOG_PROCESS_SHADER_MAX,147};148149struct ParamsUBO {150float fog_frustum_size_begin[2];151float fog_frustum_size_end[2];152153float fog_frustum_end;154float ambient_inject;155float z_far;156uint32_t filter_axis;157158float ambient_color[3];159float sky_contribution;160161int32_t fog_volume_size[3];162uint32_t directional_light_count;163164float base_emission[3];165float base_density;166167float base_scattering[3];168float phase_g;169170float detail_spread;171float gi_inject;172uint32_t max_voxel_gi_instances;173uint32_t cluster_type_size;174175float screen_size[2];176uint32_t cluster_shift;177uint32_t cluster_width;178179uint32_t max_cluster_element_count_div_32;180uint32_t use_temporal_reprojection;181uint32_t temporal_frame;182float temporal_blend;183184float sky_border_size[2];185float pad[2];186187float cam_rotation[12];188float to_prev_view[16];189float radiance_inverse_xform[12];190};191192VolumetricFogProcessShaderRD process_shader;193194RID process_shader_version;195PipelineDeferredRD process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX];196197} volumetric_fog;198199Vector3i _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);200201struct FogShaderData : public RendererRD::MaterialStorage::ShaderData {202bool valid = false;203RID version;204205PipelineDeferredRD pipeline;206Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;207208Vector<uint32_t> ubo_offsets;209uint32_t ubo_size = 0;210211String code;212213bool uses_time = false;214215virtual void set_code(const String &p_Code);216virtual bool is_animated() const;217virtual bool casts_shadows() const;218virtual RS::ShaderNativeSourceCode get_native_source_code() const;219virtual Pair<ShaderRD *, RID> get_native_shader_and_version() const;220221FogShaderData() {}222virtual ~FogShaderData();223};224225struct FogMaterialData : public RendererRD::MaterialStorage::MaterialData {226FogShaderData *shader_data = nullptr;227RID uniform_set;228bool uniform_set_updated;229230virtual void set_render_priority(int p_priority) {}231virtual void set_next_pass(RID p_pass) {}232virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);233virtual ~FogMaterialData();234};235236RendererRD::MaterialStorage::ShaderData *_create_fog_shader_func();237static RendererRD::MaterialStorage::ShaderData *_create_fog_shader_funcs();238239RendererRD::MaterialStorage::MaterialData *_create_fog_material_func(FogShaderData *p_shader);240static RendererRD::MaterialStorage::MaterialData *_create_fog_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader);241242public:243static Fog *get_singleton() { return singleton; }244245Fog();246~Fog();247248/* FOG VOLUMES */249250bool owns_fog_volume(RID p_rid) { return fog_volume_owner.owns(p_rid); }251252virtual RID fog_volume_allocate() override;253virtual void fog_volume_initialize(RID p_rid) override;254virtual void fog_volume_free(RID p_rid) override;255Dependency *fog_volume_get_dependency(RID p_fog_volume) const;256257virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;258virtual void fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) override;259virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override;260virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;261RID fog_volume_get_material(RID p_fog_volume) const;262virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;263Vector3 fog_volume_get_size(RID p_fog_volume) const;264265/* FOG VOLUMES INSTANCE */266267bool owns_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.owns(p_rid); }268269RID fog_volume_instance_create(RID p_fog_volume);270void fog_instance_free(RID p_rid);271272void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) {273Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);274ERR_FAIL_NULL(fvi);275fvi->transform = p_transform;276}277278void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) {279Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);280ERR_FAIL_NULL(fvi);281fvi->active = p_active;282}283284RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const {285Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);286ERR_FAIL_NULL_V(fvi, RID());287return fvi->volume;288}289290Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const {291Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);292ERR_FAIL_NULL_V(fvi, Vector3());293return fvi->transform.get_origin();294}295296/* Volumetric FOG */297class VolumetricFog : public RenderBufferCustomDataRD {298GDCLASS(VolumetricFog, RenderBufferCustomDataRD)299300public:301enum {302MAX_TEMPORAL_FRAMES = 16303};304305uint32_t width = 0;306uint32_t height = 0;307uint32_t depth = 0;308309float length;310float spread;311312RID light_density_map;313RID prev_light_density_map;314RID fog_map;315RID density_map;316RID light_map;317RID emissive_map;318319RID fog_uniform_set;320RID copy_uniform_set;321322struct {323RID process_uniform_set_density;324RID process_uniform_set;325RID process_uniform_set2;326} gi_dependent_sets;327328RID sdfgi_uniform_set;329RID sky_uniform_set;330331int last_shadow_filter = -1;332333// If the device doesn't support image atomics, use storage buffers instead.334RD::UniformType atomic_type = RD::UNIFORM_TYPE_IMAGE;335336virtual void configure(RenderSceneBuffersRD *p_render_buffers) override {}337virtual void free_data() override {}338339bool sync_gi_dependent_sets_validity(bool p_ensure_freed = false);340341void init(const Vector3i &fog_size, RID p_sky_shader);342~VolumetricFog();343};344345void init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_octmap_array);346void free_fog_shader();347348struct VolumetricFogSettings {349Vector2i rb_size;350double time;351bool is_using_radiance_octmap_array;352uint32_t max_cluster_elements;353bool volumetric_fog_filter_active;354RID shadow_sampler;355RID voxel_gi_buffer;356RID shadow_atlas_depth;357RID omni_light_buffer;358RID spot_light_buffer;359RID directional_shadow_depth;360RID directional_light_buffer;361362// Objects related to our render buffer363Ref<VolumetricFog> vfog;364ClusterBuilderRD *cluster_builder;365GI *gi;366Ref<GI::SDFGI> sdfgi;367Ref<GI::RenderBuffersGI> rbgi;368RID env;369SkyRD *sky;370};371void 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);372};373374} // namespace RendererRD375376377