diff options
Diffstat (limited to 'servers/rendering/renderer_rd/environment')
-rw-r--r-- | servers/rendering/renderer_rd/environment/fog.cpp | 166 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/fog.h | 106 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/gi.cpp | 234 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/gi.h | 70 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/sky.cpp | 566 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/sky.h | 134 |
6 files changed, 504 insertions, 772 deletions
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 3390e9cf64..2787693aeb 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* fog.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* fog.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "fog.h" @@ -57,12 +57,19 @@ void Fog::fog_volume_initialize(RID p_rid) { fog_volume_owner.initialize_rid(p_rid, FogVolume()); } -void Fog::fog_free(RID p_rid) { +void Fog::fog_volume_free(RID p_rid) { FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid); fog_volume->dependency.deleted_notify(p_rid); fog_volume_owner.free(p_rid); } +Dependency *Fog::fog_volume_get_dependency(RID p_fog_volume) const { + FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); + ERR_FAIL_NULL_V(fog_volume, nullptr); + + return &fog_volume->dependency; +} + void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) { FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume); ERR_FAIL_COND(!fog_volume); @@ -136,7 +143,7 @@ Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const { bool Fog::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { uniform_set_updated = true; - return 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, 0), VolumetricFogShader::FogSet::FOG_SET_MATERIAL); + return 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, 0), VolumetricFogShader::FogSet::FOG_SET_MATERIAL, true); } Fog::FogMaterialData::~FogMaterialData() { @@ -312,10 +319,6 @@ void Fog::free_fog_shader() { material_storage->material_free(volumetric_fog.default_material); } -void Fog::FogShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void Fog::FogShaderData::set_code(const String &p_code) { //compile @@ -359,83 +362,6 @@ void Fog::FogShaderData::set_code(const String &p_code) { valid = true; } -void Fog::FogShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void Fog::FogShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - RBMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void Fog::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool Fog::FogShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool Fog::FogShaderData::is_animated() const { return false; } @@ -444,15 +370,6 @@ bool Fog::FogShaderData::casts_shadows() const { return false; } -Variant Fog::FogShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode Fog::FogShaderData::get_native_source_code() const { Fog *fog_singleton = Fog::get_singleton(); @@ -720,9 +637,9 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P any_uses_time |= shader_data->uses_time; - Vector3i min = Vector3i(); - Vector3i max = Vector3i(); - Vector3i kernel_size = Vector3i(); + Vector3i min; + Vector3i max; + Vector3i kernel_size; Vector3 position = fog_volume_instance->transform.get_origin(); RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); @@ -782,6 +699,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE); if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL); + material->set_as_used(); } RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h index 9ecd5699dc..eb0a2fc7b5 100644 --- a/servers/rendering/renderer_rd/environment/fog.h +++ b/servers/rendering/renderer_rd/environment/fog.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* fog.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* fog.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #ifndef FOG_RD_H #define FOG_RD_H @@ -46,7 +46,9 @@ namespace RendererRD { class Fog : public RendererFog { -public: +private: + static Fog *singleton; + /* FOG VOLUMES */ struct FogVolume { @@ -58,16 +60,14 @@ public: Dependency dependency; }; + mutable RID_Owner<FogVolume, true> fog_volume_owner; + struct FogVolumeInstance { RID volume; Transform3D transform; bool active = false; }; -private: - static Fog *singleton; - - mutable RID_Owner<FogVolume, true> fog_volume_owner; mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner; /* Volumetric Fog */ @@ -188,27 +188,18 @@ private: RID version; RID pipeline; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; - String path; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time = false; - virtual void set_path_hint(const String &p_hint); virtual void set_code(const String &p_Code); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; FogShaderData() {} @@ -240,12 +231,12 @@ public: /* FOG VOLUMES */ - FogVolume *get_fog_volume(RID p_rid) { return fog_volume_owner.get_or_null(p_rid); }; bool owns_fog_volume(RID p_rid) { return fog_volume_owner.owns(p_rid); }; virtual RID fog_volume_allocate() override; virtual void fog_volume_initialize(RID p_rid) override; - virtual void fog_free(RID p_rid) override; + virtual void fog_volume_free(RID p_rid) override; + Dependency *fog_volume_get_dependency(RID p_fog_volume) const; virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override; virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override; @@ -257,12 +248,35 @@ public: /* FOG VOLUMES INSTANCE */ - FogVolumeInstance *get_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.get_or_null(p_rid); }; bool owns_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.owns(p_rid); }; RID fog_volume_instance_create(RID p_fog_volume); void fog_instance_free(RID p_rid); + void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) { + Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + ERR_FAIL_COND(!fvi); + fvi->transform = p_transform; + } + + void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) { + Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + ERR_FAIL_COND(!fvi); + fvi->active = p_active; + } + + RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const { + Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + ERR_FAIL_COND_V(!fvi, RID()); + return fvi->volume; + } + + Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const { + Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + ERR_FAIL_COND_V(!fvi, Vector3()); + return fvi->transform.get_origin(); + } + /* Volumetric FOG */ class VolumetricFog : public RenderBufferCustomDataRD { GDCLASS(VolumetricFog, RenderBufferCustomDataRD) diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index ced0f6380f..08133bf8d6 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* gi.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gi.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "gi.h" @@ -540,9 +540,7 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re occlusion_texture = RD::get_singleton()->texture_create_shared(tv, occlusion_data); } - for (uint32_t i = 0; i < cascades.size(); i++) { - SDFGI::Cascade &cascade = cascades[i]; - + for (SDFGI::Cascade &cascade : cascades) { /* 3D Textures */ cascade.sdf_tex = RD::get_singleton()->texture_create(tf_sdf, RD::TextureView()); @@ -743,9 +741,7 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re } //direct light - for (uint32_t i = 0; i < cascades.size(); i++) { - SDFGI::Cascade &cascade = cascades[i]; - + for (SDFGI::Cascade &cascade : cascades) { Vector<RD::Uniform> uniforms; { RD::Uniform u; @@ -1134,8 +1130,7 @@ void GI::SDFGI::free_data() { } GI::SDFGI::~SDFGI() { - for (uint32_t i = 0; i < cascades.size(); i++) { - const SDFGI::Cascade &c = cascades[i]; + for (const SDFGI::Cascade &c : cascades) { RD::get_singleton()->free(c.light_data); RD::get_singleton()->free(c.light_aniso_0_tex); RD::get_singleton()->free(c.light_aniso_1_tex); @@ -1198,8 +1193,7 @@ void GI::SDFGI::update(RID p_env, const Vector3 &p_world_position) { int32_t drag_margin = (cascade_size / SDFGI::PROBE_DIVISOR) / 2; - for (uint32_t i = 0; i < cascades.size(); i++) { - SDFGI::Cascade &cascade = cascades[i]; + for (SDFGI::Cascade &cascade : cascades) { cascade.dirty_regions = Vector3i(); Vector3 probe_half_size = Vector3(1, 1, 1) * cascade.cell_size * float(cascade_size / SDFGI::PROBE_DIVISOR) * 0.5; @@ -1634,7 +1628,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection Projection inv_projection = p_projections[v].inverse(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { - push_constant.inv_projection[j][i] = inv_projection.matrix[i][j]; + push_constant.inv_projection[j][i] = inv_projection.columns[i][j]; } } @@ -1644,8 +1638,8 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection RD::get_singleton()->compute_list_end(); } - Size2 rtsize = texture_storage->render_target_get_size(p_render_target); - copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true, false, false, false, RID(), p_view_count > 1); + Size2i rtsize = texture_storage->render_target_get_size(p_render_target); + copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2i(Point2i(), rtsize), true, false, false, false, RID(), p_view_count > 1); } void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { @@ -1798,7 +1792,8 @@ void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, con RD::get_singleton()->draw_list_end(); } -void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data) { + RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); /* Update general SDFGI Buffer */ SDFGIData sdfgi_data; @@ -1881,40 +1876,43 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r SDFGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS]; uint32_t idx = 0; - for (uint32_t j = 0; j < (uint32_t)p_scene_render->render_state.sdfgi_update_data->directional_lights->size(); j++) { + for (uint32_t j = 0; j < (uint32_t)p_render_data->sdfgi_update_data->directional_lights->size(); j++) { if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { break; } - RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->directional_lights->get(j)); - ERR_CONTINUE(!li); + RID light_instance = p_render_data->sdfgi_update_data->directional_lights->get(j); + ERR_CONTINUE(!light_storage->owns_light_instance(light_instance)); + + RID light = light_storage->light_instance_get_base_light(light_instance); + Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance); - if (RSG::light_storage->light_directional_get_sky_mode(li->light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { + if (RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { continue; } - Vector3 dir = -li->transform.basis.get_column(Vector3::AXIS_Z); + Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z); dir.y *= y_mult; dir.normalize(); lights[idx].direction[0] = dir.x; lights[idx].direction[1] = dir.y; lights[idx].direction[2] = dir.z; - Color color = RSG::light_storage->light_get_color(li->light); + Color color = RSG::light_storage->light_get_color(light); color = color.srgb_to_linear(); lights[idx].color[0] = color.r; lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; lights[idx].type = RS::LIGHT_DIRECTIONAL; - lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY); - if (p_scene_render->is_using_physical_light_units()) { - lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY); + lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); + if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { + lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); } if (p_render_data->camera_attributes.is_valid()) { lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); } - lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light); + lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light); idx++; } @@ -1923,45 +1921,49 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascade.position)) * cascade.cell_size; cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cascade.cell_size; - for (uint32_t j = 0; j < p_scene_render->render_state.sdfgi_update_data->positional_light_count; j++) { + for (uint32_t j = 0; j < p_render_data->sdfgi_update_data->positional_light_count; j++) { if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { break; } - RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->positional_light_instances[j]); - ERR_CONTINUE(!li); + RID light_instance = p_render_data->sdfgi_update_data->positional_light_instances[j]; + ERR_CONTINUE(!light_storage->owns_light_instance(light_instance)); + + RID light = light_storage->light_instance_get_base_light(light_instance); + AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance); + Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance); - uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(li->light); + uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light); if (i > max_sdfgi_cascade) { continue; } - if (!cascade_aabb.intersects(li->aabb)) { + if (!cascade_aabb.intersects(light_aabb)) { continue; } - Vector3 dir = -li->transform.basis.get_column(Vector3::AXIS_Z); + Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z); //faster to not do this here //dir.y *= y_mult; //dir.normalize(); lights[idx].direction[0] = dir.x; lights[idx].direction[1] = dir.y; lights[idx].direction[2] = dir.z; - Vector3 pos = li->transform.origin; + Vector3 pos = light_transform.origin; pos.y *= y_mult; lights[idx].position[0] = pos.x; lights[idx].position[1] = pos.y; lights[idx].position[2] = pos.z; - Color color = RSG::light_storage->light_get_color(li->light); + Color color = RSG::light_storage->light_get_color(light); color = color.srgb_to_linear(); lights[idx].color[0] = color.r; lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; - lights[idx].type = RSG::light_storage->light_get_type(li->light); + lights[idx].type = RSG::light_storage->light_get_type(light); - lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY); - if (p_scene_render->is_using_physical_light_units()) { - lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY); + lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); + if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { + lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); // Convert from Luminous Power to Luminous Intensity if (lights[idx].type == RS::LIGHT_OMNI) { @@ -1977,11 +1979,11 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); } - lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light); - lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); - lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); - lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE))); - lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light); + lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); + lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE); + lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); + lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); idx++; } @@ -1994,7 +1996,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r } } -void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render, float p_exposure_normalization) { +void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization) { //print_line("rendering region " + itos(p_region)); ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but... AABB bounds; @@ -2015,7 +2017,7 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_ } //print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(cascades[cascade].cell_size)); - p_scene_render->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing, p_exposure_normalization); + RendererSceneRenderRD::get_singleton()->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing, p_exposure_normalization); if (cascade_next != cascade) { RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade"); @@ -2327,7 +2329,7 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_ img.instantiate(); for (uint32_t i = 0; i < cascade_size; i++) { Vector<uint8_t> subarr = data.slice(128 * 128 * i, 128 * 128 * (i + 1)); - img->create(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr); + img->set_data(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr); img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png"); } @@ -2353,9 +2355,11 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_ } } -void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) { ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but... + RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); + RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lights"); update_cascades(); @@ -2381,21 +2385,25 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen break; } - RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_positional_light_cull_result[i][j]); - ERR_CONTINUE(!li); + RID light_instance = p_positional_light_cull_result[i][j]; + ERR_CONTINUE(!light_storage->owns_light_instance(light_instance)); + + RID light = light_storage->light_instance_get_base_light(light_instance); + AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance); + Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance); - uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(li->light); + uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light); if (p_cascade_indices[i] > max_sdfgi_cascade) { continue; } - if (!cascade_aabb.intersects(li->aabb)) { + if (!cascade_aabb.intersects(light_aabb)) { continue; } - lights[idx].type = RSG::light_storage->light_get_type(li->light); + lights[idx].type = RSG::light_storage->light_get_type(light); - Vector3 dir = -li->transform.basis.get_column(Vector3::AXIS_Z); + Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z); if (lights[idx].type == RS::LIGHT_DIRECTIONAL) { dir.y *= y_mult; //only makes sense for directional dir.normalize(); @@ -2403,20 +2411,20 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen lights[idx].direction[0] = dir.x; lights[idx].direction[1] = dir.y; lights[idx].direction[2] = dir.z; - Vector3 pos = li->transform.origin; + Vector3 pos = light_transform.origin; pos.y *= y_mult; lights[idx].position[0] = pos.x; lights[idx].position[1] = pos.y; lights[idx].position[2] = pos.z; - Color color = RSG::light_storage->light_get_color(li->light); + Color color = RSG::light_storage->light_get_color(light); color = color.srgb_to_linear(); lights[idx].color[0] = color.r; lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; - lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY); - if (p_scene_render->is_using_physical_light_units()) { - lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY); + lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); + if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { + lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); // Convert from Luminous Power to Luminous Intensity if (lights[idx].type == RS::LIGHT_OMNI) { @@ -2432,11 +2440,11 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); } - lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light); - lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); - lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); - lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE))); - lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light); + lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); + lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE); + lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); + lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); idx++; } @@ -2492,7 +2500,8 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen //////////////////////////////////////////////////////////////////////////////// // VoxelGIInstance -void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { + RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); uint32_t data_version = gi->voxel_gi_get_data_version(probe); @@ -2834,7 +2843,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID last_probe_data_version = data_version; p_update_light_instances = true; //just in case - p_scene_render->_base_uniforms_changed(); + RendererSceneRenderRD::get_singleton()->base_uniforms_changed(); } // UDPDATE TIME @@ -2851,13 +2860,14 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID { Transform3D to_cell = gi->voxel_gi_get_to_cell_xform(probe); - Transform3D to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse(); + Transform3D to_probe_xform = to_cell * transform.affine_inverse(); + //update lights for (uint32_t i = 0; i < light_count; i++) { VoxelGILight &l = gi->voxel_gi_lights[i]; RID light_instance = p_light_instances[i]; - RID light = p_scene_render->light_instance_get_base_light(light_instance); + RID light = light_storage->light_instance_get_base_light(light_instance); l.type = RSG::light_storage->light_get_type(light); if (l.type == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { @@ -2868,7 +2878,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID l.attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); l.energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); - if (p_scene_render->is_using_physical_light_units()) { + if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { l.energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); l.energy *= gi->voxel_gi_get_baked_exposure_normalization(probe); @@ -2892,7 +2902,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID l.cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); l.inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); - Transform3D xform = p_scene_render->light_instance_get_base_transform(light_instance); + Transform3D xform = light_storage->light_instance_get_base_transform(light_instance); Vector3 pos = to_probe_xform.xform(xform.origin); Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_column(2)).normalized(); @@ -3087,17 +3097,17 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID Projection cm; cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]); - if (p_scene_render->cull_argument.size() == 0) { - p_scene_render->cull_argument.push_back(nullptr); + if (RendererSceneRenderRD::get_singleton()->cull_argument.size() == 0) { + RendererSceneRenderRD::get_singleton()->cull_argument.push_back(nullptr); } - p_scene_render->cull_argument[0] = instance; + RendererSceneRenderRD::get_singleton()->cull_argument[0] = instance; float exposure_normalization = 1.0; - if (p_scene_render->is_using_physical_light_units()) { + if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { exposure_normalization = gi->voxel_gi_get_baked_exposure_normalization(probe); } - p_scene_render->_render_material(to_world_xform * xform, cm, true, p_scene_render->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size), exposure_normalization); + RendererSceneRenderRD::get_singleton()->_render_material(to_world_xform * xform, cm, true, RendererSceneRenderRD::get_singleton()->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size), exposure_normalization); VoxelGIDynamicPushConstant push_constant; memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant)); @@ -3270,7 +3280,7 @@ void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, c for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - push_constant.projection[i * 4 + j] = cam_transform.matrix[i][j]; + push_constant.projection[i * 4 + j] = cam_transform.columns[i][j]; } } @@ -3480,6 +3490,10 @@ void GI::init(SkyRD *p_sky) { { //calculate tables String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n"; + if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) { + defines += "\n#define USE_VRS\n"; + } + Vector<String> gi_modes; gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_VOXEL_GI @@ -3591,7 +3605,7 @@ Ref<GI::SDFGI> GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint return sdfgi; } -void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) { +void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used) { ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); @@ -3805,10 +3819,10 @@ void GI::process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_nor push_constant.z_far = p_projections[0].get_z_far(); // these are only used if we have 1 view, else we use the projections in our scene data - push_constant.proj_info[0] = -2.0f / (internal_size.x * p_projections[0].matrix[0][0]); - push_constant.proj_info[1] = -2.0f / (internal_size.y * p_projections[0].matrix[1][1]); - push_constant.proj_info[2] = (1.0f - p_projections[0].matrix[0][2]) / p_projections[0].matrix[0][0]; - push_constant.proj_info[3] = (1.0f + p_projections[0].matrix[1][2]) / p_projections[0].matrix[1][1]; + push_constant.proj_info[0] = -2.0f / (internal_size.x * p_projections[0].columns[0][0]); + push_constant.proj_info[1] = -2.0f / (internal_size.y * p_projections[0].columns[1][1]); + push_constant.proj_info[2] = (1.0f - p_projections[0].columns[0][2]) / p_projections[0].columns[0][0]; + push_constant.proj_info[3] = (1.0f + p_projections[0].columns[1][2]) / p_projections[0].columns[1][1]; bool use_sdfgi = p_render_buffers->has_custom_data(RB_SCOPE_SDFGI); bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0; @@ -3995,7 +4009,7 @@ void GI::process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_nor u.append_id(rbgi->scene_data_ubo); uniforms.push_back(u); } - { + if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 19; @@ -4051,11 +4065,11 @@ bool GI::voxel_gi_needs_update(RID p_probe) const { return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe); } -void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe); ERR_FAIL_COND(!voxel_gi); - voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render); + voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects); } void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h index e567c67a3b..651a660f5c 100644 --- a/servers/rendering/renderer_rd/environment/gi.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* gi.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gi.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #ifndef GI_RD_H #define GI_RD_H @@ -145,7 +145,7 @@ public: Transform3D transform; - void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects); void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); void free_resources(); }; @@ -687,9 +687,9 @@ public: void debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views); void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); - void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); - void render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render, float p_exposure_normalization); - void render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); + void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data); + void render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization); + void render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result); }; RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16; @@ -812,13 +812,13 @@ public: Ref<SDFGI> create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); - void setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); + void setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used); void process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances); RID voxel_gi_instance_create(RID p_base); void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); bool voxel_gi_needs_update(RID p_probe) const; - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects); void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 307af99e91..7fff349b3c 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1,54 +1,56 @@ -/*************************************************************************/ -/* sky.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* sky.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "sky.h" #include "core/config/project_settings.h" #include "core/math/math_defs.h" #include "servers/rendering/renderer_rd/effects/copy_effects.h" +#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" #include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_globals.h" using namespace RendererRD; +#define RB_SCOPE_SKY SNAME("sky_buffers") +#define RB_HALF_TEXTURE SNAME("half_texture") +#define RB_QUARTER_TEXTURE SNAME("quarter_texture") + //////////////////////////////////////////////////////////////////////////////// // SKY SHADER -void SkyRD::SkyShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void SkyRD::SkyShaderData::set_code(const String &p_code) { //compile @@ -152,82 +154,6 @@ void SkyRD::SkyShaderData::set_code(const String &p_code) { valid = true; } -void SkyRD::SkyShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void SkyRD::SkyShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void SkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool SkyRD::SkyShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool SkyRD::SkyShaderData::is_animated() const { return false; } @@ -236,15 +162,6 @@ bool SkyRD::SkyShaderData::casts_shadows() const { return false; } -Variant SkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode SkyRD::SkyShaderData::get_native_source_code() const { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); @@ -268,7 +185,7 @@ bool SkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant uniform_set_updated = true; - return 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, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL); + return 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, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL, true); } SkyRD::SkyMaterialData::~SkyMaterialData() { @@ -293,18 +210,17 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } -void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) { +void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) { SkyPushConstant sky_push_constant; memset(&sky_push_constant, 0, sizeof(SkyPushConstant)); - for (uint32_t v = 0; v < p_view_count; v++) { - // We only need key components of our projection matrix - sky_push_constant.projections[v][0] = p_projections[v].matrix[2][0]; - sky_push_constant.projections[v][1] = p_projections[v].matrix[0][0]; - sky_push_constant.projections[v][2] = p_projections[v].matrix[2][1]; - sky_push_constant.projections[v][3] = p_projections[v].matrix[1][1]; - } + // We only need key components of our projection matrix + sky_push_constant.projection[0] = p_projection.columns[2][0]; + sky_push_constant.projection[1] = p_projection.columns[0][0]; + sky_push_constant.projection[2] = p_projection.columns[2][1]; + sky_push_constant.projection[3] = p_projection.columns[1][1]; + sky_push_constant.position[0] = p_position.x; sky_push_constant.position[1] = p_position.y; sky_push_constant.position[2] = p_position.z; @@ -361,7 +277,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo uint32_t w = p_size, h = p_size; EffectsRD *effects = RendererCompositorRD::singleton->get_effects(); - ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialized"); bool prefer_raster_effects = effects->get_prefer_raster_effects(); if (p_use_array) { @@ -431,7 +347,10 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.array_layers = 6; tf.mipmaps = p_low_quality ? 7 : mipmaps - 1; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT; + } downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView()); RD::get_singleton()->set_resource_name(downsampled_radiance_cubemap, "downsampled radiance cubemap"); @@ -465,7 +384,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); - ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialized"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); if (prefer_raster_effects) { @@ -523,7 +442,7 @@ void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); - ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialized"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); if (prefer_raster_effects) { @@ -592,7 +511,7 @@ void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_array void SkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); - ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialized"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); RD::get_singleton()->draw_command_begin_label("Update Radiance Cubemap Array Mipmaps"); @@ -629,28 +548,15 @@ void SkyRD::Sky::free() { uniform_buffer = RID(); } - if (half_res_pass.is_valid()) { - RD::get_singleton()->free(half_res_pass); - half_res_pass = RID(); - } - - if (quarter_res_pass.is_valid()) { - RD::get_singleton()->free(quarter_res_pass); - quarter_res_pass = RID(); - } - if (material.is_valid()) { RSG::material_storage->material_free(material); material = RID(); } } -RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) { +RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref<RenderSceneBuffersRD> p_render_buffers) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); - if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) { - return texture_uniform_sets[p_version]; - } Vector<RD::Uniform> uniforms; { RD::Uniform u; @@ -667,17 +573,18 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; // half res - if (half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) { - if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { + if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { + if (reflection.layers.size() && reflection.layers[0].views.size() >= 2 && reflection.layers[0].views[1].is_valid() && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) { u.append_id(reflection.layers[0].views[1]); } else { - u.append_id(half_res_pass); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } else { - if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); + RID half_texture = p_render_buffers->has_texture(RB_SCOPE_SKY, RB_HALF_TEXTURE) ? p_render_buffers->get_texture(RB_SCOPE_SKY, RB_HALF_TEXTURE) : RID(); + if (half_texture.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES) { + u.append_id(half_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); } } uniforms.push_back(u); @@ -686,24 +593,24 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; // quarter res - if (quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) { - if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { + if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { + if (reflection.layers.size() && reflection.layers[0].views.size() >= 3 && reflection.layers[0].views[2].is_valid() && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) { u.append_id(reflection.layers[0].views[2]); } else { - u.append_id(quarter_res_pass); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } else { - if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); + RID quarter_texture = p_render_buffers->has_texture(RB_SCOPE_SKY, RB_QUARTER_TEXTURE) ? p_render_buffers->get_texture(RB_SCOPE_SKY, RB_QUARTER_TEXTURE) : RID(); + if (quarter_texture.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES) { + u.append_id(quarter_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); } } uniforms.push_back(u); } - texture_uniform_sets[p_version] = RD::get_singleton()->uniform_set_create(uniforms, p_default_shader_rd, SKY_SET_TEXTURES); - return texture_uniform_sets[p_version]; + return UniformSetCacheRD::get_singleton()->get_cache_vec(p_default_shader_rd, SKY_SET_TEXTURES, uniforms); } bool SkyRD::Sky::set_radiance_size(int p_radiance_size) { @@ -772,9 +679,7 @@ Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, con Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0); RD::get_singleton()->free(rad_tex); - Ref<Image> img; - img.instantiate(); - img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data); + Ref<Image> img = Image::create_from_data(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data); for (int i = 0; i < p_size.width; i++) { for (int j = 0; j < p_size.height; j++) { Color c = img->get_pixel(i, j); @@ -1111,11 +1016,17 @@ SkyRD::~SkyRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency } -void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { +void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, uint32_t p_view_count, const Projection *p_view_projections, const Vector3 *p_view_eye_offsets, const Transform3D &p_cam_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); + ERR_FAIL_COND(p_render_buffers.is_null()); + + // make sure we support our view count + ERR_FAIL_COND(p_view_count == 0); + ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); + SkyMaterialData *material = nullptr; Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); @@ -1144,31 +1055,14 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P ERR_FAIL_COND(!shader_data); - // Invalidate supbass buffers if screen size changes - if (sky->screen_size != p_screen_size) { - sky->screen_size = p_screen_size; - sky->screen_size.x = sky->screen_size.x < 4 ? 4 : sky->screen_size.x; - sky->screen_size.y = sky->screen_size.y < 4 ? 4 : sky->screen_size.y; - if (shader_data->uses_half_res) { - if (sky->half_res_pass.is_valid()) { - RD::get_singleton()->free(sky->half_res_pass); - sky->half_res_pass = RID(); - } - invalidate_sky(sky); - } - if (shader_data->uses_quarter_res) { - if (sky->quarter_res_pass.is_valid()) { - RD::get_singleton()->free(sky->quarter_res_pass); - sky->quarter_res_pass = RID(); - } - invalidate_sky(sky); - } - } + material->set_as_used(); - // Create new subpass buffers if necessary - if ((shader_data->uses_half_res && sky->half_res_pass.is_null()) || - (shader_data->uses_quarter_res && sky->quarter_res_pass.is_null()) || - sky->radiance.is_null()) { + // Save our screen size, our buffers will already have been cleared + sky->screen_size.x = p_screen_size.x < 4 ? 4 : p_screen_size.x; + sky->screen_size.y = p_screen_size.y < 4 ? 4 : p_screen_size.y; + + // Trigger updating radiance buffers + if (sky->radiance.is_null()) { invalidate_sky(sky); update_dirty_skys(); } @@ -1189,29 +1083,28 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P sky->reflection.dirty = true; } - if (!p_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) { - sky->prev_position = p_transform.origin; + if (!p_cam_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) { + sky->prev_position = p_cam_transform.origin; sky->reflection.dirty = true; } + sky_scene_state.ubo.directional_light_count = 0; if (shader_data->uses_light) { - sky_scene_state.ubo.directional_light_count = 0; // Run through the list of lights in the scene and pick out the Directional Lights. // This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called // after the depth prepass, but this runs before the depth prepass for (int i = 0; i < (int)p_lights.size(); i++) { - RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_lights[i]); - if (!li) { + if (!light_storage->owns_light_instance(p_lights[i])) { continue; } - RID base = li->light; + RID base = light_storage->light_instance_get_base_light(p_lights[i]); ERR_CONTINUE(base.is_null()); RS::LightType type = light_storage->light_get_type(base); if (type == RS::LIGHT_DIRECTIONAL && light_storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) { SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count]; - Transform3D light_transform = li->transform; + Transform3D light_transform = light_storage->light_instance_get_base_transform(p_lights[i]); Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); sky_light_data.direction[0] = world_direction.x; @@ -1319,7 +1212,20 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P } } - sky_scene_state.ubo.z_far = p_projection.get_z_far(); + sky_scene_state.view_count = p_view_count; + sky_scene_state.cam_transform = p_cam_transform; + sky_scene_state.cam_projection = p_view_projections[0]; // We only use this when rendering a single view + + // Our info in our UBO is only used if we're rendering stereo + for (uint32_t i = 0; i < p_view_count; i++) { + RendererRD::MaterialStorage::store_camera(p_view_projections[i].inverse(), sky_scene_state.ubo.view_inv_projections[i]); + sky_scene_state.ubo.view_eye_offsets[i][0] = p_view_eye_offsets[i].x; + sky_scene_state.ubo.view_eye_offsets[i][1] = p_view_eye_offsets[i].y; + sky_scene_state.ubo.view_eye_offsets[i][2] = p_view_eye_offsets[i].z; + sky_scene_state.ubo.view_eye_offsets[i][3] = 0.0; + } + + sky_scene_state.ubo.z_far = p_view_projections[0].get_z_far(); // Should be the same for all projection sky_scene_state.ubo.fog_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_env); sky_scene_state.ubo.fog_density = RendererSceneRenderRD::get_singleton()->environment_get_fog_density(p_env); sky_scene_state.ubo.fog_aerial_perspective = RendererSceneRenderRD::get_singleton()->environment_get_fog_aerial_perspective(p_env); @@ -1336,7 +1242,8 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } -void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier) { + ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -1414,7 +1321,9 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D correction.set_depth_correction(true); cm = correction * cm; - if (shader_data->uses_quarter_res) { + // Note, we ignore environment_get_sky_orientation here as this is applied when we do our lookup in our scene shader. + + if (shader_data->uses_quarter_res && roughness_layers >= 3) { RD::get_singleton()->draw_command_begin_label("Render Sky to Quarter Res Cubemap"); PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES]; @@ -1424,16 +1333,18 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D for (int i = 0; i < 6; i++) { Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); + } else if (shader_data->uses_quarter_res && roughness_layers < 3) { + ERR_PRINT_ED("Cannot use quarter res buffer in sky shader when roughness layers is less than 3. Please increase rendering/reflections/sky_reflections/roughness_layers."); } - if (shader_data->uses_half_res) { + if (shader_data->uses_half_res && roughness_layers >= 2) { RD::get_singleton()->draw_command_begin_label("Render Sky to Half Res Cubemap"); PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES]; @@ -1443,13 +1354,15 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D for (int i = 0; i < 6; i++) { Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd, p_render_buffers); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); + } else if (shader_data->uses_half_res && roughness_layers < 2) { + ERR_PRINT_ED("Cannot use half res buffer in sky shader when roughness layers is less than 2. Please increase rendering/reflections/sky_reflections/roughness_layers."); } RD::DrawListID cubemap_draw_list; @@ -1458,10 +1371,10 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D RD::get_singleton()->draw_command_begin_label("Render Sky Cubemap"); for (int i = 0; i < 6; i++) { Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd, p_render_buffers); cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); @@ -1503,13 +1416,11 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D } } -void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier) { + ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); - ERR_FAIL_COND(p_view_count == 0); - ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; @@ -1542,105 +1453,16 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth ERR_FAIL_COND(!material); SkyShaderData *shader_data = material->shader_data; - ERR_FAIL_COND(!shader_data); - Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); - sky_transform.invert(); - - float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); - - // Camera - Projection camera; - uint32_t view_count = p_view_count; - const Projection *projections = p_projections; - - if (custom_fov) { - // With custom fov we don't support stereo... - float near_plane = p_projections[0].get_z_near(); - float far_plane = p_projections[0].get_z_far(); - float aspect = p_projections[0].get_aspect(); - - camera.set_perspective(custom_fov, aspect, near_plane, far_plane); - - view_count = 1; - projections = &camera; - } - - sky_transform = sky_transform * p_transform.basis; - - if (shader_data->uses_quarter_res) { - PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; - - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd); - - Vector<Color> clear_colors; - clear_colors.push_back(Color(0.0, 0.0, 0.0)); - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); - _render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); - RD::get_singleton()->draw_list_end(); - } - - if (shader_data->uses_half_res) { - PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES]; - - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd); - - Vector<Color> clear_colors; - clear_colors.push_back(Color(0.0, 0.0, 0.0)); - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); - _render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); - RD::get_singleton()->draw_list_end(); - } - - PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND]; - - RID texture_uniform_set; - if (sky) { - texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd); - } else { - texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set; - } - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); - _render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); - RD::get_singleton()->draw_list_end(); -} - -void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(p_env.is_null()); - - ERR_FAIL_COND(p_view_count == 0); - ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - - Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); - ERR_FAIL_COND(!sky); - - SkyMaterialData *material = nullptr; - RID sky_material; - - sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); - - if (sky_material.is_valid()) { - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); - if (!material || !material->shader_data->valid) { - material = nullptr; - } - } - - if (!material) { - sky_material = sky_shader.default_material; - material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); + if (!shader_data->uses_quarter_res && !shader_data->uses_half_res) { + return; } - ERR_FAIL_COND(!material); + material->set_as_used(); - SkyShaderData *shader_data = material->shader_data; - - ERR_FAIL_COND(!shader_data); + RENDER_TIMESTAMP("Setup Sky Resolution Buffers"); + RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers"); Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); @@ -1648,58 +1470,65 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera - Projection camera; - uint32_t view_count = p_view_count; - const Projection *projections = p_projections; + Projection projection = sky_scene_state.cam_projection; - if (custom_fov) { + if (custom_fov && sky_scene_state.view_count == 1) { // With custom fov we don't support stereo... - float near_plane = p_projections[0].get_z_near(); - float far_plane = p_projections[0].get_z_far(); - float aspect = p_projections[0].get_aspect(); + float near_plane = projection.get_z_near(); + float far_plane = projection.get_z_far(); + float aspect = projection.get_aspect(); - camera.set_perspective(custom_fov, aspect, near_plane, far_plane); - - view_count = 1; - projections = &camera; + projection.set_perspective(custom_fov, aspect, near_plane, far_plane); } - sky_transform = p_transform.basis * sky_transform; + sky_transform = sky_transform * sky_scene_state.cam_transform.basis; if (shader_data->uses_quarter_res) { - PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; + + // Grab texture and framebuffer from cache, create if needed... + uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + Size2i quarter_size = sky->screen_size / 4; + RID texture = p_render_buffers->create_texture(RB_SCOPE_SKY, RB_QUARTER_TEXTURE, texture_format, usage_bits, RD::TEXTURE_SAMPLES_1, quarter_size); + RID framebuffer = FramebufferCacheRD::get_singleton()->get_cache_multiview(sky_scene_state.view_count, texture); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers); Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); - _render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); + _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } if (shader_data->uses_half_res) { - PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES]; + + // Grab texture and framebuffer from cache, create if needed... + uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + Size2i half_size = sky->screen_size / 2; + RID texture = p_render_buffers->create_texture(RB_SCOPE_SKY, RB_HALF_TEXTURE, texture_format, usage_bits, RD::TEXTURE_SAMPLES_1, half_size); + RID framebuffer = FramebufferCacheRD::get_singleton()->get_cache_multiview(sky_scene_state.view_count, texture); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd, p_render_buffers); Vector<Color> clear_colors; clear_colors.push_back(Color(0.0, 0.0, 0.0)); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); - _render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); + _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } + + RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers } -void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier) { + ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); - ERR_FAIL_COND(p_view_count == 0); - ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; @@ -1732,43 +1561,39 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie ERR_FAIL_COND(!material); SkyShaderData *shader_data = material->shader_data; - ERR_FAIL_COND(!shader_data); + material->set_as_used(); + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera - Projection camera; - uint32_t view_count = p_view_count; - const Projection *projections = p_projections; + Projection projection = sky_scene_state.cam_projection; - if (custom_fov) { + if (custom_fov && sky_scene_state.view_count == 1) { // With custom fov we don't support stereo... - float near_plane = p_projections[0].get_z_near(); - float far_plane = p_projections[0].get_z_far(); - float aspect = p_projections[0].get_aspect(); - - camera.set_perspective(custom_fov, aspect, near_plane, far_plane); + float near_plane = projection.get_z_near(); + float far_plane = projection.get_z_far(); + float aspect = projection.get_aspect(); - view_count = 1; - projections = &camera; + projection.set_perspective(custom_fov, aspect, near_plane, far_plane); } - sky_transform = p_transform.basis * sky_transform; + sky_transform = sky_transform * sky_scene_state.cam_transform.basis; - PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND]; + PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND]; RID texture_uniform_set; if (sky) { - texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd); + texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd, p_render_buffers); } else { texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set; } - _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); + _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier); } void SkyRD::invalidate_sky(Sky *p_sky) { @@ -1783,9 +1608,11 @@ void SkyRD::update_dirty_skys() { Sky *sky = dirty_sky_list; while (sky) { - bool texture_set_dirty = false; //update sky configuration if texture is missing + // TODO See if we can move this into `update_radiance_buffers` and remove our dirty_sky logic. + // As this is basically a duplicate of the logic in reflection probes we could move this logic + // into RenderSceneBuffersRD and use that from both places. if (sky->radiance.is_null()) { int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1; @@ -1807,7 +1634,10 @@ void SkyRD::update_dirty_skys() { tf.mipmaps = mipmaps; tf.width = w; tf.height = h; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT; + } sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -1822,53 +1652,15 @@ void SkyRD::update_dirty_skys() { tf.mipmaps = MIN(mipmaps, layers); tf.width = w; tf.height = h; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT; + } sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format); } - texture_set_dirty = true; - } - - // Create subpass buffers if they haven't been created already - if (sky->half_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->half_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) { - RD::TextureFormat tformat; - tformat.format = texture_format; - tformat.width = sky->screen_size.x / 2; - tformat.height = sky->screen_size.y / 2; - tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_2D; - - sky->half_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView()); - Vector<RID> texs; - texs.push_back(sky->half_res_pass); - sky->half_res_framebuffer = RD::get_singleton()->framebuffer_create(texs); - texture_set_dirty = true; - } - - if (sky->quarter_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->quarter_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) { - RD::TextureFormat tformat; - tformat.format = texture_format; - tformat.width = sky->screen_size.x / 4; - tformat.height = sky->screen_size.y / 4; - tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_2D; - - sky->quarter_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView()); - Vector<RID> texs; - texs.push_back(sky->quarter_res_pass); - sky->quarter_res_framebuffer = RD::get_singleton()->framebuffer_create(texs); - texture_set_dirty = true; - } - - if (texture_set_dirty) { - for (int i = 0; i < SKY_TEXTURE_SET_MAX; i++) { - if (sky->texture_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(sky->texture_uniform_sets[i])) { - RD::get_singleton()->free(sky->texture_uniform_sets[i]); - sky->texture_uniform_sets[i] = RID(); - } - } } sky->reflection.dirty = true; diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index 45c4f9bda7..4ace59dfa5 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* sky.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ +/**************************************************************************/ +/* sky.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ #ifndef SKY_RD_H #define SKY_RD_H @@ -99,11 +99,11 @@ private: struct SkyPushConstant { float orientation[12]; // 48 - 48 - float projections[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 80 - float position[3]; // 12 - 92 - float time; // 4 - 96 - float pad[3]; // 12 - 108 - float luminance_multiplier; // 4 - 112 + float projection[4]; // 16 - 64 + float position[3]; // 12 - 76 + float time; // 4 - 80 + float pad[3]; // 12 - 92 + float luminance_multiplier; // 4 - 96 // 128 is the max size of a push constant. We can replace "pad" but we can't add any more. }; @@ -112,15 +112,12 @@ private: RID version; PipelineCacheRD pipelines[SKY_VERSION_MAX]; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; - String path; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time = false; bool uses_position = false; @@ -129,46 +126,47 @@ private: bool uses_light = false; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; SkyShaderData() {} virtual ~SkyShaderData(); }; - void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier); + void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier); public: struct SkySceneState { struct UBO { - uint32_t volumetric_fog_enabled; // 4 - 4 - float volumetric_fog_inv_length; // 4 - 8 - float volumetric_fog_detail_spread; // 4 - 12 - float volumetric_fog_sky_affect; // 4 - 16 - - uint32_t fog_enabled; // 4 - 20 - float fog_sky_affect; // 4 - 24 - float fog_density; // 4 - 28 - float fog_sun_scatter; // 4 - 32 - - float fog_light_color[3]; // 12 - 44 - float fog_aerial_perspective; // 4 - 48 - - float z_far; // 4 - 52 - uint32_t directional_light_count; // 4 - 56 - uint32_t pad1; // 4 - 60 - uint32_t pad2; // 4 - 64 + float view_inv_projections[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 128 + float view_eye_offsets[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 160 + + uint32_t volumetric_fog_enabled; // 4 - 164 + float volumetric_fog_inv_length; // 4 - 168 + float volumetric_fog_detail_spread; // 4 - 172 + float volumetric_fog_sky_affect; // 4 - 176 + + uint32_t fog_enabled; // 4 - 180 + float fog_sky_affect; // 4 - 184 + float fog_density; // 4 - 188 + float fog_sun_scatter; // 4 - 192 + + float fog_light_color[3]; // 12 - 204 + float fog_aerial_perspective; // 4 - 208 + + float z_far; // 4 - 212 + uint32_t directional_light_count; // 4 - 216 + uint32_t pad1; // 4 - 220 + uint32_t pad2; // 4 - 224 }; UBO ubo; + uint32_t view_count = 1; + Transform3D cam_transform; + Projection cam_projection; + SkyDirectionalLightData *directional_lights = nullptr; SkyDirectionalLightData *last_frame_directional_lights = nullptr; uint32_t max_directional_lights; @@ -247,13 +245,10 @@ public: struct Sky { RID radiance; - RID half_res_pass; - RID half_res_framebuffer; RID quarter_res_pass; RID quarter_res_framebuffer; Size2i screen_size; - RID texture_uniform_sets[SKY_TEXTURE_SET_MAX]; RID uniform_set; RID material; @@ -276,7 +271,7 @@ public: void free(); - RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd); + RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref<RenderSceneBuffersRD> p_render_buffers); bool set_radiance_size(int p_radiance_size); bool set_mode(RS::SkyMode p_mode); bool set_material(RID p_material); @@ -300,11 +295,10 @@ public: void set_texture_format(RD::DataFormat p_texture_format); ~SkyRD(); - void setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); - void update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); // only called by clustered renderer - void update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, uint32_t p_view_count, const Projection *p_view_projections, const Vector3 *p_view_eye_offsets, const Transform3D &p_cam_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); + void update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier = 1.0); + void update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier = 1.0); + void draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier = 1.0); void invalidate_sky(Sky *p_sky); void update_dirty_skys(); |