Path: blob/master/servers/rendering/renderer_rd/environment/fog.h
10279 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/shaders/environment/volumetric_fog.glsl.gen.h"38#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl.gen.h"39#include "servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h"40#include "servers/rendering/storage/utilities.h"4142#define RB_SCOPE_FOG SNAME("Fog")4344namespace RendererRD {4546class Fog : public RendererFog {47private:48static Fog *singleton;4950static int _get_fog_shader_group();51static int _get_fog_variant();52static int _get_fog_process_variant(int p_idx);5354/* FOG VOLUMES */5556struct FogVolume {57RID material;58Vector3 size = Vector3(2, 2, 2);5960RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;6162Dependency dependency;63};6465mutable RID_Owner<FogVolume, true> fog_volume_owner;6667struct FogVolumeInstance {68RID volume;69Transform3D transform;70bool active = false;71};7273mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner;7475const int SAMPLERS_BINDING_FIRST_INDEX = 3;7677/* Volumetric Fog */78struct VolumetricFogShader {79enum ShaderGroup {80SHADER_GROUP_BASE,81SHADER_GROUP_NO_ATOMICS,82SHADER_GROUP_VULKAN_MEMORY_MODEL,83SHADER_GROUP_VULKAN_MEMORY_MODEL_NO_ATOMICS,84};8586enum FogSet {87FOG_SET_BASE,88FOG_SET_UNIFORMS,89FOG_SET_MATERIAL,90FOG_SET_MAX,91};9293struct FogPushConstant {94float position[3];95float pad;9697float size[3];98float pad2;99100int32_t corner[3];101uint32_t shape;102103float transform[16];104};105106struct VolumeUBO {107float fog_frustum_size_begin[2];108float fog_frustum_size_end[2];109110float fog_frustum_end;111float z_near;112float z_far;113float time;114115int32_t fog_volume_size[3];116uint32_t directional_light_count;117118uint32_t use_temporal_reprojection;119uint32_t temporal_frame;120float detail_spread;121float temporal_blend;122123float to_prev_view[16];124float transform[16];125};126127ShaderCompiler compiler;128VolumetricFogShaderRD shader;129RID volume_ubo;130131RID default_shader;132RID default_material;133RID default_shader_rd;134135RID base_uniform_set;136137RID params_ubo;138139enum {140VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY,141VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI,142VOLUMETRIC_FOG_PROCESS_SHADER_FILTER,143VOLUMETRIC_FOG_PROCESS_SHADER_FOG,144VOLUMETRIC_FOG_PROCESS_SHADER_COPY,145VOLUMETRIC_FOG_PROCESS_SHADER_MAX,146};147148struct ParamsUBO {149float fog_frustum_size_begin[2];150float fog_frustum_size_end[2];151152float fog_frustum_end;153float ambient_inject;154float z_far;155uint32_t filter_axis;156157float ambient_color[3];158float sky_contribution;159160int32_t fog_volume_size[3];161uint32_t directional_light_count;162163float base_emission[3];164float base_density;165166float base_scattering[3];167float phase_g;168169float detail_spread;170float gi_inject;171uint32_t max_voxel_gi_instances;172uint32_t cluster_type_size;173174float screen_size[2];175uint32_t cluster_shift;176uint32_t cluster_width;177178uint32_t max_cluster_element_count_div_32;179uint32_t use_temporal_reprojection;180uint32_t temporal_frame;181float temporal_blend;182183float cam_rotation[12];184float to_prev_view[16];185float radiance_inverse_xform[12];186};187188VolumetricFogProcessShaderRD process_shader;189190RID process_shader_version;191RID process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX];192193} volumetric_fog;194195Vector3i _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);196197struct FogShaderData : public RendererRD::MaterialStorage::ShaderData {198bool valid = false;199RID version;200201RID pipeline;202Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;203204Vector<uint32_t> ubo_offsets;205uint32_t ubo_size = 0;206207String code;208209bool uses_time = false;210211virtual void set_code(const String &p_Code);212virtual bool is_animated() const;213virtual bool casts_shadows() const;214virtual RS::ShaderNativeSourceCode get_native_source_code() const;215virtual Pair<ShaderRD *, RID> get_native_shader_and_version() const;216217FogShaderData() {}218virtual ~FogShaderData();219};220221struct FogMaterialData : public RendererRD::MaterialStorage::MaterialData {222FogShaderData *shader_data = nullptr;223RID uniform_set;224bool uniform_set_updated;225226virtual void set_render_priority(int p_priority) {}227virtual void set_next_pass(RID p_pass) {}228virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);229virtual ~FogMaterialData();230};231232RendererRD::MaterialStorage::ShaderData *_create_fog_shader_func();233static RendererRD::MaterialStorage::ShaderData *_create_fog_shader_funcs();234235RendererRD::MaterialStorage::MaterialData *_create_fog_material_func(FogShaderData *p_shader);236static RendererRD::MaterialStorage::MaterialData *_create_fog_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader);237238public:239static Fog *get_singleton() { return singleton; }240241Fog();242~Fog();243244/* FOG VOLUMES */245246bool owns_fog_volume(RID p_rid) { return fog_volume_owner.owns(p_rid); }247248virtual RID fog_volume_allocate() override;249virtual void fog_volume_initialize(RID p_rid) override;250virtual void fog_volume_free(RID p_rid) override;251Dependency *fog_volume_get_dependency(RID p_fog_volume) const;252253virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;254virtual void fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) override;255virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override;256virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;257RID fog_volume_get_material(RID p_fog_volume) const;258virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;259Vector3 fog_volume_get_size(RID p_fog_volume) const;260261/* FOG VOLUMES INSTANCE */262263bool owns_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.owns(p_rid); }264265RID fog_volume_instance_create(RID p_fog_volume);266void fog_instance_free(RID p_rid);267268void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) {269Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);270ERR_FAIL_NULL(fvi);271fvi->transform = p_transform;272}273274void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) {275Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);276ERR_FAIL_NULL(fvi);277fvi->active = p_active;278}279280RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const {281Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);282ERR_FAIL_NULL_V(fvi, RID());283return fvi->volume;284}285286Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const {287Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);288ERR_FAIL_NULL_V(fvi, Vector3());289return fvi->transform.get_origin();290}291292/* Volumetric FOG */293class VolumetricFog : public RenderBufferCustomDataRD {294GDCLASS(VolumetricFog, RenderBufferCustomDataRD)295296public:297enum {298MAX_TEMPORAL_FRAMES = 16299};300301uint32_t width = 0;302uint32_t height = 0;303uint32_t depth = 0;304305float length;306float spread;307308RID light_density_map;309RID prev_light_density_map;310RID fog_map;311RID density_map;312RID light_map;313RID emissive_map;314315RID fog_uniform_set;316RID copy_uniform_set;317318struct {319RID process_uniform_set_density;320RID process_uniform_set;321RID process_uniform_set2;322} gi_dependent_sets;323324RID sdfgi_uniform_set;325RID sky_uniform_set;326327int last_shadow_filter = -1;328329// If the device doesn't support image atomics, use storage buffers instead.330RD::UniformType atomic_type = RD::UNIFORM_TYPE_IMAGE;331332virtual void configure(RenderSceneBuffersRD *p_render_buffers) override {}333virtual void free_data() override {}334335bool sync_gi_dependent_sets_validity(bool p_ensure_freed = false);336337void init(const Vector3i &fog_size, RID p_sky_shader);338~VolumetricFog();339};340341void init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array);342void free_fog_shader();343344struct VolumetricFogSettings {345Vector2i rb_size;346double time;347bool is_using_radiance_cubemap_array;348uint32_t max_cluster_elements;349bool volumetric_fog_filter_active;350RID shadow_sampler;351RID voxel_gi_buffer;352RID shadow_atlas_depth;353RID omni_light_buffer;354RID spot_light_buffer;355RID directional_shadow_depth;356RID directional_light_buffer;357358// Objects related to our render buffer359Ref<VolumetricFog> vfog;360ClusterBuilderRD *cluster_builder;361GI *gi;362Ref<GI::SDFGI> sdfgi;363Ref<GI::RenderBuffersGI> rbgi;364RID env;365SkyRD *sky;366};367void 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);368};369370} // namespace RendererRD371372373