diff options
Diffstat (limited to 'servers')
-rw-r--r-- | servers/rendering/dummy/rasterizer_scene_dummy.h | 57 | ||||
-rw-r--r-- | servers/rendering/dummy/storage/mesh_storage.cpp | 58 | ||||
-rw-r--r-- | servers/rendering/dummy/storage/mesh_storage.h | 26 | ||||
-rw-r--r-- | servers/rendering/dummy/storage/texture_storage.h | 1 | ||||
-rw-r--r-- | servers/rendering/dummy/storage/utilities.cpp | 43 | ||||
-rw-r--r-- | servers/rendering/dummy/storage/utilities.h | 20 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.cpp | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.h | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl | 89 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/shaders/light_data_inc.glsl | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/storage_rd/light_storage.cpp | 2 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/storage_rd/light_storage.h | 7 | ||||
-rw-r--r-- | servers/rendering/renderer_scene_cull.cpp | 32 | ||||
-rw-r--r-- | servers/rendering_server.cpp | 2 | ||||
-rw-r--r-- | servers/rendering_server.h | 2 |
15 files changed, 279 insertions, 72 deletions
diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h index be98770b90..8d3a45d696 100644 --- a/servers/rendering/dummy/rasterizer_scene_dummy.h +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -31,12 +31,65 @@ #ifndef RASTERIZER_SCENE_DUMMY_H #define RASTERIZER_SCENE_DUMMY_H +#include "core/templates/paged_allocator.h" #include "servers/rendering/renderer_scene_render.h" +#include "storage/utilities.h" class RasterizerSceneDummy : public RendererSceneRender { public: - RenderGeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } - void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override {} + class GeometryInstanceDummy : public RenderGeometryInstance { + public: + GeometryInstanceDummy() {} + + virtual void _mark_dirty() override {} + + virtual void set_skeleton(RID p_skeleton) override {} + virtual void set_material_override(RID p_override) override {} + virtual void set_material_overlay(RID p_overlay) override {} + virtual void set_surface_materials(const Vector<RID> &p_materials) override {} + virtual void set_mesh_instance(RID p_mesh_instance) override {} + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override {} + virtual void set_lod_bias(float p_lod_bias) override {} + virtual void set_layer_mask(uint32_t p_layer_mask) override {} + virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {} + virtual void set_parent_fade_alpha(float p_alpha) override {} + virtual void set_transparency(float p_transparency) override {} + virtual void set_use_baked_light(bool p_enable) override {} + virtual void set_use_dynamic_gi(bool p_enable) override {} + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {} + virtual void set_lightmap_capture(const Color *p_sh9) override {} + virtual void set_instance_shader_uniforms_offset(int32_t p_offset) override {} + virtual void set_cast_double_sided_shadows(bool p_enable) override {} + + virtual Transform3D get_transform() override { return Transform3D(); } + virtual AABB get_aabb() override { return AABB(); } + + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override {} + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} + + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override {} + }; + + PagedAllocator<GeometryInstanceDummy> geometry_instance_alloc; + +public: + RenderGeometryInstance *geometry_instance_create(RID p_base) override { + RS::InstanceType type = RendererDummy::Utilities::get_singleton()->get_base_type(p_base); + ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); + + GeometryInstanceDummy *ginstance = geometry_instance_alloc.alloc(); + + return ginstance; + } + + void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override { + GeometryInstanceDummy *ginstance = static_cast<GeometryInstanceDummy *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + + geometry_instance_alloc.free(ginstance); + } uint32_t geometry_instance_get_pair_mask() override { return 0; } diff --git a/servers/rendering/dummy/storage/mesh_storage.cpp b/servers/rendering/dummy/storage/mesh_storage.cpp new file mode 100644 index 0000000000..adf736eee3 --- /dev/null +++ b/servers/rendering/dummy/storage/mesh_storage.cpp @@ -0,0 +1,58 @@ +/*************************************************************************/ +/* mesh_storage.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "mesh_storage.h" + +using namespace RendererDummy; + +MeshStorage *MeshStorage::singleton = nullptr; + +MeshStorage::MeshStorage() { + singleton = this; +} + +MeshStorage::~MeshStorage() { + singleton = nullptr; +} + +RID MeshStorage::mesh_allocate() { + return mesh_owner.allocate_rid(); +} + +void MeshStorage::mesh_initialize(RID p_rid) { + mesh_owner.initialize_rid(p_rid, DummyMesh()); +} + +void MeshStorage::mesh_free(RID p_rid) { + DummyMesh *mesh = mesh_owner.get_or_null(p_rid); + ERR_FAIL_COND(!mesh); + + mesh_owner.free(p_rid); +} diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index aab5145982..1eb4fd854f 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -31,14 +31,17 @@ #ifndef MESH_STORAGE_DUMMY_H #define MESH_STORAGE_DUMMY_H +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" #include "servers/rendering/storage/mesh_storage.h" -#include "servers/rendering/storage/utilities.h" namespace RendererDummy { class MeshStorage : public RendererMeshStorage { private: - struct DummyMesh : public RID { + static MeshStorage *singleton; + + struct DummyMesh { Vector<RS::SurfaceData> surfaces; int blend_shape_count; RS::BlendShapeMode blend_shape_mode; @@ -48,16 +51,20 @@ private: mutable RID_Owner<DummyMesh> mesh_owner; public: + static MeshStorage *get_singleton() { + return singleton; + }; + + MeshStorage(); + ~MeshStorage(); + /* MESH API */ - virtual RID mesh_allocate() override { - return mesh_owner.allocate_rid(); - } + bool owns_mesh(RID p_rid) { return mesh_owner.owns(p_rid); }; - virtual void mesh_initialize(RID p_rid) override { - mesh_owner.initialize_rid(p_rid, DummyMesh()); - } - virtual void mesh_free(RID p_rid) override {} + virtual RID mesh_allocate() override; + virtual void mesh_initialize(RID p_rid) override; + virtual void mesh_free(RID p_rid) override; virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override {} virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override { return false; } @@ -98,7 +105,6 @@ public: virtual int mesh_get_surface_count(RID p_mesh) const override { DummyMesh *m = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!m, 0); - print_line(m->surfaces.size()); return m->surfaces.size(); } diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index d4f832b5f8..c15b656d06 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -69,7 +69,6 @@ public: /* Texture API */ - DummyTexture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); }; bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); }; virtual RID texture_allocate() override { diff --git a/servers/rendering/dummy/storage/utilities.cpp b/servers/rendering/dummy/storage/utilities.cpp new file mode 100644 index 0000000000..125ed81917 --- /dev/null +++ b/servers/rendering/dummy/storage/utilities.cpp @@ -0,0 +1,43 @@ +/*************************************************************************/ +/* utilities.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "utilities.h" + +using namespace RendererDummy; + +Utilities *Utilities::singleton = nullptr; + +Utilities::Utilities() { + singleton = this; +} + +Utilities::~Utilities() { + singleton = nullptr; +} diff --git a/servers/rendering/dummy/storage/utilities.h b/servers/rendering/dummy/storage/utilities.h index b94f678c75..cb7b2a2b63 100644 --- a/servers/rendering/dummy/storage/utilities.h +++ b/servers/rendering/dummy/storage/utilities.h @@ -31,20 +31,38 @@ #ifndef UTILITIES_DUMMY_H #define UTILITIES_DUMMY_H +#include "mesh_storage.h" #include "servers/rendering/storage/utilities.h" #include "texture_storage.h" namespace RendererDummy { class Utilities : public RendererUtilities { +private: + static Utilities *singleton; + public: + static Utilities *get_singleton() { return singleton; } + + Utilities(); + ~Utilities(); + /* INSTANCES */ - virtual RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; } + virtual RS::InstanceType get_base_type(RID p_rid) const override { + if (RendererDummy::MeshStorage::get_singleton()->owns_mesh(p_rid)) { + return RS::INSTANCE_MESH; + } + return RS::INSTANCE_NONE; + } + virtual bool free(RID p_rid) override { if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) { RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid); return true; + } else if (RendererDummy::MeshStorage::get_singleton()->owns_mesh(p_rid)) { + RendererDummy::MeshStorage::get_singleton()->mesh_free(p_rid); + return true; } return false; } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 2d004baf48..fa83428367 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2871,6 +2871,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.color[2] = linear_col.b; light_data.specular = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR); + light_data.volumetric_fog_energy = light_storage->light_get_param(base, RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); light_data.mask = light_storage->light_get_cull_mask(base); float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); @@ -2952,7 +2953,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const float fade_start = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START); light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep light_data.fade_to = -light_data.shadow_split_offsets[3]; - light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base); light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); light_data.softshadow_angle = angular_diameter; @@ -3082,6 +3082,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.color[1] = linear_col.g * energy; light_data.color[2] = linear_col.b * energy; light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0; + light_data.volumetric_fog_energy = light_storage->light_get_param(base, RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); light_data.bake_mode = light_storage->light_get_bake_mode(base); float radius = MAX(0.001, light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE)); @@ -3176,7 +3177,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.atlas_rect[3] = rect.size.height; light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); - light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base); if (type == RS::LIGHT_OMNI) { Transform3D proj = (inverse_transform * light_transform).inverse(); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 8e59b21aa8..3867fd8605 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -618,7 +618,7 @@ private: float soft_shadow_size; float soft_shadow_scale; uint32_t mask; - float shadow_volumetric_fog_fade; + float volumetric_fog_energy; uint32_t bake_mode; float projector_rect[4]; }; @@ -638,7 +638,7 @@ private: float fade_to; uint32_t pad[2]; uint32_t bake_mode; - float shadow_volumetric_fog_fade; + float volumetric_fog_energy; float shadow_bias[4]; float shadow_normal_bias[4]; float shadow_transmittance_bias[4]; diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index 6f79b9e771..07d5223472 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -270,6 +270,9 @@ const vec3 halton_map[TEMPORAL_FRAMES] = vec3[]( vec3(0.9375, 0.25925926, 0.12), vec3(0.03125, 0.59259259, 0.32)); +// Higher values will make light in volumetric fog fade out sooner when it's occluded by shadow. +const float INV_FOG_FADE = 10.0; + void main() { vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size); @@ -375,46 +378,48 @@ void main() { if (total_density > 0.001) { for (uint i = 0; i < params.directional_light_count; i++) { - vec3 shadow_attenuation = vec3(1.0); - - if (directional_lights.data[i].shadow_opacity > 0.001) { - float depth_z = -view_pos.z; - - vec4 pssm_coord; - vec3 light_dir = directional_lights.data[i].direction; - vec4 v = vec4(view_pos, 1.0); - float z_range; - - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.x; - - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.y; - - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.z; - - } else { - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.w; - } + if (directional_lights.data[i].volumetric_fog_energy > 0.001) { + vec3 shadow_attenuation = vec3(1.0); + + if (directional_lights.data[i].shadow_opacity > 0.001) { + float depth_z = -view_pos.z; + + vec4 pssm_coord; + vec3 light_dir = directional_lights.data[i].direction; + vec4 v = vec4(view_pos, 1.0); + float z_range; + + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.x; + + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.y; + + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.z; + + } else { + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.w; + } - float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; - float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * directional_lights.data[i].shadow_volumetric_fog_fade); + float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; + float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * INV_FOG_FADE); - shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance + shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance - shadow_attenuation = mix(vec3(0.0), vec3(1.0), shadow); - } + shadow_attenuation = mix(vec3(1.0 - directional_lights.data[i].shadow_opacity), vec3(1.0), shadow); + } - total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g); + total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g) * directional_lights.data[i].volumetric_fog_energy; + } } // Compute light from sky @@ -481,7 +486,7 @@ void main() { float d = distance(omni_lights.data[light_index].position, view_pos); float shadow_attenuation = 1.0; - if (d * omni_lights.data[light_index].inv_radius < 1.0) { + if (omni_lights.data[light_index].volumetric_fog_energy > 0.001 && d * omni_lights.data[light_index].inv_radius < 1.0) { float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation); vec3 light = omni_lights.data[light_index].color; @@ -509,9 +514,9 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade); + shadow_attenuation = mix(1.0 - omni_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * INV_FOG_FADE)); } - total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g); + total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g) * omni_lights.data[light_index].volumetric_fog_energy; } } } @@ -562,7 +567,7 @@ void main() { float d = length(light_rel_vec); float shadow_attenuation = 1.0; - if (d * spot_lights.data[light_index].inv_radius < 1.0) { + if (spot_lights.data[light_index].volumetric_fog_energy > 0.001 && d * spot_lights.data[light_index].inv_radius < 1.0) { float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation); vec3 spot_dir = spot_lights.data[light_index].direction; @@ -595,9 +600,9 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade); + shadow_attenuation = mix(1.0 - spot_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * INV_FOG_FADE)); } - total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g); + total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g) * spot_lights.data[light_index].volumetric_fog_energy; } } } diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 799f7087b6..a7fca25a6b 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -25,7 +25,7 @@ struct LightData { //this structure needs to be as packed as possible highp float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle highp float soft_shadow_scale; // scales the shadow kernel for blurrier shadows uint mask; - mediump float shadow_volumetric_fog_fade; + mediump float volumetric_fog_energy; uint bake_mode; highp vec4 projector_rect; //projector rect in srgb decal atlas }; @@ -65,7 +65,7 @@ struct DirectionalLightData { highp float fade_to; uvec2 pad; uint bake_mode; - mediump float shadow_volumetric_fog_fade; + mediump float volumetric_fog_energy; highp vec4 shadow_bias; highp vec4 shadow_normal_bias; highp vec4 shadow_transmittance_bias; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 7b58cc08dd..b845c1155e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -75,6 +75,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0; + light.param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5; light.param[RS::LIGHT_PARAM_RANGE] = 1.0; light.param[RS::LIGHT_PARAM_SIZE] = 0.0; @@ -91,7 +92,6 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; light_owner.initialize_rid(p_light, light); diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 3e3246e8e9..7e98a3cb8e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -250,13 +250,6 @@ public: return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; } - _FORCE_INLINE_ float light_get_shadow_volumetric_fog_fade(RID p_light) const { - const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, 0.0); - - return light->param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE]; - } - virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override; virtual uint64_t light_get_version(RID p_light) const override; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 80c4ecea2d..6846916f3f 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -637,6 +637,8 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { instance->base_data = geom; geom->geometry_instance = scene_render->geometry_instance_create(p_base); + ERR_FAIL_NULL(geom->geometry_instance); + geom->geometry_instance->set_skeleton(instance->skeleton); geom->geometry_instance->set_material_override(instance->material_override); geom->geometry_instance->set_material_overlay(instance->material_overlay); @@ -836,6 +838,7 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_layer_mask(p_mask); } } @@ -848,6 +851,7 @@ void RendererSceneCull::instance_geometry_set_transparency(RID p_instance, float if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_transparency(p_transparency); } } @@ -1009,6 +1013,7 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) _instance_update_mesh_instance(instance); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_skeleton(p_skeleton); } } @@ -1129,6 +1134,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_use_baked_light(p_enabled); } @@ -1149,6 +1155,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_use_dynamic_gi(p_enabled); } @@ -1207,6 +1214,8 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); + geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); } @@ -1222,6 +1231,7 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_material_override(p_material); } } @@ -1235,6 +1245,7 @@ void RendererSceneCull::instance_geometry_set_material_overlay(RID p_instance, R if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_material_overlay(p_material); } } @@ -1407,6 +1418,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_use_lightmap(lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index); } } @@ -1419,6 +1431,7 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_lod_bias(p_lod_bias); } } @@ -1587,10 +1600,12 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { if (!p_instance->lightmap_sh.is_empty()) { p_instance->lightmap_sh.clear(); //don't need SH p_instance->lightmap_target_sh.clear(); //don't need SH + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_lightmap_capture(nullptr); } } + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_transform(p_instance->transform, p_instance->aabb, p_instance->transformed_aabb); } @@ -1817,6 +1832,7 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { // Clear these now because the InstanceData containing the dirty flags is gone InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->pair_light_instances(nullptr, 0); geom->geometry_instance->pair_reflection_probe_instances(nullptr, 0); @@ -1990,6 +2006,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) } } + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_lightmap_capture(p_instance->lightmap_sh.ptr()); } @@ -2757,6 +2774,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->pair_light_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); } @@ -2764,6 +2782,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul if (idata.flags & InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_softshadow_projector_pairing(geom->softshadow_count > 0, geom->projector_count > 0); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY); } @@ -2781,6 +2800,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->pair_reflection_probe_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY); } @@ -2797,7 +2817,10 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul break; } } + + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->pair_decal_instances(instance_pair_buffer, idx); + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY); } @@ -2813,7 +2836,9 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx); + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } @@ -2824,6 +2849,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul for (uint32_t j = 0; j < 9; j++) { sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); } + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_lightmap_capture(sh); idata.instance->last_frame_pass = frame_number; } @@ -3588,11 +3614,13 @@ void RendererSceneCull::render_probes() { } } + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx); ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } + ERR_FAIL_NULL(geom->geometry_instance); scene_cull_result.geometry_instances.push_back(geom->geometry_instance); } @@ -3633,6 +3661,7 @@ void RendererSceneCull::render_particle_colliders() { continue; } InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); scene_cull_result.geometry_instances.push_back(geom->geometry_instance); } @@ -3851,6 +3880,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { p_instance->instance_allocated_shader_uniforms = (p_instance->instance_shader_uniforms.size() > 0); if (p_instance->instance_allocated_shader_uniforms) { p_instance->instance_allocated_shader_uniforms_offset = RSG::material_storage->global_shader_uniforms_instance_allocate(p_instance->self); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_instance_shader_uniforms_offset(p_instance->instance_allocated_shader_uniforms_offset); for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) { @@ -3861,6 +3891,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { } else { RSG::material_storage->global_shader_uniforms_instance_free(p_instance->self); p_instance->instance_allocated_shader_uniforms_offset = -1; + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_instance_shader_uniforms_offset(-1); } } @@ -3874,6 +3905,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_surface_materials(p_instance->materials); } } diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 3e850a9798..88c20914e1 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1898,6 +1898,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_ENERGY); BIND_ENUM_CONSTANT(LIGHT_PARAM_INDIRECT_ENERGY); + BIND_ENUM_CONSTANT(LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR); BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SIZE); @@ -1914,7 +1915,6 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_PANCAKE_SIZE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_OPACITY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BLUR); - BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE); BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index efa8a24325..3feec448e4 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -416,6 +416,7 @@ public: enum LightParam { LIGHT_PARAM_ENERGY, LIGHT_PARAM_INDIRECT_ENERGY, + LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY, LIGHT_PARAM_SPECULAR, LIGHT_PARAM_RANGE, LIGHT_PARAM_SIZE, @@ -432,7 +433,6 @@ public: LIGHT_PARAM_SHADOW_PANCAKE_SIZE, LIGHT_PARAM_SHADOW_OPACITY, LIGHT_PARAM_SHADOW_BLUR, - LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE, LIGHT_PARAM_TRANSMITTANCE_BIAS, LIGHT_PARAM_MAX }; |