summaryrefslogtreecommitdiff
path: root/servers/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering')
-rw-r--r--servers/rendering/dummy/environment/fog.h60
-rw-r--r--servers/rendering/dummy/environment/gi.h58
-rw-r--r--servers/rendering/dummy/rasterizer_canvas_dummy.h59
-rw-r--r--servers/rendering/dummy/rasterizer_dummy.h58
-rw-r--r--servers/rendering/dummy/rasterizer_scene_dummy.h60
-rw-r--r--servers/rendering/dummy/storage/light_storage.h64
-rw-r--r--servers/rendering/dummy/storage/material_storage.h60
-rw-r--r--servers/rendering/dummy/storage/mesh_storage.cpp65
-rw-r--r--servers/rendering/dummy/storage/mesh_storage.h62
-rw-r--r--servers/rendering/dummy/storage/particles_storage.h61
-rw-r--r--servers/rendering/dummy/storage/texture_storage.cpp58
-rw-r--r--servers/rendering/dummy/storage/texture_storage.h69
-rw-r--r--servers/rendering/dummy/storage/utilities.cpp58
-rw-r--r--servers/rendering/dummy/storage/utilities.h60
-rw-r--r--servers/rendering/environment/renderer_fog.h60
-rw-r--r--servers/rendering/environment/renderer_gi.h58
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp446
-rw-r--r--servers/rendering/renderer_canvas_cull.h78
-rw-r--r--servers/rendering/renderer_canvas_render.cpp62
-rw-r--r--servers/rendering/renderer_canvas_render.h59
-rw-r--r--servers/rendering/renderer_compositor.cpp58
-rw-r--r--servers/rendering/renderer_compositor.h58
-rw-r--r--servers/rendering/renderer_geometry_instance.cpp63
-rw-r--r--servers/rendering/renderer_geometry_instance.h66
-rw-r--r--servers/rendering/renderer_rd/SCsub1
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp104
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.h157
-rw-r--r--servers/rendering/renderer_rd/effects/bokeh_dof.cpp58
-rw-r--r--servers/rendering/renderer_rd/effects/bokeh_dof.h58
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.cpp181
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.h94
-rw-r--r--servers/rendering/renderer_rd/effects/fsr.cpp58
-rw-r--r--servers/rendering/renderer_rd/effects/fsr.h58
-rw-r--r--servers/rendering/renderer_rd/effects/luminance.cpp255
-rw-r--r--servers/rendering/renderer_rd/effects/luminance.h120
-rw-r--r--servers/rendering/renderer_rd/effects/resolve.cpp58
-rw-r--r--servers/rendering/renderer_rd/effects/resolve.h62
-rw-r--r--servers/rendering/renderer_rd/effects/ss_effects.cpp1023
-rw-r--r--servers/rendering/renderer_rd/effects/ss_effects.h139
-rw-r--r--servers/rendering/renderer_rd/effects/taa.cpp58
-rw-r--r--servers/rendering/renderer_rd/effects/taa.h58
-rw-r--r--servers/rendering/renderer_rd/effects/tone_mapper.cpp58
-rw-r--r--servers/rendering/renderer_rd/effects/tone_mapper.h58
-rw-r--r--servers/rendering/renderer_rd/effects/vrs.cpp75
-rw-r--r--servers/rendering/renderer_rd/effects/vrs.h58
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp196
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h109
-rw-r--r--servers/rendering/renderer_rd/environment/fog.cpp177
-rw-r--r--servers/rendering/renderer_rd/environment/fog.h75
-rw-r--r--servers/rendering/renderer_rd/environment/gi.cpp81
-rw-r--r--servers/rendering/renderer_rd/environment/gi.h58
-rw-r--r--servers/rendering/renderer_rd/environment/sky.cpp553
-rw-r--r--servers/rendering/renderer_rd/environment/sky.h134
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp589
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h95
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp220
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h77
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp299
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h74
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp189
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h76
-rw-r--r--servers/rendering/renderer_rd/framebuffer_cache_rd.cpp58
-rw-r--r--servers/rendering/renderer_rd/framebuffer_cache_rd.h62
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.cpp58
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.h58
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp266
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h88
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp67
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h58
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp308
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h77
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp67
-rw-r--r--servers/rendering/renderer_rd/shader_rd.h58
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl63
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl5
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_render.glsl15
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl49
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/copy.glsl38
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl61
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl11
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl58
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/luminance_reduce.glsl (renamed from servers/rendering/renderer_rd/shaders/luminance_reduce.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster.glsl (renamed from servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster_inc.glsl (renamed from servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl21
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssao.glsl8
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/vrs.glsl14
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/gi.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl10
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl26
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sky.glsl61
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl21
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl120
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl20
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl51
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl7
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl15
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_data_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl7
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl14
-rw-r--r--servers/rendering/renderer_rd/shaders/skeleton.glsl30
-rw-r--r--servers/rendering/renderer_rd/spirv-reflect/SCsub17
-rw-r--r--servers/rendering/renderer_rd/storage_rd/forward_id_storage.cpp58
-rw-r--r--servers/rendering/renderer_rd/storage_rd/forward_id_storage.h58
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.cpp140
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.h76
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp211
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.h94
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp127
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.h82
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.cpp180
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.h96
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h58
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp191
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h110
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp59
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h61
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp228
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h80
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.cpp74
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.h60
-rw-r--r--servers/rendering/renderer_rd/uniform_set_cache_rd.cpp58
-rw-r--r--servers/rendering/renderer_rd/uniform_set_cache_rd.h58
-rw-r--r--servers/rendering/renderer_scene_cull.cpp190
-rw-r--r--servers/rendering/renderer_scene_cull.h75
-rw-r--r--servers/rendering/renderer_scene_occlusion_cull.cpp60
-rw-r--r--servers/rendering/renderer_scene_occlusion_cull.h58
-rw-r--r--servers/rendering/renderer_scene_render.cpp64
-rw-r--r--servers/rendering/renderer_scene_render.h62
-rw-r--r--servers/rendering/renderer_viewport.cpp267
-rw-r--r--servers/rendering/renderer_viewport.h68
-rw-r--r--servers/rendering/rendering_device.cpp470
-rw-r--r--servers/rendering/rendering_device.h146
-rw-r--r--servers/rendering/rendering_device_binds.cpp60
-rw-r--r--servers/rendering/rendering_device_binds.h60
-rw-r--r--servers/rendering/rendering_method.cpp58
-rw-r--r--servers/rendering/rendering_method.h60
-rw-r--r--servers/rendering/rendering_server_default.cpp70
-rw-r--r--servers/rendering/rendering_server_default.h81
-rw-r--r--servers/rendering/rendering_server_globals.cpp58
-rw-r--r--servers/rendering/rendering_server_globals.h58
-rw-r--r--servers/rendering/shader_compiler.cpp219
-rw-r--r--servers/rendering/shader_compiler.h62
-rw-r--r--servers/rendering/shader_language.cpp368
-rw-r--r--servers/rendering/shader_language.h69
-rw-r--r--servers/rendering/shader_preprocessor.cpp226
-rw-r--r--servers/rendering/shader_preprocessor.h65
-rw-r--r--servers/rendering/shader_types.cpp68
-rw-r--r--servers/rendering/shader_types.h58
-rw-r--r--servers/rendering/shader_warnings.cpp58
-rw-r--r--servers/rendering/shader_warnings.h58
-rw-r--r--servers/rendering/storage/camera_attributes_storage.cpp58
-rw-r--r--servers/rendering/storage/camera_attributes_storage.h58
-rw-r--r--servers/rendering/storage/environment_storage.cpp60
-rw-r--r--servers/rendering/storage/environment_storage.h62
-rw-r--r--servers/rendering/storage/light_storage.h65
-rw-r--r--servers/rendering/storage/material_storage.h60
-rw-r--r--servers/rendering/storage/mesh_storage.h59
-rw-r--r--servers/rendering/storage/particles_storage.h61
-rw-r--r--servers/rendering/storage/render_scene_buffers.cpp62
-rw-r--r--servers/rendering/storage/render_scene_buffers.h62
-rw-r--r--servers/rendering/storage/texture_storage.h68
-rw-r--r--servers/rendering/storage/utilities.cpp58
-rw-r--r--servers/rendering/storage/utilities.h60
172 files changed, 8431 insertions, 7395 deletions
diff --git a/servers/rendering/dummy/environment/fog.h b/servers/rendering/dummy/environment/fog.h
index 047b8e133d..10aa242060 100644
--- a/servers/rendering/dummy/environment/fog.h
+++ b/servers/rendering/dummy/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_DUMMY_H
#define FOG_DUMMY_H
@@ -44,7 +44,7 @@ public:
virtual void fog_volume_free(RID p_rid) override {}
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 {}
+ virtual void fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) override {}
virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override {}
virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override { return AABB(); }
virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override { return RS::FOG_VOLUME_SHAPE_BOX; }
diff --git a/servers/rendering/dummy/environment/gi.h b/servers/rendering/dummy/environment/gi.h
index fea7994cfe..a26938c740 100644
--- a/servers/rendering/dummy/environment/gi.h
+++ b/servers/rendering/dummy/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_DUMMY_H
#define GI_DUMMY_H
diff --git a/servers/rendering/dummy/rasterizer_canvas_dummy.h b/servers/rendering/dummy/rasterizer_canvas_dummy.h
index 64c4cf5024..455a669277 100644
--- a/servers/rendering/dummy/rasterizer_canvas_dummy.h
+++ b/servers/rendering/dummy/rasterizer_canvas_dummy.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rasterizer_canvas_dummy.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rasterizer_canvas_dummy.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 RASTERIZER_CANVAS_DUMMY_H
#define RASTERIZER_CANVAS_DUMMY_H
@@ -39,7 +39,6 @@ public:
void free_polygon(PolygonID p_polygon) override {}
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override {}
- void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override {}
RID light_create() override { return RID(); }
void light_set_texture(RID p_rid, RID p_texture) override {}
diff --git a/servers/rendering/dummy/rasterizer_dummy.h b/servers/rendering/dummy/rasterizer_dummy.h
index 0fde97e395..179c41f286 100644
--- a/servers/rendering/dummy/rasterizer_dummy.h
+++ b/servers/rendering/dummy/rasterizer_dummy.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rasterizer_dummy.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rasterizer_dummy.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 RASTERIZER_DUMMY_H
#define RASTERIZER_DUMMY_H
diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h
index bc8f7c523b..965d837ea8 100644
--- a/servers/rendering/dummy/rasterizer_scene_dummy.h
+++ b/servers/rendering/dummy/rasterizer_scene_dummy.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rasterizer_scene_dummy.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rasterizer_scene_dummy.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 RASTERIZER_SCENE_DUMMY_H
#define RASTERIZER_SCENE_DUMMY_H
@@ -49,6 +49,7 @@ public:
virtual void set_surface_materials(const Vector<RID> &p_materials) override {}
virtual void set_mesh_instance(RID p_mesh_instance) override {}
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override {}
+ virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override {}
virtual void set_lod_bias(float p_lod_bias) override {}
virtual void set_layer_mask(uint32_t p_layer_mask) override {}
virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {}
@@ -112,7 +113,6 @@ public:
/* ENVIRONMENT API */
void environment_glow_set_use_bicubic_upscale(bool p_enable) override {}
- void environment_glow_set_use_high_quality(bool p_enable) override {}
void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {}
diff --git a/servers/rendering/dummy/storage/light_storage.h b/servers/rendering/dummy/storage/light_storage.h
index 13c342d823..b9e8bcc6f1 100644
--- a/servers/rendering/dummy/storage/light_storage.h
+++ b/servers/rendering/dummy/storage/light_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* light_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* light_storage.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 LIGHT_STORAGE_DUMMY_H
#define LIGHT_STORAGE_DUMMY_H
@@ -80,6 +80,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override { return RS::LIGHT_BAKE_DISABLED; }
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
virtual uint64_t light_get_version(RID p_light) const override { return 0; }
+ virtual uint32_t light_get_cull_mask(RID p_light) const override { return 0; }
/* LIGHT INSTANCE API */
@@ -101,7 +102,7 @@ public:
virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override {}
virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override {}
virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) override {}
- virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override {}
+ virtual void reflection_probe_set_size(RID p_probe, const Vector3 &p_size) override {}
virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override {}
virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override {}
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override {}
@@ -114,7 +115,7 @@ public:
virtual AABB reflection_probe_get_aabb(RID p_probe) const override { return AABB(); }
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override { return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; }
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override { return 0; }
- virtual Vector3 reflection_probe_get_extents(RID p_probe) const override { return Vector3(); }
+ virtual Vector3 reflection_probe_get_size(RID p_probe) const override { return Vector3(); }
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override { return Vector3(); }
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
virtual bool reflection_probe_renders_shadows(RID p_probe) const override { return false; }
@@ -135,6 +136,7 @@ public:
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; }
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; }
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override { return false; }
+ virtual Ref<RenderSceneBuffers> reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) override { return Ref<RenderSceneBuffers>(); }
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; }
/* LIGHTMAP CAPTURE */
diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h
index ed8fefc558..e8766b4a21 100644
--- a/servers/rendering/dummy/storage/material_storage.h
+++ b/servers/rendering/dummy/storage/material_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* material_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* material_storage.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 MATERIAL_STORAGE_DUMMY_H
#define MATERIAL_STORAGE_DUMMY_H
@@ -54,7 +54,7 @@ public:
virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override { return 0; }
virtual void global_shader_parameters_instance_free(RID p_instance) override {}
- virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override {}
+ virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override {}
/* SHADER API */
diff --git a/servers/rendering/dummy/storage/mesh_storage.cpp b/servers/rendering/dummy/storage/mesh_storage.cpp
index adf736eee3..20980e0db8 100644
--- a/servers/rendering/dummy/storage/mesh_storage.cpp
+++ b/servers/rendering/dummy/storage/mesh_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* mesh_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* mesh_storage.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 "mesh_storage.h"
@@ -56,3 +56,10 @@ void MeshStorage::mesh_free(RID p_rid) {
mesh_owner.free(p_rid);
}
+
+void MeshStorage::mesh_clear(RID p_mesh) {
+ DummyMesh *m = mesh_owner.get_or_null(p_mesh);
+ ERR_FAIL_COND(!m);
+
+ m->surfaces.clear();
+}
diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h
index b0914e70e4..aba362c956 100644
--- a/servers/rendering/dummy/storage/mesh_storage.h
+++ b/servers/rendering/dummy/storage/mesh_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* mesh_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* mesh_storage.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 MESH_STORAGE_DUMMY_H
#define MESH_STORAGE_DUMMY_H
@@ -81,6 +81,7 @@ public:
s->vertex_count = p_surface.vertex_count;
s->index_data = p_surface.index_data;
s->index_count = p_surface.index_count;
+ s->aabb = p_surface.aabb;
s->skin_data = p_surface.skin_data;
}
@@ -115,7 +116,7 @@ public:
virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override { return AABB(); }
virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override {}
- virtual void mesh_clear(RID p_mesh) override {}
+ virtual void mesh_clear(RID p_mesh) override;
/* MESH INSTANCE */
@@ -125,6 +126,7 @@ public:
virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override {}
virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override {}
virtual void mesh_instance_check_for_update(RID p_mesh_instance) override {}
+ virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) override {}
virtual void update_mesh_instances() override {}
/* MULTIMESH API */
diff --git a/servers/rendering/dummy/storage/particles_storage.h b/servers/rendering/dummy/storage/particles_storage.h
index 7cee55922d..a40c96a8f5 100644
--- a/servers/rendering/dummy/storage/particles_storage.h
+++ b/servers/rendering/dummy/storage/particles_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* particles_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* particles_storage.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 PARTICLES_STORAGE_DUMMY_H
#define PARTICLES_STORAGE_DUMMY_H
@@ -89,8 +89,6 @@ public:
virtual void particles_add_collision(RID p_particles, RID p_instance) override {}
virtual void particles_remove_collision(RID p_particles, RID p_instance) override {}
- virtual void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) override {}
-
virtual void update_particles() override {}
/* PARTICLES COLLISION */
@@ -111,7 +109,6 @@ public:
virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) override {}
virtual AABB particles_collision_get_aabb(RID p_particles_collision) const override { return AABB(); }
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override { return false; }
- virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override { return RID(); }
virtual RID particles_collision_instance_create(RID p_collision) override { return RID(); }
virtual void particles_collision_instance_free(RID p_rid) override {}
diff --git a/servers/rendering/dummy/storage/texture_storage.cpp b/servers/rendering/dummy/storage/texture_storage.cpp
index 62e2a306a2..7f446eb633 100644
--- a/servers/rendering/dummy/storage/texture_storage.cpp
+++ b/servers/rendering/dummy/storage/texture_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* texture_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* texture_storage.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 "texture_storage.h"
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index 98acd5ad74..67661ce821 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* texture_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* texture_storage.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 TEXTURE_STORAGE_DUMMY_H
#define TEXTURE_STORAGE_DUMMY_H
@@ -80,6 +80,7 @@ public:
virtual void texture_free(RID p_rid) override {
// delete the texture
DummyTexture *texture = texture_owner.get_or_null(p_rid);
+ ERR_FAIL_COND(!texture);
texture_owner.free(p_rid);
memdelete(texture);
};
@@ -126,12 +127,14 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); };
+ virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override { return RID(); };
+
/* DECAL API */
virtual RID decal_allocate() override { return RID(); }
virtual void decal_initialize(RID p_rid) override {}
virtual void decal_free(RID p_rid) override{};
- virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
+ virtual void decal_set_size(RID p_decal, const Vector3 &p_size) override {}
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override {}
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
@@ -142,6 +145,7 @@ public:
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {}
virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
+ virtual uint32_t decal_get_cull_mask(RID p_decal) const override { return 0; }
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
@@ -151,6 +155,7 @@ public:
virtual RID decal_instance_create(RID p_decal) override { return RID(); }
virtual void decal_instance_free(RID p_decal_instance) override {}
virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override {}
+ virtual void decal_instance_set_sorting_offset(RID p_decal_instance, float p_sorting_offset) override {}
/* RENDER TARGET */
@@ -184,11 +189,9 @@ public:
virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override {}
virtual RID render_target_get_vrs_texture(RID p_render_target) const override { return RID(); }
- virtual void render_target_set_override_color(RID p_render_target, RID p_texture) override {}
+ virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override {}
virtual RID render_target_get_override_color(RID p_render_target) const override { return RID(); }
- virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) override {}
virtual RID render_target_get_override_depth(RID p_render_target) const override { return RID(); }
- virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) override {}
virtual RID render_target_get_override_velocity(RID p_render_target) const override { return RID(); }
virtual RID render_target_get_texture(RID p_render_target) override { return RID(); }
diff --git a/servers/rendering/dummy/storage/utilities.cpp b/servers/rendering/dummy/storage/utilities.cpp
index 125ed81917..87377de3ae 100644
--- a/servers/rendering/dummy/storage/utilities.cpp
+++ b/servers/rendering/dummy/storage/utilities.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* utilities.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* utilities.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 "utilities.h"
diff --git a/servers/rendering/dummy/storage/utilities.h b/servers/rendering/dummy/storage/utilities.h
index cb7b2a2b63..72327fbf4d 100644
--- a/servers/rendering/dummy/storage/utilities.h
+++ b/servers/rendering/dummy/storage/utilities.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* utilities.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* utilities.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 UTILITIES_DUMMY_H
#define UTILITIES_DUMMY_H
@@ -109,6 +109,8 @@ public:
virtual String get_video_adapter_vendor() const override { return String(); }
virtual RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; }
virtual String get_video_adapter_api_version() const override { return String(); }
+
+ virtual Size2i get_maximum_viewport_size() const override { return Size2i(); };
};
} // namespace RendererDummy
diff --git a/servers/rendering/environment/renderer_fog.h b/servers/rendering/environment/renderer_fog.h
index 8f38d5745e..f5c4134d14 100644
--- a/servers/rendering/environment/renderer_fog.h
+++ b/servers/rendering/environment/renderer_fog.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_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 RENDERER_FOG_H
#define RENDERER_FOG_H
@@ -44,7 +44,7 @@ public:
virtual void fog_volume_free(RID p_rid) = 0;
virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) = 0;
- virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) = 0;
+ virtual void fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) = 0;
virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) = 0;
virtual AABB fog_volume_get_aabb(RID p_fog_volume) const = 0;
virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const = 0;
diff --git a/servers/rendering/environment/renderer_gi.h b/servers/rendering/environment/renderer_gi.h
index 0faf683015..6eff319882 100644
--- a/servers/rendering/environment/renderer_gi.h
+++ b/servers/rendering/environment/renderer_gi.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_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 RENDERER_GI_H
#define RENDERER_GI_H
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index ffd8f695c6..b9e3c4f303 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_canvas_cull.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_canvas_cull.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 "renderer_canvas_cull.h"
@@ -38,17 +38,17 @@
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
-void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) {
+void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) {
RENDER_TIMESTAMP("Cull CanvasItem Tree");
memset(z_list, 0, z_range * sizeof(RendererCanvasRender::Item *));
memset(z_last_list, 0, z_range * sizeof(RendererCanvasRender::Item *));
for (int i = 0; i < p_child_item_count; i++) {
- _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true);
+ _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true, canvas_cull_mask);
}
if (p_canvas_item) {
- _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true);
+ _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true, canvas_cull_mask);
}
RendererCanvasRender::Item *list = nullptr;
@@ -223,13 +223,17 @@ void RendererCanvasCull::_attach_canvas_item_for_draw(RendererCanvasCull::Item *
}
}
-void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort) {
+void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort, uint32_t canvas_cull_mask) {
Item *ci = p_canvas_item;
if (!ci->visible) {
return;
}
+ if (!(ci->visibility_layer & canvas_cull_mask)) {
+ return;
+ }
+
if (ci->children_order_dirty) {
ci->child_items.sort_custom<ItemIndexSort>();
ci->children_order_dirty = false;
@@ -271,12 +275,12 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (ci->clip) {
if (p_canvas_clip != nullptr) {
ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect);
- if (ci->final_clip_rect == Rect2()) {
- // Clip rects do not intersect, so don't draw this item.
- return;
- }
} else {
- ci->final_clip_rect = global_rect;
+ ci->final_clip_rect = p_clip_rect.intersection(global_rect);
+ }
+ if (ci->final_clip_rect.size.width < 0.5 || ci->final_clip_rect.size.height < 0.5) {
+ // The clip rect area is 0, so don't draw the item.
+ return;
}
ci->final_clip_rect.position = ci->final_clip_rect.position.round();
ci->final_clip_rect.size = ci->final_clip_rect.size.round();
@@ -313,7 +317,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
sorter.sort(child_items, child_item_count);
for (i = 0; i < child_item_count; i++) {
- _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
+ _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false, canvas_cull_mask);
}
} else {
RendererCanvasRender::Item *canvas_group_from = nullptr;
@@ -337,19 +341,19 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (!child_items[i]->behind && !use_canvas_group) {
continue;
}
- _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true);
+ _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, canvas_cull_mask);
}
_attach_canvas_item_for_draw(ci, p_canvas_clip, r_z_list, r_z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from, xform);
for (int i = 0; i < child_item_count; i++) {
if (child_items[i]->behind || use_canvas_group) {
continue;
}
- _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true);
+ _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, canvas_cull_mask);
}
}
}
-void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) {
+void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) {
RENDER_TIMESTAMP("> Render Canvas");
sdf_used = false;
@@ -372,26 +376,26 @@ void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, co
}
if (!has_mirror) {
- _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask);
} else {
//used for parallaxlayer mirroring
for (int i = 0; i < l; i++) {
const Canvas::ChildItem &ci2 = p_canvas->child_items[i];
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask);
//mirroring (useful for scrolling backgrounds)
if (ci2.mirror.x != 0) {
Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0));
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask);
}
if (ci2.mirror.y != 0) {
Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y));
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask);
}
if (ci2.mirror.y != 0 && ci2.mirror.x != 0) {
Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror);
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask);
}
}
}
@@ -513,6 +517,20 @@ void RendererCanvasCull::canvas_item_set_transform(RID p_item, const Transform2D
canvas_item->xform = p_transform;
}
+void RendererCanvasCull::canvas_item_set_visibility_layer(RID p_item, uint32_t p_visibility_layer) {
+ Item *canvas_item = canvas_item_owner.get_or_null(p_item);
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->visibility_layer = p_visibility_layer;
+}
+
+uint32_t RendererCanvasCull::canvas_item_get_visibility_layer(RID p_item) {
+ Item *canvas_item = canvas_item_owner.get_or_null(p_item);
+ if (!canvas_item)
+ return 0;
+ return canvas_item->visibility_layer;
+}
+
void RendererCanvasCull::canvas_item_set_clip(RID p_item, bool p_clip) {
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -579,7 +597,7 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from,
Vector2 end_left;
Vector2 end_right;
- if (p_width > 1.001) {
+ if (p_width >= 0.0) {
begin_left = p_from + t;
begin_right = p_from - t;
end_left = p_to + t;
@@ -610,7 +628,7 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from,
// This value is empirically determined to provide good antialiasing quality
// while not making lines appear too soft.
float border_size = 1.25f;
- if (p_width < 1.0f) {
+ if (0.0f <= p_width && p_width < 1.0f) {
border_size *= p_width;
}
Vector2 dir2 = diff.normalized();
@@ -751,6 +769,49 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from,
}
}
+static Vector2 compute_polyline_segment_dir(const Vector<Point2> &p_points, int p_index, const Vector2 &p_prev_segment_dir) {
+ int point_count = p_points.size();
+
+ bool is_last_point = (p_index == point_count - 1);
+
+ Vector2 segment_dir;
+
+ if (is_last_point) {
+ segment_dir = p_prev_segment_dir;
+ } else {
+ segment_dir = (p_points[p_index + 1] - p_points[p_index]).normalized();
+
+ if (segment_dir.is_zero_approx()) {
+ segment_dir = p_prev_segment_dir;
+ }
+ }
+
+ return segment_dir;
+}
+
+static Vector2 compute_polyline_edge_offset_clamped(const Vector2 &p_segment_dir, const Vector2 &p_prev_segment_dir) {
+ Vector2 bisector;
+ float length = 1.0f;
+
+ bisector = (p_prev_segment_dir * p_segment_dir.length() - p_segment_dir * p_prev_segment_dir.length()).normalized();
+
+ float angle = atan2f(bisector.cross(p_prev_segment_dir), bisector.dot(p_prev_segment_dir));
+ float sin_angle = sinf(angle);
+
+ if (!Math::is_zero_approx(sin_angle) && !p_segment_dir.is_equal_approx(p_prev_segment_dir)) {
+ length = 1.0f / sin_angle;
+ length = CLAMP(length, -3.0f, 3.0f);
+ } else {
+ bisector = p_segment_dir.orthogonal();
+ }
+
+ if (bisector.is_zero_approx()) {
+ bisector = p_segment_dir.orthogonal();
+ }
+
+ return bisector * length;
+}
+
void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
ERR_FAIL_COND(p_points.size() < 2);
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
@@ -759,20 +820,68 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
Color color = Color(1, 1, 1, 1);
Vector<int> indices;
- int pc = p_points.size();
- int pc2 = pc * 2;
-
- Vector2 prev_t;
- int j2;
+ int point_count = p_points.size();
Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);
+ if (p_width < 0) {
+ if (p_antialiased) {
+ WARN_PRINT("Antialiasing is not supported for thin polylines drawn using line strips (`p_width < 0`).");
+ }
+
+ pline->primitive = RS::PRIMITIVE_LINE_STRIP;
+
+ if (p_colors.size() == 1 || p_colors.size() == point_count) {
+ pline->polygon.create(indices, p_points, p_colors);
+ } else {
+ Vector<Color> colors;
+ if (p_colors.is_empty()) {
+ colors.push_back(color);
+ } else {
+ colors.resize(point_count);
+ Color *colors_ptr = colors.ptrw();
+ for (int i = 0; i < point_count; i++) {
+ if (i < p_colors.size()) {
+ color = p_colors[i];
+ }
+ colors_ptr[i] = color;
+ }
+ }
+ pline->polygon.create(indices, p_points, colors);
+ }
+ return;
+ }
+
+ int polyline_point_count = point_count * 2;
+
+ bool loop = p_points[0].is_equal_approx(p_points[point_count - 1]);
+ Vector2 first_segment_dir;
+ Vector2 last_segment_dir;
+
+ // Search for first non-zero vector between two segments.
+ for (int i = 1; i < point_count; i++) {
+ first_segment_dir = (p_points[i] - p_points[i - 1]).normalized();
+
+ if (!first_segment_dir.is_zero_approx()) {
+ break;
+ }
+ }
+
+ // Search for last non-zero vector between two segments.
+ for (int i = point_count - 1; i >= 1; i--) {
+ last_segment_dir = (p_points[i] - p_points[i - 1]).normalized();
+
+ if (!last_segment_dir.is_zero_approx()) {
+ break;
+ }
+ }
+
PackedColorArray colors;
PackedVector2Array points;
- colors.resize(pc2);
- points.resize(pc2);
+ colors.resize(polyline_point_count);
+ points.resize(polyline_point_count);
Vector2 *points_ptr = points.ptrw();
Color *colors_ptr = colors.ptrw();
@@ -827,14 +936,14 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
PackedColorArray colors_left;
PackedVector2Array points_left;
- colors_left.resize(pc2);
- points_left.resize(pc2);
+ colors_left.resize(polyline_point_count);
+ points_left.resize(polyline_point_count);
PackedColorArray colors_right;
PackedVector2Array points_right;
- colors_right.resize(pc2);
- points_right.resize(pc2);
+ colors_right.resize(polyline_point_count);
+ points_right.resize(polyline_point_count);
Item::CommandPolygon *pline_begin = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline_begin);
@@ -880,79 +989,81 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
Color *colors_left_ptr = colors_left.ptrw();
Color *colors_right_ptr = colors_right.ptrw();
- for (int i = 0, j = 0; i < pc; i++, j += 2) {
- bool is_begin = i == 0;
- bool is_end = i == pc - 1;
+ Vector2 prev_segment_dir;
+ for (int i = 0; i < point_count; i++) {
+ bool is_first_point = (i == 0);
+ bool is_last_point = (i == point_count - 1);
- Vector2 t;
- Vector2 end_border;
- Vector2 begin_border;
- if (is_end) {
- t = prev_t;
- end_border = (p_points[i] - p_points[i - 1]).normalized() * border_size;
- } else {
- t = (p_points[i + 1] - p_points[i]).normalized().orthogonal();
- if (is_begin) {
- prev_t = t;
- begin_border = (p_points[i] - p_points[i + 1]).normalized() * border_size;
- }
+ Vector2 segment_dir = compute_polyline_segment_dir(p_points, i, prev_segment_dir);
+ if (is_first_point && loop) {
+ prev_segment_dir = last_segment_dir;
+ } else if (is_last_point && loop) {
+ prev_segment_dir = first_segment_dir;
}
- j2 = j + 1;
+ Vector2 base_edge_offset;
+ if (is_first_point && !loop) {
+ base_edge_offset = first_segment_dir.orthogonal();
+ } else if (is_last_point && !loop) {
+ base_edge_offset = last_segment_dir.orthogonal();
+ } else {
+ base_edge_offset = compute_polyline_edge_offset_clamped(segment_dir, prev_segment_dir);
+ }
- Vector2 dir = (t + prev_t).normalized();
- Vector2 tangent = dir * p_width * 0.5;
- Vector2 border = dir * border_size;
+ Vector2 edge_offset = base_edge_offset * (p_width * 0.5f);
+ Vector2 border = base_edge_offset * border_size;
Vector2 pos = p_points[i];
- points_ptr[j] = pos + tangent;
- points_ptr[j2] = pos - tangent;
+ points_ptr[i * 2 + 0] = pos + edge_offset;
+ points_ptr[i * 2 + 1] = pos - edge_offset;
- points_left_ptr[j] = pos + tangent + border;
- points_left_ptr[j2] = pos + tangent;
+ points_left_ptr[i * 2 + 0] = pos + edge_offset + border;
+ points_left_ptr[i * 2 + 1] = pos + edge_offset;
- points_right_ptr[j] = pos - tangent;
- points_right_ptr[j2] = pos - tangent - border;
+ points_right_ptr[i * 2 + 0] = pos - edge_offset;
+ points_right_ptr[i * 2 + 1] = pos - edge_offset - border;
if (i < p_colors.size()) {
color = p_colors[i];
color2 = Color(color.r, color.g, color.b, 0);
}
- colors_ptr[j] = color;
- colors_ptr[j2] = color;
+ colors_ptr[i * 2 + 0] = color;
+ colors_ptr[i * 2 + 1] = color;
- colors_left_ptr[j] = color2;
- colors_left_ptr[j2] = color;
+ colors_left_ptr[i * 2 + 0] = color2;
+ colors_left_ptr[i * 2 + 1] = color;
- colors_right_ptr[j] = color;
- colors_right_ptr[j2] = color2;
+ colors_right_ptr[i * 2 + 0] = color;
+ colors_right_ptr[i * 2 + 1] = color2;
- if (is_begin) {
- points_begin_ptr[0] = pos + tangent + begin_border;
- points_begin_ptr[1] = pos - tangent + begin_border;
- points_begin_ptr[2] = pos + tangent;
- points_begin_ptr[3] = pos - tangent;
+ if (is_first_point) {
+ Vector2 begin_border = loop ? Vector2() : -segment_dir * border_size;
+
+ points_begin_ptr[0] = pos + edge_offset + begin_border;
+ points_begin_ptr[1] = pos - edge_offset + begin_border;
+ points_begin_ptr[2] = pos + edge_offset;
+ points_begin_ptr[3] = pos - edge_offset;
colors_begin_ptr[0] = color2;
colors_begin_ptr[1] = color2;
colors_begin_ptr[2] = color;
colors_begin_ptr[3] = color;
- points_begin_left_corner_ptr[0] = pos - tangent - border;
- points_begin_left_corner_ptr[1] = pos - tangent + begin_border - border;
- points_begin_left_corner_ptr[2] = pos - tangent;
- points_begin_left_corner_ptr[3] = pos - tangent + begin_border;
+ points_begin_left_corner_ptr[0] = pos - edge_offset - border;
+ points_begin_left_corner_ptr[1] = pos - edge_offset + begin_border - border;
+ points_begin_left_corner_ptr[2] = pos - edge_offset;
+ points_begin_left_corner_ptr[3] = pos - edge_offset + begin_border;
colors_begin_left_corner_ptr[0] = color2;
colors_begin_left_corner_ptr[1] = color2;
colors_begin_left_corner_ptr[2] = color;
colors_begin_left_corner_ptr[3] = color2;
- points_begin_right_corner_ptr[0] = pos + tangent + begin_border;
- points_begin_right_corner_ptr[1] = pos + tangent + begin_border + border;
- points_begin_right_corner_ptr[2] = pos + tangent;
- points_begin_right_corner_ptr[3] = pos + tangent + border;
+ points_begin_right_corner_ptr[0] = pos + edge_offset + begin_border;
+ points_begin_right_corner_ptr[1] = pos + edge_offset + begin_border + border;
+ points_begin_right_corner_ptr[2] = pos + edge_offset;
+ points_begin_right_corner_ptr[3] = pos + edge_offset + border;
colors_begin_right_corner_ptr[0] = color2;
colors_begin_right_corner_ptr[1] = color2;
@@ -960,31 +1071,33 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
colors_begin_right_corner_ptr[3] = color2;
}
- if (is_end) {
- points_end_ptr[0] = pos + tangent + end_border;
- points_end_ptr[1] = pos - tangent + end_border;
- points_end_ptr[2] = pos + tangent;
- points_end_ptr[3] = pos - tangent;
+ if (is_last_point) {
+ Vector2 end_border = loop ? Vector2() : prev_segment_dir * border_size;
+
+ points_end_ptr[0] = pos + edge_offset + end_border;
+ points_end_ptr[1] = pos - edge_offset + end_border;
+ points_end_ptr[2] = pos + edge_offset;
+ points_end_ptr[3] = pos - edge_offset;
colors_end_ptr[0] = color2;
colors_end_ptr[1] = color2;
colors_end_ptr[2] = color;
colors_end_ptr[3] = color;
- points_end_left_corner_ptr[0] = pos - tangent - border;
- points_end_left_corner_ptr[1] = pos - tangent + end_border - border;
- points_end_left_corner_ptr[2] = pos - tangent;
- points_end_left_corner_ptr[3] = pos - tangent + end_border;
+ points_end_left_corner_ptr[0] = pos - edge_offset - border;
+ points_end_left_corner_ptr[1] = pos - edge_offset + end_border - border;
+ points_end_left_corner_ptr[2] = pos - edge_offset;
+ points_end_left_corner_ptr[3] = pos - edge_offset + end_border;
colors_end_left_corner_ptr[0] = color2;
colors_end_left_corner_ptr[1] = color2;
colors_end_left_corner_ptr[2] = color;
colors_end_left_corner_ptr[3] = color2;
- points_end_right_corner_ptr[0] = pos + tangent + end_border;
- points_end_right_corner_ptr[1] = pos + tangent + end_border + border;
- points_end_right_corner_ptr[2] = pos + tangent;
- points_end_right_corner_ptr[3] = pos + tangent + border;
+ points_end_right_corner_ptr[0] = pos + edge_offset + end_border;
+ points_end_right_corner_ptr[1] = pos + edge_offset + end_border + border;
+ points_end_right_corner_ptr[2] = pos + edge_offset;
+ points_end_right_corner_ptr[3] = pos + edge_offset + border;
colors_end_right_corner_ptr[0] = color2;
colors_end_right_corner_ptr[1] = color2;
@@ -992,7 +1105,7 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
colors_end_right_corner_ptr[3] = color2;
}
- prev_t = t;
+ prev_segment_dir = segment_dir;
}
pline_begin->primitive = RS::PRIMITIVE_TRIANGLE_STRIP;
@@ -1021,33 +1134,41 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
} else {
// Makes a single triangle strip for drawing the line.
- for (int i = 0, j = 0; i < pc; i++, j += 2) {
- Vector2 t;
- if (i == pc - 1) {
- t = prev_t;
- } else {
- t = (p_points[i + 1] - p_points[i]).normalized().orthogonal();
- if (i == 0) {
- prev_t = t;
- }
+ Vector2 prev_segment_dir;
+ for (int i = 0; i < point_count; i++) {
+ bool is_first_point = (i == 0);
+ bool is_last_point = (i == point_count - 1);
+
+ Vector2 segment_dir = compute_polyline_segment_dir(p_points, i, prev_segment_dir);
+ if (is_first_point && loop) {
+ prev_segment_dir = last_segment_dir;
+ } else if (is_last_point && loop) {
+ prev_segment_dir = first_segment_dir;
}
- j2 = j + 1;
+ Vector2 base_edge_offset;
+ if (is_first_point && !loop) {
+ base_edge_offset = first_segment_dir.orthogonal();
+ } else if (is_last_point && !loop) {
+ base_edge_offset = last_segment_dir.orthogonal();
+ } else {
+ base_edge_offset = compute_polyline_edge_offset_clamped(segment_dir, prev_segment_dir);
+ }
- Vector2 tangent = ((t + prev_t).normalized()) * p_width * 0.5;
+ Vector2 edge_offset = base_edge_offset * (p_width * 0.5f);
Vector2 pos = p_points[i];
- points_ptr[j] = pos + tangent;
- points_ptr[j2] = pos - tangent;
+ points_ptr[i * 2 + 0] = pos + edge_offset;
+ points_ptr[i * 2 + 1] = pos - edge_offset;
if (i < p_colors.size()) {
color = p_colors[i];
}
- colors_ptr[j] = color;
- colors_ptr[j2] = color;
+ colors_ptr[i * 2 + 0] = color;
+ colors_ptr[i * 2 + 1] = color;
- prev_t = t;
+ prev_segment_dir = segment_dir;
}
}
@@ -1057,18 +1178,36 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
ERR_FAIL_COND(p_points.size() < 2);
- Item *canvas_item = canvas_item_owner.get_or_null(p_item);
- ERR_FAIL_COND(!canvas_item);
-
- Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
- ERR_FAIL_COND(!pline);
- if (true || p_width <= 1) {
-#define TODO make thick lines possible
+ // TODO: `canvas_item_add_line`(`multiline`, `polyline`) share logic, should factor out.
+ if (p_width < 0) {
+ Item *canvas_item = canvas_item_owner.get_or_null(p_item);
+ ERR_FAIL_COND(!canvas_item);
+ Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
+ ERR_FAIL_COND(!pline);
pline->primitive = RS::PRIMITIVE_LINES;
pline->polygon.create(Vector<int>(), p_points, p_colors);
} else {
+ if (p_colors.size() == 1) {
+ Color color = p_colors[0];
+ for (int i = 0; i < p_points.size() >> 1; i++) {
+ Vector2 from = p_points[i * 2 + 0];
+ Vector2 to = p_points[i * 2 + 1];
+
+ canvas_item_add_line(p_item, from, to, color, p_width);
+ }
+ } else if (p_colors.size() == p_points.size() >> 1) {
+ for (int i = 0; i < p_points.size() >> 1; i++) {
+ Color color = p_colors[i];
+ Vector2 from = p_points[i * 2 + 0];
+ Vector2 to = p_points[i * 2 + 1];
+
+ canvas_item_add_line(p_item, from, to, color, p_width);
+ }
+ } else {
+ ERR_FAIL_MSG("Length of p_colors is invalid.");
+ }
}
}
@@ -1097,20 +1236,23 @@ void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos,
static const int circle_points = 64;
points.resize(circle_points);
+ Vector2 *points_ptr = points.ptrw();
const real_t circle_point_step = Math_TAU / circle_points;
for (int i = 0; i < circle_points; i++) {
float angle = i * circle_point_step;
- points.write[i].x = Math::cos(angle) * p_radius;
- points.write[i].y = Math::sin(angle) * p_radius;
- points.write[i] += p_pos;
+ points_ptr[i].x = Math::cos(angle) * p_radius;
+ points_ptr[i].y = Math::sin(angle) * p_radius;
+ points_ptr[i] += p_pos;
}
+
indices.resize((circle_points - 2) * 3);
+ int *indices_ptr = indices.ptrw();
for (int i = 0; i < circle_points - 2; i++) {
- indices.write[i * 3 + 0] = 0;
- indices.write[i * 3 + 1] = i + 1;
- indices.write[i * 3 + 2] = i + 2;
+ indices_ptr[i * 3 + 0] = 0;
+ indices_ptr[i * 3 + 1] = i + 1;
+ indices_ptr[i * 3 + 2] = i + 2;
}
Vector<Color> color;
@@ -1149,7 +1291,7 @@ void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
rect->texture = p_texture;
}
-void RendererCanvasCull::canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, int p_outline_size, float p_px_range) {
+void RendererCanvasCull::canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, int p_outline_size, float p_px_range, float p_scale) {
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -1179,7 +1321,7 @@ void RendererCanvasCull::canvas_item_add_msdf_texture_rect_region(RID p_item, co
rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_V;
rect->source.size.y = -rect->source.size.y;
}
- rect->outline = p_outline_size;
+ rect->outline = (float)p_outline_size / p_scale / 4.0;
rect->px_range = p_px_range;
}
@@ -1277,7 +1419,7 @@ void RendererCanvasCull::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_r
style->axis_y = p_y_axis_mode;
}
-void RendererCanvasCull::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width) {
+void RendererCanvasCull::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
uint32_t pc = p_points.size();
ERR_FAIL_COND(pc == 0 || pc > 4);
@@ -1946,7 +2088,7 @@ void RendererCanvasCull::update_visibility_notifiers() {
if (!visibility_notifier->enter_callable.is_null()) {
if (RSG::threaded) {
- visibility_notifier->enter_callable.call_deferredp(nullptr, 0);
+ visibility_notifier->enter_callable.call_deferred();
} else {
Callable::CallError ce;
Variant ret;
@@ -1959,7 +2101,7 @@ void RendererCanvasCull::update_visibility_notifiers() {
if (!visibility_notifier->exit_callable.is_null()) {
if (RSG::threaded) {
- visibility_notifier->exit_callable.call_deferredp(nullptr, 0);
+ visibility_notifier->exit_callable.call_deferred();
} else {
Callable::CallError ce;
Variant ret;
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index 7a01fad9de..1106fc4f1e 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_canvas_cull.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_canvas_cull.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 RENDERER_CANVAS_CULL_H
#define RENDERER_CANVAS_CULL_H
@@ -54,6 +54,7 @@ public:
Vector2 ysort_pos;
int ysort_index;
int ysort_parent_abs_z_index; // Absolute Z index of parent. Only populated and used when y-sorting.
+ uint32_t visibility_layer = 0xffffffff;
Vector<Item *> child_items;
@@ -179,14 +180,14 @@ public:
_FORCE_INLINE_ void _attach_canvas_item_for_draw(Item *ci, Item *p_canvas_clip, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, const Transform2D &xform, const Rect2 &p_clip_rect, Rect2 global_rect, const Color &modulate, int p_z, RendererCanvasCull::Item *p_material_owner, bool p_use_canvas_group, RendererCanvasRender::Item *canvas_group_from, const Transform2D &p_xform);
private:
- void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel);
- void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort);
+ void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask);
+ void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort, uint32_t canvas_cull_mask);
RendererCanvasRender::Item **z_list;
RendererCanvasRender::Item **z_last_list;
public:
- void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel);
+ void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask);
bool was_sdf_used();
@@ -206,6 +207,9 @@ public:
void canvas_item_set_visible(RID p_item, bool p_visible);
void canvas_item_set_light_mask(RID p_item, int p_mask);
+ void canvas_item_set_visibility_layer(RID p_item, uint32_t p_layer);
+ uint32_t canvas_item_get_visibility_layer(RID p_item);
+
void canvas_item_set_transform(RID p_item, const Transform2D &p_transform);
void canvas_item_set_clip(RID p_item, bool p_clip);
void canvas_item_set_distance_field_mode(RID p_item, bool p_enable);
@@ -217,17 +221,17 @@ public:
void canvas_item_set_update_when_visible(RID p_item, bool p_update);
- void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
- void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
- void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0);
+ void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = -1.0, bool p_antialiased = false);
+ void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0, bool p_antialiased = false);
+ void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0);
void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color);
void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color);
void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false);
- void canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, float p_px_range = 1.0);
+ void canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, float p_px_range = 1.0, float p_scale = 1.0);
void canvas_item_add_lcd_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1));
void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode = RS::NINE_PATCH_STRETCH, RS::NinePatchAxisMode p_y_axis_mode = RS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1));
- void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0);
+ void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture);
void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID());
void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1);
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID());
diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp
index 623f0c647b..af0ec621e5 100644
--- a/servers/rendering/renderer_canvas_render.cpp
+++ b/servers/rendering/renderer_canvas_render.cpp
@@ -1,38 +1,38 @@
-/*************************************************************************/
-/* renderer_canvas_render.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_canvas_render.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 "renderer_canvas_render.h"
#include "servers/rendering/rendering_server_globals.h"
const Rect2 &RendererCanvasRender::Item::get_rect() const {
- if (custom_rect || (!rect_dirty && !update_when_visible)) {
+ if (custom_rect || (!rect_dirty && !update_when_visible && skeleton == RID())) {
return rect;
}
@@ -80,7 +80,7 @@ const Rect2 &RendererCanvasRender::Item::get_rect() const {
} break;
case Item::Command::TYPE_MESH: {
const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
- AABB aabb = RSG::mesh_storage->mesh_get_aabb(mesh->mesh, RID());
+ AABB aabb = RSG::mesh_storage->mesh_get_aabb(mesh->mesh, skeleton);
r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
index 6791ed9626..dc838047cc 100644
--- a/servers/rendering/renderer_canvas_render.h
+++ b/servers/rendering/renderer_canvas_render.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_canvas_render.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_canvas_render.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 RENDERER_CANVAS_RENDER_H
#define RENDERER_CANVAS_RENDER_H
@@ -476,7 +476,6 @@ public:
};
virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) = 0;
- virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0;
struct LightOccluderInstance {
bool enabled;
diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp
index 80e71a0df3..069b51feaa 100644
--- a/servers/rendering/renderer_compositor.cpp
+++ b/servers/rendering/renderer_compositor.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_compositor.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_compositor.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 "renderer_compositor.h"
diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h
index 169988f72c..9fb79a290b 100644
--- a/servers/rendering/renderer_compositor.h
+++ b/servers/rendering/renderer_compositor.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_compositor.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_compositor.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 RENDERER_COMPOSITOR_H
#define RENDERER_COMPOSITOR_H
diff --git a/servers/rendering/renderer_geometry_instance.cpp b/servers/rendering/renderer_geometry_instance.cpp
index 675659f4c8..4bdd1ea5a4 100644
--- a/servers/rendering/renderer_geometry_instance.cpp
+++ b/servers/rendering/renderer_geometry_instance.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_geometry_instance.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_geometry_instance.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 "servers/rendering/renderer_geometry_instance.h"
@@ -80,6 +80,11 @@ void RenderGeometryInstanceBase::set_transform(const Transform3D &p_transform, c
lod_model_scale = max_scale;
}
+void RenderGeometryInstanceBase::set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) {
+ sorting_offset = p_sorting_offset;
+ use_aabb_center = p_use_aabb_center;
+}
+
void RenderGeometryInstanceBase::set_lod_bias(float p_lod_bias) {
lod_bias = p_lod_bias;
}
diff --git a/servers/rendering/renderer_geometry_instance.h b/servers/rendering/renderer_geometry_instance.h
index fecb9878c2..600c526396 100644
--- a/servers/rendering/renderer_geometry_instance.h
+++ b/servers/rendering/renderer_geometry_instance.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_geometry_instance.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_geometry_instance.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 RENDERER_GEOMETRY_INSTANCE_H
#define RENDERER_GEOMETRY_INSTANCE_H
@@ -50,6 +50,7 @@ public:
virtual void set_surface_materials(const Vector<RID> &p_materials) = 0;
virtual void set_mesh_instance(RID p_mesh_instance) = 0;
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) = 0;
+ virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) = 0;
virtual void set_lod_bias(float p_lod_bias) = 0;
virtual void set_layer_mask(uint32_t p_layer_mask) = 0;
virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) = 0;
@@ -86,11 +87,13 @@ public:
RID mesh_instance;
Transform3D transform;
- bool mirror = false; // move into data?
- AABB transformed_aabb; //needed for LOD
+ bool mirror = false;
+ AABB transformed_aabb;
bool non_uniform_scale = false;
float lod_model_scale = 1.0;
float lod_bias = 0.0;
+ float sorting_offset = 0.0;
+ bool use_aabb_center = true;
uint32_t layer_mask = 1;
@@ -133,6 +136,7 @@ public:
virtual void set_surface_materials(const Vector<RID> &p_materials) override;
virtual void set_mesh_instance(RID p_mesh_instance) override;
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
+ virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override;
virtual void set_lod_bias(float p_lod_bias) override;
virtual void set_layer_mask(uint32_t p_layer_mask) override;
virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override;
diff --git a/servers/rendering/renderer_rd/SCsub b/servers/rendering/renderer_rd/SCsub
index 10b83dca11..a27439e931 100644
--- a/servers/rendering/renderer_rd/SCsub
+++ b/servers/rendering/renderer_rd/SCsub
@@ -9,4 +9,5 @@ SConscript("environment/SCsub")
SConscript("forward_clustered/SCsub")
SConscript("forward_mobile/SCsub")
SConscript("shaders/SCsub")
+SConscript("spirv-reflect/SCsub")
SConscript("storage_rd/SCsub")
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index 1bb45cbcc1..959a752fba 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* cluster_builder_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* cluster_builder_rd.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 "cluster_builder_rd.h"
#include "servers/rendering/rendering_device.h"
@@ -74,7 +74,7 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
cluster_debug.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_debug.shader);
}
- { // SPHERE
+ { // Sphere mesh data.
static const uint32_t icosphere_vertex_count = 42;
static const float icosphere_vertices[icosphere_vertex_count * 3] = {
0, 0, -1, 0.7236073, -0.5257253, -0.4472195, -0.276388, -0.8506492, -0.4472199, -0.8944262, 0, -0.4472156, -0.276388, 0.8506492, -0.4472199, 0.7236073, 0.5257253, -0.4472195, 0.276388, -0.8506492, 0.4472199, -0.7236073, -0.5257253, 0.4472195, -0.7236073, 0.5257253, 0.4472195, 0.276388, 0.8506492, 0.4472199, 0.8944262, 0, 0.4472156, 0, 0, 1, -0.1624555, -0.4999952, -0.8506544, 0.4253227, -0.3090114, -0.8506542, 0.2628688, -0.8090116, -0.5257377, 0.8506479, 0, -0.5257359, 0.4253227, 0.3090114, -0.8506542, -0.5257298, 0, -0.8506517, -0.6881894, -0.4999969, -0.5257362, -0.1624555, 0.4999952, -0.8506544, -0.6881894, 0.4999969, -0.5257362, 0.2628688, 0.8090116, -0.5257377, 0.9510579, -0.3090126, 0, 0.9510579, 0.3090126, 0, 0, -1, 0, 0.5877856, -0.8090167, 0, -0.9510579, -0.3090126, 0, -0.5877856, -0.8090167, 0, -0.5877856, 0.8090167, 0, -0.9510579, 0.3090126, 0, 0.5877856, 0.8090167, 0, 0, 1, 0, 0.6881894, -0.4999969, 0.5257362, -0.2628688, -0.8090116, 0.5257377, -0.8506479, 0, 0.5257359, -0.2628688, 0.8090116, 0.5257377, 0.6881894, 0.4999969, 0.5257362, 0.1624555, -0.4999952, 0.8506544, 0.5257298, 0, 0.8506517, -0.4253227, -0.3090114, 0.8506542, -0.4253227, 0.3090114, 0.8506542, 0.1624555, 0.4999952, 0.8506544
@@ -118,7 +118,7 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
sphere_overfit = 1.0 / min_d;
}
- { // CONE
+ { // Cone mesh data.
static const uint32_t cone_vertex_count = 99;
static const float cone_vertices[cone_vertex_count * 3] = {
0, 1, -1, 0.1950903, 0.9807853, -1, 0.3826835, 0.9238795, -1, 0.5555703, 0.8314696, -1, 0.7071068, 0.7071068, -1, 0.8314697, 0.5555702, -1, 0.9238795, 0.3826834, -1, 0.9807853, 0.1950903, -1, 1, 0, -1, 0.9807853, -0.1950902, -1, 0.9238796, -0.3826833, -1, 0.8314697, -0.5555702, -1, 0.7071068, -0.7071068, -1, 0.5555702, -0.8314697, -1, 0.3826833, -0.9238796, -1, 0.1950901, -0.9807853, -1, -3.25841e-7, -1, -1, -0.1950907, -0.9807852, -1, -0.3826839, -0.9238793, -1, -0.5555707, -0.8314693, -1, -0.7071073, -0.7071063, -1, -0.83147, -0.5555697, -1, -0.9238799, -0.3826827, -1, 0, 0, 0, -0.9807854, -0.1950894, -1, -1, 9.65599e-7, -1, -0.9807851, 0.1950913, -1, -0.9238791, 0.3826845, -1, -0.8314689, 0.5555713, -1, -0.7071059, 0.7071077, -1, -0.5555691, 0.8314704, -1, -0.3826821, 0.9238801, -1, -0.1950888, 0.9807856, -1
@@ -172,7 +172,7 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
cone_overfit = 1.0 / min_d;
}
- { // BOX
+ { // Box mesh data.
static const uint32_t box_vertex_count = 8;
static const float box_vertices[box_vertex_count * 3] = {
-1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1
@@ -219,8 +219,9 @@ ClusterBuilderSharedDataRD::~ClusterBuilderSharedDataRD() {
void ClusterBuilderRD::_clear() {
if (cluster_buffer.is_null()) {
- return; //nothing to clear
+ return;
}
+
RD::get_singleton()->free(cluster_buffer);
RD::get_singleton()->free(cluster_render_buffer);
RD::get_singleton()->free(element_buffer);
@@ -254,7 +255,7 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID
cluster_screen_size.height = (p_screen_size.height - 1) / cluster_size + 1;
max_elements_by_type = p_max_elements;
- if (max_elements_by_type % 32) { //need to be 32 aligned
+ if (max_elements_by_type % 32) { // Needs to be aligned to 32.
max_elements_by_type += 32 - (max_elements_by_type % 32);
}
@@ -264,7 +265,8 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID
uint32_t element_tag_bits_size = render_element_max / 32;
uint32_t element_tag_depth_bits_size = render_element_max;
- cluster_render_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (element_tag_bits_size + element_tag_depth_bits_size) * 4; // tag bits (element was used) and tag depth (depth range in which it was used)
+
+ cluster_render_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (element_tag_bits_size + element_tag_depth_bits_size) * 4; // Tag bits (element was used) and tag depth (depth range in which it was used).
cluster_render_buffer = RD::get_singleton()->storage_buffer_create(cluster_render_buffer_size);
cluster_buffer = RD::get_singleton()->storage_buffer_create(cluster_buffer_size);
@@ -379,9 +381,9 @@ void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const Projecti
projection = p_cam_projection;
z_near = projection.get_z_near();
z_far = projection.get_z_far();
- orthogonal = p_cam_projection.is_orthogonal();
+ camera_orthogonal = p_cam_projection.is_orthogonal();
adjusted_projection = projection;
- if (!orthogonal) {
+ if (!camera_orthogonal) {
adjusted_projection.adjust_perspective_znear(0.0001);
}
@@ -390,7 +392,7 @@ void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const Projecti
projection = correction * projection;
adjusted_projection = correction * adjusted_projection;
- //reset counts
+ // Reset counts.
render_element_count = 0;
for (uint32_t i = 0; i < ELEMENT_TYPE_MAX; i++) {
cluster_count_by_type[i] = 0;
@@ -402,14 +404,14 @@ void ClusterBuilderRD::bake_cluster() {
RD::get_singleton()->draw_command_begin_label("Bake Light Cluster");
- //clear cluster buffer
+ // Clear cluster buffer.
RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
if (render_element_count > 0) {
- //clear render buffer
+ // Clear render buffer.
RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size, RD::BARRIER_MASK_RASTER);
- { //fill state uniform
+ { // Fill state uniform.
StateUniform state;
@@ -425,13 +427,13 @@ void ClusterBuilderRD::bake_cluster() {
RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
}
- //update instances
+ // Update instances.
RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
RENDER_TIMESTAMP("Render 3D Cluster Elements");
- //render elements
+ // Render elements.
{
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
ClusterBuilderSharedDataRD::ClusterRender::PushConstant push_constant = {};
@@ -447,8 +449,16 @@ void ClusterBuilderRD::bake_cluster() {
RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);
} break;
case ELEMENT_TYPE_SPOT_LIGHT: {
- RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->cone_vertex_array);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->cone_index_array);
+ // If the spot angle is above a certain threshold, use a sphere instead of a cone for building the clusters
+ // since the cone gets too flat/large (spot angle close to 90 degrees) or
+ // can't even cover the affected area of the light (spot angle above 90 degrees).
+ if (render_elements[i].has_wide_spot_angle) {
+ RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);
+ } else {
+ RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->cone_vertex_array);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->cone_index_array);
+ }
} break;
case ELEMENT_TYPE_DECAL:
case ELEMENT_TYPE_REFLECTION_PROBE: {
@@ -465,7 +475,7 @@ void ClusterBuilderRD::bake_cluster() {
}
RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE);
}
- //store elements
+ // Store elements.
RENDER_TIMESTAMP("Pack 3D Cluster Elements");
{
@@ -509,7 +519,7 @@ void ClusterBuilderRD::debug(ElementType p_element) {
push_constant.cluster_screen_size[1] = cluster_screen_size.y;
push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size);
push_constant.cluster_type = p_element;
- push_constant.orthogonal = orthogonal;
+ push_constant.orthogonal = camera_orthogonal;
push_constant.z_far = z_far;
push_constant.z_near = z_near;
push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h
index ef17ceb98c..3ca7af70ca 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.h
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* cluster_builder_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* cluster_builder_rd.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 CLUSTER_BUILDER_RD_H
#define CLUSTER_BUILDER_RD_H
@@ -43,13 +43,13 @@ class ClusterBuilderSharedDataRD {
RID sphere_vertex_array;
RID sphere_index_buffer;
RID sphere_index_array;
- float sphere_overfit = 0.0; //because an icosphere is not a perfect sphere, we need to enlarge it to cover the sphere area
+ float sphere_overfit = 0.0; // Because an icosphere is not a perfect sphere, we need to enlarge it to cover the sphere area.
RID cone_vertex_buffer;
RID cone_vertex_array;
RID cone_index_buffer;
RID cone_index_array;
- float cone_overfit = 0.0; //because an cone mesh is not a perfect sphere, we need to enlarge it to cover the actual cone area
+ float cone_overfit = 0.0; // Because an cone mesh is not a perfect cone, we need to enlarge it to cover the actual cone area.
RID box_vertex_buffer;
RID box_vertex_array;
@@ -73,6 +73,7 @@ class ClusterBuilderSharedDataRD {
ClusterRenderShaderRD cluster_render_shader;
RID shader_version;
RID shader;
+
enum PipelineVersion {
PIPELINE_NORMAL,
PIPELINE_MSAA,
@@ -85,10 +86,11 @@ class ClusterBuilderSharedDataRD {
struct ClusterStore {
struct PushConstant {
uint32_t cluster_render_data_size; // how much data for a single cluster takes
- uint32_t max_render_element_count_div_32; //divided by 32
+ uint32_t max_render_element_count_div_32; // divided by 32
uint32_t cluster_screen_size[2];
- uint32_t render_element_count_div_32; //divided by 32
- uint32_t max_cluster_element_count_div_32; //divided by 32
+ uint32_t render_element_count_div_32; // divided by 32
+ uint32_t max_cluster_element_count_div_32; // divided by 32
+
uint32_t pad1;
uint32_t pad2;
};
@@ -111,6 +113,7 @@ class ClusterBuilderSharedDataRD {
uint32_t orthogonal;
uint32_t max_cluster_element_count_div_32;
+
uint32_t pad1;
uint32_t pad2;
};
@@ -128,6 +131,8 @@ public:
class ClusterBuilderRD {
public:
+ static constexpr float WIDE_SPOT_ANGLE_THRESHOLD_DEG = 60.0f;
+
enum LightType {
LIGHT_TYPE_OMNI,
LIGHT_TYPE_SPOT
@@ -144,21 +149,20 @@ public:
ELEMENT_TYPE_DECAL,
ELEMENT_TYPE_REFLECTION_PROBE,
ELEMENT_TYPE_MAX,
-
};
private:
ClusterBuilderSharedDataRD *shared = nullptr;
struct RenderElementData {
- uint32_t type; //0-4
+ uint32_t type; // 0-4
uint32_t touches_near;
uint32_t touches_far;
uint32_t original_index;
- float transform_inv[12]; //transposed transform for less space
+ float transform_inv[12]; // Transposed transform for less space.
float scale[3];
- uint32_t pad;
- };
+ uint32_t has_wide_spot_angle;
+ }; // Keep aligned to 32 bytes.
uint32_t cluster_count_by_type[ELEMENT_TYPE_MAX] = {};
uint32_t max_elements_by_type = 0;
@@ -172,7 +176,7 @@ private:
Projection projection;
float z_far = 0;
float z_near = 0;
- bool orthogonal = false;
+ bool camera_orthogonal = false;
enum Divisor {
DIVISOR_1,
@@ -188,26 +192,27 @@ private:
Size2i cluster_screen_size;
RID framebuffer;
- RID cluster_render_buffer; //used for creating
- RID cluster_buffer; //used for rendering
- RID element_buffer; //used for storing, to hint element touches far plane or near plane
+ RID cluster_render_buffer; // Used for creating.
+ RID cluster_buffer; // Used for rendering.
+ RID element_buffer; // Used for storing, to hint element touches far plane or near plane.
uint32_t cluster_render_buffer_size = 0;
uint32_t cluster_buffer_size = 0;
RID cluster_render_uniform_set;
RID cluster_store_uniform_set;
- //persistent data
+ // Persistent data.
void _clear();
struct StateUniform {
float projection[16];
float inv_z_far;
- uint32_t screen_to_clusters_shift; // shift to obtain coordinates in block indices
- uint32_t cluster_screen_width; //
- uint32_t cluster_data_size; // how much data for a single cluster takes
+ uint32_t screen_to_clusters_shift; // Shift to obtain coordinates in block indices.
+ uint32_t cluster_screen_width;
+ uint32_t cluster_data_size; // How much data is needed for a single cluster.
uint32_t cluster_depth_offset;
+
uint32_t pad0;
uint32_t pad1;
uint32_t pad2;
@@ -224,10 +229,10 @@ public:
_FORCE_INLINE_ void add_light(LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) {
if (p_type == LIGHT_TYPE_OMNI && cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT] == max_elements_by_type) {
- return; //max number elements reached
+ return; // Max number elements reached.
}
if (p_type == LIGHT_TYPE_SPOT && cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT] == max_elements_by_type) {
- return; //max number elements reached
+ return; // Max number elements reached.
}
RenderElementData &e = render_elements[render_element_count];
@@ -242,15 +247,14 @@ public:
radius *= p_radius;
if (p_type == LIGHT_TYPE_OMNI) {
- radius *= shared->sphere_overfit; // overfit icosphere
+ radius *= shared->sphere_overfit; // Overfit icosphere.
- //omni
float depth = -xform.origin.z;
- if (orthogonal) {
+ if (camera_orthogonal) {
e.touches_near = (depth - radius) < z_near;
} else {
- //contains camera inside light
- float radius2 = radius * shared->sphere_overfit; // overfit again for outer size (camera may be outside actual sphere but behind an icosphere vertex)
+ // Contains camera inside light.
+ float radius2 = radius * shared->sphere_overfit; // Overfit again for outer size (camera may be outside actual sphere but behind an icosphere vertex)
e.touches_near = xform.origin.length_squared() < radius2 * radius2;
}
@@ -265,12 +269,11 @@ public:
cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]++;
- } else {
- //spot
- radius *= shared->cone_overfit; // overfit icosphere
+ } else /*LIGHT_TYPE_SPOT */ {
+ radius *= shared->cone_overfit; // Overfit icosphere
real_t len = Math::tan(Math::deg_to_rad(p_spot_aperture)) * radius;
- //approximate, probably better to use a cone support function
+ // Approximate, probably better to use a cone support function.
float max_d = -1e20;
float min_d = 1e20;
#define CONE_MINMAX(m_x, m_y) \
@@ -285,14 +288,13 @@ public:
CONE_MINMAX(-1, -1);
CONE_MINMAX(1, -1);
- if (orthogonal) {
+ if (camera_orthogonal) {
e.touches_near = min_d < z_near;
} else {
- //contains camera inside light
Plane base_plane(-xform.basis.get_column(Vector3::AXIS_Z), xform.origin);
float dist = base_plane.distance_to(Vector3());
if (dist >= 0 && dist < radius) {
- //inside, check angle
+ // Contains camera inside light, check angle.
float angle = Math::rad_to_deg(Math::acos((-xform.origin.normalized()).dot(-xform.basis.get_column(Vector3::AXIS_Z))));
e.touches_near = angle < p_spot_aperture * 1.05; //overfit aperture a little due to cone overfit
} else {
@@ -302,12 +304,23 @@ public:
e.touches_far = max_d > z_far;
- e.scale[0] = len * shared->cone_overfit;
- e.scale[1] = len * shared->cone_overfit;
- e.scale[2] = radius;
+ // If the spot angle is above the threshold, use a sphere instead of a cone for building the clusters
+ // since the cone gets too flat/large (spot angle close to 90 degrees) or
+ // can't even cover the affected area of the light (spot angle above 90 degrees).
+ if (p_spot_aperture > WIDE_SPOT_ANGLE_THRESHOLD_DEG) {
+ e.scale[0] = radius;
+ e.scale[1] = radius;
+ e.scale[2] = radius;
+ e.has_wide_spot_angle = true;
+ } else {
+ e.scale[0] = len * shared->cone_overfit;
+ e.scale[1] = len * shared->cone_overfit;
+ e.scale[2] = radius;
+ e.has_wide_spot_angle = false;
+ }
e.type = ELEMENT_TYPE_SPOT_LIGHT;
- e.original_index = cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]; //use omni since they share index
+ e.original_index = cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]; // Use omni light since they share index.
RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv);
@@ -317,19 +330,19 @@ public:
render_element_count++;
}
- _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform3D &p_transform, const Vector3 &p_half_extents) {
+ _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform3D &p_transform, const Vector3 &p_half_size) {
if (p_box_type == BOX_TYPE_DECAL && cluster_count_by_type[ELEMENT_TYPE_DECAL] == max_elements_by_type) {
- return; //max number elements reached
+ return; // Max number elements reached.
}
if (p_box_type == BOX_TYPE_REFLECTION_PROBE && cluster_count_by_type[ELEMENT_TYPE_REFLECTION_PROBE] == max_elements_by_type) {
- return; //max number elements reached
+ return; // Max number elements reached.
}
RenderElementData &e = render_elements[render_element_count];
Transform3D xform = view_xform * p_transform;
- //extract scale and scale the matrix by it, makes things simpler
- Vector3 scale = p_half_extents;
+ // Extract scale and scale the matrix by it, makes things simpler.
+ Vector3 scale = p_half_size;
for (uint32_t i = 0; i < 3; i++) {
float s = xform.basis.rows[i].length();
scale[i] *= s;
@@ -339,10 +352,10 @@ public:
float box_depth = Math::abs(xform.basis.xform_inv(Vector3(0, 0, -1)).dot(scale));
float depth = -xform.origin.z;
- if (orthogonal) {
+ if (camera_orthogonal) {
e.touches_near = depth - box_depth < z_near;
} else {
- //contains camera inside box
+ // Contains camera inside box.
Vector3 inside = xform.xform_inv(Vector3(0, 0, 0)).abs();
e.touches_near = inside.x < scale.x && inside.y < scale.y && inside.z < scale.z;
}
diff --git a/servers/rendering/renderer_rd/effects/bokeh_dof.cpp b/servers/rendering/renderer_rd/effects/bokeh_dof.cpp
index 27850695b0..971f8b7f6f 100644
--- a/servers/rendering/renderer_rd/effects/bokeh_dof.cpp
+++ b/servers/rendering/renderer_rd/effects/bokeh_dof.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* bokeh_dof.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* bokeh_dof.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 "bokeh_dof.h"
#include "copy_effects.h"
diff --git a/servers/rendering/renderer_rd/effects/bokeh_dof.h b/servers/rendering/renderer_rd/effects/bokeh_dof.h
index 33dbdfcdc1..13f228c476 100644
--- a/servers/rendering/renderer_rd/effects/bokeh_dof.h
+++ b/servers/rendering/renderer_rd/effects/bokeh_dof.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* bokeh_dof.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* bokeh_dof.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 BOKEH_DOF_RD_H
#define BOKEH_DOF_RD_H
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp
index 53237c1dfb..bcea9225ea 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* copy_effects.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* copy_effects.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 "copy_effects.h"
#include "core/config/project_settings.h"
@@ -56,6 +56,7 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) {
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); // BLUR_MODE_GAUSSIAN_GLOW
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); // BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE
blur_modes.push_back("\n#define MODE_COPY\n"); // BLUR_MODE_COPY
+ blur_modes.push_back("\n#define MODE_SET_COLOR\n"); // BLUR_MODE_SET_COLOR
blur_raster.shader.initialize(blur_modes);
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
@@ -105,6 +106,7 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) {
copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_COPY2
copy_modes.push_back("\n#define MULTIVIEW\n"); // COPY_TO_FB_MULTIVIEW
copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_MULTIVIEW_WITH_DEPTH
+ copy_modes.push_back("\n#define MODE_SET_COLOR\n"); // COPY_TO_FB_SET_COLOR
copy_to_fb.shader.initialize(copy_modes);
@@ -357,8 +359,8 @@ void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, cons
copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE;
}
- copy.push_constant.section[0] = 0;
- copy.push_constant.section[1] = 0;
+ copy.push_constant.section[0] = p_rect.position.x;
+ copy.push_constant.section[1] = p_rect.position.y;
copy.push_constant.section[2] = p_rect.size.width;
copy.push_constant.section[3] = p_rect.size.height;
copy.push_constant.target[0] = p_rect.position.x;
@@ -508,16 +510,18 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
- copy_to_fb.push_constant.use_section = true;
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION;
copy_to_fb.push_constant.section[0] = p_uv_rect.position.x;
copy_to_fb.push_constant.section[1] = p_uv_rect.position.y;
copy_to_fb.push_constant.section[2] = p_uv_rect.size.x;
copy_to_fb.push_constant.section[3] = p_uv_rect.size.y;
if (p_flip_y) {
- copy_to_fb.push_constant.flip_y = true;
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
}
+ copy_to_fb.push_constant.luminance_multiplier = 1.0;
+
// setup our uniforms
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
@@ -535,25 +539,35 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff
RD::get_singleton()->draw_list_draw(draw_list, true);
}
-void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview) {
+void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
ERR_FAIL_NULL(material_storage);
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
+ copy_to_fb.push_constant.luminance_multiplier = 1.0;
if (p_flip_y) {
- copy_to_fb.push_constant.flip_y = true;
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
}
if (p_force_luminance) {
- copy_to_fb.push_constant.force_luminance = true;
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE;
}
if (p_alpha_to_zero) {
- copy_to_fb.push_constant.alpha_to_zero = true;
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO;
}
if (p_srgb) {
- copy_to_fb.push_constant.srgb = true;
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_SRGB;
+ }
+ if (p_alpha_to_one) {
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE;
+ }
+ if (p_linear) {
+ // Used for copying to a linear buffer. In the mobile renderer we divide the contents of the linear buffer
+ // to allow for a wider effective range.
+ copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR;
+ copy_to_fb.push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0;
}
// setup our uniforms
@@ -608,15 +622,13 @@ void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) {
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0);
RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
-
- memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
RD::get_singleton()->draw_list_end();
}
-void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst) {
+void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, const Size2i &p_size, bool p_8bit_dst) {
ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer.");
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
@@ -628,8 +640,10 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re
copy.push_constant.section[0] = p_region.position.x;
copy.push_constant.section[1] = p_region.position.y;
- copy.push_constant.section[2] = p_region.size.width;
- copy.push_constant.section[3] = p_region.size.height;
+ copy.push_constant.target[0] = p_region.position.x;
+ copy.push_constant.target[1] = p_region.position.y;
+ copy.push_constant.section[2] = p_size.width;
+ copy.push_constant.section[3] = p_size.height;
// setup our uniforms
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
@@ -641,7 +655,6 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
ERR_FAIL_COND(shader.is_null());
- //HORIZONTAL
RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
@@ -654,7 +667,44 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re
RD::get_singleton()->compute_list_end();
}
-void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) {
+void CopyEffects::gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_region, const Size2i &p_size) {
+ ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the gaussian blur with the clustered renderer.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);
+
+ memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
+
+ BlurRasterMode blur_mode = BLUR_MODE_GAUSSIAN_BLUR;
+
+ blur_raster.push_constant.pixel_size[0] = 1.0 / float(p_size.x);
+ blur_raster.push_constant.pixel_size[1] = 1.0 / float(p_size.y);
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
+
+ RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
+
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
+void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) {
ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian glow with the mobile renderer.");
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
@@ -698,14 +748,14 @@ void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, con
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1);
}
- copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0);
+ copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1);
RD::get_singleton()->compute_list_end();
}
-void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) {
+void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) {
ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the gaussian glow with the clustered renderer.");
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
@@ -882,6 +932,36 @@ void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect
RD::get_singleton()->compute_list_end();
}
+void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region) {
+ ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the set_color shader with the clustered renderer.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
+
+ copy_to_fb.push_constant.set_color[0] = p_color.r;
+ copy_to_fb.push_constant.set_color[1] = p_color.g;
+ copy_to_fb.push_constant.set_color[2] = p_color.b;
+ copy_to_fb.push_constant.set_color[3] = p_color.a;
+
+ RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);
+
+ CopyToFBMode mode = COPY_TO_FB_SET_COLOR;
+
+ RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_region);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
@@ -1075,7 +1155,8 @@ void CopyEffects::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture,
memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant));
roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id;
- roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.
+ // Remap to perceptual-roughness^2 to create more detail in lower mips and match the mapping of cubemap_filter.
+ roughness.push_constant.roughness = p_roughness * p_roughness;
roughness.push_constant.sample_count = p_sample_count;
roughness.push_constant.use_direct_write = p_roughness == 0.0;
roughness.push_constant.face_size = p_size;
@@ -1122,8 +1203,8 @@ void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_f
roughness.push_constant.use_direct_write = p_roughness == 0.0;
roughness.push_constant.face_size = p_size;
- // setup our uniforms
- RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ // Setup our uniforms.
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h
index 0ddb60ebef..3cd26d0f7e 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.h
+++ b/servers/rendering/renderer_rd/effects/copy_effects.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* copy_effects.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* copy_effects.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 COPY_EFFECTS_RD_H
#define COPY_EFFECTS_RD_H
@@ -63,6 +63,8 @@ private:
BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE,
BLUR_MODE_COPY,
+ BLUR_MODE_SET_COLOR,
+
BLUR_MODE_MAX
};
@@ -130,8 +132,7 @@ private:
COPY_FLAG_FLIP_Y = (1 << 5),
COPY_FLAG_FORCE_LUMINANCE = (1 << 6),
COPY_FLAG_ALL_SOURCE = (1 << 7),
- COPY_FLAG_HIGH_QUALITY_GLOW = (1 << 8),
- COPY_FLAG_ALPHA_TO_ONE = (1 << 9),
+ COPY_FLAG_ALPHA_TO_ONE = (1 << 8),
};
struct CopyPushConstant {
@@ -174,19 +175,28 @@ private:
COPY_TO_FB_MULTIVIEW,
COPY_TO_FB_MULTIVIEW_WITH_DEPTH,
+
+ COPY_TO_FB_SET_COLOR,
COPY_TO_FB_MAX,
};
+ enum CopyToFBFlags {
+ COPY_TO_FB_FLAG_FLIP_Y = (1 << 0),
+ COPY_TO_FB_FLAG_USE_SECTION = (1 << 1),
+ COPY_TO_FB_FLAG_FORCE_LUMINANCE = (1 << 2),
+ COPY_TO_FB_FLAG_ALPHA_TO_ZERO = (1 << 3),
+ COPY_TO_FB_FLAG_SRGB = (1 << 4),
+ COPY_TO_FB_FLAG_ALPHA_TO_ONE = (1 << 5),
+ COPY_TO_FB_FLAG_LINEAR = (1 << 6),
+ };
+
struct CopyToFbPushConstant {
float section[4];
float pixel_size[2];
- uint32_t flip_y;
- uint32_t use_section;
+ float luminance_multiplier;
+ uint32_t flags;
- uint32_t force_luminance;
- uint32_t alpha_to_zero;
- uint32_t srgb;
- uint32_t pad;
+ float set_color[4];
};
struct CopyToFb {
@@ -316,18 +326,20 @@ public:
void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array);
void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
- void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false);
+ void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false);
void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
void copy_raster(RID p_source_texture, RID p_dest_framebuffer);
- void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst = false);
- void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0);
- void gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0);
+ void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, const Size2i &p_size, bool p_8bit_dst = false);
+ void gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_region, const Size2i &p_size);
+ void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0);
+ void gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0);
void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false);
+ void set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region);
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip);
void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size);
diff --git a/servers/rendering/renderer_rd/effects/fsr.cpp b/servers/rendering/renderer_rd/effects/fsr.cpp
index 92b34ede0e..0c51adf9ee 100644
--- a/servers/rendering/renderer_rd/effects/fsr.cpp
+++ b/servers/rendering/renderer_rd/effects/fsr.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* fsr.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* fsr.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 "fsr.h"
#include "../storage_rd/material_storage.h"
diff --git a/servers/rendering/renderer_rd/effects/fsr.h b/servers/rendering/renderer_rd/effects/fsr.h
index 69088e526a..9cb4894f8d 100644
--- a/servers/rendering/renderer_rd/effects/fsr.h
+++ b/servers/rendering/renderer_rd/effects/fsr.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* fsr.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* fsr.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 FSR_RD_H
#define FSR_RD_H
diff --git a/servers/rendering/renderer_rd/effects/luminance.cpp b/servers/rendering/renderer_rd/effects/luminance.cpp
new file mode 100644
index 0000000000..7462282932
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/luminance.cpp
@@ -0,0 +1,255 @@
+/**************************************************************************/
+/* luminance.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 "luminance.h"
+#include "../framebuffer_cache_rd.h"
+#include "../uniform_set_cache_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
+
+using namespace RendererRD;
+
+Luminance::Luminance(bool p_prefer_raster_effects) {
+ prefer_raster_effects = p_prefer_raster_effects;
+
+ if (prefer_raster_effects) {
+ Vector<String> luminance_reduce_modes;
+ luminance_reduce_modes.push_back("\n#define FIRST_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FIRST
+ luminance_reduce_modes.push_back("\n"); // LUMINANCE_REDUCE_FRAGMENT
+ luminance_reduce_modes.push_back("\n#define FINAL_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FINAL
+
+ luminance_reduce_raster.shader.initialize(luminance_reduce_modes);
+ luminance_reduce_raster.shader_version = luminance_reduce_raster.shader.version_create();
+
+ for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) {
+ luminance_reduce_raster.pipelines[i].setup(luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ }
+ } else {
+ // Initialize luminance_reduce
+ Vector<String> luminance_reduce_modes;
+ luminance_reduce_modes.push_back("\n#define READ_TEXTURE\n");
+ luminance_reduce_modes.push_back("\n");
+ luminance_reduce_modes.push_back("\n#define WRITE_LUMINANCE\n");
+
+ luminance_reduce.shader.initialize(luminance_reduce_modes);
+ luminance_reduce.shader_version = luminance_reduce.shader.version_create();
+
+ for (int i = 0; i < LUMINANCE_REDUCE_MAX; i++) {
+ luminance_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, i));
+ }
+
+ for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) {
+ luminance_reduce_raster.pipelines[i].clear();
+ }
+ }
+}
+
+Luminance::~Luminance() {
+ if (prefer_raster_effects) {
+ luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version);
+ } else {
+ luminance_reduce.shader.version_free(luminance_reduce.shader_version);
+ }
+}
+
+void Luminance::LuminanceBuffers::set_prefer_raster_effects(bool p_prefer_raster_effects) {
+ prefer_raster_effects = p_prefer_raster_effects;
+}
+
+void Luminance::LuminanceBuffers::configure(RenderSceneBuffersRD *p_render_buffers) {
+ Size2i internal_size = p_render_buffers->get_internal_size();
+ int w = internal_size.x;
+ int h = internal_size.y;
+
+ while (true) {
+ w = MAX(w / 8, 1);
+ h = MAX(h / 8, 1);
+
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R32_SFLOAT;
+ tf.width = w;
+ tf.height = h;
+
+ bool final = w == 1 && h == 1;
+
+ if (prefer_raster_effects) {
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+ } else {
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
+ if (final) {
+ tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT;
+ }
+ }
+
+ RID texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ reduce.push_back(texture);
+
+ if (final) {
+ current = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ break;
+ }
+ }
+}
+
+void Luminance::LuminanceBuffers::free_data() {
+ for (int i = 0; i < reduce.size(); i++) {
+ RD::get_singleton()->free(reduce[i]);
+ }
+ reduce.clear();
+
+ if (current.is_valid()) {
+ RD::get_singleton()->free(current);
+ current = RID();
+ }
+}
+
+Ref<Luminance::LuminanceBuffers> Luminance::get_luminance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers) {
+ if (p_render_buffers->has_custom_data(RB_LUMINANCE_BUFFERS)) {
+ return p_render_buffers->get_custom_data(RB_LUMINANCE_BUFFERS);
+ }
+
+ Ref<LuminanceBuffers> buffers;
+ buffers.instantiate();
+ buffers->set_prefer_raster_effects(prefer_raster_effects);
+ buffers->configure(p_render_buffers.ptr());
+
+ p_render_buffers->set_custom_data(RB_LUMINANCE_BUFFERS, buffers);
+
+ return buffers;
+}
+
+RID Luminance::get_current_luminance_buffer(Ref<RenderSceneBuffersRD> p_render_buffers) {
+ if (p_render_buffers->has_custom_data(RB_LUMINANCE_BUFFERS)) {
+ Ref<LuminanceBuffers> buffers = p_render_buffers->get_custom_data(RB_LUMINANCE_BUFFERS);
+ return buffers->current;
+ }
+
+ return RID();
+}
+
+void Luminance::luminance_reduction(RID p_source_texture, const Size2i p_source_size, Ref<LuminanceBuffers> p_luminance_buffers, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ if (prefer_raster_effects) {
+ LuminanceReduceRasterPushConstant push_constant;
+ memset(&push_constant, 0, sizeof(LuminanceReduceRasterPushConstant));
+
+ push_constant.max_luminance = p_max_luminance;
+ push_constant.min_luminance = p_min_luminance;
+ push_constant.exposure_adjust = p_adjust;
+
+ for (int i = 0; i < p_luminance_buffers->reduce.size(); i++) {
+ push_constant.source_size[0] = i == 0 ? p_source_size.x : push_constant.dest_size[0];
+ push_constant.source_size[1] = i == 0 ? p_source_size.y : push_constant.dest_size[1];
+ push_constant.dest_size[0] = MAX(push_constant.source_size[0] / 8, 1);
+ push_constant.dest_size[1] = MAX(push_constant.source_size[1] / 8, 1);
+
+ bool final = !p_set && (push_constant.dest_size[0] == 1) && (push_constant.dest_size[1] == 1);
+ LuminanceReduceRasterMode mode = final ? LUMINANCE_REDUCE_FRAGMENT_FINAL : (i == 0 ? LUMINANCE_REDUCE_FRAGMENT_FIRST : LUMINANCE_REDUCE_FRAGMENT);
+ RID shader = luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, mode);
+
+ RID framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_luminance_buffers->reduce[i]);
+
+ RD::Uniform u_source_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, i == 0 ? p_source_texture : p_luminance_buffers->reduce[i - 1] }));
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, luminance_reduce_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0);
+ if (final) {
+ RD::Uniform u_current_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_luminance_buffers->current }));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_current_texture), 1);
+ }
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(LuminanceReduceRasterPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+ }
+ } else {
+ LuminanceReducePushConstant push_constant;
+ memset(&push_constant, 0, sizeof(LuminanceReducePushConstant));
+
+ push_constant.source_size[0] = p_source_size.x;
+ push_constant.source_size[1] = p_source_size.y;
+ push_constant.max_luminance = p_max_luminance;
+ push_constant.min_luminance = p_min_luminance;
+ push_constant.exposure_adjust = p_adjust;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ for (int i = 0; i < p_luminance_buffers->reduce.size(); i++) {
+ RID shader;
+
+ if (i == 0) {
+ shader = luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, LUMINANCE_REDUCE_READ);
+ RD::Uniform u_source_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_texture }));
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_READ]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0);
+ } else {
+ RD::get_singleton()->compute_list_add_barrier(compute_list); //needs barrier, wait until previous is done
+
+ if (i == p_luminance_buffers->reduce.size() - 1 && !p_set) {
+ shader = luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, LUMINANCE_REDUCE_WRITE);
+ RD::Uniform u_current_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_luminance_buffers->current }));
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_WRITE]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_current_texture), 2);
+ } else {
+ shader = luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, LUMINANCE_REDUCE);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE]);
+ }
+
+ RD::Uniform u_source_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_luminance_buffers->reduce[i - 1]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0);
+ }
+
+ RD::Uniform u_reduce_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_luminance_buffers->reduce[i]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_reduce_texture), 1);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(LuminanceReducePushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.source_size[0], push_constant.source_size[1], 1);
+
+ push_constant.source_size[0] = MAX(push_constant.source_size[0] / 8, 1);
+ push_constant.source_size[1] = MAX(push_constant.source_size[1] / 8, 1);
+ }
+
+ RD::get_singleton()->compute_list_end();
+ }
+
+ SWAP(p_luminance_buffers->current, p_luminance_buffers->reduce.write[p_luminance_buffers->reduce.size() - 1]);
+}
diff --git a/servers/rendering/renderer_rd/effects/luminance.h b/servers/rendering/renderer_rd/effects/luminance.h
new file mode 100644
index 0000000000..0f343fceab
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/luminance.h
@@ -0,0 +1,120 @@
+/**************************************************************************/
+/* luminance.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 LUMINANCE_RD_H
+#define LUMINANCE_RD_H
+
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/shaders/effects/luminance_reduce.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
+#include "servers/rendering/renderer_scene_render.h"
+
+#include "servers/rendering_server.h"
+
+#define RB_LUMINANCE_BUFFERS SNAME("luminance_buffers")
+
+namespace RendererRD {
+
+class Luminance {
+private:
+ bool prefer_raster_effects;
+
+ enum LuminanceReduceMode {
+ LUMINANCE_REDUCE_READ,
+ LUMINANCE_REDUCE,
+ LUMINANCE_REDUCE_WRITE,
+ LUMINANCE_REDUCE_MAX
+ };
+
+ struct LuminanceReducePushConstant {
+ int32_t source_size[2];
+ float max_luminance;
+ float min_luminance;
+ float exposure_adjust;
+ float pad[3];
+ };
+
+ struct LuminanceReduce {
+ LuminanceReduceShaderRD shader;
+ RID shader_version;
+ RID pipelines[LUMINANCE_REDUCE_MAX];
+ } luminance_reduce;
+
+ enum LuminanceReduceRasterMode {
+ LUMINANCE_REDUCE_FRAGMENT_FIRST,
+ LUMINANCE_REDUCE_FRAGMENT,
+ LUMINANCE_REDUCE_FRAGMENT_FINAL,
+ LUMINANCE_REDUCE_FRAGMENT_MAX
+ };
+
+ struct LuminanceReduceRasterPushConstant {
+ int32_t source_size[2];
+ int32_t dest_size[2];
+ float exposure_adjust;
+ float min_luminance;
+ float max_luminance;
+ uint32_t pad1;
+ };
+
+ struct LuminanceReduceFragment {
+ LuminanceReduceRasterShaderRD shader;
+ RID shader_version;
+ PipelineCacheRD pipelines[LUMINANCE_REDUCE_FRAGMENT_MAX];
+ } luminance_reduce_raster;
+
+public:
+ class LuminanceBuffers : public RenderBufferCustomDataRD {
+ GDCLASS(LuminanceBuffers, RenderBufferCustomDataRD);
+
+ private:
+ bool prefer_raster_effects;
+
+ public:
+ Vector<RID> reduce;
+ RID current;
+
+ virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
+ virtual void free_data() override;
+
+ void set_prefer_raster_effects(bool p_prefer_raster_effects);
+ };
+
+ Ref<LuminanceBuffers> get_luminance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers);
+ RID get_current_luminance_buffer(Ref<RenderSceneBuffersRD> p_render_buffers);
+ void luminance_reduction(RID p_source_texture, const Size2i p_source_size, Ref<LuminanceBuffers> p_luminance_buffers, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
+
+ Luminance(bool p_prefer_raster_effects);
+ ~Luminance();
+};
+
+} // namespace RendererRD
+
+#endif // LUMINANCE_RD_H
diff --git a/servers/rendering/renderer_rd/effects/resolve.cpp b/servers/rendering/renderer_rd/effects/resolve.cpp
index 6c49a2ebce..18671d06e1 100644
--- a/servers/rendering/renderer_rd/effects/resolve.cpp
+++ b/servers/rendering/renderer_rd/effects/resolve.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* resolve.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* resolve.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 "resolve.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
diff --git a/servers/rendering/renderer_rd/effects/resolve.h b/servers/rendering/renderer_rd/effects/resolve.h
index 2a4cd06827..fcc1021904 100644
--- a/servers/rendering/renderer_rd/effects/resolve.h
+++ b/servers/rendering/renderer_rd/effects/resolve.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* resolve.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* resolve.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 RESOLVE_RD_H
#define RESOLVE_RD_H
@@ -65,8 +65,8 @@ public:
Resolve();
~Resolve();
- void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
- void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
+ void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
};
} // namespace RendererRD
diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp
index 9653382e96..e031e33041 100644
--- a/servers/rendering/renderer_rd/effects/ss_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* ss_effects.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* ss_effects.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 "ss_effects.h"
@@ -411,12 +411,21 @@ SSEffects::~SSEffects() {
/* SS Downsampler */
-void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, bool p_invalidate_uniform_set, Size2i p_full_screen_size, const Projection &p_projection) {
+void SSEffects::downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_view, const Projection &p_projection) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
ERR_FAIL_NULL(material_storage);
+ uint32_t view_count = p_render_buffers->get_view_count();
+ Size2i full_screen_size = p_render_buffers->get_internal_size();
+ Size2i size((full_screen_size.x + 1) / 2, (full_screen_size.y + 1) / 2);
+
+ // Make sure our buffers exist, buffers are automatically cleared if view count or size changes.
+ if (!p_render_buffers->has_texture(RB_SCOPE_SSDS, RB_LINEAR_DEPTH)) {
+ p_render_buffers->create_texture(RB_SCOPE_SSDS, RB_LINEAR_DEPTH, RD::DATA_FORMAT_R16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, size, view_count * 4, 5);
+ }
+
// Downsample and deinterleave the depth buffer for SSAO and SSIL
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -447,45 +456,32 @@ void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_
}
}
+ RID shader = ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, downsample_mode);
int depth_index = use_half_size ? 1 : 0;
RD::get_singleton()->draw_command_begin_label("Downsample Depth");
- if (p_invalidate_uniform_set || use_full_mips != ss_effects.used_full_mips_last_frame || use_half_size != ss_effects.used_half_size_last_frame || use_mips != ss_effects.used_mips_last_frame) {
- if (ss_effects.downsample_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(ss_effects.downsample_uniform_set)) {
- RD::get_singleton()->free(ss_effects.downsample_uniform_set);
- ss_effects.downsample_uniform_set = RID();
- }
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.append_id(p_depth_mipmaps[depth_index + 1]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.append_id(p_depth_mipmaps[depth_index + 2]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.append_id(p_depth_mipmaps[depth_index + 3]);
- uniforms.push_back(u);
- }
- if (use_full_mips) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- u.append_id(p_depth_mipmaps[4]);
- uniforms.push_back(u);
+ RID downsample_uniform_set;
+ if (use_mips) {
+ // Grab our downsample uniform set from cache, these are automatically cleaned up if the depth textures are cleared.
+ // This also ensures we can switch between left eye and right eye uniform sets without recreating the uniform twice a frame.
+ Vector<RD::Uniform> u_depths;
+
+ // Note, use_full_mips is true if either SSAO or SSIL uses half size, but the other full size and we're using mips.
+ // That means we're filling all 5 levels.
+ // In this scenario `depth_index` will be 0.
+ for (int i = 0; i < (use_full_mips ? 4 : 3); i++) {
+ RID depth_mipmap = p_render_buffers->get_texture_slice(RB_SCOPE_SSDS, RB_LINEAR_DEPTH, p_view * 4, depth_index + i + 1, 4, 1);
+
+ RD::Uniform u_depth;
+ u_depth.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u_depth.binding = i;
+ u_depth.append_id(depth_mipmap);
+ u_depths.push_back(u_depth);
}
- ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2);
+
+ // This before only used SS_EFFECTS_DOWNSAMPLE_MIPMAP or SS_EFFECTS_DOWNSAMPLE_FULL_MIPS
+ downsample_uniform_set = uniform_set_cache->get_cache_vec(shader, 2, u_depths);
}
float depth_linearize_mul = -p_projection.columns[3][2];
@@ -501,25 +497,30 @@ void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_
ss_effects.downsample_push_constant.z_near = p_projection.get_z_near();
ss_effects.downsample_push_constant.z_far = p_projection.get_z_far();
}
- ss_effects.downsample_push_constant.pixel_size[0] = 1.0 / p_full_screen_size.x;
- ss_effects.downsample_push_constant.pixel_size[1] = 1.0 / p_full_screen_size.y;
+ ss_effects.downsample_push_constant.pixel_size[0] = 1.0 / full_screen_size.x;
+ ss_effects.downsample_push_constant.pixel_size[1] = 1.0 / full_screen_size.y;
ss_effects.downsample_push_constant.radius_sq = 1.0;
- RID shader = ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, downsample_mode);
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- RD::Uniform u_depth_buffer(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_depth_buffer }));
- RD::Uniform u_depth_mipmaps(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_depth_mipmaps[depth_index + 0] }));
+ RID depth_texture = p_render_buffers->get_depth_texture(p_view);
+ RID depth_mipmap = p_render_buffers->get_texture_slice(RB_SCOPE_SSDS, RB_LINEAR_DEPTH, p_view * 4, depth_index, 4, 1);
+
+ RD::Uniform u_depth_buffer(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, depth_texture }));
+ RD::Uniform u_depth_mipmap(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ depth_mipmap }));
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ss_effects.pipelines[downsample_mode]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_depth_buffer), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth_mipmaps), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth_mipmap), 1);
if (use_mips) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ss_effects.downsample_uniform_set, 2);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, downsample_uniform_set, 2);
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant));
- Size2i size(MAX(1, p_full_screen_size.x >> (use_half_size ? 2 : 1)), MAX(1, p_full_screen_size.y >> (use_half_size ? 2 : 1)));
+ if (use_half_size) {
+ size.x = MAX(1, size.x >> 1);
+ size.y = MAX(1, size.y >> 1);
+ }
RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -543,7 +544,7 @@ void SSEffects::ssil_set_quality(RS::EnvironmentSSILQuality p_quality, bool p_ha
ssil_fadeout_to = p_fadeout_to;
}
-void SSEffects::gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set) {
+void SSEffects::gather_ssil(RD::ComputeListID p_compute_list, const RID *p_ssil_slices, const RID *p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
@@ -578,12 +579,13 @@ void SSEffects::gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID>
RD::get_singleton()->compute_list_add_barrier(p_compute_list);
}
-void SSEffects::ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth) {
+void SSEffects::ssil_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings) {
if (p_ssil_buffers.half_size != ssil_half_size) {
- ssil_free(p_ssil_buffers);
+ p_render_buffers->clear_context(RB_SCOPE_SSIL);
}
- if (ssil_half_size) {
+ p_ssil_buffers.half_size = ssil_half_size;
+ if (p_ssil_buffers.half_size) {
p_ssil_buffers.buffer_width = (p_settings.full_screen_size.x + 3) / 4;
p_ssil_buffers.buffer_height = (p_settings.full_screen_size.y + 3) / 4;
p_ssil_buffers.half_buffer_width = (p_settings.full_screen_size.x + 7) / 8;
@@ -595,104 +597,59 @@ void SSEffects::ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const S
p_ssil_buffers.half_buffer_height = (p_settings.full_screen_size.y + 3) / 4;
}
- if (p_ssil_buffers.ssil_final.is_null()) {
- {
- p_ssil_buffers.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_linear_depth, 0, ssil_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.width = p_settings.full_screen_size.x;
- tf.height = p_settings.full_screen_size.y;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
- p_ssil_buffers.ssil_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssil_buffers.ssil_final, "SSIL texture");
- RD::get_singleton()->texture_clear(p_ssil_buffers.ssil_final, Color(0, 0, 0, 0), 0, 1, 0, 1);
- if (p_ssil_buffers.last_frame.is_null()) {
- tf.mipmaps = 6;
- p_ssil_buffers.last_frame = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssil_buffers.last_frame, "Last Frame Radiance");
- RD::get_singleton()->texture_clear(p_ssil_buffers.last_frame, Color(0, 0, 0, 0), 0, tf.mipmaps, 0, 1);
- for (uint32_t i = 0; i < 6; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.last_frame, 0, i);
- p_ssil_buffers.last_frame_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "Last Frame Radiance Mip " + itos(i) + " ");
- }
- }
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = p_ssil_buffers.buffer_width;
- tf.height = p_ssil_buffers.buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssil_buffers.deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssil_buffers.deinterleaved, "SSIL deinterleaved buffer");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.deinterleaved, i, 0);
- p_ssil_buffers.deinterleaved_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer array " + itos(i) + " ");
- }
- }
+ uint32_t view_count = p_render_buffers->get_view_count();
+ Size2i full_size = Size2i(p_ssil_buffers.buffer_width, p_ssil_buffers.buffer_height);
+ Size2i half_size = Size2i(p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height);
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = p_ssil_buffers.buffer_width;
- tf.height = p_ssil_buffers.buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssil_buffers.pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssil_buffers.pong, "SSIL deinterleaved pong buffer");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.pong, i, 0);
- p_ssil_buffers.pong_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer pong array " + itos(i) + " ");
- }
- }
+ // We create our intermediate and final results as render buffers.
+ // These are automatically cached and cleaned up when our viewport resizes
+ // or when our viewport gets destroyed.
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = p_ssil_buffers.buffer_width;
- tf.height = p_ssil_buffers.buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssil_buffers.edges = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssil_buffers.edges, "SSIL edges buffer");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.edges, i, 0);
- p_ssil_buffers.edges_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSIL edges buffer slice " + itos(i) + " ");
- }
- }
+ if (!p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_FINAL)) { // We don't strictly have to check if it exists but we only want to clear it when we create it...
+ RID final = p_render_buffers->create_texture(RB_SCOPE_SSIL, RB_FINAL, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT);
+ RD::get_singleton()->texture_clear(final, Color(0, 0, 0, 0), 0, 1, 0, view_count);
+ }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = p_ssil_buffers.half_buffer_width;
- tf.height = p_ssil_buffers.half_buffer_height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssil_buffers.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssil_buffers.importance_map[0], "SSIL Importance Map");
- p_ssil_buffers.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssil_buffers.importance_map[1], "SSIL Importance Map Pong");
- }
- p_ssil_buffers.half_size = ssil_half_size;
+ if (!p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_LAST_FRAME)) {
+ RID last_frame = p_render_buffers->create_texture(RB_SCOPE_SSIL, RB_LAST_FRAME, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT, RD::TEXTURE_SAMPLES_1, p_settings.full_screen_size, 0, 6);
+ RD::get_singleton()->texture_clear(last_frame, Color(0, 0, 0, 0), 0, 6, 0, view_count);
}
+
+ // As we're not clearing these, and render buffers will return the cached texture if it already exists,
+ // we don't first check has_texture here
+
+ p_render_buffers->create_texture(RB_SCOPE_SSIL, RB_DEINTERLEAVED, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, full_size, 4 * view_count);
+ p_render_buffers->create_texture(RB_SCOPE_SSIL, RB_DEINTERLEAVED_PONG, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, full_size, 4 * view_count);
+ p_render_buffers->create_texture(RB_SCOPE_SSIL, RB_EDGES, RD::DATA_FORMAT_R8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, full_size, 4 * view_count);
+ p_render_buffers->create_texture(RB_SCOPE_SSIL, RB_IMPORTANCE_MAP, RD::DATA_FORMAT_R8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, half_size);
+ p_render_buffers->create_texture(RB_SCOPE_SSIL, RB_IMPORTANCE_PONG, RD::DATA_FORMAT_R8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, half_size);
}
-void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings) {
+void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
ERR_FAIL_NULL(material_storage);
RD::get_singleton()->draw_command_begin_label("Process Screen Space Indirect Lighting");
+
+ // Obtain our (cached) buffer slices for the view we are rendering.
+ RID last_frame = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_LAST_FRAME, p_view, 0, 1, 6);
+ RID deinterleaved = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_DEINTERLEAVED, p_view * 4, 0, 4, 1);
+ RID deinterleaved_pong = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_DEINTERLEAVED_PONG, 4 * p_view, 0, 4, 1);
+ RID edges = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_EDGES, 4 * p_view, 0, 4, 1);
+ RID importance_map = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_IMPORTANCE_MAP, p_view, 0);
+ RID importance_pong = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_IMPORTANCE_PONG, p_view, 0);
+
+ RID deinterleaved_slices[4];
+ RID deinterleaved_pong_slices[4];
+ RID edges_slices[4];
+ for (uint32_t i = 0; i < 4; i++) {
+ deinterleaved_slices[i] = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_DEINTERLEAVED, p_view * 4 + i, 0);
+ deinterleaved_pong_slices[i] = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_DEINTERLEAVED_PONG, p_view * 4 + i, 0);
+ edges_slices[i] = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_EDGES, p_view * 4 + i, 0);
+ }
+
//Store projection info before starting the compute list
SSILProjectionUniforms projection_uniforms;
store_camera(p_last_projection, projection_uniforms.inv_last_frame_projection_matrix);
@@ -701,7 +658,7 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
memset(&ssil.gather_push_constant, 0, sizeof(SSILGatherPushConstant));
- RID shader = ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0);
+ RID shader = ssil.gather_shader.version_get_shader(ssil.gather_shader_version, SSIL_GATHER);
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
@@ -749,78 +706,69 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
ssil.gather_push_constant.quality = MAX(0, ssil_quality - 1);
ssil.gather_push_constant.size_multiplier = ssil_half_size ? 2 : 1;
- if (p_ssil_buffers.projection_uniform_set.is_null()) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 0;
- u.append_id(default_mipmap_sampler);
- u.append_id(p_ssil_buffers.last_frame);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 1;
- u.append_id(ssil.projection_uniform_buffer);
- uniforms.push_back(u);
- }
- p_ssil_buffers.projection_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 3);
+ // We are using our uniform cache so our uniform sets are automatically freed when our textures are freed.
+ // It also ensures that we're reusing the right cached entry in a multiview situation without us having to
+ // remember each instance of the uniform set.
+
+ RID projection_uniform_set;
+ {
+ RD::Uniform u_last_frame;
+ u_last_frame.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u_last_frame.binding = 0;
+ u_last_frame.append_id(default_mipmap_sampler);
+ u_last_frame.append_id(last_frame);
+
+ RD::Uniform u_projection;
+ u_projection.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u_projection.binding = 1;
+ u_projection.append_id(ssil.projection_uniform_buffer);
+
+ projection_uniform_set = uniform_set_cache->get_cache(shader, 3, u_last_frame, u_projection);
}
- if (p_ssil_buffers.gather_uniform_set.is_null()) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 0;
- u.append_id(default_sampler);
- u.append_id(p_ssil_buffers.depth_texture_view);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.append_id(p_normal_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 2;
- u.append_id(ss_effects.gather_constants_buffer);
- uniforms.push_back(u);
- }
- p_ssil_buffers.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 0);
+ RID gather_uniform_set;
+ {
+ RID depth_texture_view = p_render_buffers->get_texture_slice(RB_SCOPE_SSDS, RB_LINEAR_DEPTH, p_view * 4, ssil_half_size ? 1 : 0, 4, 4);
+
+ RD::Uniform u_depth_texture_view;
+ u_depth_texture_view.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u_depth_texture_view.binding = 0;
+ u_depth_texture_view.append_id(default_sampler);
+ u_depth_texture_view.append_id(depth_texture_view);
+
+ RD::Uniform u_normal_buffer;
+ u_normal_buffer.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u_normal_buffer.binding = 1;
+ u_normal_buffer.append_id(p_normal_buffer);
+
+ RD::Uniform u_gather_constants_buffer;
+ u_gather_constants_buffer.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u_gather_constants_buffer.binding = 2;
+ u_gather_constants_buffer.append_id(ss_effects.gather_constants_buffer);
+
+ gather_uniform_set = uniform_set_cache->get_cache(shader, 0, u_depth_texture_view, u_normal_buffer, u_gather_constants_buffer);
}
- if (p_ssil_buffers.importance_map_uniform_set.is_null()) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.append_id(p_ssil_buffers.pong);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 1;
- u.append_id(default_sampler);
- u.append_id(p_ssil_buffers.importance_map[0]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 2;
- u.append_id(ssil.importance_map_load_counter);
- uniforms.push_back(u);
- }
- p_ssil_buffers.importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 2), 1);
+ RID importance_map_uniform_set;
+ {
+ RD::Uniform u_pong;
+ u_pong.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u_pong.binding = 0;
+ u_pong.append_id(deinterleaved_pong);
+
+ RD::Uniform u_importance_map;
+ u_importance_map.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u_importance_map.binding = 1;
+ u_importance_map.append_id(default_sampler);
+ u_importance_map.append_id(importance_map);
+
+ RD::Uniform u_load_counter;
+ u_load_counter.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u_load_counter.binding = 2;
+ u_load_counter.append_id(ssil.importance_map_load_counter);
+
+ RID shader_adaptive = ssil.gather_shader.version_get_shader(ssil.gather_shader_version, SSIL_GATHER_ADAPTIVE);
+ importance_map_uniform_set = uniform_set_cache->get_cache(shader_adaptive, 1, u_pong, u_importance_map, u_load_counter);
}
if (ssil_quality == RS::ENV_SSIL_QUALITY_ULTRA) {
@@ -828,38 +776,42 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
ssil.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width;
ssil.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height;
ssil.importance_map_push_constant.intensity = p_settings.intensity * Math_PI;
+
//base pass
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_BASE]);
- gather_ssil(compute_list, p_ssil_buffers.pong_slices, p_ssil_buffers.edges_slices, p_settings, true, p_ssil_buffers.gather_uniform_set, p_ssil_buffers.importance_map_uniform_set, p_ssil_buffers.projection_uniform_set);
+ gather_ssil(compute_list, deinterleaved_pong_slices, edges_slices, p_settings, true, gather_uniform_set, importance_map_uniform_set, projection_uniform_set);
//generate importance map
- RD::Uniform u_ssil_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong }));
- RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.importance_map[0] }));
+ RID gen_imp_shader = ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 0);
+ RD::Uniform u_ssil_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, deinterleaved_pong }));
+ RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ importance_map }));
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GENERATE_IMPORTANCE_MAP]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_with_sampler), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(gen_imp_shader, 0, u_ssil_pong_with_sampler), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(gen_imp_shader, 1, u_importance_map), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
// process Importance Map A
- RD::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.importance_map[0] }));
- RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.importance_map[1] }));
+ RID proc_imp_shader_a = ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 1);
+ RD::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, importance_map }));
+ RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ importance_pong }));
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPA]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_with_sampler), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map_pong), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_a, 0, u_importance_map_with_sampler), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_a, 1, u_importance_map_pong), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
// process Importance Map B
- RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.importance_map[1] }));
+ RID proc_imp_shader_b = ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 2);
+ RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, importance_pong }));
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPB]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_pong_with_sampler), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_b, 0, u_importance_map_pong_with_sampler), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_b, 1, u_importance_map), 1);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssil.counter_uniform_set, 2);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1);
@@ -872,7 +824,7 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER]);
}
- gather_ssil(compute_list, p_ssil_buffers.deinterleaved_slices, p_ssil_buffers.edges_slices, p_settings, false, p_ssil_buffers.gather_uniform_set, p_ssil_buffers.importance_map_uniform_set, p_ssil_buffers.projection_uniform_set);
+ gather_ssil(compute_list, deinterleaved_slices, edges_slices, p_settings, false, gather_uniform_set, importance_map_uniform_set, projection_uniform_set);
RD::get_singleton()->draw_command_end_label(); //Gather
}
@@ -895,6 +847,8 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
}
}
+ RID blur_shader = ssil.blur_shader.version_get_shader(ssil.blur_shader_version, blur_pipeline - SSIL_BLUR_PASS);
+
for (int i = 0; i < 4; i++) {
if ((ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
continue;
@@ -903,30 +857,30 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[blur_pipeline]);
if (pass % 2 == 0) {
if (ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
- RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.deinterleaved_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_slice), 0);
+ RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ssil_slice), 0);
} else {
- RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssil_buffers.deinterleaved_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_slice), 0);
+ RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ssil_slice), 0);
}
- RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.pong_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_pong_slice), 1);
+ RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ deinterleaved_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 1, u_ssil_pong_slice), 1);
} else {
if (ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
- RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_slice), 0);
+ RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, deinterleaved_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ssil_pong_slice), 0);
} else {
- RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssil_buffers.pong_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_slice), 0);
+ RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, deinterleaved_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ssil_pong_slice), 0);
}
- RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.deinterleaved_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_slice), 1);
+ RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 1, u_ssil_slice), 1);
}
- RD::Uniform u_edges_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.edges_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_edges_slice), 2);
+ RD::Uniform u_edges_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ edges_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 2, u_edges_slice), 2);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.blur_push_constant, sizeof(SSILBlurPushConstant));
@@ -961,18 +915,19 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[interleave_pipeline]);
- RD::Uniform u_destination(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.ssil_final }));
+ RID final = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_FINAL, p_view, 0);
+ RD::Uniform u_destination(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ final }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_destination), 0);
if (ssil_quality > RS::ENV_SSIL_QUALITY_VERY_LOW && ssil_blur_passes % 2 == 0) {
- RD::Uniform u_ssil(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.deinterleaved }));
+ RD::Uniform u_ssil(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, deinterleaved }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil), 1);
} else {
- RD::Uniform u_ssil_pong(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong }));
+ RD::Uniform u_ssil_pong(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, deinterleaved_pong }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_pong), 1);
}
- RD::Uniform u_edges(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.edges }));
+ RD::Uniform u_edges(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ edges }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_edges), 2);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.interleave_push_constant, sizeof(SSILInterleavePushConstant));
@@ -990,34 +945,6 @@ void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers
RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
}
-void SSEffects::ssil_free(SSILRenderBuffers &p_ssil_buffers) {
- if (p_ssil_buffers.ssil_final.is_valid()) {
- RD::get_singleton()->free(p_ssil_buffers.ssil_final);
- RD::get_singleton()->free(p_ssil_buffers.deinterleaved);
- RD::get_singleton()->free(p_ssil_buffers.pong);
- RD::get_singleton()->free(p_ssil_buffers.edges);
- RD::get_singleton()->free(p_ssil_buffers.importance_map[0]);
- RD::get_singleton()->free(p_ssil_buffers.importance_map[1]);
- RD::get_singleton()->free(p_ssil_buffers.last_frame);
-
- p_ssil_buffers.ssil_final = RID();
- p_ssil_buffers.deinterleaved = RID();
- p_ssil_buffers.pong = RID();
- p_ssil_buffers.edges = RID();
- p_ssil_buffers.deinterleaved_slices.clear();
- p_ssil_buffers.pong_slices.clear();
- p_ssil_buffers.edges_slices.clear();
- p_ssil_buffers.importance_map[0] = RID();
- p_ssil_buffers.importance_map[1] = RID();
- p_ssil_buffers.last_frame = RID();
- p_ssil_buffers.last_frame_slices.clear();
-
- p_ssil_buffers.gather_uniform_set = RID();
- p_ssil_buffers.importance_map_uniform_set = RID();
- p_ssil_buffers.projection_uniform_set = RID();
- }
-}
-
/* SSAO */
void SSEffects::ssao_set_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) {
@@ -1029,13 +956,13 @@ void SSEffects::ssao_set_quality(RS::EnvironmentSSAOQuality p_quality, bool p_ha
ssao_fadeout_to = p_fadeout_to;
}
-void SSEffects::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) {
+void SSEffects::gather_ssao(RD::ComputeListID p_compute_list, const RID *p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
if ((ssao_quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) {
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1);
}
RID shader = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 1); //
@@ -1062,11 +989,12 @@ void SSEffects::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID>
RD::get_singleton()->compute_list_add_barrier(p_compute_list);
}
-void SSEffects::ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth) {
+void SSEffects::ssao_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings) {
if (p_ssao_buffers.half_size != ssao_half_size) {
- ssao_free(p_ssao_buffers);
+ p_render_buffers->clear_context(RB_SCOPE_SSAO);
}
+ p_ssao_buffers.half_size = ssao_half_size;
if (ssao_half_size) {
p_ssao_buffers.buffer_width = (p_settings.full_screen_size.x + 3) / 4;
p_ssao_buffers.buffer_height = (p_settings.full_screen_size.y + 3) / 4;
@@ -1079,79 +1007,45 @@ void SSEffects::ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const S
p_ssao_buffers.half_buffer_height = (p_settings.full_screen_size.y + 3) / 4;
}
- if (p_ssao_buffers.ao_deinterleaved.is_null()) {
- {
- p_ssao_buffers.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_linear_depth, 0, ssao_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8G8_UNORM;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = p_ssao_buffers.buffer_width;
- tf.height = p_ssao_buffers.buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssao_buffers.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_deinterleaved, "SSAO De-interleaved Array");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssao_buffers.ao_deinterleaved, i, 0);
- p_ssao_buffers.ao_deinterleaved_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " ");
- }
- }
+ uint32_t view_count = p_render_buffers->get_view_count();
+ Size2i full_size = Size2i(p_ssao_buffers.buffer_width, p_ssao_buffers.buffer_height);
+ Size2i half_size = Size2i(p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height);
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8G8_UNORM;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = p_ssao_buffers.buffer_width;
- tf.height = p_ssao_buffers.buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssao_buffers.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_pong, "SSAO De-interleaved Array Pong");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssao_buffers.ao_pong, i, 0);
- p_ssao_buffers.ao_pong_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " Pong");
- }
- }
+ // As we're not clearing these, and render buffers will return the cached texture if it already exists,
+ // we don't first check has_texture here
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = p_ssao_buffers.buffer_width;
- tf.height = p_ssao_buffers.buffer_height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssao_buffers.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map[0], "SSAO Importance Map");
- p_ssao_buffers.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map[1], "SSAO Importance Map Pong");
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = p_settings.full_screen_size.x;
- tf.height = p_settings.full_screen_size.y;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- p_ssao_buffers.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_final, "SSAO Final");
- }
- p_ssao_buffers.half_size = ssao_half_size;
- }
+ p_render_buffers->create_texture(RB_SCOPE_SSAO, RB_DEINTERLEAVED, RD::DATA_FORMAT_R8G8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, full_size, 4 * view_count);
+ p_render_buffers->create_texture(RB_SCOPE_SSAO, RB_DEINTERLEAVED_PONG, RD::DATA_FORMAT_R8G8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, full_size, 4 * view_count);
+ p_render_buffers->create_texture(RB_SCOPE_SSAO, RB_IMPORTANCE_MAP, RD::DATA_FORMAT_R8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, half_size);
+ p_render_buffers->create_texture(RB_SCOPE_SSAO, RB_IMPORTANCE_PONG, RD::DATA_FORMAT_R8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, half_size);
+ p_render_buffers->create_texture(RB_SCOPE_SSAO, RB_FINAL, RD::DATA_FORMAT_R8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1);
}
-void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings) {
+void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
ERR_FAIL_NULL(material_storage);
+ // Obtain our (cached) buffer slices for the view we are rendering.
+ RID ao_deinterleaved = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_DEINTERLEAVED, p_view * 4, 0, 4, 1);
+ RID ao_pong = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_DEINTERLEAVED_PONG, p_view * 4, 0, 4, 1);
+ RID importance_map = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_IMPORTANCE_MAP, p_view, 0);
+ RID importance_pong = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_IMPORTANCE_PONG, p_view, 0);
+ RID ao_final = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_FINAL, p_view, 0);
+
+ RID ao_deinterleaved_slices[4];
+ RID ao_pong_slices[4];
+ for (uint32_t i = 0; i < 4; i++) {
+ ao_deinterleaved_slices[i] = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_DEINTERLEAVED, p_view * 4 + i, 0);
+ ao_pong_slices[i] = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_DEINTERLEAVED_PONG, p_view * 4 + i, 0);
+ }
+
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
memset(&ssao.gather_push_constant, 0, sizeof(SSAOGatherPushConstant));
/* FIRST PASS */
- RID shader = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0);
+ RID shader = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, SSAO_GATHER);
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
RD::get_singleton()->draw_command_begin_label("Process Screen Space Ambient Occlusion");
@@ -1201,60 +1095,52 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
ssao.gather_push_constant.quality = MAX(0, ssao_quality - 1);
ssao.gather_push_constant.size_multiplier = ssao_half_size ? 2 : 1;
- if (p_ssao_buffers.gather_uniform_set.is_null()) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 0;
- u.append_id(default_sampler);
- u.append_id(p_ssao_buffers.depth_texture_view);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.append_id(p_normal_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 2;
- u.append_id(ss_effects.gather_constants_buffer);
- uniforms.push_back(u);
- }
- p_ssao_buffers.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader, 0);
- RD::get_singleton()->set_resource_name(p_ssao_buffers.gather_uniform_set, "SSAO Gather Uniform Set");
+ // We are using our uniform cache so our uniform sets are automatically freed when our textures are freed.
+ // It also ensures that we're reusing the right cached entry in a multiview situation without us having to
+ // remember each instance of the uniform set.
+ RID gather_uniform_set;
+ {
+ RID depth_texture_view = p_render_buffers->get_texture_slice(RB_SCOPE_SSDS, RB_LINEAR_DEPTH, p_view * 4, ssao_half_size ? 1 : 0, 4, 4);
+
+ RD::Uniform u_depth_texture_view;
+ u_depth_texture_view.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u_depth_texture_view.binding = 0;
+ u_depth_texture_view.append_id(default_sampler);
+ u_depth_texture_view.append_id(depth_texture_view);
+
+ RD::Uniform u_normal_buffer;
+ u_normal_buffer.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u_normal_buffer.binding = 1;
+ u_normal_buffer.append_id(p_normal_buffer);
+
+ RD::Uniform u_gather_constants_buffer;
+ u_gather_constants_buffer.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u_gather_constants_buffer.binding = 2;
+ u_gather_constants_buffer.append_id(ss_effects.gather_constants_buffer);
+
+ gather_uniform_set = uniform_set_cache->get_cache(shader, 0, u_depth_texture_view, u_normal_buffer, u_gather_constants_buffer);
}
- if (p_ssao_buffers.importance_map_uniform_set.is_null()) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.append_id(p_ssao_buffers.ao_pong);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 1;
- u.append_id(default_sampler);
- u.append_id(p_ssao_buffers.importance_map[0]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 2;
- u.append_id(ssao.importance_map_load_counter);
- uniforms.push_back(u);
- }
- p_ssao_buffers.importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1);
- RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map_uniform_set, "SSAO Importance Map Uniform Set");
+ RID importance_map_uniform_set;
+ {
+ RD::Uniform u_pong;
+ u_pong.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u_pong.binding = 0;
+ u_pong.append_id(ao_pong);
+
+ RD::Uniform u_importance_map;
+ u_importance_map.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u_importance_map.binding = 1;
+ u_importance_map.append_id(default_sampler);
+ u_importance_map.append_id(importance_map);
+
+ RD::Uniform u_load_counter;
+ u_load_counter.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u_load_counter.binding = 2;
+ u_load_counter.append_id(ssao.importance_map_load_counter);
+
+ RID shader_adaptive = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, SSAO_GATHER_ADAPTIVE);
+ importance_map_uniform_set = uniform_set_cache->get_cache(shader_adaptive, 1, u_pong, u_importance_map, u_load_counter);
}
if (ssao_quality == RS::ENV_SSAO_QUALITY_ULTRA) {
@@ -1266,41 +1152,44 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
//base pass
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]);
- gather_ssao(compute_list, p_ssao_buffers.ao_pong_slices, p_settings, true, p_ssao_buffers.gather_uniform_set, RID());
+ gather_ssao(compute_list, ao_pong_slices, p_settings, true, gather_uniform_set, RID());
//generate importance map
+ RID gen_imp_shader = ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 0);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]);
- RD::Uniform u_ao_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_with_sampler), 0);
+ RD::Uniform u_ao_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, ao_pong }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(gen_imp_shader, 0, u_ao_pong_with_sampler), 0);
- RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.importance_map[0] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+ RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ importance_map }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(gen_imp_shader, 1, u_importance_map), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
//process importance map A
+ RID proc_imp_shader_a = ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 1);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPA]);
- RD::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.importance_map[0] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_with_sampler), 0);
+ RD::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, importance_map }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_a, 0, u_importance_map_with_sampler), 0);
- RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.importance_map[1] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map_pong), 1);
+ RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ importance_pong }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_a, 1, u_importance_map_pong), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
//process Importance Map B
+ RID proc_imp_shader_b = ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPB]);
- RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.importance_map[1] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_pong_with_sampler), 0);
+ RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, importance_pong }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_b, 0, u_importance_map_pong_with_sampler), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(proc_imp_shader_b, 1, u_importance_map), 1);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.counter_uniform_set, 2);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 1);
@@ -1312,7 +1201,7 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]);
}
- gather_ssao(compute_list, p_ssao_buffers.ao_deinterleaved_slices, p_settings, false, p_ssao_buffers.gather_uniform_set, p_ssao_buffers.importance_map_uniform_set);
+ gather_ssao(compute_list, ao_deinterleaved_slices, p_settings, false, gather_uniform_set, importance_map_uniform_set);
RD::get_singleton()->draw_command_end_label(); // Gather SSAO
}
@@ -1332,7 +1221,6 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
for (int pass = 0; pass < blur_passes; pass++) {
int blur_pipeline = SSAO_BLUR_PASS;
if (ssao_quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
- blur_pipeline = SSAO_BLUR_PASS_SMART;
if (pass < blur_passes - 2) {
blur_pipeline = SSAO_BLUR_PASS_WIDE;
} else {
@@ -1345,29 +1233,30 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
continue;
}
+ RID blur_shader = ssao.blur_shader.version_get_shader(ssao.blur_shader_version, blur_pipeline - SSAO_BLUR_PASS);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[blur_pipeline]);
if (pass % 2 == 0) {
if (ssao_quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
- RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_deinterleaved_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_slices_with_sampler), 0);
+ RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, ao_deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ao_slices_with_sampler), 0);
} else {
- RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssao_buffers.ao_deinterleaved_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_slices_with_sampler), 0);
+ RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, ao_deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ao_slices_with_sampler), 0);
}
- RD::Uniform u_ao_pong_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_pong_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao_pong_slices), 1);
+ RD::Uniform u_ao_pong_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ ao_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 1, u_ao_pong_slices), 1);
} else {
if (ssao_quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
- RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_slices_with_sampler), 0);
+ RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, ao_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ao_pong_slices_with_sampler), 0);
} else {
- RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssao_buffers.ao_pong_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_slices_with_sampler), 0);
+ RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, ao_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 0, u_ao_pong_slices_with_sampler), 0);
}
- RD::Uniform u_ao_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_deinterleaved_slices[i] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao_slices), 1);
+ RD::Uniform u_ao_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ ao_deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(blur_shader, 1, u_ao_slices), 1);
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant));
@@ -1401,17 +1290,18 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
interleave_pipeline = SSAO_INTERLEAVE_SMART;
}
+ RID interleave_shader = ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, interleave_pipeline - SSAO_INTERLEAVE);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[interleave_pipeline]);
- RD::Uniform u_upscale_buffer(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_final }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_upscale_buffer), 0);
+ RD::Uniform u_upscale_buffer(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ ao_final }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(interleave_shader, 0, u_upscale_buffer), 0);
if (ssao_quality > RS::ENV_SSAO_QUALITY_VERY_LOW && ssao_blur_passes % 2 == 0) {
- RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_deinterleaved }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao), 1);
+ RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, ao_deinterleaved }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(interleave_shader, 1, u_ao), 1);
} else {
- RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao), 1);
+ RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, ao_pong }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(interleave_shader, 1, u_ao), 1);
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant));
@@ -1427,116 +1317,43 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu
RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
}
-void SSEffects::ssao_free(SSAORenderBuffers &p_ssao_buffers) {
- if (p_ssao_buffers.ao_final.is_valid()) {
- RD::get_singleton()->free(p_ssao_buffers.ao_deinterleaved);
- RD::get_singleton()->free(p_ssao_buffers.ao_pong);
- RD::get_singleton()->free(p_ssao_buffers.ao_final);
-
- RD::get_singleton()->free(p_ssao_buffers.importance_map[0]);
- RD::get_singleton()->free(p_ssao_buffers.importance_map[1]);
-
- p_ssao_buffers.ao_deinterleaved = RID();
- p_ssao_buffers.ao_pong = RID();
- p_ssao_buffers.ao_final = RID();
- p_ssao_buffers.importance_map[0] = RID();
- p_ssao_buffers.importance_map[1] = RID();
- p_ssao_buffers.ao_deinterleaved_slices.clear();
- p_ssao_buffers.ao_pong_slices.clear();
-
- p_ssao_buffers.gather_uniform_set = RID();
- p_ssao_buffers.importance_map_uniform_set = RID();
- }
-}
-
/* Screen Space Reflection */
void SSEffects::ssr_set_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {
ssr_roughness_quality = p_quality;
}
-void SSEffects::ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, const Size2i &p_screen_size, const uint32_t p_view_count) {
- // As we are processing one view at a time, we can reuse buffers, only our output needs to have layers for each view.
- if (p_ssr_buffers.size != p_screen_size || p_ssr_buffers.roughness_quality != ssr_roughness_quality) {
- ssr_free(p_ssr_buffers);
- }
-
- if (p_ssr_buffers.output.is_valid()) {
- // already allocated
- return;
+void SSEffects::ssr_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format) {
+ if (p_ssr_buffers.roughness_quality != ssr_roughness_quality) {
+ // Buffers will already be cleared if view count or viewport size has changed, also cleared them if we change roughness.
+ p_render_buffers->clear_context(RB_SCOPE_SSR);
}
- p_ssr_buffers.size = p_screen_size;
+ Size2i internal_size = p_render_buffers->get_internal_size();
+ p_ssr_buffers.size = Size2i(internal_size.x / 2, internal_size.y / 2);
p_ssr_buffers.roughness_quality = ssr_roughness_quality;
- if (p_ssr_buffers.depth_scaled.is_null()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- tf.width = p_screen_size.x;
- tf.height = p_screen_size.y;
- tf.texture_type = RD::TEXTURE_TYPE_2D;
- tf.array_layers = 1;
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
-
- p_ssr_buffers.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssr_buffers.depth_scaled, "SSR Depth Scaled");
+ // We are using barriers so we do not need to allocate textures for both views on anything but output...
- tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ p_render_buffers->create_texture(RB_SCOPE_SSR, RB_DEPTH_SCALED, RD::DATA_FORMAT_R32_SFLOAT, RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, p_ssr_buffers.size, 1);
+ p_render_buffers->create_texture(RB_SCOPE_SSR, RB_NORMAL_SCALED, RD::DATA_FORMAT_R8G8B8A8_UNORM, RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, p_ssr_buffers.size, 1);
- p_ssr_buffers.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssr_buffers.normal_scaled, "SSR Normal Scaled");
+ if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !p_render_buffers->has_texture(RB_SCOPE_SSR, RB_BLUR_RADIUS)) {
+ p_render_buffers->create_texture(RB_SCOPE_SSR, RB_BLUR_RADIUS, RD::DATA_FORMAT_R8_UNORM, RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT, RD::TEXTURE_SAMPLES_1, p_ssr_buffers.size, 2); // 2 layers, for our two blur stages
}
- if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !p_ssr_buffers.blur_radius[0].is_valid()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = p_screen_size.x;
- tf.height = p_screen_size.y;
- tf.texture_type = RD::TEXTURE_TYPE_2D;
- tf.array_layers = 1;
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
-
- p_ssr_buffers.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssr_buffers.blur_radius[0], "SSR Blur Radius 0");
- p_ssr_buffers.blur_radius[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssr_buffers.blur_radius[1], "SSR Blur Radius 1");
- }
-
- if (p_ssr_buffers.intermediate.is_null()) {
- RD::TextureFormat tf;
- tf.format = p_color_format;
- tf.width = p_screen_size.x;
- tf.height = p_screen_size.y;
- tf.texture_type = RD::TEXTURE_TYPE_2D;
- tf.array_layers = 1;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
- p_ssr_buffers.intermediate = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssr_buffers.intermediate, "SSR Intermediate");
-
- if (p_view_count > 1) {
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.array_layers = p_view_count;
- } else {
- tf.texture_type = RD::TEXTURE_TYPE_2D;
- tf.array_layers = 1;
- }
-
- p_ssr_buffers.output = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(p_ssr_buffers.output, "SSR Output");
-
- for (uint32_t v = 0; v < p_view_count; v++) {
- p_ssr_buffers.output_slices[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssr_buffers.output, v, 0);
- }
- }
+ p_render_buffers->create_texture(RB_SCOPE_SSR, RB_INTERMEDIATE, p_color_format, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, p_ssr_buffers.size, 1);
+ p_render_buffers->create_texture(RB_SCOPE_SSR, RB_OUTPUT, p_color_format, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT, RD::TEXTURE_SAMPLES_1, p_ssr_buffers.size);
}
-void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, const RID *p_metallic_slices, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets) {
+void SSEffects::screen_space_reflection(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RID *p_normal_roughness_slices, const RID *p_metallic_slices, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const Projection *p_projections, const Vector3 *p_eye_offsets) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
ERR_FAIL_NULL(material_storage);
+ uint32_t view_count = p_render_buffers->get_view_count();
+
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
{
@@ -1547,7 +1364,7 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
ssr.ubo = RD::get_singleton()->uniform_buffer_create(sizeof(ScreenSpaceReflectionSceneData));
}
- for (uint32_t v = 0; v < p_view_count; v++) {
+ for (uint32_t v = 0; v < view_count; v++) {
store_camera(p_projections[v], scene_data.projection[v]);
store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]);
scene_data.eye_offset[v][0] = p_eye_offsets[v].x;
@@ -1560,13 +1377,27 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
}
uint32_t pipeline_specialization = 0;
- if (p_view_count > 1) {
+ if (view_count > 1) {
pipeline_specialization |= SSR_MULTIVIEW;
}
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- for (uint32_t v = 0; v < p_view_count; v++) {
+ for (uint32_t v = 0; v < view_count; v++) {
+ // get buffers we need to use for this view
+ RID diffuse_slice = p_render_buffers->get_internal_texture(v);
+ RID depth_slice = p_render_buffers->get_depth_texture(v);
+ RID depth_scaled = p_render_buffers->get_texture(RB_SCOPE_SSR, RB_DEPTH_SCALED);
+ RID normal_scaled = p_render_buffers->get_texture(RB_SCOPE_SSR, RB_NORMAL_SCALED);
+ RID intermediate = p_render_buffers->get_texture(RB_SCOPE_SSR, RB_INTERMEDIATE);
+ RID output = p_render_buffers->get_texture_slice(RB_SCOPE_SSR, RB_OUTPUT, v, 0);
+
+ RID blur_radius[2];
+ if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) {
+ blur_radius[0] = p_render_buffers->get_texture_slice(RB_SCOPE_SSR, RB_BLUR_RADIUS, 0, 0);
+ blur_radius[1] = p_render_buffers->get_texture_slice(RB_SCOPE_SSR, RB_BLUR_RADIUS, 1, 0);
+ }
+
RD::get_singleton()->draw_command_begin_label(String("SSR View ") + itos(v));
{ //scale color and depth to half
@@ -1578,34 +1409,29 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
push_constant.camera_z_near = p_projections[v].get_z_near();
push_constant.orthogonal = p_projections[v].is_orthogonal();
push_constant.filter = false; //enabling causes arctifacts
- push_constant.screen_size[0] = p_screen_size.x;
- push_constant.screen_size[1] = p_screen_size.y;
+ push_constant.screen_size[0] = p_ssr_buffers.size.x;
+ push_constant.screen_size[1] = p_ssr_buffers.size.y;
RID shader = ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_scale.pipelines[pipeline_specialization]);
- RD::Uniform u_diffuse(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_diffuse_slices[v] }));
+ RD::Uniform u_diffuse(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, diffuse_slice }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_diffuse), 0);
- RD::Uniform u_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_depth_slices[v] }));
+ RD::Uniform u_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, depth_slice }));
RD::Uniform u_normal_roughness(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, Vector<RID>({ default_sampler, p_normal_roughness_slices[v] }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth, u_normal_roughness), 1);
- if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) {
- RD::Uniform u_output(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_output), 2);
- } else {
- RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_intermediate), 2);
- }
+ RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ intermediate }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_intermediate), 2);
- RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.depth_scaled }));
- RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.normal_scaled }));
+ RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ depth_scaled }));
+ RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ normal_scaled }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth, u_scale_normal), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionScalePushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssr_buffers.size.width, p_ssr_buffers.size.height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -1620,15 +1446,15 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
push_constant.camera_z_far = p_projections[v].get_z_far();
push_constant.camera_z_near = p_projections[v].get_z_near();
push_constant.orthogonal = p_projections[v].is_orthogonal();
- push_constant.screen_size[0] = p_screen_size.x;
- push_constant.screen_size[1] = p_screen_size.y;
+ push_constant.screen_size[0] = p_ssr_buffers.size.x;
+ push_constant.screen_size[1] = p_ssr_buffers.size.y;
push_constant.curve_fade_in = p_fade_in;
push_constant.distance_fade = p_fade_out;
push_constant.num_steps = p_max_steps;
push_constant.depth_tolerance = p_tolerance;
push_constant.use_half_res = true;
- push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].columns[0][0]);
- push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].columns[1][1]);
+ push_constant.proj_info[0] = -2.0f / (p_ssr_buffers.size.width * p_projections[v].columns[0][0]);
+ push_constant.proj_info[1] = -2.0f / (p_ssr_buffers.size.height * p_projections[v].columns[1][1]);
push_constant.proj_info[2] = (1.0f - p_projections[v].columns[0][2]) / p_projections[v].columns[0][0];
push_constant.proj_info[3] = (1.0f + p_projections[v].columns[1][2]) / p_projections[v].columns[1][1];
@@ -1640,35 +1466,30 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
RD::Uniform u_scene_data(RD::UNIFORM_TYPE_UNIFORM_BUFFER, 0, ssr.ubo);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4);
+ // read from intermediate
+ RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ intermediate }));
+ RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ depth_scaled }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_intermediate, u_scale_depth), 0);
+
if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) {
- // read from output slices (our scale wrote into these)
- RD::Uniform u_output(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] }));
- RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.depth_scaled }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_output, u_scale_depth), 0);
-
- // write to intermediate (our roughness pass will output into output slices)
- RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate }));
- RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[0] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_intermediate, u_blur_radius), 1);
+ // write to output and blur radius
+ RD::Uniform u_output(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ output }));
+ RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ blur_radius[0] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_output, u_blur_radius), 1);
} else {
- // read from intermediate (our scale wrote into these)
- RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate }));
- RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.depth_scaled }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_intermediate, u_scale_depth), 0);
-
- // We are not performing our blur so go directly to output.
- RD::Uniform u_output(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] }));
+ // We are only writing output
+ RD::Uniform u_output(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ output }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_output), 1);
}
- RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.normal_scaled }));
+ RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ normal_scaled }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_scale_normal), 2);
RD::Uniform u_metallic(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_metallic_slices[v] }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_metallic), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssr_buffers.size.width, p_ssr_buffers.size.height, 1);
RD::get_singleton()->draw_command_end_label();
}
@@ -1683,8 +1504,8 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
push_constant.view_index = v;
push_constant.orthogonal = p_projections[v].is_orthogonal();
push_constant.edge_tolerance = Math::sin(Math::deg_to_rad(15.0));
- push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].columns[0][0]);
- push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].columns[1][1]);
+ push_constant.proj_info[0] = -2.0f / (p_ssr_buffers.size.width * p_projections[v].columns[0][0]);
+ push_constant.proj_info[1] = -2.0f / (p_ssr_buffers.size.height * p_projections[v].columns[1][1]);
push_constant.proj_info[2] = (1.0f - p_projections[v].columns[0][2]) / p_projections[v].columns[0][0];
push_constant.proj_info[3] = (1.0f + p_projections[v].columns[1][2]) / p_projections[v].columns[1][1];
push_constant.vertical = 0;
@@ -1699,8 +1520,8 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
push_constant.increment = 1;
}
- push_constant.screen_size[0] = p_screen_size.width;
- push_constant.screen_size[1] = p_screen_size.height;
+ push_constant.screen_size[0] = p_ssr_buffers.size.width;
+ push_constant.screen_size[1] = p_ssr_buffers.size.height;
// Horizontal pass
@@ -1710,25 +1531,25 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[pipeline_specialization][mode]);
- RD::Uniform u_scene_data(RD::UNIFORM_TYPE_UNIFORM_BUFFER, 0, ssr.ubo);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4);
-
- RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate }));
- RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[0] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_intermediate, u_blur_radius), 0);
+ RD::Uniform u_output(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ output }));
+ RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ blur_radius[0] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_output, u_blur_radius), 0);
- RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.normal_scaled }));
+ RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ normal_scaled }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_scale_normal), 1);
- RD::Uniform u_output_blur(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] }));
- RD::Uniform u_blur_radius2(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[1] }));
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_output_blur, u_blur_radius2), 2);
+ RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ intermediate }));
+ RD::Uniform u_blur_radius2(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ blur_radius[1] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_intermediate, u_blur_radius2), 2);
- RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.depth_scaled }));
+ RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ depth_scaled }));
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth), 3);
+ RD::Uniform u_scene_data(RD::UNIFORM_TYPE_UNIFORM_BUFFER, 0, ssr.ubo);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4);
+
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssr_buffers.size.width, p_ssr_buffers.size.height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
// Vertical pass
@@ -1740,16 +1561,16 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
push_constant.vertical = 1;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_output_blur, u_blur_radius2), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_intermediate, u_blur_radius2), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_scale_normal), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_intermediate), 2);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_output), 2);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth), 3);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssr_buffers.size.width, p_ssr_buffers.size.height, 1);
- if (v != p_view_count - 1) {
+ if (v != view_count - 1) {
RD::get_singleton()->compute_list_add_barrier(compute_list);
}
@@ -1762,36 +1583,6 @@ void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const R
RD::get_singleton()->compute_list_end();
}
-void SSEffects::ssr_free(SSRRenderBuffers &p_ssr_buffers) {
- for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
- p_ssr_buffers.output_slices[v] = RID();
- }
-
- if (p_ssr_buffers.output.is_valid()) {
- RD::get_singleton()->free(p_ssr_buffers.output);
- p_ssr_buffers.output = RID();
- }
-
- if (p_ssr_buffers.intermediate.is_valid()) {
- RD::get_singleton()->free(p_ssr_buffers.intermediate);
- p_ssr_buffers.intermediate = RID();
- }
-
- if (p_ssr_buffers.blur_radius[0].is_valid()) {
- RD::get_singleton()->free(p_ssr_buffers.blur_radius[0]);
- RD::get_singleton()->free(p_ssr_buffers.blur_radius[1]);
- p_ssr_buffers.blur_radius[0] = RID();
- p_ssr_buffers.blur_radius[1] = RID();
- }
-
- if (p_ssr_buffers.depth_scaled.is_valid()) {
- RD::get_singleton()->free(p_ssr_buffers.depth_scaled);
- p_ssr_buffers.depth_scaled = RID();
- RD::get_singleton()->free(p_ssr_buffers.normal_scaled);
- p_ssr_buffers.normal_scaled = RID();
- }
-}
-
/* Subsurface scattering */
void SSEffects::sss_set_quality(RS::SubSurfaceScatteringQuality p_quality) {
diff --git a/servers/rendering/renderer_rd/effects/ss_effects.h b/servers/rendering/renderer_rd/effects/ss_effects.h
index dfaf3881bb..8585277e19 100644
--- a/servers/rendering/renderer_rd/effects/ss_effects.h
+++ b/servers/rendering/renderer_rd/effects/ss_effects.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* ss_effects.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* ss_effects.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 SS_EFFECTS_RD_H
#define SS_EFFECTS_RD_H
@@ -48,6 +48,26 @@
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
+#define RB_SCOPE_SSDS SNAME("rb_ssds")
+#define RB_SCOPE_SSIL SNAME("rb_ssil")
+#define RB_SCOPE_SSAO SNAME("rb_ssao")
+#define RB_SCOPE_SSR SNAME("rb_ssr")
+
+#define RB_LINEAR_DEPTH SNAME("linear_depth")
+#define RB_FINAL SNAME("final")
+#define RB_LAST_FRAME SNAME("last_frame")
+#define RB_DEINTERLEAVED SNAME("deinterleaved")
+#define RB_DEINTERLEAVED_PONG SNAME("deinterleaved_pong")
+#define RB_EDGES SNAME("edges")
+#define RB_IMPORTANCE_MAP SNAME("importance_map")
+#define RB_IMPORTANCE_PONG SNAME("importance_pong")
+
+#define RB_DEPTH_SCALED SNAME("depth_scaled")
+#define RB_NORMAL_SCALED SNAME("normal_scaled")
+#define RB_BLUR_RADIUS SNAME("blur_radius")
+#define RB_INTERMEDIATE SNAME("intermediate")
+#define RB_OUTPUT SNAME("output")
+
class RenderSceneBuffersRD;
namespace RendererRD {
@@ -64,7 +84,7 @@ public:
/* SS Downsampler */
- void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, bool p_invalidate_uniform_set, Size2i p_full_screen_size, const Projection &p_projection);
+ void downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_view, const Projection &p_projection);
/* SSIL */
void ssil_set_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to);
@@ -75,23 +95,6 @@ public:
int buffer_height;
int half_buffer_width;
int half_buffer_height;
-
- RID ssil_final;
- RID deinterleaved;
- Vector<RID> deinterleaved_slices;
- RID pong;
- Vector<RID> pong_slices;
- RID edges;
- Vector<RID> edges_slices;
- RID importance_map[2];
- RID depth_texture_view;
-
- RID last_frame;
- Vector<RID> last_frame_slices;
-
- RID gather_uniform_set;
- RID importance_map_uniform_set;
- RID projection_uniform_set;
};
struct SSILSettings {
@@ -100,12 +103,11 @@ public:
float sharpness = 0.98;
float normal_rejection = 1.0;
- Size2i full_screen_size = Size2i();
+ Size2i full_screen_size;
};
- void ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth);
- void screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings);
- void ssil_free(SSILRenderBuffers &p_ssil_buffers);
+ void ssil_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings);
+ void screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings);
/* SSAO */
void ssao_set_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to);
@@ -116,17 +118,6 @@ public:
int buffer_height;
int half_buffer_width;
int half_buffer_height;
-
- RID ao_deinterleaved;
- Vector<RID> ao_deinterleaved_slices;
- RID ao_pong;
- Vector<RID> ao_pong_slices;
- RID ao_final;
- RID importance_map[2];
- RID depth_texture_view;
-
- RID gather_uniform_set;
- RID importance_map_uniform_set;
};
struct SSAOSettings {
@@ -137,12 +128,11 @@ public:
float horizon = 0.06;
float sharpness = 0.98;
- Size2i full_screen_size = Size2i();
+ Size2i full_screen_size;
};
- void ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth);
- void generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings);
- void ssao_free(SSAORenderBuffers &p_ssao_buffers);
+ void ssao_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings);
+ void generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings);
/* Screen Space Reflection */
void ssr_set_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality);
@@ -150,18 +140,10 @@ public:
struct SSRRenderBuffers {
Size2i size;
RenderingServer::EnvironmentSSRRoughnessQuality roughness_quality = RenderingServer::ENV_SSR_ROUGHNESS_QUALITY_DISABLED;
-
- RID normal_scaled;
- RID depth_scaled;
- RID blur_radius[2];
- RID intermediate;
- RID output;
- RID output_slices[RendererSceneRender::MAX_RENDER_VIEWS];
};
- void ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, const Size2i &p_screen_size, const uint32_t p_view_count);
- void screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, const RID *p_metallic_slices, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets);
- void ssr_free(SSRRenderBuffers &p_ssr_buffers);
+ void ssr_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format);
+ void screen_space_reflection(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RID *p_normal_roughness_slices, const RID *p_metallic_slices, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const Projection *p_projections, const Vector3 *p_eye_offsets);
/* subsurface scattering */
void sss_set_quality(RS::SubSurfaceScatteringQuality p_quality);
@@ -223,7 +205,6 @@ private:
SSEffectsDownsamplePushConstant downsample_push_constant;
SsEffectsDownsampleShaderRD downsample_shader;
RID downsample_shader_version;
- RID downsample_uniform_set;
bool used_half_size_last_frame = false;
bool used_mips_last_frame = false;
bool used_full_mips_last_frame = false;
@@ -332,7 +313,7 @@ private:
RID pipelines[SSIL_MAX];
} ssil;
- void gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set);
+ void gather_ssil(RD::ComputeListID p_compute_list, const RID *p_ssil_slices, const RID *p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set);
/* SSAO */
@@ -426,7 +407,7 @@ private:
RID pipelines[SSAO_MAX];
} ssao;
- void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
+ void gather_ssao(RD::ComputeListID p_compute_list, const RID *p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
/* Screen Space Reflection */
diff --git a/servers/rendering/renderer_rd/effects/taa.cpp b/servers/rendering/renderer_rd/effects/taa.cpp
index 657385a509..61e0d3866c 100644
--- a/servers/rendering/renderer_rd/effects/taa.cpp
+++ b/servers/rendering/renderer_rd/effects/taa.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* taa.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* taa.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 "taa.h"
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
diff --git a/servers/rendering/renderer_rd/effects/taa.h b/servers/rendering/renderer_rd/effects/taa.h
index ce4af18866..9e7ad76fb8 100644
--- a/servers/rendering/renderer_rd/effects/taa.h
+++ b/servers/rendering/renderer_rd/effects/taa.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* taa.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* taa.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 TAA_RD_H
#define TAA_RD_H
diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.cpp b/servers/rendering/renderer_rd/effects/tone_mapper.cpp
index 3a47b1420b..7b152b524f 100644
--- a/servers/rendering/renderer_rd/effects/tone_mapper.cpp
+++ b/servers/rendering/renderer_rd/effects/tone_mapper.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* tone_mapper.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* tone_mapper.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 "tone_mapper.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.h b/servers/rendering/renderer_rd/effects/tone_mapper.h
index e91118e241..afd2f8e401 100644
--- a/servers/rendering/renderer_rd/effects/tone_mapper.h
+++ b/servers/rendering/renderer_rd/effects/tone_mapper.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* tone_mapper.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* tone_mapper.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 TONE_MAPPER_RD_H
#define TONE_MAPPER_RD_H
diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp
index 5ff00aa94c..4bc5d7b597 100644
--- a/servers/rendering/renderer_rd/effects/vrs.cpp
+++ b/servers/rendering/renderer_rd/effects/vrs.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* vrs.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* vrs.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 "vrs.h"
#include "../renderer_compositor_rd.h"
@@ -92,18 +92,15 @@ void VRS::copy_vrs(RID p_source_rd_texture, RID p_dest_framebuffer, bool p_multi
}
Size2i VRS::get_vrs_texture_size(const Size2i p_base_size) const {
- // TODO we should find some way to store this properly, we're assuming 16x16 as this seems to be the standard but in our vrs_capacities we
- // obtain a minimum and maximum size, and we should choose something within this range and then make sure that is consistently set when creating
- // our frame buffer. Also it is important that we make the resulting size we calculate down below available to the end user so they know the size
- // of the VRS buffer to supply.
- Size2i texel_size = Size2i(16, 16);
-
- int width = p_base_size.x / texel_size.x;
- if (p_base_size.x % texel_size.x != 0) {
+ int32_t texel_width = RD::get_singleton()->limit_get(RD::LIMIT_VRS_TEXEL_WIDTH);
+ int32_t texel_height = RD::get_singleton()->limit_get(RD::LIMIT_VRS_TEXEL_HEIGHT);
+
+ int width = p_base_size.x / texel_width;
+ if (p_base_size.x % texel_width != 0) {
width++;
}
- int height = p_base_size.y / texel_size.y;
- if (p_base_size.y % texel_size.y != 0) {
+ int height = p_base_size.y / texel_height;
+ if (p_base_size.y % texel_height != 0) {
height++;
}
return Size2i(width, height);
diff --git a/servers/rendering/renderer_rd/effects/vrs.h b/servers/rendering/renderer_rd/effects/vrs.h
index 7125c6455d..b18cf55791 100644
--- a/servers/rendering/renderer_rd/effects/vrs.h
+++ b/servers/rendering/renderer_rd/effects/vrs.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* vrs.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* vrs.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 VRS_RD_H
#define VRS_RD_H
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index b03415f2e3..b7a1396f9c 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* effects_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* effects_rd.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 "effects_rd.h"
@@ -55,36 +55,13 @@ RID EffectsRD::_get_uniform_set_from_image(RID p_image) {
u.append_id(p_image);
uniforms.push_back(u);
//any thing with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 1);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0), 1);
image_to_uniform_set_cache[p_image] = uniform_set;
return uniform_set;
}
-RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
- if (texture_to_uniform_set_cache.has(p_texture)) {
- RID uniform_set = texture_to_uniform_set_cache[p_texture];
- if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- return uniform_set;
- }
- }
-
- Vector<RD::Uniform> uniforms;
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 0;
- u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
- u.append_id(p_texture);
- uniforms.push_back(u);
- // anything with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, 0), 0);
-
- texture_to_uniform_set_cache[p_texture] = uniform_set;
-
- return uniform_set;
-}
-
RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
if (texture_to_compute_uniform_set_cache.has(p_texture)) {
RID uniform_set = texture_to_compute_uniform_set_cache[p_texture];
@@ -101,86 +78,13 @@ RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_m
u.append_id(p_texture);
uniforms.push_back(u);
//any thing with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 0);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0), 0);
texture_to_compute_uniform_set_cache[p_texture] = uniform_set;
return uniform_set;
}
-void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
- ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of luminance reduction with the mobile renderer.");
-
- luminance_reduce.push_constant.source_size[0] = p_source_size.x;
- luminance_reduce.push_constant.source_size[1] = p_source_size.y;
- luminance_reduce.push_constant.max_luminance = p_max_luminance;
- luminance_reduce.push_constant.min_luminance = p_min_luminance;
- luminance_reduce.push_constant.exposure_adjust = p_adjust;
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- for (int i = 0; i < p_reduce.size(); i++) {
- if (i == 0) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_READ]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_texture), 0);
- } else {
- RD::get_singleton()->compute_list_add_barrier(compute_list); //needs barrier, wait until previous is done
-
- if (i == p_reduce.size() - 1 && !p_set) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_WRITE]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_prev_luminance), 2);
- } else {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE]);
- }
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_reduce[i - 1]), 0);
- }
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_reduce[i]), 1);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &luminance_reduce.push_constant, sizeof(LuminanceReducePushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, luminance_reduce.push_constant.source_size[0], luminance_reduce.push_constant.source_size[1], 1);
-
- luminance_reduce.push_constant.source_size[0] = MAX(luminance_reduce.push_constant.source_size[0] / 8, 1);
- luminance_reduce.push_constant.source_size[1] = MAX(luminance_reduce.push_constant.source_size[1] / 8, 1);
- }
-
- RD::get_singleton()->compute_list_end();
-}
-
-void EffectsRD::luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
- ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster version of luminance reduction with the clustered renderer.");
- ERR_FAIL_COND_MSG(p_reduce.size() != p_fb.size(), "Incorrect frame buffer account for luminance reduction.");
-
- luminance_reduce_raster.push_constant.max_luminance = p_max_luminance;
- luminance_reduce_raster.push_constant.min_luminance = p_min_luminance;
- luminance_reduce_raster.push_constant.exposure_adjust = p_adjust;
-
- for (int i = 0; i < p_reduce.size(); i++) {
- luminance_reduce_raster.push_constant.source_size[0] = i == 0 ? p_source_size.x : luminance_reduce_raster.push_constant.dest_size[0];
- luminance_reduce_raster.push_constant.source_size[1] = i == 0 ? p_source_size.y : luminance_reduce_raster.push_constant.dest_size[1];
- luminance_reduce_raster.push_constant.dest_size[0] = MAX(luminance_reduce_raster.push_constant.source_size[0] / 8, 1);
- luminance_reduce_raster.push_constant.dest_size[1] = MAX(luminance_reduce_raster.push_constant.source_size[1] / 8, 1);
-
- bool final = !p_set && (luminance_reduce_raster.push_constant.dest_size[0] == 1) && (luminance_reduce_raster.push_constant.dest_size[1] == 1);
- LuminanceReduceRasterMode mode = final ? LUMINANCE_REDUCE_FRAGMENT_FINAL : (i == 0 ? LUMINANCE_REDUCE_FRAGMENT_FIRST : LUMINANCE_REDUCE_FRAGMENT);
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, luminance_reduce_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_fb[i])));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(i == 0 ? p_source_texture : p_reduce[i - 1]), 0);
- if (final) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_prev_luminance), 1);
- }
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
-
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &luminance_reduce_raster.push_constant, sizeof(LuminanceReduceRasterPushConstant));
-
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
- }
-}
-
void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
roughness_limiter.push_constant.screen_size[0] = p_size.x;
roughness_limiter.push_constant.screen_size[1] = p_size.y;
@@ -270,39 +174,6 @@ void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
prefer_raster_effects = p_prefer_raster_effects;
- if (prefer_raster_effects) {
- Vector<String> luminance_reduce_modes;
- luminance_reduce_modes.push_back("\n#define FIRST_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FIRST
- luminance_reduce_modes.push_back("\n"); // LUMINANCE_REDUCE_FRAGMENT
- luminance_reduce_modes.push_back("\n#define FINAL_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FINAL
-
- luminance_reduce_raster.shader.initialize(luminance_reduce_modes);
- memset(&luminance_reduce_raster.push_constant, 0, sizeof(LuminanceReduceRasterPushConstant));
- luminance_reduce_raster.shader_version = luminance_reduce_raster.shader.version_create();
-
- for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) {
- luminance_reduce_raster.pipelines[i].setup(luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
- }
- } else {
- // Initialize luminance_reduce
- Vector<String> luminance_reduce_modes;
- luminance_reduce_modes.push_back("\n#define READ_TEXTURE\n");
- luminance_reduce_modes.push_back("\n");
- luminance_reduce_modes.push_back("\n#define WRITE_LUMINANCE\n");
-
- luminance_reduce.shader.initialize(luminance_reduce_modes);
-
- luminance_reduce.shader_version = luminance_reduce.shader.version_create();
-
- for (int i = 0; i < LUMINANCE_REDUCE_MAX; i++) {
- luminance_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, i));
- }
-
- for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) {
- luminance_reduce_raster.pipelines[i].clear();
- }
- }
-
if (!prefer_raster_effects) {
// Initialize roughness limiter
Vector<String> shader_modes;
@@ -368,11 +239,6 @@ EffectsRD::~EffectsRD() {
RD::get_singleton()->free(default_mipmap_sampler);
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
- if (prefer_raster_effects) {
- luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version);
- } else {
- luminance_reduce.shader.version_free(luminance_reduce.shader_version);
- }
if (!prefer_raster_effects) {
roughness_limiter.shader.version_free(roughness_limiter.shader_version);
}
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index b05af73cf3..45198e5fc5 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -1,40 +1,38 @@
-/*************************************************************************/
-/* effects_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* effects_rd.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 EFFECTS_RD_H
#define EFFECTS_RD_H
#include "core/math/projection.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
-#include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
@@ -45,51 +43,6 @@ class EffectsRD {
private:
bool prefer_raster_effects;
- enum LuminanceReduceMode {
- LUMINANCE_REDUCE_READ,
- LUMINANCE_REDUCE,
- LUMINANCE_REDUCE_WRITE,
- LUMINANCE_REDUCE_MAX
- };
-
- struct LuminanceReducePushConstant {
- int32_t source_size[2];
- float max_luminance;
- float min_luminance;
- float exposure_adjust;
- float pad[3];
- };
-
- struct LuminanceReduce {
- LuminanceReducePushConstant push_constant;
- LuminanceReduceShaderRD shader;
- RID shader_version;
- RID pipelines[LUMINANCE_REDUCE_MAX];
- } luminance_reduce;
-
- enum LuminanceReduceRasterMode {
- LUMINANCE_REDUCE_FRAGMENT_FIRST,
- LUMINANCE_REDUCE_FRAGMENT,
- LUMINANCE_REDUCE_FRAGMENT_FINAL,
- LUMINANCE_REDUCE_FRAGMENT_MAX
- };
-
- struct LuminanceReduceRasterPushConstant {
- int32_t source_size[2];
- int32_t dest_size[2];
- float exposure_adjust;
- float min_luminance;
- float max_luminance;
- uint32_t pad1;
- };
-
- struct LuminanceReduceFragment {
- LuminanceReduceRasterPushConstant push_constant;
- LuminanceReduceRasterShaderRD shader;
- RID shader_version;
- PipelineCacheRD pipelines[LUMINANCE_REDUCE_FRAGMENT_MAX];
- } luminance_reduce_raster;
-
struct RoughnessLimiterPushConstant {
int32_t screen_size[2];
float curve;
@@ -164,15 +117,11 @@ private:
RBMap<TextureSamplerPair, RID> texture_sampler_to_compute_uniform_set_cache;
RID _get_uniform_set_from_image(RID p_texture);
- RID _get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false);
RID _get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false);
public:
bool get_prefer_raster_effects();
- void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
- void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
-
void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve);
void sort_buffer(RID p_uniform_set, int p_size);
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp
index 74082906c4..4253ea8610 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"
@@ -82,11 +82,11 @@ void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
-void Fog::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
+void Fog::fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) {
FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
ERR_FAIL_COND(!fog_volume);
- fog_volume->extents = p_extents;
+ fog_volume->size = p_size;
fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
@@ -120,8 +120,8 @@ AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const {
case RS::FOG_VOLUME_SHAPE_CYLINDER:
case RS::FOG_VOLUME_SHAPE_BOX: {
AABB aabb;
- aabb.position = -fog_volume->extents;
- aabb.size = fog_volume->extents * 2;
+ aabb.position = -fog_volume->size / 2;
+ aabb.size = fog_volume->size;
return aabb;
}
default: {
@@ -131,10 +131,10 @@ AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const {
}
}
-Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const {
+Vector3 Fog::fog_volume_get_size(RID p_fog_volume) const {
const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
ERR_FAIL_COND_V(!fog_volume, Vector3());
- return fog_volume->extents;
+ return fog_volume->size;
}
////////////////////////////////////////////////////////////////////////////////
@@ -210,7 +210,7 @@ void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_lay
actions.renames["WORLD_POSITION"] = "world.xyz";
actions.renames["OBJECT_POSITION"] = "params.position";
actions.renames["UVW"] = "uvw";
- actions.renames["EXTENTS"] = "params.extents";
+ actions.renames["SIZE"] = "params.size";
actions.renames["ALBEDO"] = "albedo";
actions.renames["DENSITY"] = "density";
actions.renames["EMISSION"] = "emission";
@@ -319,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
@@ -366,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;
}
@@ -451,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();
@@ -727,13 +637,13 @@ 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);
- Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume);
+ Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_size(fog_volume) / 2;
if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {
// Local fog volume.
@@ -773,9 +683,9 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
push_constant.position[0] = position.x;
push_constant.position[1] = position.y;
push_constant.position[2] = position.z;
- push_constant.extents[0] = extents.x;
- push_constant.extents[1] = extents.y;
- push_constant.extents[2] = extents.z;
+ push_constant.size[0] = extents.x * 2;
+ push_constant.size[1] = extents.y * 2;
+ push_constant.size[2] = extents.z * 2;
push_constant.corner[0] = min.x;
push_constant.corner[1] = min.y;
push_constant.corner[2] = min.z;
@@ -789,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 0ade995758..0b6bcc29fb 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
@@ -53,7 +53,7 @@ private:
struct FogVolume {
RID material;
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;
@@ -83,7 +83,7 @@ private:
float position[3];
float pad;
- float extents[3];
+ float size[3];
float pad2;
int32_t corner[3];
@@ -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() {}
@@ -248,12 +239,12 @@ public:
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;
+ virtual void fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) override;
virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override;
virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;
RID fog_volume_get_material(RID p_fog_volume) const;
virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;
- Vector3 fog_volume_get_extents(RID p_fog_volume) const;
+ Vector3 fog_volume_get_size(RID p_fog_volume) const;
/* FOG VOLUMES INSTANCE */
diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp
index f4a27144d9..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;
@@ -2866,7 +2860,8 @@ 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++) {
@@ -3495,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
@@ -4010,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;
diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h
index 2182ca6a20..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
diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp
index 6940276040..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);
@@ -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].columns[2][0];
- sky_push_constant.projections[v][1] = p_projections[v].columns[0][0];
- sky_push_constant.projections[v][2] = p_projections[v].columns[2][1];
- sky_push_constant.projections[v][3] = p_projections[v].columns[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) {
@@ -1109,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));
@@ -1142,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();
}
@@ -1187,13 +1083,13 @@ 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
@@ -1316,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);
@@ -1333,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());
@@ -1411,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];
@@ -1421,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];
@@ -1440,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;
@@ -1455,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();
@@ -1500,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;
@@ -1539,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();
@@ -1645,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;
@@ -1729,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) {
@@ -1780,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;
@@ -1804,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());
@@ -1819,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();
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 59a8cdf30a..6d5e55ee6a 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -1,35 +1,36 @@
-/*************************************************************************/
-/* render_forward_clustered.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_forward_clustered.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 "render_forward_clustered.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
@@ -108,6 +109,10 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::free_data() {
// JIC, should already have been cleared
if (render_buffers) {
render_buffers->clear_context(RB_SCOPE_FORWARD_CLUSTERED);
+ render_buffers->clear_context(RB_SCOPE_SSDS);
+ render_buffers->clear_context(RB_SCOPE_SSIL);
+ render_buffers->clear_context(RB_SCOPE_SSAO);
+ render_buffers->clear_context(RB_SCOPE_SSR);
}
if (cluster_builder) {
@@ -118,21 +123,6 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::free_data() {
if (!render_sdfgi_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_sdfgi_uniform_set)) {
RD::get_singleton()->free(render_sdfgi_uniform_set);
}
-
- if (ss_effects_data.linear_depth.is_valid()) {
- RD::get_singleton()->free(ss_effects_data.linear_depth);
- ss_effects_data.linear_depth = RID();
- ss_effects_data.linear_depth_slices.clear();
- }
-
- if (ss_effects_data.downsample_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(ss_effects_data.downsample_uniform_set)) {
- RD::get_singleton()->free(ss_effects_data.downsample_uniform_set);
- ss_effects_data.downsample_uniform_set = RID();
- }
-
- RenderForwardClustered::get_singleton()->get_ss_effects()->ssao_free(ss_effects_data.ssao);
- RenderForwardClustered::get_singleton()->get_ss_effects()->ssil_free(ss_effects_data.ssil);
- RenderForwardClustered::get_singleton()->get_ss_effects()->ssr_free(ss_effects_data.ssr);
}
void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RenderSceneBuffersRD *p_render_buffers) {
@@ -348,6 +338,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
#endif
material_uniform_set = surf->material_uniform_set;
shader = surf->shader;
+ surf->material->set_as_used();
#ifdef DEBUG_ENABLED
}
#endif
@@ -666,7 +657,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
scene_state.ubo.ss_effects_flags = 0;
- } else if (is_environment(p_render_data->environment)) {
+ } else if (p_render_data->reflection_probe.is_null() && is_environment(p_render_data->environment)) {
scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment);
scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment);
uint32_t ss_flags = 0;
@@ -830,8 +821,18 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>((*p_render_data->instances)[i]);
- Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
- inst->depth = near_plane.distance_to(support_min);
+ Vector3 center = inst->transform.origin;
+ if (p_render_data->scene_data->cam_orthogonal) {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.get_support(-near_plane.normal);
+ }
+ inst->depth = near_plane.distance_to(center) - inst->sorting_offset;
+ } else {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
+ }
+ inst->depth = p_render_data->scene_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
+ }
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
uint32_t flags = inst->base_flags; //fill flags if appropriate
@@ -963,8 +964,8 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
distance = 1.0;
}
- uint32_t indices;
- surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices);
+ uint32_t indices = 0;
+ surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices);
if (p_render_data->render_info) {
indices = _indices_to_primitives(surf->primitive, indices);
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
@@ -1151,6 +1152,7 @@ void RenderForwardClustered::_update_volumetric_fog(Ref<RenderSceneBuffersRD> p_
ERR_FAIL_COND(p_render_buffers.is_null());
Ref<RenderBufferDataForwardClustered> rb_data = p_render_buffers->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
+ ERR_FAIL_COND(rb_data.is_null());
ERR_FAIL_COND(!p_render_buffers->has_custom_data(RB_SCOPE_GI));
Ref<RendererRD::GI::RenderBuffersGI> rbgi = p_render_buffers->get_custom_data(RB_SCOPE_GI);
@@ -1220,9 +1222,9 @@ void RenderForwardClustered::_update_volumetric_fog(Ref<RenderSceneBuffersRD> p_
/* Lighting */
-void RenderForwardClustered::setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_extents) {
+void RenderForwardClustered::setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_size) {
if (current_cluster_builder != nullptr) {
- current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_REFLECTION_PROBE, p_transform, p_half_extents);
+ current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_REFLECTION_PROBE, p_transform, p_half_size);
}
}
@@ -1232,15 +1234,15 @@ void RenderForwardClustered::setup_added_light(const RS::LightType p_type, const
}
}
-void RenderForwardClustered::setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_extents) {
+void RenderForwardClustered::setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_size) {
if (current_cluster_builder != nullptr) {
- current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, p_transform, p_half_extents);
+ current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, p_transform, p_half_size);
}
}
/* Render scene */
-void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection) {
+void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections) {
ERR_FAIL_NULL(ss_effects);
ERR_FAIL_COND(p_render_buffers.is_null());
ERR_FAIL_COND(p_environment.is_null());
@@ -1259,11 +1261,14 @@ void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_bu
settings.sharpness = environment_get_ssao_sharpness(p_environment);
settings.full_screen_size = p_render_buffers->get_internal_size();
- ss_effects->ssao_allocate_buffers(rb_data->ss_effects_data.ssao, settings, rb_data->ss_effects_data.linear_depth);
- ss_effects->generate_ssao(rb_data->ss_effects_data.ssao, p_normal_buffer, p_projection, settings);
+ ss_effects->ssao_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssao, settings);
+
+ for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) {
+ ss_effects->generate_ssao(p_render_buffers, rb_data->ss_effects_data.ssao, v, p_normal_buffers[v], p_projections[v], settings);
+ }
}
-void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform) {
+void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform) {
ERR_FAIL_NULL(ss_effects);
ERR_FAIL_COND(p_render_buffers.is_null());
ERR_FAIL_COND(p_environment.is_null());
@@ -1280,36 +1285,46 @@ void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_bu
settings.normal_rejection = environment_get_ssil_normal_rejection(p_environment);
settings.full_screen_size = p_render_buffers->get_internal_size();
- Projection correction;
- correction.set_depth_correction(true);
- Projection projection = correction * p_projection;
+ ss_effects->ssil_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssil, settings);
+
Transform3D transform = p_transform;
transform.set_origin(Vector3(0.0, 0.0, 0.0));
- Projection last_frame_projection = rb_data->ss_effects_data.last_frame_projection * Projection(rb_data->ss_effects_data.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse();
- ss_effects->ssil_allocate_buffers(rb_data->ss_effects_data.ssil, settings, rb_data->ss_effects_data.linear_depth);
- ss_effects->screen_space_indirect_lighting(rb_data->ss_effects_data.ssil, p_normal_buffer, p_projection, last_frame_projection, settings);
- rb_data->ss_effects_data.last_frame_projection = projection;
+ for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) {
+ Projection correction;
+ correction.set_depth_correction(true);
+ Projection projection = correction * p_projections[v];
+ Projection last_frame_projection = rb_data->ss_effects_data.last_frame_projections[v] * Projection(rb_data->ss_effects_data.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse();
+
+ ss_effects->screen_space_indirect_lighting(p_render_buffers, rb_data->ss_effects_data.ssil, v, p_normal_buffers[v], p_projections[v], last_frame_projection, settings);
+
+ rb_data->ss_effects_data.last_frame_projections[v] = projection;
+ }
rb_data->ss_effects_data.last_frame_transform = transform;
}
void RenderForwardClustered::_copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers) {
ERR_FAIL_COND(p_render_buffers.is_null());
- Ref<RenderBufferDataForwardClustered> rb_data = p_render_buffers->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
- ERR_FAIL_COND(rb_data.is_null());
-
- if (rb_data->ss_effects_data.ssil.last_frame.is_valid()) {
+ if (p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_LAST_FRAME)) {
Size2i size = p_render_buffers->get_internal_size();
- RID texture = p_render_buffers->get_internal_texture();
- copy_effects->copy_to_rect(texture, rb_data->ss_effects_data.ssil.last_frame, Rect2i(0, 0, size.x, size.y));
-
- int width = size.x;
- int height = size.y;
- for (int i = 0; i < rb_data->ss_effects_data.ssil.last_frame_slices.size() - 1; i++) {
- width = MAX(1, width >> 1);
- height = MAX(1, height >> 1);
- copy_effects->make_mipmap(rb_data->ss_effects_data.ssil.last_frame_slices[i], rb_data->ss_effects_data.ssil.last_frame_slices[i + 1], Size2i(width, height));
+ uint32_t mipmaps = p_render_buffers->get_texture_format(RB_SCOPE_SSIL, RB_LAST_FRAME).mipmaps;
+ for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) {
+ RID source = p_render_buffers->get_internal_texture(v);
+ RID dest = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_LAST_FRAME, v, 0);
+ copy_effects->copy_to_rect(source, dest, Rect2i(0, 0, size.x, size.y));
+
+ int width = size.x;
+ int height = size.y;
+ for (uint32_t m = 1; m < mipmaps; m++) {
+ width = MAX(1, width >> 1);
+ height = MAX(1, height >> 1);
+
+ source = dest;
+ dest = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_LAST_FRAME, v, m);
+
+ copy_effects->make_mipmap(source, dest, Size2i(width, height));
+ }
}
}
}
@@ -1321,7 +1336,9 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
Ref<RenderBufferDataForwardClustered> rb_data;
- if (rb.is_valid()) {
+ if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_FORWARD_CLUSTERED)) {
+ // Our forward clustered custom data buffer will only be available when we're rendering our normal view.
+ // This will not be available when rendering reflection probes.
rb_data = rb->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
}
@@ -1351,8 +1368,8 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
}
//cube shadows are rendered in their own way
- for (uint32_t i = 0; i < p_render_data->cube_shadows.size(); i++) {
- _render_shadow_pass(p_render_data->render_shadows[p_render_data->cube_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->cube_shadows[i]].pass, p_render_data->render_shadows[p_render_data->cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
+ for (const int &index : p_render_data->cube_shadows) {
+ _render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
}
if (p_render_data->directional_shadows.size()) {
@@ -1407,46 +1424,28 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
}
if (rb_data.is_valid() && ss_effects) {
- if (p_use_ssao || p_use_ssil) {
- Size2i size = rb->get_internal_size();
+ // Note, in multiview we're allocating buffers for each eye/view we're rendering.
+ // This should allow most of the processing to happen in parallel even if we're doing
+ // drawcalls per eye/view. It will all sync up at the barrier.
- bool invalidate_uniform_set = false;
- if (rb_data->ss_effects_data.linear_depth.is_null()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16_SFLOAT;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = (size.x + 1) / 2;
- tf.height = (size.y + 1) / 2;
- tf.mipmaps = 5;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb_data->ss_effects_data.linear_depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb_data->ss_effects_data.linear_depth, "SS Effects Depth");
- for (uint32_t i = 0; i < tf.mipmaps; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb_data->ss_effects_data.linear_depth, 0, i, 1, RD::TEXTURE_SLICE_2D_ARRAY);
- rb_data->ss_effects_data.linear_depth_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SS Effects Depth Mip " + itos(i) + " ");
- }
- invalidate_uniform_set = true;
+ if (p_use_ssao || p_use_ssil) {
+ // Convert our depth buffer data to linear data in
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
+ ss_effects->downsample_depth(rb, v, p_render_data->scene_data->view_projection[v]);
}
- RID depth_texture = rb->get_depth_texture();
- ss_effects->downsample_depth(depth_texture, rb_data->ss_effects_data.linear_depth_slices, invalidate_uniform_set, size, p_render_data->scene_data->cam_projection);
- }
-
- if (p_use_ssao) {
- // TODO make these proper stereo
- _process_ssao(rb, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection);
- }
+ if (p_use_ssao) {
+ _process_ssao(rb, p_render_data->environment, p_normal_roughness_slices, p_render_data->scene_data->view_projection);
+ }
- if (p_use_ssil) {
- // TODO make these proper stereo
- _process_ssil(rb, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform);
+ if (p_use_ssil) {
+ _process_ssil(rb, p_render_data->environment, p_normal_roughness_slices, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform);
+ }
}
}
//full barrier here, we need raster, transfer and compute and it depends from the previous work
- RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);
if (current_cluster_builder) {
current_cluster_builder->begin(p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, !p_render_data->reflection_probe.is_valid());
@@ -1466,7 +1465,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0;
light_storage->update_light_buffers(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
- texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform.affine_inverse());
+ texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform);
p_render_data->directional_light_count = directional_light_count;
@@ -1474,7 +1473,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
current_cluster_builder->bake_cluster();
}
- if (rb.is_valid()) {
+ if (rb_data.is_valid()) {
bool directional_shadows = RendererRD::LightStorage::get_singleton()->has_directional_shadows(directional_light_count);
_update_volumetric_fog(rb, p_render_data->environment, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, p_render_data->scene_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, p_render_data->voxel_gi_count, *p_render_data->fog_volumes);
}
@@ -1500,17 +1499,11 @@ void RenderForwardClustered::_process_ssr(Ref<RenderSceneBuffersRD> p_render_buf
ERR_FAIL_COND(p_environment.is_null());
ERR_FAIL_COND(!environment_get_ssr_enabled(p_environment));
- Size2i half_size = Size2i(internal_size.x / 2, internal_size.y / 2);
- ss_effects->ssr_allocate_buffers(rb_data->ss_effects_data.ssr, _render_buffers_get_color_format(), half_size, view_count);
+ ss_effects->ssr_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssr, _render_buffers_get_color_format());
+ ss_effects->screen_space_reflection(p_render_buffers, rb_data->ss_effects_data.ssr, p_normal_slices, p_metallic_slices, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), p_projections, p_eye_offsets);
- RID texture_slices[RendererSceneRender::MAX_RENDER_VIEWS];
- RID depth_slices[RendererSceneRender::MAX_RENDER_VIEWS];
- for (uint32_t v = 0; v < view_count; v++) {
- texture_slices[v] = p_render_buffers->get_internal_texture(v);
- depth_slices[v] = p_render_buffers->get_depth_texture(v);
- }
- ss_effects->screen_space_reflection(rb_data->ss_effects_data.ssr, texture_slices, p_normal_slices, p_metallic_slices, depth_slices, half_size, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), view_count, p_projections, p_eye_offsets);
- copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : p_render_buffers->get_internal_texture(), rb_data->ss_effects_data.ssr.output, view_count);
+ RID output = p_render_buffers->get_texture(RB_SCOPE_SSR, RB_OUTPUT);
+ copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : p_render_buffers->get_internal_texture(), output, view_count);
}
void RenderForwardClustered::_process_sss(Ref<RenderSceneBuffersRD> p_render_buffers, const Projection &p_camera) {
@@ -1536,12 +1529,18 @@ void RenderForwardClustered::_process_sss(Ref<RenderSceneBuffersRD> p_render_buf
void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
- Ref<RenderSceneBuffersRD> rb;
+ ERR_FAIL_NULL(p_render_data);
+
+ Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
+ ERR_FAIL_COND(rb.is_null());
Ref<RenderBufferDataForwardClustered> rb_data;
- if (p_render_data && p_render_data->render_buffers.is_valid()) {
- rb = p_render_data->render_buffers;
+ if (rb->has_custom_data(RB_SCOPE_FORWARD_CLUSTERED)) {
+ // Our forward clustered custom data buffer will only be available when we're rendering our normal view.
+ // This will not be available when rendering reflection probes.
rb_data = rb->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
}
+ bool is_reflection_probe = p_render_data->reflection_probe.is_valid();
+
static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8 };
//first of all, make a new render pass
@@ -1559,22 +1558,17 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
// obtain cluster builder
- if (rb_data.is_valid()) {
- current_cluster_builder = rb_data->cluster_builder;
- } else if (light_storage->owns_reflection_probe_instance(p_render_data->reflection_probe)) {
+ if (light_storage->owns_reflection_probe_instance(p_render_data->reflection_probe)) {
current_cluster_builder = light_storage->reflection_probe_instance_get_cluster_builder(p_render_data->reflection_probe, &cluster_builder_shared);
if (p_render_data->camera_attributes.is_valid()) {
light_storage->reflection_probe_set_baked_exposure(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe), RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes));
}
- } else {
- ERR_PRINT("No render buffer nor reflection atlas, bug"); //should never happen, will crash
- current_cluster_builder = nullptr;
- }
+ } else if (rb_data.is_valid()) {
+ current_cluster_builder = rb_data->cluster_builder;
- p_render_data->voxel_gi_count = 0;
+ p_render_data->voxel_gi_count = 0;
- if (rb.is_valid()) {
if (rb->has_custom_data(RB_SCOPE_SDFGI)) {
Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
if (sdfgi.is_valid()) {
@@ -1585,6 +1579,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
gi.setup_voxel_gi_instances(p_render_data, p_render_data->render_buffers, p_render_data->scene_data->cam_transform, *p_render_data->voxel_gi_instances, p_render_data->voxel_gi_count);
+ } else {
+ ERR_PRINT("No render buffer nor reflection atlas, bug"); //should never happen, will crash
+ current_cluster_builder = nullptr;
}
if (current_cluster_builder != nullptr) {
@@ -1600,7 +1597,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
// check if we need motion vectors
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
p_render_data->scene_data->calculate_motion_vectors = true;
- } else if (rb.is_valid() && rb->get_use_taa()) {
+ } else if (!is_reflection_probe && rb->get_use_taa()) {
p_render_data->scene_data->calculate_motion_vectors = true;
} else {
p_render_data->scene_data->calculate_motion_vectors = false;
@@ -1622,10 +1619,24 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool using_ssr = false;
bool using_sdfgi = false;
bool using_voxelgi = false;
- bool reverse_cull = false;
- bool using_ssil = p_render_data->environment.is_valid() && environment_get_ssil_enabled(p_render_data->environment);
+ bool reverse_cull = p_render_data->scene_data->cam_transform.basis.determinant() < 0;
+ bool using_ssil = !is_reflection_probe && p_render_data->environment.is_valid() && environment_get_ssil_enabled(p_render_data->environment);
+
+ if (is_reflection_probe) {
+ uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
+ screen_size.x = resolution;
+ screen_size.y = resolution;
+
+ color_framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
+ color_only_framebuffer = color_framebuffer;
+ depth_framebuffer = light_storage->reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
- if (rb.is_valid()) {
+ if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+ p_render_data->environment = RID(); //no environment on interiors
+ }
+
+ reverse_cull = true; // for some reason our views are inverted
+ } else {
screen_size = rb->get_internal_size();
if (rb->get_use_taa() || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
@@ -1636,39 +1647,15 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
using_voxelgi = true;
}
- if (p_render_data->environment.is_null() && using_voxelgi) {
- depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
- } else if (p_render_data->environment.is_valid() && (environment_get_ssr_enabled(p_render_data->environment) || environment_get_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) {
+ if (p_render_data->environment.is_valid()) {
if (environment_get_sdfgi_enabled(p_render_data->environment)) {
- depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also voxelgi
using_sdfgi = true;
- } else {
- depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
}
if (environment_get_ssr_enabled(p_render_data->environment)) {
using_separate_specular = true;
using_ssr = true;
color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR;
}
- } else if (p_render_data->environment.is_valid() && (environment_get_ssao_enabled(p_render_data->environment) || using_ssil || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) {
- depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
- }
-
- switch (depth_pass_mode) {
- case PASS_MODE_DEPTH: {
- depth_framebuffer = rb_data->get_depth_fb();
- } break;
- case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
- depth_framebuffer = rb_data->get_depth_fb(RenderBufferDataForwardClustered::DEPTH_FB_ROUGHNESS);
- depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0));
- } break;
- case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
- depth_framebuffer = rb_data->get_depth_fb(RenderBufferDataForwardClustered::DEPTH_FB_ROUGHNESS_VOXELGI);
- depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0));
- depth_pass_clear.push_back(Color(0, 0, 0, 0));
- } break;
- default: {
- };
}
if (p_render_data->scene_data->view_count > 1) {
@@ -1677,22 +1664,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
color_framebuffer = rb_data->get_color_pass_fb(color_pass_flags);
color_only_framebuffer = rb_data->get_color_only_fb();
- } else if (p_render_data->reflection_probe.is_valid()) {
- uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
- screen_size.x = resolution;
- screen_size.y = resolution;
-
- color_framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
- color_only_framebuffer = color_framebuffer;
- depth_framebuffer = light_storage->reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
-
- if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
- p_render_data->environment = RID(); //no environment on interiors
- }
-
- reverse_cull = true; // for some reason our views are inverted
- } else {
- ERR_FAIL(); //bug?
}
p_render_data->scene_data->emissive_exposure_normalization = -1.0;
@@ -1701,7 +1672,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->scene_data->cam_transform);
_setup_voxelgis(*p_render_data->voxel_gi_instances);
- _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
+ _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, false);
_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
@@ -1713,7 +1684,39 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_end_label();
- bool using_sss = rb_data.is_valid() && scene_state.used_sss && ss_effects->sss_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
+ if (!is_reflection_probe) {
+ if (using_voxelgi) {
+ depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
+ } else if (p_render_data->environment.is_valid()) {
+ if (environment_get_ssr_enabled(p_render_data->environment) ||
+ environment_get_sdfgi_enabled(p_render_data->environment) ||
+ environment_get_ssao_enabled(p_render_data->environment) ||
+ using_ssil ||
+ get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER ||
+ scene_state.used_normal_texture) {
+ depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
+ }
+ }
+
+ switch (depth_pass_mode) {
+ case PASS_MODE_DEPTH: {
+ depth_framebuffer = rb_data->get_depth_fb();
+ } break;
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
+ depth_framebuffer = rb_data->get_depth_fb(RenderBufferDataForwardClustered::DEPTH_FB_ROUGHNESS);
+ depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0));
+ } break;
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
+ depth_framebuffer = rb_data->get_depth_fb(RenderBufferDataForwardClustered::DEPTH_FB_ROUGHNESS_VOXELGI);
+ depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0));
+ depth_pass_clear.push_back(Color(0, 0, 0, 0));
+ } break;
+ default: {
+ };
+ }
+ }
+
+ bool using_sss = rb_data.is_valid() && !is_reflection_probe && scene_state.used_sss && ss_effects->sss_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
if (using_sss && !using_separate_specular) {
using_separate_specular = true;
@@ -1746,7 +1749,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.r *= bg_energy_multiplier;
clear_color.g *= bg_energy_multiplier;
clear_color.b *= bg_energy_multiplier;
- if ((rb.is_valid() && rb->has_custom_data(RB_SCOPE_FOG)) || environment_get_fog_enabled(p_render_data->environment)) {
+ if ((rb->has_custom_data(RB_SCOPE_FOG)) || environment_get_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
@@ -1756,7 +1759,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.r *= bg_energy_multiplier;
clear_color.g *= bg_energy_multiplier;
clear_color.b *= bg_energy_multiplier;
- if ((rb.is_valid() && rb->has_custom_data(RB_SCOPE_FOG)) || environment_get_fog_enabled(p_render_data->environment)) {
+ if ((rb->has_custom_data(RB_SCOPE_FOG)) || environment_get_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
@@ -1765,6 +1768,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
draw_sky = true;
} break;
case RS::ENV_BG_CANVAS: {
+ if (!is_reflection_probe) {
+ RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target());
+ copy_effects->copy_to_fb_rect(texture, color_only_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
+ }
keep_color = true;
} break;
case RS::ENV_BG_KEEP: {
@@ -1775,29 +1782,40 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
default: {
}
}
+
// setup sky if used for ambient, reflections, or background
if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky");
- Projection projection = p_render_data->scene_data->cam_projection;
- if (p_render_data->reflection_probe.is_valid()) {
+
+ // Setup our sky render information for this frame/viewport
+ if (is_reflection_probe) {
+ Vector3 eye_offset;
Projection correction;
correction.set_depth_correction(true);
- projection = correction * p_render_data->scene_data->cam_projection;
- }
+ Projection projection = correction * p_render_data->scene_data->cam_projection;
- sky.setup(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this);
+ sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
+ } else {
+ sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
+ }
sky_energy_multiplier *= bg_energy_multiplier;
RID sky_rid = environment_get_sky(p_render_data->environment);
if (sky_rid.is_valid()) {
- sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
+ sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_energy_multiplier);
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else {
// do not try to draw sky if invalid
draw_sky = false;
}
+
+ if (draw_sky || draw_sky_fog_only) {
+ // update sky half/quarter res buffers (if required)
+ sky.update_res_buffers(rb, p_render_data->environment, time, sky_energy_multiplier);
+ }
+
RD::get_singleton()->draw_command_end_label();
}
} else {
@@ -1808,7 +1826,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid();
- bool using_ssao = depth_pre_pass && rb.is_valid() && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment);
+ bool using_ssao = depth_pre_pass && !is_reflection_probe && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment);
bool continue_depth = false;
if (depth_pre_pass) { //depth pre pass
@@ -1840,7 +1858,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_pre_resolve_render(p_render_data, using_sdfgi || using_voxelgi);
}
- if (rb.is_valid() && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
+ if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)");
RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)");
if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) {
@@ -1874,14 +1892,14 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count;
p_render_data->scene_data->opaque_prepass_threshold = 0.0f;
- _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, rb.is_valid());
+ _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, true);
RENDER_TIMESTAMP("Render Opaque Pass");
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true);
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
- bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
+ bool can_continue_depth = !(scene_state.used_depth_texture || scene_state.used_normal_texture) && !using_ssr && !using_sss;
{
bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes);
@@ -1947,19 +1965,15 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Render Sky");
RD::get_singleton()->draw_command_begin_label("Draw Sky");
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
- if (p_render_data->reflection_probe.is_valid()) {
- Projection correction;
- correction.set_depth_correction(true);
- Projection projection = correction * p_render_data->scene_data->cam_projection;
- sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
- } else {
- sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
- }
+ sky.draw_sky(draw_list, rb, p_render_data->environment, color_only_framebuffer, time, sky_energy_multiplier);
+
+ RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label();
}
- if (rb.is_valid() && !can_continue_color && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
+ if (!can_continue_color && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
// Handle views individual, might want to look at rewriting our resolve to do both layers in one pass.
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb_data->get_color_msaa(v), rb->get_internal_texture(v));
@@ -1971,7 +1985,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
}
- if (rb.is_valid() && !can_continue_depth && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
+ if (!can_continue_depth && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
resolve_effects->resolve_depth(rb_data->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
}
@@ -2017,7 +2031,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, true);
- _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
+ _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, false);
{
uint32_t transparent_color_pass_flags = (color_pass_flags | COLOR_PASS_FLAG_TRANSPARENT) & ~(COLOR_PASS_FLAG_SEPARATE_SPECULAR);
@@ -2032,7 +2046,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_begin_label("Resolve");
- if (rb.is_valid() && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
+ if (rb_data.is_valid() && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb_data->get_color_msaa(v), rb->get_internal_texture(v));
resolve_effects->resolve_depth(rb_data->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
@@ -2051,12 +2065,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
RD::get_singleton()->draw_command_end_label();
- if (rb.is_valid() && taa && rb->get_use_taa()) {
+ if (rb_data.is_valid() && taa && rb->get_use_taa()) {
RENDER_TIMESTAMP("TAA")
taa->process(rb, _render_buffers_get_color_format(), p_render_data->scene_data->z_near, p_render_data->scene_data->z_far);
}
- if (rb.is_valid()) {
+ if (rb_data.is_valid()) {
_debug_draw_cluster(rb);
RENDER_TIMESTAMP("Tonemap");
@@ -2064,7 +2078,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_render_buffers_post_process_and_tonemap(p_render_data);
}
- if (rb.is_valid()) {
+ if (rb_data.is_valid()) {
_render_buffers_debug_draw(rb, p_render_data->shadow_atlas, p_render_data->occluder_debug_tex);
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI && rb->has_custom_data(RB_SCOPE_SDFGI)) {
@@ -2094,14 +2108,16 @@ void RenderForwardClustered::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD
RID render_target = p_render_buffers->get_render_target();
- if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb_data->ss_effects_data.ssao.ao_final.is_valid()) {
+ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSAO && p_render_buffers->has_texture(RB_SCOPE_SSAO, RB_FINAL)) {
+ RID final = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_FINAL, 0, 0);
Size2i rtsize = texture_storage->render_target_get_size(render_target);
- copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, true);
+ copy_effects->copy_to_fb_rect(final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, true);
}
- if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb_data->ss_effects_data.ssil.ssil_final.is_valid()) {
+ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSIL && p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_FINAL)) {
+ RID final = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_FINAL, 0, 0);
Size2i rtsize = texture_storage->render_target_get_size(render_target);
- copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false);
+ copy_effects->copy_to_fb_rect(final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false);
}
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && p_render_buffers->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT)) {
@@ -2311,6 +2327,8 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
scene_data.lod_distance_multiplier = p_lod_distance_multiplier;
scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
scene_data.opaque_prepass_threshold = 0.1f;
+ scene_data.time = time;
+ scene_data.time_step = time_step;
RenderDataRD render_data;
render_data.scene_data = &scene_data;
@@ -2376,8 +2394,7 @@ void RenderForwardClustered::_render_shadow_process() {
void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
RD::get_singleton()->draw_command_begin_label("Shadow Render");
- for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
- SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
+ for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) {
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, 0, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
}
@@ -2401,6 +2418,8 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
scene_data.z_far = p_cam_projection.get_z_far();
scene_data.dual_paraboloid_side = 0;
scene_data.opaque_prepass_threshold = 0.0;
+ scene_data.time = time;
+ scene_data.time_step = time_step;
RenderDataRD render_data;
render_data.scene_data = &scene_data;
@@ -2443,6 +2462,8 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
scene_data.material_uv2_mode = false;
scene_data.opaque_prepass_threshold = 0.0f;
scene_data.emissive_exposure_normalization = p_exposure_normalization;
+ scene_data.time = time;
+ scene_data.time_step = time_step;
RenderDataRD render_data;
render_data.scene_data = &scene_data;
@@ -2575,8 +2596,8 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
- Vector3 half_extents = p_bounds.size * 0.5;
- Vector3 center = p_bounds.position + half_extents;
+ Vector3 half_size = p_bounds.size * 0.5;
+ Vector3 center = p_bounds.position + half_size;
Vector<RID> sbs = {
p_albedo_texture,
@@ -2604,16 +2625,16 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu
fb_size.x = p_size[right_axis];
fb_size.y = p_size[up_axis];
- scene_data.cam_transform.origin = center + axis * half_extents;
+ scene_data.cam_transform.origin = center + axis * half_size;
scene_data.cam_transform.basis.set_column(0, right);
scene_data.cam_transform.basis.set_column(1, up);
scene_data.cam_transform.basis.set_column(2, axis);
//print_line("pass: " + itos(i) + " xform " + scene_data.cam_transform);
- float h_size = half_extents[right_axis];
- float v_size = half_extents[up_axis];
- float d_size = half_extents[i] * 2.0;
+ float h_size = half_size[right_axis];
+ float v_size = half_size[up_axis];
+ float d_size = half_size[i] * 2.0;
scene_data.cam_projection.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size);
//print_line("pass: " + itos(i) + " cam hsize: " + rtos(h_size) + " vsize: " + rtos(v_size) + " dsize " + rtos(d_size));
@@ -2848,7 +2869,11 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
Ref<RenderBufferDataForwardClustered> rb_data;
if (p_render_data && p_render_data->render_buffers.is_valid()) {
rb = p_render_data->render_buffers;
- rb_data = rb->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
+ if (rb->has_custom_data(RB_SCOPE_FORWARD_CLUSTERED)) {
+ // Our forward clustered custom data buffer will only be available when we're rendering our normal view.
+ // This will not be available when rendering reflection probes.
+ rb_data = rb->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
+ }
}
//default render buffer and scene state uniform set
@@ -3014,7 +3039,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 13;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID aot = rb_data.is_valid() ? rb_data->get_ao_texture() : RID();
+ RID aot = rb.is_valid() && rb->has_texture(RB_SCOPE_SSAO, RB_FINAL) ? rb->get_texture(RB_SCOPE_SSAO, RB_FINAL) : RID();
RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);
u.append_id(texture);
uniforms.push_back(u);
@@ -3083,7 +3108,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 19;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID vfog = RID();
+ RID vfog;
if (rb_data.is_valid() && rb->has_custom_data(RB_SCOPE_FOG)) {
Ref<RendererRD::Fog::VolumetricFog> fog = rb->get_custom_data(RB_SCOPE_FOG);
vfog = fog->fog_map;
@@ -3100,7 +3125,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 20;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID ssil = rb_data.is_valid() ? rb_data->get_ssil_texture() : RID();
+ RID ssil = rb.is_valid() && rb->has_texture(RB_SCOPE_SSIL, RB_FINAL) ? rb->get_texture(RB_SCOPE_SSIL, RB_FINAL) : RID();
RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);
u.append_id(texture);
uniforms.push_back(u);
@@ -3281,6 +3306,97 @@ void RenderForwardClustered::sub_surface_scattering_set_scale(float p_scale, flo
RenderForwardClustered *RenderForwardClustered::singleton = nullptr;
+void RenderForwardClustered::sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) {
+ Ref<RenderSceneBuffersRD> rb = p_render_buffers;
+ ERR_FAIL_COND(rb.is_null());
+ Ref<RendererRD::GI::SDFGI> sdfgi;
+ if (rb->has_custom_data(RB_SCOPE_SDFGI)) {
+ sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
+ }
+
+ bool needs_sdfgi = p_environment.is_valid() && environment_get_sdfgi_enabled(p_environment);
+
+ if (!needs_sdfgi) {
+ if (sdfgi.is_valid()) {
+ // delete it
+ sdfgi.unref();
+ rb->set_custom_data(RB_SCOPE_SDFGI, sdfgi);
+ }
+ return;
+ }
+
+ static const uint32_t history_frames_to_converge[RS::ENV_SDFGI_CONVERGE_MAX] = { 5, 10, 15, 20, 25, 30 };
+ uint32_t requested_history_size = history_frames_to_converge[gi.sdfgi_frames_to_converge];
+
+ if (sdfgi.is_valid() && (sdfgi->num_cascades != environment_get_sdfgi_cascades(p_environment) || sdfgi->min_cell_size != environment_get_sdfgi_min_cell_size(p_environment) || requested_history_size != sdfgi->history_size || sdfgi->uses_occlusion != environment_get_sdfgi_use_occlusion(p_environment) || sdfgi->y_scale_mode != environment_get_sdfgi_y_scale(p_environment))) {
+ //configuration changed, erase
+ sdfgi.unref();
+ rb->set_custom_data(RB_SCOPE_SDFGI, sdfgi);
+ }
+
+ if (sdfgi.is_null()) {
+ // re-create
+ sdfgi = gi.create_sdfgi(p_environment, p_world_position, requested_history_size);
+ rb->set_custom_data(RB_SCOPE_SDFGI, sdfgi);
+ } else {
+ //check for updates
+ sdfgi->update(p_environment, p_world_position);
+ }
+}
+
+int RenderForwardClustered::sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const {
+ Ref<RenderSceneBuffersRD> rb = p_render_buffers;
+ ERR_FAIL_COND_V(rb.is_null(), 0);
+
+ if (!rb->has_custom_data(RB_SCOPE_SDFGI)) {
+ return 0;
+ }
+ Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
+
+ int dirty_count = 0;
+ for (const RendererRD::GI::SDFGI::Cascade &c : sdfgi->cascades) {
+ if (c.dirty_regions == RendererRD::GI::SDFGI::Cascade::DIRTY_ALL) {
+ dirty_count++;
+ } else {
+ for (int j = 0; j < 3; j++) {
+ if (c.dirty_regions[j] != 0) {
+ dirty_count++;
+ }
+ }
+ }
+ }
+
+ return dirty_count;
+}
+
+AABB RenderForwardClustered::sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const {
+ AABB bounds;
+ Vector3i from;
+ Vector3i size;
+
+ Ref<RenderSceneBuffersRD> rb = p_render_buffers;
+ ERR_FAIL_COND_V(rb.is_null(), AABB());
+ Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
+ ERR_FAIL_COND_V(sdfgi.is_null(), AABB());
+
+ int c = sdfgi->get_pending_region_data(p_region, from, size, bounds);
+ ERR_FAIL_COND_V(c == -1, AABB());
+ return bounds;
+}
+
+uint32_t RenderForwardClustered::sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const {
+ AABB bounds;
+ Vector3i from;
+ Vector3i size;
+
+ Ref<RenderSceneBuffersRD> rb = p_render_buffers;
+ ERR_FAIL_COND_V(rb.is_null(), -1);
+ Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
+ ERR_FAIL_COND_V(sdfgi.is_null(), -1);
+
+ return sdfgi->get_pending_region_data(p_region, from, size, bounds);
+}
+
void RenderForwardClustered::GeometryInstanceForwardClustered::_mark_dirty() {
if (dirty_list_element.in_list()) {
return;
@@ -3304,7 +3420,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
- bool has_base_alpha = (p_material->shader_data->uses_alpha && !p_material->shader_data->uses_alpha_clip) || has_read_screen_alpha;
+ bool has_base_alpha = (p_material->shader_data->uses_alpha && (!p_material->shader_data->uses_alpha_clip || p_material->shader_data->uses_alpha_antialiasing)) || has_read_screen_alpha;
bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
bool has_alpha = has_base_alpha || has_blend_alpha;
@@ -3333,7 +3449,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED) {
//material is only meant for alpha pass
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA;
- if (p_material->shader_data->uses_depth_pre_pass && !(p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED)) {
+ if ((p_material->shader_data->uses_depth_prepass_alpha || p_material->shader_data->uses_alpha_antialiasing) && !(p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED)) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
}
@@ -3349,7 +3465,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
SceneShaderForwardClustered::MaterialData *material_shadow = nullptr;
void *surface_shadow = nullptr;
- if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK) {
+ if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_prepass_alpha && !p_material->shader_data->uses_alpha_clip && !p_material->shader_data->uses_alpha_antialiasing && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK && !p_material->shader_data->uses_point_size) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
material_shadow = static_cast<SceneShaderForwardClustered::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D));
@@ -3368,6 +3484,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
sdcache->flags = flags;
sdcache->shader = p_material->shader_data;
+ sdcache->material = p_material;
sdcache->material_uniform_set = p_material->uniform_set;
sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface);
sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface);
@@ -3586,6 +3703,10 @@ void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p
}
ginstance->transforms_uniform_set = particles_storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ if (particles_storage->particles_get_frame_counter(ginstance->data->base) == 0) {
+ // Particles haven't been cleared or updated, update once now to ensure they are ready to render.
+ particles_storage->update_particles();
+ }
} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {
ginstance->transforms_uniform_set = mesh_storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
@@ -3626,6 +3747,7 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D
case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
+ static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata)->data->dirty_dependencies = true;
} break;
case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata);
@@ -3640,6 +3762,7 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D
}
void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
+ static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata)->data->dirty_dependencies = true;
}
RenderGeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) {
@@ -3862,11 +3985,11 @@ RenderForwardClustered::~RenderForwardClustered() {
RSG::light_storage->directional_shadow_atlas_set_size(0);
{
- for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) {
- RD::get_singleton()->free(scene_state.uniform_buffers[i]);
+ for (const RID &rid : scene_state.uniform_buffers) {
+ RD::get_singleton()->free(rid);
}
- for (uint32_t i = 0; i < scene_state.implementation_uniform_buffers.size(); i++) {
- RD::get_singleton()->free(scene_state.implementation_uniform_buffers[i]);
+ for (const RID &rid : scene_state.implementation_uniform_buffers) {
+ RD::get_singleton()->free(rid);
}
RD::get_singleton()->free(scene_state.lightmap_buffer);
RD::get_singleton()->free(scene_state.lightmap_capture_buffer);
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index 670eb93e20..e07d2f2258 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_forward_clustered.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_forward_clustered.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 RENDER_FORWARD_CLUSTERED_H
#define RENDER_FORWARD_CLUSTERED_H
@@ -104,16 +104,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
ClusterBuilderRD *cluster_builder = nullptr;
struct SSEffectsData {
- RID linear_depth;
- Vector<RID> linear_depth_slices;
-
- RID downsample_uniform_set;
-
- Projection last_frame_projection;
+ Projection last_frame_projections[RendererSceneRender::MAX_RENDER_VIEWS];
Transform3D last_frame_transform;
- RendererRD::SSEffects::SSAORenderBuffers ssao;
RendererRD::SSEffects::SSILRenderBuffers ssil;
+ RendererRD::SSEffects::SSAORenderBuffers ssao;
RendererRD::SSEffects::SSRRenderBuffers ssr;
} ss_effects_data;
@@ -155,9 +150,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID get_depth_fb(DepthFrameBufferType p_type = DEPTH_FB);
RID get_specular_only_fb();
- RID get_ao_texture() const { return ss_effects_data.ssao.ao_final; }
- RID get_ssil_texture() const { return ss_effects_data.ssil.ssil_final; }
-
virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
virtual void free_data() override;
};
@@ -210,10 +202,10 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float screen_mesh_lod_threshold = 0.0;
RD::FramebufferFormatID framebuffer_format = 0;
uint32_t element_offset = 0;
- uint32_t barrier = RD::BARRIER_MASK_ALL;
+ uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS;
bool use_directional_soft_shadow = false;
- RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) {
elements = p_elements;
element_info = p_element_info;
element_count = p_element_count;
@@ -441,6 +433,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
void *surface = nullptr;
RID material_uniform_set;
SceneShaderForwardClustered::ShaderData *shader = nullptr;
+ SceneShaderForwardClustered::MaterialData *material = nullptr;
void *surface_shadow = nullptr;
RID material_uniform_set_shadow;
@@ -596,11 +589,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
void _render_shadow_begin();
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
void _render_shadow_process();
- void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
/* Render Scene */
- void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection);
- void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform);
+ void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections);
+ void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform);
void _copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers);
void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer);
void _process_ssr(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive);
@@ -639,9 +632,9 @@ public:
RendererRD::SSEffects *get_ss_effects() { return ss_effects; }
/* callback from updating our lighting UBOs, used to populate cluster builder */
- virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_extents) override;
+ virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_size) override;
virtual void setup_added_light(const RS::LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) override;
- virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_extents) override;
+ virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_size) override;
virtual void base_uniforms_changed() override;
_FORCE_INLINE_ virtual void update_uniform_sets() override {
@@ -649,6 +642,16 @@ public:
_update_render_base_uniform_set();
}
+ /* SDFGI UPDATE */
+
+ virtual void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override;
+ virtual int sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const override;
+ virtual AABB sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override;
+ virtual uint32_t sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override;
+ RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
+
+ /* GEOMETRY INSTANCE */
+
virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override;
virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override;
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index c01919a606..3b3979b198 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* scene_shader_forward_clustered.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* scene_shader_forward_clustered.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 "scene_shader_forward_clustered.h"
#include "core/config/project_settings.h"
@@ -37,10 +37,6 @@
using namespace RendererSceneRenderImplementation;
-void SceneShaderForwardClustered::ShaderData::set_path_hint(const String &p_path) {
- path = p_path;
-}
-
void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
//compile
@@ -48,7 +44,6 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
valid = false;
ubo_size = 0;
uniforms.clear();
- uses_screen_texture = false;
if (code.is_empty()) {
return; //just invalid, but no error
@@ -64,8 +59,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
uses_point_size = false;
uses_alpha = false;
uses_alpha_clip = false;
+ uses_alpha_antialiasing = false;
uses_blend_alpha = false;
- uses_depth_pre_pass = false;
+ uses_depth_prepass_alpha = false;
uses_discard = false;
uses_roughness = false;
uses_normal = false;
@@ -76,9 +72,6 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
uses_position = false;
uses_sss = false;
uses_transmittance = false;
- uses_screen_texture = false;
- uses_depth_texture = false;
- uses_normal_texture = false;
uses_time = false;
writes_modelview_or_projection = false;
uses_world_coordinates = false;
@@ -115,14 +108,14 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
actions.usage_flag_pointers["ALPHA"] = &uses_alpha;
actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip;
- actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
+ actions.usage_flag_pointers["ALPHA_HASH_SCALE"] = &uses_alpha_clip;
+ actions.usage_flag_pointers["ALPHA_ANTIALIASING_EDGE"] = &uses_alpha_antialiasing;
+ actions.usage_flag_pointers["ALPHA_TEXTURE_COORDINATE"] = &uses_alpha_antialiasing;
+ actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_prepass_alpha;
actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
- actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
- actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture;
- actions.usage_flag_pointers["NORMAL_TEXTURE"] = &uses_normal_texture;
actions.usage_flag_pointers["DISCARD"] = &uses_discard;
actions.usage_flag_pointers["TIME"] = &uses_time;
actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
@@ -151,6 +144,11 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
depth_test = DepthTest(depth_testi);
cull_mode = Cull(cull_modei);
uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
+ uses_screen_texture = gen_code.uses_screen_texture;
+ uses_depth_texture = gen_code.uses_depth_texture;
+ uses_normal_texture = gen_code.uses_normal_roughness_texture;
+ uses_vertex_time = gen_code.uses_vertex_time;
+ uses_fragment_time = gen_code.uses_fragment_time;
#if 0
print_line("**compiling shader:");
@@ -255,6 +253,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
}
+ bool depth_pre_pass_enabled = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));
for (int i = 0; i < CULL_VARIANT_MAX; i++) {
RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = {
@@ -306,8 +305,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
continue;
}
- RD::PipelineColorBlendState blend_state;
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
+
+ RD::PipelineColorBlendState blend_state;
RD::PipelineMultisampleState multisample_state;
int shader_flags = 0;
@@ -327,6 +327,14 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
} else {
blend_state = blend_state_color_opaque;
+ if (depth_pre_pass_enabled) {
+ // We already have a depth from the depth pre-pass, there is no need to write it again.
+ // In addition we can use COMPARE_OP_EQUAL instead of COMPARE_OP_LESS_OR_EQUAL.
+ // This way we can use the early depth test to discard transparent fragments before the fragment shader even starts.
+ depth_stencil.depth_compare_operator = RD::COMPARE_OP_EQUAL;
+ depth_stencil.enable_depth_write = false;
+ }
+
if (l & PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR) {
shader_flags |= SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR;
}
@@ -345,6 +353,11 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
}
int variant = shader_version + shader_flags;
+
+ if (!static_cast<SceneShaderForwardClustered *>(singleton)->shader.is_variant_enabled(variant)) {
+ continue;
+ }
+
RID shader_variant = shader_singleton->shader.version_get_shader(version, variant);
color_pipelines[i][j][l].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
}
@@ -375,102 +388,16 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
valid = true;
}
-void SceneShaderForwardClustered::ShaderData::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 SceneShaderForwardClustered::ShaderData::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_LOCAL ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
- // Don't expose any of these.
- 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 SceneShaderForwardClustered::ShaderData::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 SceneShaderForwardClustered::ShaderData::is_parameter_texture(const StringName &p_param) const {
- if (!uniforms.has(p_param)) {
- return false;
- }
-
- return uniforms[p_param].texture_order >= 0;
-}
-
bool SceneShaderForwardClustered::ShaderData::is_animated() const {
- return false;
+ return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex);
}
bool SceneShaderForwardClustered::ShaderData::casts_shadows() const {
- return false;
-}
+ bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture;
+ bool has_base_alpha = (uses_alpha && (!uses_alpha_clip || uses_alpha_antialiasing)) || has_read_screen_alpha;
+ bool has_alpha = has_base_alpha || uses_blend_alpha;
-Variant SceneShaderForwardClustered::ShaderData::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();
+ return !has_alpha || (uses_depth_prepass_alpha && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED));
}
RS::ShaderNativeSourceCode SceneShaderForwardClustered::ShaderData::get_native_source_code() const {
@@ -581,7 +508,14 @@ void SceneShaderForwardClustered::init(const String p_defines) {
shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_MULTIVIEW, false);
shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW, false);
shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW, false);
- // TODO Add a way to enable/disable color pass flags
+
+ // Disable Color Passes
+ for (int i = 0; i < SHADER_COLOR_PASS_FLAG_COUNT; i++) {
+ // Selectively disable any shader pass that includes Multiview.
+ if ((i & SHADER_COLOR_PASS_FLAG_MULTIVIEW)) {
+ shader.set_variant_enabled(i + SHADER_VERSION_COLOR_PASS, false);
+ }
+ }
}
}
@@ -681,9 +615,6 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.renames["POINT_COORD"] = "gl_PointCoord";
actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
actions.renames["SCREEN_UV"] = "screen_uv";
- actions.renames["SCREEN_TEXTURE"] = "color_buffer";
- actions.renames["DEPTH_TEXTURE"] = "depth_buffer";
- actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer";
actions.renames["DEPTH"] = "gl_FragDepth";
actions.renames["OUTPUT_IS_SRGB"] = "true";
actions.renames["FOG"] = "fog";
@@ -697,14 +628,16 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.renames["CUSTOM3"] = "custom3_attrib";
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
- actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz";
+ actions.renames["NODE_POSITION_WORLD"] = "read_model_matrix[3].xyz";
actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz";
actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz";
- actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz";
+ actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers";
+ actions.renames["NODE_POSITION_VIEW"] = "(read_model_matrix * scene_data.view_matrix)[3].xyz";
actions.renames["VIEW_INDEX"] = "ViewIndex";
actions.renames["VIEW_MONO_LEFT"] = "0";
actions.renames["VIEW_RIGHT"] = "1";
+ actions.renames["EYE_OFFSET"] = "eye_offset";
//for light
actions.renames["VIEW"] = "view";
@@ -747,7 +680,6 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n";
actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n";
- actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions.usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
@@ -780,10 +712,6 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
- actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; // linear filter with mipmaps
- actions.custom_samplers["DEPTH_TEXTURE"] = "material_samplers[3]";
- actions.custom_samplers["NORMAL_ROUGHNESS_TEXTURE"] = "material_samplers[1]"; // linear filter
-
actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
@@ -802,6 +730,8 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.global_buffer_array_variable = "global_shader_uniforms.data";
actions.instance_uniform_index_variable = "instances.data[instance_index_interp].instance_uniforms_ofs";
+ actions.check_multiview_samplers = true; // make sure we check sampling multiview textures
+
compiler.initialize(actions);
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index a9a9fa94de..ffaf091b36 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* scene_shader_forward_clustered.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* scene_shader_forward_clustered.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 SCENE_SHADER_FORWARD_CLUSTERED_H
#define SCENE_SHADER_FORWARD_CLUSTERED_H
@@ -139,25 +139,22 @@ public:
PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_VERSION_MAX];
PipelineCacheRD color_pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_COLOR_PASS_FLAG_COUNT];
- String path;
-
- HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size = 0;
String code;
- HashMap<StringName, HashMap<int, RID>> default_texture_params;
- DepthDraw depth_draw;
- DepthTest depth_test;
+ DepthDraw depth_draw = DEPTH_DRAW_OPAQUE;
+ DepthTest depth_test = DEPTH_TEST_ENABLED;
bool uses_point_size = false;
bool uses_alpha = false;
bool uses_blend_alpha = false;
bool uses_alpha_clip = false;
- bool uses_depth_pre_pass = false;
+ bool uses_alpha_antialiasing = false;
+ bool uses_depth_prepass_alpha = false;
bool uses_discard = false;
bool uses_roughness = false;
bool uses_normal = false;
@@ -172,6 +169,8 @@ public:
bool uses_depth_texture = false;
bool uses_normal_texture = false;
bool uses_time = false;
+ bool uses_vertex_time = false;
+ bool uses_fragment_time = false;
bool writes_modelview_or_projection = false;
bool uses_world_coordinates = false;
bool uses_screen_texture_mipmaps = false;
@@ -181,15 +180,9 @@ public:
uint32_t index = 0;
virtual void set_code(const String &p_Code);
- virtual void set_path_hint(const String &p_path);
- 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;
- 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;
SelfList<ShaderData> shader_list_element;
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 2dfdb302dc..45fe067a6f 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -1,35 +1,36 @@
-/*************************************************************************/
-/* render_forward_mobile.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_forward_mobile.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 "render_forward_mobile.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
@@ -70,17 +71,17 @@ void RenderForwardMobile::ForwardIDStorageMobile::map_forward_id(RendererRD::For
void RenderForwardMobile::ForwardIDStorageMobile::fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance) {
// first zero out our indices
- p_push_constant->omni_lights[0] = 0xFFFF;
- p_push_constant->omni_lights[1] = 0xFFFF;
+ p_push_constant->omni_lights[0] = 0xFFFFFFFF;
+ p_push_constant->omni_lights[1] = 0xFFFFFFFF;
- p_push_constant->spot_lights[0] = 0xFFFF;
- p_push_constant->spot_lights[1] = 0xFFFF;
+ p_push_constant->spot_lights[0] = 0xFFFFFFFF;
+ p_push_constant->spot_lights[1] = 0xFFFFFFFF;
- p_push_constant->decals[0] = 0xFFFF;
- p_push_constant->decals[1] = 0xFFFF;
+ p_push_constant->decals[0] = 0xFFFFFFFF;
+ p_push_constant->decals[1] = 0xFFFFFFFF;
- p_push_constant->reflection_probes[0] = 0xFFFF;
- p_push_constant->reflection_probes[1] = 0xFFFF;
+ p_push_constant->reflection_probes[0] = 0xFFFFFFFF;
+ p_push_constant->reflection_probes[1] = 0xFFFFFFFF;
if (p_instance->omni_light_count == 0) {
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_OMNI_LIGHTS;
@@ -154,8 +155,8 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RenderSceneBu
render_buffers->create_texture(RB_SCOPE_MOBILE, RB_TEX_COLOR_MSAA, format, usage_bits, texture_samples);
- format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+ format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, usage_bits) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
render_buffers->create_texture(RB_SCOPE_MOBILE, RB_TEX_DEPTH_MSAA, format, usage_bits, texture_samples);
}
@@ -251,7 +252,7 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
Size2i target_size = render_buffers->get_target_size();
Size2i internal_size = render_buffers->get_internal_size();
- // can't do our blit pass if resolutions don't match
+ // can't do our blit pass if resolutions don't match, this should already have been checked.
ERR_FAIL_COND_V(target_size != internal_size, RID());
// - opaque pass
@@ -361,7 +362,11 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
Ref<RenderSceneBuffersRD> rb;
if (p_render_data && p_render_data->render_buffers.is_valid()) {
rb = p_render_data->render_buffers;
- rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
+ if (rb->has_custom_data(RB_SCOPE_MOBILE)) {
+ // Our forward mobile custom data buffer will only be available when we're rendering our normal view.
+ // This will not be available when rendering reflection probes.
+ rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
+ }
}
// default render buffer and scene state uniform set
@@ -575,8 +580,8 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
}
//cube shadows are rendered in their own way
- for (uint32_t i = 0; i < p_render_data->cube_shadows.size(); i++) {
- _render_shadow_pass(p_render_data->render_shadows[p_render_data->cube_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->cube_shadows[i]].pass, p_render_data->render_shadows[p_render_data->cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
+ for (const int &index : p_render_data->cube_shadows) {
+ _render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
}
if (p_render_data->directional_shadows.size()) {
@@ -589,12 +594,10 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
bool render_shadows = p_render_data->directional_shadows.size() || p_render_data->shadows.size();
+ //prepare shadow rendering
if (render_shadows) {
RENDER_TIMESTAMP("Render Shadows");
- }
- //prepare shadow rendering
- if (render_shadows) {
_render_shadow_begin();
//render directional shadows
@@ -612,7 +615,7 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
}
//full barrier here, we need raster, transfer and compute and it depends from the previous work
- RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);
bool using_shadows = true;
@@ -628,7 +631,7 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0;
light_storage->update_light_buffers(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
- texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform.affine_inverse());
+ texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform);
p_render_data->directional_light_count = directional_light_count;
}
@@ -636,12 +639,18 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
- Ref<RenderSceneBuffersRD> rb;
+ ERR_FAIL_NULL(p_render_data);
+
+ Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
+ ERR_FAIL_COND(rb.is_null());
+
Ref<RenderBufferDataForwardMobile> rb_data;
- if (p_render_data->render_buffers.is_valid()) {
- rb = p_render_data->render_buffers;
+ if (rb->has_custom_data(RB_SCOPE_MOBILE)) {
+ // Our forward mobile custom data buffer will only be available when we're rendering our normal view.
+ // This will not be available when rendering reflection probes.
rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
}
+ bool is_reflection_probe = p_render_data->reflection_probe.is_valid();
RENDER_TIMESTAMP("Prepare 3D Scene");
@@ -673,7 +682,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
Size2i screen_size;
RID framebuffer;
- bool reverse_cull = false;
+ bool reverse_cull = p_render_data->scene_data->cam_transform.basis.determinant() < 0;
bool using_subpass_transparent = true;
bool using_subpass_post_process = true;
@@ -689,24 +698,44 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_render_data->instances->size();
}
- if (rb_data.is_valid()) {
+ if (is_reflection_probe) {
+ uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
+ screen_size.x = resolution;
+ screen_size.y = resolution;
+
+ framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
+
+ if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+ p_render_data->environment = RID(); //no environment on interiors
+ }
+
+ reverse_cull = true;
+ using_subpass_transparent = true; // we ignore our screen/depth texture here
+ using_subpass_post_process = false; // not applicable at all for reflection probes.
+ } else if (rb_data.is_valid()) {
// setup rendering to render buffer
screen_size = p_render_data->render_buffers->get_internal_size();
- if (rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_FOUR_SUBPASSES).is_null()) {
- // can't do blit subpass
+ if (rb->get_scaling_3d_mode() != RS::VIEWPORT_SCALING_3D_MODE_OFF) {
+ // can't do blit subpass because we're scaling
using_subpass_post_process = false;
} else if (p_render_data->environment.is_valid() && (environment_get_glow_enabled(p_render_data->environment) || RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) || RSG::camera_attributes->camera_attributes_uses_dof(p_render_data->camera_attributes))) {
- // can't do blit subpass
+ // can't do blit subpass because we're using post processes
using_subpass_post_process = false;
}
if (scene_state.used_screen_texture || scene_state.used_depth_texture) {
- // can't use our last two subpasses
+ // can't use our last two subpasses because we're reading from screen texture or depth texture
using_subpass_transparent = false;
using_subpass_post_process = false;
}
+ // We do this last because our get_color_fbs creates and caches the framebuffer if we need it.
+ if (using_subpass_post_process && rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_FOUR_SUBPASSES).is_null()) {
+ // can't do blit subpass because we don't have all subpasses
+ using_subpass_post_process = false;
+ }
+
if (using_subpass_post_process) {
// all as subpasses
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_FOUR_SUBPASSES);
@@ -717,20 +746,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
// only opaque and sky as subpasses
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_TWO_SUBPASSES);
}
- } else if (p_render_data->reflection_probe.is_valid()) {
- uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
- screen_size.x = resolution;
- screen_size.y = resolution;
-
- framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
-
- if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
- p_render_data->environment = RID(); //no environment on interiors
- }
-
- reverse_cull = true;
- using_subpass_transparent = true; // we ignore our screen/depth texture here
- using_subpass_post_process = false; // not applicable at all for reflection probes.
} else {
ERR_FAIL(); //bug?
}
@@ -740,7 +755,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_begin_label("Render Setup");
_setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->scene_data->cam_transform);
- _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
+ _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, false);
_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
@@ -796,6 +811,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
draw_sky = true;
} break;
case RS::ENV_BG_CANVAS: {
+ if (rb_data.is_valid()) {
+ RID dest_framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
+ RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target());
+ copy_effects->copy_to_fb_rect(texture, dest_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
+ }
keep_color = true;
} break;
case RS::ENV_BG_KEEP: {
@@ -806,55 +826,45 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
default: {
}
}
+
// setup sky if used for ambient, reflections, or background
if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky");
- Projection projection = p_render_data->scene_data->cam_projection;
- if (p_render_data->reflection_probe.is_valid()) {
+
+ // Setup our sky render information for this frame/viewport
+ if (is_reflection_probe) {
+ Vector3 eye_offset;
Projection correction;
correction.set_depth_correction(true);
- projection = correction * p_render_data->scene_data->cam_projection;
- }
+ Projection projection = correction * p_render_data->scene_data->cam_projection;
- sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this);
+ sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
+ } else {
+ sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
+ }
sky_energy_multiplier *= bg_energy_multiplier;
RID sky_rid = environment_get_sky(p_render_data->environment);
if (sky_rid.is_valid()) {
- sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
+ sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_energy_multiplier);
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else {
// do not try to draw sky if invalid
draw_sky = false;
}
+
+ if (draw_sky || draw_sky_fog_only) {
+ // update sky half/quarter res buffers (if required)
+ sky.update_res_buffers(rb, p_render_data->environment, time, sky_energy_multiplier);
+ }
RD::get_singleton()->draw_command_end_label(); // Setup Sky
}
} else {
clear_color = p_default_bg_color;
}
- // update sky buffers (if required)
- if (draw_sky || draw_sky_fog_only) {
- // !BAS! @TODO See if we can limit doing some things double and maybe even move this into _pre_opaque_render
- // and change Forward Clustered in the same way as we have here (but without using subpasses)
- RENDER_TIMESTAMP("Setup Sky Resolution Buffers");
-
- RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers");
-
- if (p_render_data->reflection_probe.is_valid()) {
- Projection correction;
- correction.set_depth_correction(true);
- Projection projection = correction * p_render_data->scene_data->cam_projection;
- sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
- } else {
- sky.update_res_buffers(p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
- }
-
- RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
- }
-
_pre_opaque_render(p_render_data);
uint32_t spec_constant_base_flags = 0;
@@ -887,7 +897,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count;
- _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, p_render_data->render_buffers.is_valid());
+ _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, p_render_data->render_buffers.is_valid());
if (using_subpass_transparent && using_subpass_post_process) {
RENDER_TIMESTAMP("Render Opaque + Transparent + Tonemap");
@@ -939,16 +949,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (draw_sky || draw_sky_fog_only) {
RD::get_singleton()->draw_command_begin_label("Draw Sky Subpass");
+ // Note, sky.setup should have been called up above and setup stuff we need.
+
RD::DrawListID draw_list = RD::get_singleton()->draw_list_switch_to_next_pass();
- if (p_render_data->reflection_probe.is_valid()) {
- Projection correction;
- correction.set_depth_correction(true);
- Projection projection = correction * p_render_data->scene_data->cam_projection;
- sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
- } else {
- sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
- }
+ sky.draw_sky(draw_list, rb, p_render_data->environment, framebuffer, time, sky_energy_multiplier);
RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass
@@ -960,7 +965,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (!using_subpass_transparent) {
// We're done with our subpasses so end our container pass
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL);
+ RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS);
RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass
}
@@ -1012,14 +1017,16 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL);
+ RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS);
} else {
RENDER_TIMESTAMP("Render Transparent");
- framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
+ if (rb_data.is_valid()) {
+ framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
+ }
// this may be needed if we re-introduced steps that change info, not sure which do so in the previous implementation
- // _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
+ // _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, false);
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count);
@@ -1032,12 +1039,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL);
+ RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS);
} else {
//single threaded
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
_render_list(draw_list, fb_format, &render_list_params, 0, render_list_params.element_count);
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL);
+ RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS);
}
RD::get_singleton()->draw_command_end_label(); // Render Transparent Subpass
@@ -1059,9 +1066,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
_disable_clear_request(p_render_data);
}
- if (rb.is_valid()) {
- _render_buffers_debug_draw(rb, p_render_data->shadow_atlas, p_render_data->occluder_debug_tex);
- }
+ _render_buffers_debug_draw(rb, p_render_data->shadow_atlas, p_render_data->occluder_debug_tex);
}
/* these are being called from RendererSceneRenderRD::_pre_opaque_render */
@@ -1269,6 +1274,8 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
scene_data.lod_distance_multiplier = p_lod_distance_multiplier;
scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
scene_data.opaque_prepass_threshold = 0.1;
+ scene_data.time = time;
+ scene_data.time_step = time_step;
RenderDataRD render_data;
render_data.scene_data = &scene_data;
@@ -1332,8 +1339,7 @@ void RenderForwardMobile::_render_shadow_process() {
void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) {
RD::get_singleton()->draw_command_begin_label("Shadow Render");
- for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
- SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
+ for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) {
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
}
@@ -1361,6 +1367,8 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
scene_data.material_uv2_mode = false;
scene_data.opaque_prepass_threshold = 0.0f;
scene_data.emissive_exposure_normalization = p_exposure_normalization;
+ scene_data.time = time;
+ scene_data.time_step = time_step;
RenderDataRD render_data;
render_data.scene_data = &scene_data;
@@ -1484,6 +1492,8 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
scene_data.z_far = p_cam_projection.get_z_far();
scene_data.dual_paraboloid_side = 0;
scene_data.opaque_prepass_threshold = 0.0;
+ scene_data.time = time;
+ scene_data.time_step = time_step;
RenderDataRD render_data;
render_data.scene_data = &scene_data;
@@ -1746,8 +1756,18 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
GeometryInstanceForwardMobile *inst = static_cast<GeometryInstanceForwardMobile *>((*p_render_data->instances)[i]);
- Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
- inst->depth = near_plane.distance_to(support_min);
+ Vector3 center = inst->transform.origin;
+ if (p_render_data->scene_data->cam_orthogonal) {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.get_support(-near_plane.normal);
+ }
+ inst->depth = near_plane.distance_to(center) - inst->sorting_offset;
+ } else {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
+ }
+ inst->depth = p_render_data->scene_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
+ }
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
uint32_t flags = inst->base_flags; //fill flags if appropriate
@@ -1830,8 +1850,8 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
distance = 1.0;
}
- uint32_t indices;
- surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices);
+ uint32_t indices = 0;
+ surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices);
if (p_render_data->render_info) {
indices = _indices_to_primitives(surf->primitive, indices);
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
@@ -1903,7 +1923,6 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
}
void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
- Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers;
RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID();
RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? RendererRD::LightStorage::get_singleton()->reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID();
@@ -2004,6 +2023,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
RID prev_index_array_rd;
RID prev_pipeline_rd;
RID prev_xforms_uniform_set;
+ bool should_request_redraw = false;
bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP);
@@ -2080,6 +2100,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
#endif
material_uniform_set = surf->material_uniform_set;
shader = surf->shader;
+ surf->material->set_as_used();
#ifdef DEBUG_ENABLED
}
#endif
@@ -2090,6 +2111,11 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
continue;
}
+ //request a redraw if one of the shaders uses TIME
+ if (shader->uses_time) {
+ should_request_redraw = true;
+ }
+
//find cull variant
SceneShaderForwardMobile::ShaderData::CullVariant cull_variant;
@@ -2191,6 +2217,11 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count);
}
+
+ // Make the actual redraw request
+ if (should_request_redraw) {
+ RenderingServerDefault::redraw_request();
+ }
}
/* Geometry instance */
@@ -2204,6 +2235,9 @@ RenderGeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base
ginstance->data->base = p_base;
ginstance->data->base_type = type;
+ ginstance->data->dependency_tracker.userdata = ginstance;
+ ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed;
+ ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted;
ginstance->_mark_dirty();
@@ -2321,9 +2355,9 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
- bool has_base_alpha = ((p_material->shader_data->uses_alpha && !p_material->shader_data->uses_alpha_clip) || has_read_screen_alpha);
+ bool has_base_alpha = p_material->shader_data->uses_alpha && (!p_material->shader_data->uses_alpha_clip || p_material->shader_data->uses_alpha_antialiasing);
bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
- bool has_alpha = has_base_alpha || has_blend_alpha;
+ bool has_alpha = has_base_alpha || has_blend_alpha || has_read_screen_alpha;
uint32_t flags = 0;
@@ -2347,10 +2381,10 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS;
}
- if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == SceneShaderForwardMobile::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardMobile::ShaderData::DEPTH_TEST_DISABLED) {
+ if (has_alpha || p_material->shader_data->depth_draw == SceneShaderForwardMobile::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardMobile::ShaderData::DEPTH_TEST_DISABLED) {
//material is only meant for alpha pass
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA;
- if (p_material->shader_data->uses_depth_pre_pass && !(p_material->shader_data->depth_draw == SceneShaderForwardMobile::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardMobile::ShaderData::DEPTH_TEST_DISABLED)) {
+ if ((p_material->shader_data->uses_depth_prepass_alpha || p_material->shader_data->uses_alpha_antialiasing) && !(p_material->shader_data->depth_draw == SceneShaderForwardMobile::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardMobile::ShaderData::DEPTH_TEST_DISABLED)) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
}
@@ -2366,7 +2400,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
SceneShaderForwardMobile::MaterialData *material_shadow = nullptr;
void *surface_shadow = nullptr;
- if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip) {
+ if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_prepass_alpha && !p_material->shader_data->uses_alpha_clip && !p_material->shader_data->uses_alpha_antialiasing) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
material_shadow = static_cast<SceneShaderForwardMobile::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D));
@@ -2385,6 +2419,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
sdcache->flags = flags;
sdcache->shader = p_material->shader_data;
+ sdcache->material = p_material;
sdcache->material_uniform_set = p_material->uniform_set;
sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface);
sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface);
@@ -2602,6 +2637,10 @@ void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_ge
}
ginstance->transforms_uniform_set = particles_storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ if (particles_storage->particles_get_frame_counter(ginstance->data->base) == 0) {
+ // Particles haven't been cleared or updated, update once now to ensure they are ready to render.
+ particles_storage->update_particles();
+ }
} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {
ginstance->transforms_uniform_set = mesh_storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
@@ -2635,6 +2674,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe
case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
+ static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata)->data->dirty_dependencies = true;
} break;
case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata);
@@ -2649,6 +2689,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe
}
void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
+ static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata)->data->dirty_dependencies = true;
}
/* misc */
@@ -2771,8 +2812,8 @@ RenderForwardMobile::~RenderForwardMobile() {
}
{
- for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) {
- RD::get_singleton()->free(scene_state.uniform_buffers[i]);
+ for (const RID &rid : scene_state.uniform_buffers) {
+ RD::get_singleton()->free(rid);
}
RD::get_singleton()->free(scene_state.lightmap_buffer);
RD::get_singleton()->free(scene_state.lightmap_capture_buffer);
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index ce64d805b7..214b39c496 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_forward_mobile.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_forward_mobile.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 RENDER_FORWARD_MOBILE_H
#define RENDER_FORWARD_MOBILE_H
@@ -168,10 +168,10 @@ private:
float screen_mesh_lod_threshold = 0.0;
RD::FramebufferFormatID framebuffer_format = 0;
uint32_t element_offset = 0;
- uint32_t barrier = RD::BARRIER_MASK_ALL;
+ uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS;
uint32_t subpass = 0;
- RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) {
elements = p_elements;
element_info = p_element_info;
element_count = p_element_count;
@@ -196,7 +196,7 @@ private:
void _render_shadow_begin();
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
void _render_shadow_process();
- void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
/* Render Scene */
@@ -440,6 +440,7 @@ protected:
void *surface = nullptr;
RID material_uniform_set;
SceneShaderForwardMobile::ShaderData *shader = nullptr;
+ SceneShaderForwardMobile::MaterialData *material = nullptr;
void *surface_shadow = nullptr;
RID material_uniform_set_shadow;
@@ -554,6 +555,15 @@ public:
virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override;
+ /* SDFGI UPDATE */
+
+ virtual void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
+ virtual int sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const override { return 0; }
+ virtual AABB sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override { return AABB(); }
+ virtual uint32_t sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override { return 0; }
+
+ /* GEOMETRY INSTANCE */
+
static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 71fb3ee4f5..cc4a7dfa47 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* scene_shader_forward_mobile.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* scene_shader_forward_mobile.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 "scene_shader_forward_mobile.h"
#include "core/config/project_settings.h"
@@ -39,10 +39,6 @@ using namespace RendererSceneRenderImplementation;
/* ShaderData */
-void SceneShaderForwardMobile::ShaderData::set_path_hint(const String &p_path) {
- path = p_path;
-}
-
void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
//compile
@@ -50,7 +46,6 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
valid = false;
ubo_size = 0;
uniforms.clear();
- uses_screen_texture = false;
if (code.is_empty()) {
return; //just invalid, but no error
@@ -66,8 +61,9 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
uses_point_size = false;
uses_alpha = false;
uses_alpha_clip = false;
+ uses_alpha_antialiasing = false;
uses_blend_alpha = false;
- uses_depth_pre_pass = false;
+ uses_depth_prepass_alpha = false;
uses_discard = false;
uses_roughness = false;
uses_normal = false;
@@ -77,9 +73,6 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
uses_vertex = false;
uses_sss = false;
uses_transmittance = false;
- uses_screen_texture = false;
- uses_depth_texture = false;
- uses_normal_texture = false;
uses_time = false;
writes_modelview_or_projection = false;
uses_world_coordinates = false;
@@ -116,14 +109,14 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
actions.usage_flag_pointers["ALPHA"] = &uses_alpha;
actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip;
- actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
+ actions.usage_flag_pointers["ALPHA_HASH_SCALE"] = &uses_alpha_clip;
+ actions.usage_flag_pointers["ALPHA_ANTIALIASING_EDGE"] = &uses_alpha_antialiasing;
+ actions.usage_flag_pointers["ALPHA_TEXTURE_COORDINATE"] = &uses_alpha_antialiasing;
+ actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_prepass_alpha;
// actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
// actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
- actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
- actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture;
- actions.usage_flag_pointers["NORMAL_TEXTURE"] = &uses_normal_texture;
actions.usage_flag_pointers["DISCARD"] = &uses_discard;
actions.usage_flag_pointers["TIME"] = &uses_time;
actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
@@ -150,6 +143,12 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
depth_draw = DepthDraw(depth_drawi);
depth_test = DepthTest(depth_testi);
+ uses_vertex_time = gen_code.uses_vertex_time;
+ uses_fragment_time = gen_code.uses_fragment_time;
+ uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
+ uses_screen_texture = gen_code.uses_screen_texture;
+ uses_depth_texture = gen_code.uses_depth_texture;
+ uses_normal_texture = gen_code.uses_normal_roughness_texture;
#if 0
print_line("**compiling shader:");
@@ -331,101 +330,16 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
valid = true;
}
-void SceneShaderForwardMobile::ShaderData::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 SceneShaderForwardMobile::ShaderData::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_LOCAL ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
- 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 SceneShaderForwardMobile::ShaderData::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 SceneShaderForwardMobile::ShaderData::is_parameter_texture(const StringName &p_param) const {
- if (!uniforms.has(p_param)) {
- return false;
- }
-
- return uniforms[p_param].texture_order >= 0;
-}
-
bool SceneShaderForwardMobile::ShaderData::is_animated() const {
- return false;
+ return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex);
}
bool SceneShaderForwardMobile::ShaderData::casts_shadows() const {
- return false;
-}
+ bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture;
+ bool has_base_alpha = (uses_alpha && (!uses_alpha_clip || uses_alpha_antialiasing)) || has_read_screen_alpha;
+ bool has_alpha = has_base_alpha || uses_blend_alpha;
-Variant SceneShaderForwardMobile::ShaderData::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();
+ return !has_alpha || (uses_depth_prepass_alpha && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED));
}
RS::ShaderNativeSourceCode SceneShaderForwardMobile::ShaderData::get_native_source_code() const {
@@ -581,9 +495,6 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.renames["POINT_COORD"] = "gl_PointCoord";
actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
actions.renames["SCREEN_UV"] = "screen_uv";
- actions.renames["SCREEN_TEXTURE"] = "color_buffer";
- actions.renames["DEPTH_TEXTURE"] = "depth_buffer";
- actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer";
actions.renames["DEPTH"] = "gl_FragDepth";
actions.renames["OUTPUT_IS_SRGB"] = "true";
actions.renames["FOG"] = "fog";
@@ -597,14 +508,16 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.renames["CUSTOM3"] = "custom3_attrib";
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
- actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz";
+ actions.renames["NODE_POSITION_WORLD"] = "read_model_matrix[3].xyz";
actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz";
actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz";
- actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz";
+ actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers";
+ actions.renames["NODE_POSITION_VIEW"] = "(read_model_matrix * scene_data.view_matrix)[3].xyz";
actions.renames["VIEW_INDEX"] = "ViewIndex";
actions.renames["VIEW_MONO_LEFT"] = "0";
actions.renames["VIEW_RIGHT"] = "1";
+ actions.renames["EYE_OFFSET"] = "eye_offset";
//for light
actions.renames["VIEW"] = "view";
@@ -647,7 +560,6 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n";
actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n";
- actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions.usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
@@ -698,6 +610,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
actions.apply_luminance_multiplier = true; // apply luminance multiplier to screen texture
+ actions.check_multiview_samplers = true; // make sure we check sampling multiview textures
compiler.initialize(actions);
}
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index f67665a02f..6f1f00cedc 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* scene_shader_forward_mobile.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* scene_shader_forward_mobile.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 SCENE_SHADER_FORWARD_MOBILE_H
#define SCENE_SHADER_FORWARD_MOBILE_H
@@ -100,16 +100,12 @@ public:
uint32_t vertex_input_mask = 0;
PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
- String path;
-
- HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size = 0;
String code;
- HashMap<StringName, HashMap<int, RID>> default_texture_params;
DepthDraw depth_draw;
DepthTest depth_test;
@@ -118,7 +114,8 @@ public:
bool uses_alpha = false;
bool uses_blend_alpha = false;
bool uses_alpha_clip = false;
- bool uses_depth_pre_pass = false;
+ bool uses_alpha_antialiasing = false;
+ bool uses_depth_prepass_alpha = false;
bool uses_discard = false;
bool uses_roughness = false;
bool uses_normal = false;
@@ -131,7 +128,10 @@ public:
bool uses_screen_texture = false;
bool uses_depth_texture = false;
bool uses_normal_texture = false;
+ bool uses_screen_texture_mipmaps = false;
bool uses_time = false;
+ bool uses_vertex_time = false;
+ bool uses_fragment_time = false;
bool writes_modelview_or_projection = false;
bool uses_world_coordinates = false;
@@ -139,16 +139,8 @@ public:
uint32_t index = 0;
virtual void set_code(const String &p_Code);
- virtual void set_path_hint(const String &p_path);
-
- 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;
- 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;
SelfList<ShaderData> shader_list_element;
diff --git a/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp b/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp
index 9baa86a32d..71b8136245 100644
--- a/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* framebuffer_cache_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* framebuffer_cache_rd.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 "framebuffer_cache_rd.h"
diff --git a/servers/rendering/renderer_rd/framebuffer_cache_rd.h b/servers/rendering/renderer_rd/framebuffer_cache_rd.h
index f50d6baa30..cae95ccce0 100644
--- a/servers/rendering/renderer_rd/framebuffer_cache_rd.h
+++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* framebuffer_cache_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* framebuffer_cache_rd.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 FRAMEBUFFER_CACHE_RD_H
#define FRAMEBUFFER_CACHE_RD_H
@@ -254,11 +254,11 @@ public:
RID get_cache_multipass(const Vector<RID> &p_textures, const Vector<RD::FramebufferPass> &p_passes, uint32_t p_views = 1) {
uint32_t h = hash_murmur3_one_32(p_views);
- h = hash_murmur3_one_32(p_textures.size());
+ h = hash_murmur3_one_32(p_textures.size(), h);
for (int i = 0; i < p_textures.size(); i++) {
h = hash_murmur3_one_64(p_textures[i].get_id(), h);
}
- h = hash_murmur3_one_32(p_passes.size());
+ h = hash_murmur3_one_32(p_passes.size(), h);
for (int i = 0; i < p_passes.size(); i++) {
h = _hash_pass(p_passes[i], h);
}
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
index 7a2336970b..17051d1954 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* pipeline_cache_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* pipeline_cache_rd.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 "pipeline_cache_rd.h"
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h
index 882e459bcd..0b12dab416 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.h
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* pipeline_cache_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* pipeline_cache_rd.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 PIPELINE_CACHE_RD_H
#define PIPELINE_CACHE_RD_H
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 5728444312..f102bc0650 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_canvas_render_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_canvas_render_rd.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 "renderer_canvas_render_rd.h"
@@ -398,7 +398,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
r_last_texture = p_texture;
}
-void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) {
+void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used) {
//create an empty push constant
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
@@ -455,7 +455,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
light_count++;
- if (light_count == MAX_LIGHTS_PER_ITEM) {
+ if (light_count == MAX_LIGHTS_PER_ITEM - 1) {
break;
}
}
@@ -525,10 +525,12 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
if (rect->flags & CANVAS_RECT_FLIP_H) {
src_rect.size.x *= -1;
+ push_constant.flags |= FLAGS_FLIP_H;
}
if (rect->flags & CANVAS_RECT_FLIP_V) {
src_rect.size.y *= -1;
+ push_constant.flags |= FLAGS_FLIP_V;
}
if (rect->flags & CANVAS_RECT_TRANSPOSE) {
@@ -706,7 +708,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
//bind textures
- _bind_canvas_texture(p_draw_list, RID(), current_filter, current_repeat, last_texture, push_constant, texpixel_size);
+ _bind_canvas_texture(p_draw_list, primitive->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size);
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3u, primitive->point_count) - 1]);
@@ -790,13 +792,12 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
ERR_BREAK(particles_storage->particles_get_mode(pt->particles) != RS::PARTICLES_MODE_2D);
particles_storage->particles_request_process(pt->particles);
- if (particles_storage->particles_is_inactive(pt->particles)) {
+ if (particles_storage->particles_is_inactive(pt->particles) || particles_storage->particles_get_frame_counter(pt->particles) == 0) {
break;
}
RenderingServerDefault::redraw_request(); // active particles means redraw request
- bool local_coords = true;
int dpc = particles_storage->particles_get_draw_passes(pt->particles);
if (dpc == 0) {
break; //nothing to draw
@@ -818,12 +819,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
if (particles_storage->particles_has_collision(pt->particles) && texture_storage->render_target_is_sdf_enabled(p_render_target)) {
//pass collision information
- Transform2D xform;
- if (local_coords) {
- xform = p_item->final_transform;
- } else {
- xform = p_canvas_transform_inverse;
- }
+ Transform2D xform = p_item->final_transform;
RID sdf_texture = texture_storage->render_target_get_sdf_texture(p_render_target);
@@ -839,6 +835,9 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
} else {
particles_storage->particles_set_canvas_sdf_collision(pt->particles, false, Transform2D(), Rect2(), RID());
}
+
+ // Signal that SDF texture needs to be updated.
+ r_sdf_used |= particles_storage->particles_has_collision(pt->particles);
}
if (mesh.is_null()) {
@@ -1051,7 +1050,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
return uniform_set;
}
-void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
+void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
@@ -1111,8 +1110,20 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material;
- if (material.is_null() && ci->canvas_group != nullptr) {
- material = default_canvas_group_material;
+ if (ci->canvas_group != nullptr) {
+ if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) {
+ if (!p_to_backbuffer) {
+ material = default_clip_children_material;
+ }
+ } else {
+ if (material.is_null()) {
+ if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) {
+ material = default_clip_children_material;
+ } else {
+ material = default_canvas_group_material;
+ }
+ }
+ }
}
if (material != prev_material) {
@@ -1127,6 +1138,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
// Update uniform set.
if (material_data->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material_data->uniform_set)) { // Material may not have a uniform set.
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, MATERIAL_UNIFORM_SET);
+ material_data->set_as_used();
}
} else {
pipeline_variants = &shader.pipeline_variants;
@@ -1136,7 +1148,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
}
}
- _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants);
+ _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants, r_sdf_used);
prev_material = material;
}
@@ -1419,6 +1431,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
const Item::CommandMesh *cm = static_cast<const Item::CommandMesh *>(c);
if (cm->mesh_instance.is_valid()) {
mesh_storage->mesh_instance_check_for_update(cm->mesh_instance);
+ mesh_storage->mesh_instance_set_canvas_item_transform(cm->mesh_instance, canvas_transform_inverse * ci->final_transform);
update_skeletons = true;
}
}
@@ -1434,13 +1447,15 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
item_count = 0;
- Rect2i group_rect = ci->canvas_group_owner->global_rect_cache;
-
- if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_OPAQUE) {
+ if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) {
+ Rect2i group_rect = ci->canvas_group_owner->global_rect_cache;
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false);
+ if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) {
+ items[item_count++] = ci->canvas_group_owner;
+ }
} else if (!backbuffer_cleared) {
texture_storage->render_target_clear_back_buffer(p_to_render_target, Rect2i(), Color(0, 0, 0, 0));
backbuffer_cleared = true;
@@ -1464,7 +1479,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, true);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true);
item_count = 0;
if (ci->canvas_group->blur_mipmaps) {
@@ -1483,7 +1498,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
item_count = 0;
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
@@ -1509,7 +1524,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false);
//then reset
item_count = 0;
}
@@ -1535,6 +1550,9 @@ void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
if (cl->texture == p_texture) {
return;
}
+
+ ERR_FAIL_COND(p_texture.is_valid() && !texture_storage->owns_texture(p_texture));
+
if (cl->texture.is_valid()) {
texture_storage->texture_remove_from_decal_atlas(cl->texture);
}
@@ -1620,7 +1638,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index,
projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
}
- Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
+ Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
projection = projection * Projection(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
ShadowRenderPushConstant push_constant;
@@ -1900,11 +1918,12 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve
}
}
- //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush
+ //if same buffer len is being set, just use buffer_update to avoid a pipeline flush
if (oc->vertex_array.is_null()) {
//create from scratch
//vertices
+ // TODO: geometry is always of length lc * 6 * sizeof(float), so in doubles builds this will receive half the data it needs
oc->vertex_buffer = RD::get_singleton()->vertex_buffer_create(lc * 6 * sizeof(real_t), geometry);
Vector<RID> buffer;
@@ -1989,10 +2008,6 @@ void RendererCanvasRenderRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::
oc->cull_mode = p_mode;
}
-void RendererCanvasRenderRD::CanvasShaderData::set_path_hint(const String &p_path) {
- path = p_path;
-}
-
void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
//compile
@@ -2025,7 +2040,6 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
actions.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&blend_mode, BLEND_MODE_PMALPHA);
actions.render_mode_values["blend_disabled"] = Pair<int *, int>(&blend_mode, BLEND_MODE_DISABLED);
- actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
actions.usage_flag_pointers["texture_sdf"] = &uses_sdf;
actions.usage_flag_pointers["TIME"] = &uses_time;
@@ -2037,6 +2051,7 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
+ uses_screen_texture = gen_code.uses_screen_texture;
if (version.is_null()) {
version = canvas_singleton->shader.canvas_shader.version_create();
@@ -2204,86 +2219,6 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
valid = true;
}
-void RendererCanvasRenderRD::CanvasShaderData::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 RendererCanvasRenderRD::CanvasShaderData::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_LOCAL ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
- E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
- // Don't expose any of these.
- 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 RendererCanvasRenderRD::CanvasShaderData::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 RendererCanvasRenderRD::CanvasShaderData::is_parameter_texture(const StringName &p_param) const {
- if (!uniforms.has(p_param)) {
- return false;
- }
-
- return uniforms[p_param].texture_order >= 0;
-}
-
bool RendererCanvasRenderRD::CanvasShaderData::is_animated() const {
return false;
}
@@ -2292,15 +2227,6 @@ bool RendererCanvasRenderRD::CanvasShaderData::casts_shadows() const {
return false;
}
-Variant RendererCanvasRenderRD::CanvasShaderData::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 RendererCanvasRenderRD::CanvasShaderData::get_native_source_code() const {
RendererCanvasRenderRD *canvas_singleton = static_cast<RendererCanvasRenderRD *>(RendererCanvasRender::singleton);
return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version);
@@ -2503,7 +2429,6 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
actions.renames["SPECULAR_SHININESS_TEXTURE"] = "specular_texture";
actions.renames["SPECULAR_SHININESS"] = "specular_shininess";
actions.renames["SCREEN_UV"] = "screen_uv";
- actions.renames["SCREEN_TEXTURE"] = "screen_texture";
actions.renames["SCREEN_PIXEL_SIZE"] = "canvas_data.screen_pixel_size";
actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["POINT_COORD"] = "gl_PointCoord";
@@ -2524,7 +2449,6 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
actions.renames["screen_uv_to_sdf"] = "screen_uv_to_sdf";
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
- actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions.usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV";
actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
@@ -2539,7 +2463,6 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
actions.custom_samplers["TEXTURE"] = "texture_sampler";
actions.custom_samplers["NORMAL_TEXTURE"] = "texture_sampler";
actions.custom_samplers["SPECULAR_SHININESS_TEXTURE"] = "texture_sampler";
- actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; //mipmap and filter for screen texture
actions.sampler_array_name = "material_samplers";
actions.base_texture_binding_index = 1;
actions.texture_layout_set = MATERIAL_UNIFORM_SET;
@@ -2666,16 +2589,6 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
primitive_arrays.index_array[3] = shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 6);
}
- { //default skeleton buffer
-
- shader.default_skeleton_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform));
- SkeletonUniform su;
- _update_transform_2d_to_mat4(Transform2D(), su.skeleton_inverse);
- _update_transform_2d_to_mat4(Transform2D(), su.skeleton_transform);
- RD::get_singleton()->buffer_update(shader.default_skeleton_uniform_buffer, 0, sizeof(SkeletonUniform), &su);
-
- shader.default_skeleton_texture_buffer = RD::get_singleton()->texture_buffer_create(32, RD::DATA_FORMAT_R32G32B32A32_SFLOAT);
- }
{
//default shadow texture to keep uniform set happy
RD::TextureFormat tf;
@@ -2721,9 +2634,12 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
// Default CanvasGroup shader.
shader_type canvas_item;
+render_mode unshaded;
+
+uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
void fragment() {
- vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0);
+ vec4 c = textureLod(screen_texture, SCREEN_UV, 0.0);
if (c.a > 0.0001) {
c.rgb /= c.a;
@@ -2738,6 +2654,29 @@ void fragment() {
material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
}
+ {
+ default_clip_children_shader = material_storage->shader_allocate();
+ material_storage->shader_initialize(default_clip_children_shader);
+
+ material_storage->shader_set_code(default_clip_children_shader, R"(
+// Default clip children shader.
+
+shader_type canvas_item;
+render_mode unshaded;
+
+uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
+
+void fragment() {
+ vec4 c = textureLod(screen_texture, SCREEN_UV, 0.0);
+ COLOR.rgb = c.rgb;
+}
+)");
+ default_clip_children_material = material_storage->material_allocate();
+ material_storage->material_initialize(default_clip_children_material);
+
+ material_storage->material_set_shader(default_clip_children_material, default_clip_children_shader);
+ }
+
static_assert(sizeof(PushConstant) == 128);
}
@@ -2789,6 +2728,9 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() {
material_storage->material_free(default_canvas_group_material);
material_storage->shader_free(default_canvas_group_shader);
+ material_storage->material_free(default_clip_children_material);
+ material_storage->shader_free(default_clip_children_shader);
+
{
if (state.canvas_state_buffer.is_valid()) {
RD::get_singleton()->free(state.canvas_state_buffer);
@@ -2796,8 +2738,6 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() {
memdelete_arr(state.light_uniforms);
RD::get_singleton()->free(state.lights_uniform_buffer);
- RD::get_singleton()->free(shader.default_skeleton_uniform_buffer);
- RD::get_singleton()->free(shader.default_skeleton_texture_buffer);
}
//shadow rendering
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 67db56d913..7dea4a1a65 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_canvas_render_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_canvas_render_rd.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 RENDERER_CANVAS_RENDER_RD_H
#define RENDERER_CANVAS_RENDER_RD_H
@@ -86,6 +86,9 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
FLAGS_USE_MSDF = (1 << 28),
FLAGS_USE_LCD = (1 << 29),
+
+ FLAGS_FLIP_H = (1 << 30),
+ FLAGS_FLIP_V = (1 << 31),
};
enum {
@@ -144,10 +147,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
RID quad_index_array;
PipelineVariants pipeline_variants;
- // default_skeleton uniform set
- RID default_skeleton_uniform_buffer;
- RID default_skeleton_texture_buffer;
-
ShaderCompiler compiler;
} shader;
@@ -164,16 +163,13 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
bool valid = false;
RID version;
PipelineVariants pipeline_variants;
- String path;
- HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size = 0;
String code;
- HashMap<StringName, HashMap<int, RID>> default_texture_params;
bool uses_screen_texture = false;
bool uses_screen_texture_mipmaps = false;
@@ -181,15 +177,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
bool uses_time = false;
virtual void set_code(const String &p_Code);
- virtual void set_path_hint(const String &p_path);
- 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;
CanvasShaderData() {}
@@ -409,11 +398,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
uint32_t lights[4];
};
- struct SkeletonUniform {
- float skeleton_transform[16];
- float skeleton_inverse[16];
- };
-
Item *items[MAX_RENDER_ITEMS];
bool using_directional_lights = false;
@@ -421,6 +405,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
RID default_canvas_group_shader;
RID default_canvas_group_material;
+ RID default_clip_children_material;
+ RID default_clip_children_shader;
RS::CanvasItemTextureFilter default_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
RS::CanvasItemTextureRepeat default_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
@@ -428,8 +414,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
RID _create_base_uniform_set(RID p_to_render_target, bool p_backbuffer);
inline void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size); //recursive, so regular inline used instead.
- void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants);
- void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false);
+ void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used);
+ void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
@@ -457,8 +443,6 @@ public:
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used);
- void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {}
-
virtual void set_shadow_texture_size(int p_size);
void set_time(double p_time);
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 3289bfb0ea..94e3b01486 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_compositor_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_compositor_rd.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 "renderer_compositor_rd.h"
@@ -174,13 +174,19 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color
texture_storage->texture_2d_initialize(texture, p_image);
RID rd_texture = texture_storage->texture_get_rd_texture(texture);
+ RD::SamplerState sampler_state;
+ sampler_state.min_filter = p_use_filter ? RD::SAMPLER_FILTER_LINEAR : RD::SAMPLER_FILTER_NEAREST;
+ sampler_state.mag_filter = p_use_filter ? RD::SAMPLER_FILTER_LINEAR : RD::SAMPLER_FILTER_NEAREST;
+ sampler_state.max_lod = 0;
+ RID sampler = RD::get_singleton()->sampler_create(sampler_state);
+
RID uset;
{
Vector<RD::Uniform> uniforms;
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u.binding = 0;
- u.append_id(blit.sampler);
+ u.append_id(sampler);
u.append_id(rd_texture);
uniforms.push_back(u);
uset = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0);
@@ -241,6 +247,7 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color
RD::get_singleton()->swap_buffers();
texture_storage->texture_free(texture);
+ RD::get_singleton()->free(sampler);
}
RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index a28335f800..43c8d78dee 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_compositor_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_compositor_rd.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 RENDERER_COMPOSITOR_RD_H
#define RENDERER_COMPOSITOR_RD_H
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 75fe84f46b..efd961fd89 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_scene_render_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_render_rd.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 "renderer_scene_render_rd.h"
@@ -51,99 +51,6 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) {
}
}
-void RendererSceneRenderRD::sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) {
- Ref<RenderSceneBuffersRD> rb = p_render_buffers;
- ERR_FAIL_COND(rb.is_null());
- Ref<RendererRD::GI::SDFGI> sdfgi;
- if (rb->has_custom_data(RB_SCOPE_SDFGI)) {
- sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
- }
-
- bool needs_sdfgi = p_environment.is_valid() && environment_get_sdfgi_enabled(p_environment);
-
- if (!needs_sdfgi) {
- if (sdfgi.is_valid()) {
- // delete it
- sdfgi.unref();
- rb->set_custom_data(RB_SCOPE_SDFGI, sdfgi);
- }
- return;
- }
-
- static const uint32_t history_frames_to_converge[RS::ENV_SDFGI_CONVERGE_MAX] = { 5, 10, 15, 20, 25, 30 };
- uint32_t requested_history_size = history_frames_to_converge[gi.sdfgi_frames_to_converge];
-
- if (sdfgi.is_valid() && (sdfgi->num_cascades != environment_get_sdfgi_cascades(p_environment) || sdfgi->min_cell_size != environment_get_sdfgi_min_cell_size(p_environment) || requested_history_size != sdfgi->history_size || sdfgi->uses_occlusion != environment_get_sdfgi_use_occlusion(p_environment) || sdfgi->y_scale_mode != environment_get_sdfgi_y_scale(p_environment))) {
- //configuration changed, erase
- sdfgi.unref();
- rb->set_custom_data(RB_SCOPE_SDFGI, sdfgi);
- }
-
- if (sdfgi.is_null()) {
- // re-create
- sdfgi = gi.create_sdfgi(p_environment, p_world_position, requested_history_size);
- rb->set_custom_data(RB_SCOPE_SDFGI, sdfgi);
- } else {
- //check for updates
- sdfgi->update(p_environment, p_world_position);
- }
-}
-
-int RendererSceneRenderRD::sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const {
- Ref<RenderSceneBuffersRD> rb = p_render_buffers;
- ERR_FAIL_COND_V(rb.is_null(), 0);
-
- if (!rb->has_custom_data(RB_SCOPE_SDFGI)) {
- return 0;
- }
- Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
-
- int dirty_count = 0;
- for (uint32_t i = 0; i < sdfgi->cascades.size(); i++) {
- const RendererRD::GI::SDFGI::Cascade &c = sdfgi->cascades[i];
-
- if (c.dirty_regions == RendererRD::GI::SDFGI::Cascade::DIRTY_ALL) {
- dirty_count++;
- } else {
- for (int j = 0; j < 3; j++) {
- if (c.dirty_regions[j] != 0) {
- dirty_count++;
- }
- }
- }
- }
-
- return dirty_count;
-}
-
-AABB RendererSceneRenderRD::sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const {
- AABB bounds;
- Vector3i from;
- Vector3i size;
-
- Ref<RenderSceneBuffersRD> rb = p_render_buffers;
- ERR_FAIL_COND_V(rb.is_null(), AABB());
- Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
- ERR_FAIL_COND_V(sdfgi.is_null(), AABB());
-
- int c = sdfgi->get_pending_region_data(p_region, from, size, bounds);
- ERR_FAIL_COND_V(c == -1, AABB());
- return bounds;
-}
-
-uint32_t RendererSceneRenderRD::sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const {
- AABB bounds;
- Vector3i from;
- Vector3i size;
-
- Ref<RenderSceneBuffersRD> rb = p_render_buffers;
- ERR_FAIL_COND_V(rb.is_null(), -1);
- Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
- ERR_FAIL_COND_V(sdfgi.is_null(), -1);
-
- return sdfgi->get_pending_region_data(p_region, from, size, bounds);
-}
-
RID RendererSceneRenderRD::sky_allocate() {
return sky.allocate_sky_rid();
}
@@ -171,10 +78,6 @@ void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enab
glow_bicubic_upscale = p_enable;
}
-void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) {
- glow_high_quality = p_enable;
-}
-
void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {
volumetric_fog_size = p_size;
volumetric_fog_depth = p_depth;
@@ -346,61 +249,15 @@ Ref<RenderSceneBuffers> RendererSceneRenderRD::render_buffers_create() {
return rb;
}
-void RendererSceneRenderRD::_allocate_luminance_textures(Ref<RenderSceneBuffersRD> rb) {
- ERR_FAIL_COND(!rb->luminance.current.is_null());
-
- Size2i internal_size = rb->get_internal_size();
- int w = internal_size.x;
- int h = internal_size.y;
-
- while (true) {
- w = MAX(w / 8, 1);
- h = MAX(h / 8, 1);
-
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- tf.width = w;
- tf.height = h;
-
- bool final = w == 1 && h == 1;
-
- if (_render_buffers_can_be_storage()) {
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
- if (final) {
- tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT;
- }
- } else {
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
- }
-
- RID texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- rb->luminance.reduce.push_back(texture);
- if (!_render_buffers_can_be_storage()) {
- Vector<RID> fb;
- fb.push_back(texture);
-
- rb->luminance.fb.push_back(RD::get_singleton()->framebuffer_create(fb));
- }
-
- if (final) {
- rb->luminance.current = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- if (!_render_buffers_can_be_storage()) {
- Vector<RID> fb;
- fb.push_back(rb->luminance.current);
-
- rb->luminance.current_fb = RD::get_singleton()->framebuffer_create(fb);
- }
- break;
- }
- }
-}
-
void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) {
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null());
+ if (!rb->has_internal_texture()) {
+ // We're likely rendering reflection probes where we can't use our backbuffers.
+ return;
+ }
+
RD::get_singleton()->draw_command_begin_label("Copy screen texture");
rb->allocate_blur_textures();
@@ -423,7 +280,7 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData
for (int i = 1; i < mipmaps; i++) {
RID source = dest;
dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i);
- Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i);
+ Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, i);
if (can_use_storage) {
copy_effects->make_mipmap(source, dest, msize);
@@ -440,6 +297,11 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null());
+ if (!rb->has_depth_texture()) {
+ // We're likely rendering reflection probes where we can't use our backbuffers.
+ return;
+ }
+
RD::get_singleton()->draw_command_begin_label("Copy depth texture");
// note, this only creates our back depth texture if we haven't already created it.
@@ -469,9 +331,13 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+ ERR_FAIL_NULL(p_render_data);
+
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null());
+ ERR_FAIL_COND_MSG(p_render_data->reflection_probe.is_valid(), "Post processes should not be applied on reflection probes.");
+
// Glow, auto exposure and DoF (if enabled).
Size2i internal_size = rb->get_internal_size();
@@ -540,9 +406,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
RENDER_TIMESTAMP("Auto exposure");
RD::get_singleton()->draw_command_begin_label("Auto exposure");
- if (rb->luminance.current.is_null()) {
- _allocate_luminance_textures(rb);
- }
+
+ Ref<RendererRD::Luminance::LuminanceBuffers> luminance_buffers = luminance->get_luminance_buffers(rb);
+
uint64_t auto_exposure_version = RSG::camera_attributes->camera_attributes_get_auto_exposure_version(p_render_data->camera_attributes);
bool set_immediate = auto_exposure_version != rb->get_auto_exposure_version();
rb->set_auto_exposure_version(auto_exposure_version);
@@ -550,16 +416,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
double step = RSG::camera_attributes->camera_attributes_get_auto_exposure_adjust_speed(p_render_data->camera_attributes) * time_step;
float auto_exposure_min_sensitivity = RSG::camera_attributes->camera_attributes_get_auto_exposure_min_sensitivity(p_render_data->camera_attributes);
float auto_exposure_max_sensitivity = RSG::camera_attributes->camera_attributes_get_auto_exposure_max_sensitivity(p_render_data->camera_attributes);
- if (can_use_storage) {
- RendererCompositorRD::singleton->get_effects()->luminance_reduction(internal_texture, internal_size, rb->luminance.reduce, rb->luminance.current, auto_exposure_min_sensitivity, auto_exposure_max_sensitivity, step, set_immediate);
- } else {
- RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(internal_texture, internal_size, rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, auto_exposure_min_sensitivity, auto_exposure_max_sensitivity, step, set_immediate);
- }
+ luminance->luminance_reduction(internal_texture, internal_size, luminance_buffers, auto_exposure_min_sensitivity, auto_exposure_max_sensitivity, step, set_immediate);
+
// Swap final reduce with prev luminance.
- SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]);
- if (!can_use_storage) {
- SWAP(rb->luminance.current_fb, rb->luminance.fb.write[rb->luminance.fb.size() - 1]);
- }
auto_exposure_scale = RSG::camera_attributes->camera_attributes_get_auto_exposure_scale(p_render_data->camera_attributes);
@@ -589,30 +448,30 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
float luminance_multiplier = _render_buffers_get_luminance_multiplier();
for (uint32_t l = 0; l < rb->get_view_count(); l++) {
for (int i = 0; i < (max_glow_level + 1); i++) {
- Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i);
+ Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, i);
if (i == 0) {
RID luminance_texture;
- if (RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) && rb->luminance.current.is_valid()) {
- luminance_texture = rb->luminance.current;
+ if (RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes)) {
+ luminance_texture = luminance->get_current_luminance_buffer(rb); // this will return and empty RID if we don't have an auto exposure buffer
}
RID source = rb->get_internal_texture(l);
RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i);
if (can_use_storage) {
- copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale);
+ copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment), true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale);
} else {
RID half = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, 0, i); // we can reuse this for each view
- copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale);
+ copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment), true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale);
}
} else {
RID source = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i - 1);
RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i);
if (can_use_storage) {
- copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality);
+ copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment));
} else {
RID half = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, 0, i); // we can reuse this for each view
- copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality);
+ copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment));
}
}
}
@@ -627,9 +486,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
RendererRD::ToneMapper::TonemapSettings tonemap;
- if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) && rb->luminance.current.is_valid()) {
+ tonemap.exposure_texture = luminance->get_current_luminance_buffer(rb);
+ if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) && tonemap.exposure_texture.is_valid()) {
tonemap.use_auto_exposure = true;
- tonemap.exposure_texture = rb->luminance.current;
tonemap.auto_exposure_scale = auto_exposure_scale;
} else {
tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE);
@@ -643,7 +502,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
tonemap.glow_levels[i] = environment_get_glow_levels(p_render_data->environment)[i];
}
- Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0, 0);
+ Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0);
tonemap.glow_texture_size.x = msize.width;
tonemap.glow_texture_size.y = msize.height;
tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale;
@@ -694,7 +553,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
tonemap.view_count = rb->get_view_count();
RID dest_fb;
- if (fsr && can_use_effects && (internal_size.x != target_size.x || internal_size.y != target_size.y)) {
+ if (fsr && can_use_effects && rb->get_scaling_3d_mode() == RS::VIEWPORT_SCALING_3D_MODE_FSR) {
// If we use FSR to upscale we need to write our result into an intermediate buffer.
// Note that this is cached so we only create the texture the first time.
RID dest_texture = rb->create_texture(SNAME("Tonemapper"), SNAME("destination"), _render_buffers_get_color_format(), RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
@@ -711,10 +570,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
RD::get_singleton()->draw_command_end_label();
}
- if (fsr && can_use_effects && (internal_size.x != target_size.x || internal_size.y != target_size.y)) {
- // TODO Investigate? Does this work? We never write into our render target and we've already done so up above in our tonemapper.
- // I think FSR should either work before our tonemapper or as an alternative of our tonemapper.
-
+ if (fsr && can_use_effects && rb->get_scaling_3d_mode() == RS::VIEWPORT_SCALING_3D_MODE_FSR) {
RD::get_singleton()->draw_command_begin_label("FSR 1.0 Upscale");
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
@@ -843,10 +699,11 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD>
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE) {
- if (p_render_buffers->luminance.current.is_valid()) {
+ RID luminance_texture = luminance->get_current_luminance_buffer(p_render_buffers);
+ if (luminance_texture.is_valid()) {
Size2i rtsize = texture_storage->render_target_get_size(render_target);
- copy_effects->copy_to_fb_rect(p_render_buffers->luminance.current, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize / 8), false, true);
+ copy_effects->copy_to_fb_rect(luminance_texture, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize / 8), false, true);
}
}
@@ -1006,10 +863,20 @@ bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const {
}
void RendererSceneRenderRD::_update_vrs(Ref<RenderSceneBuffersRD> p_render_buffers) {
- if (p_render_buffers.is_valid() && vrs) {
+ if (p_render_buffers.is_null()) {
+ return;
+ }
+
+ RID render_target = p_render_buffers->get_render_target();
+ if (render_target.is_null()) {
+ // must be rendering reflection probes
+ return;
+ }
+
+ if (vrs) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
- RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(p_render_buffers->get_render_target());
+ RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(render_target);
if (vrs_mode != RS::VIEWPORT_VRS_DISABLED) {
RID vrs_texture = p_render_buffers->get_texture(RB_SCOPE_VRS, RB_TEXTURE);
@@ -1065,11 +932,9 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
// getting this here now so we can direct call a bunch of things more easily
- Ref<RenderSceneBuffersRD> rb;
- if (p_render_buffers.is_valid()) {
- rb = p_render_buffers; // cast it...
- ERR_FAIL_COND(rb.is_null());
- }
+ ERR_FAIL_COND(p_render_buffers.is_null());
+ Ref<RenderSceneBuffersRD> rb = p_render_buffers;
+ ERR_FAIL_COND(rb.is_null());
// setup scene data
RenderSceneDataRD scene_data;
@@ -1078,6 +943,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
scene_data.cam_transform = p_camera_data->main_transform;
scene_data.cam_projection = p_camera_data->main_projection;
scene_data.cam_orthogonal = p_camera_data->is_orthogonal;
+ scene_data.camera_visible_layers = p_camera_data->visible_layers;
scene_data.taa_jitter = p_camera_data->taa_jitter;
scene_data.view_count = p_camera_data->view_count;
@@ -1160,7 +1026,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
}
Color clear_color;
- if (p_render_buffers.is_valid()) {
+ if (p_render_buffers.is_valid() && p_reflection_probe.is_null()) {
clear_color = texture_storage->render_target_get_clear_request_color(rb->get_render_target());
} else {
clear_color = RSG::texture_storage->get_default_clear_color();
@@ -1244,6 +1110,8 @@ float RendererSceneRenderRD::screen_space_roughness_limiter_get_limit() const {
}
TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) {
+ ERR_FAIL_COND_V_MSG(p_image_size.width <= 0, TypedArray<Image>(), "Image width must be greater than 0.");
+ ERR_FAIL_COND_V_MSG(p_image_size.height <= 0, TypedArray<Image>(), "Image height must be greater than 0.");
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tf.width = p_image_size.width; // Always 64x64
@@ -1400,7 +1268,6 @@ void RendererSceneRenderRD::init() {
screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount");
screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit");
glow_bicubic_upscale = int(GLOBAL_GET("rendering/environment/glow/upscale_mode")) > 0;
- glow_high_quality = GLOBAL_GET("rendering/environment/glow/use_high_quality");
directional_penumbra_shadow_kernel = memnew_arr(float, 128);
directional_soft_shadow_kernel = memnew_arr(float, 128);
@@ -1418,10 +1285,14 @@ void RendererSceneRenderRD::init() {
cull_argument.set_page_pool(&cull_argument_pool);
bool can_use_storage = _render_buffers_can_be_storage();
+ bool can_use_vrs = is_vrs_supported();
bokeh_dof = memnew(RendererRD::BokehDOF(!can_use_storage));
copy_effects = memnew(RendererRD::CopyEffects(!can_use_storage));
+ luminance = memnew(RendererRD::Luminance(!can_use_storage));
tone_mapper = memnew(RendererRD::ToneMapper);
- vrs = memnew(RendererRD::VRS);
+ if (can_use_vrs) {
+ vrs = memnew(RendererRD::VRS);
+ }
if (can_use_storage) {
fsr = memnew(RendererRD::FSR);
}
@@ -1438,6 +1309,9 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
if (copy_effects) {
memdelete(copy_effects);
}
+ if (luminance) {
+ memdelete(luminance);
+ }
if (tone_mapper) {
memdelete(tone_mapper);
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 2312603829..7c43021eb0 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_scene_render_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_render_rd.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 RENDERER_SCENE_RENDER_RD_H
#define RENDERER_SCENE_RENDER_RD_H
@@ -38,6 +38,7 @@
#include "servers/rendering/renderer_rd/effects/bokeh_dof.h"
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
#include "servers/rendering/renderer_rd/effects/fsr.h"
+#include "servers/rendering/renderer_rd/effects/luminance.h"
#include "servers/rendering/renderer_rd/effects/tone_mapper.h"
#include "servers/rendering/renderer_rd/effects/vrs.h"
#include "servers/rendering/renderer_rd/environment/fog.h"
@@ -105,6 +106,7 @@ protected:
RendererRD::ForwardIDStorage *forward_id_storage = nullptr;
RendererRD::BokehDOF *bokeh_dof = nullptr;
RendererRD::CopyEffects *copy_effects = nullptr;
+ RendererRD::Luminance *luminance = nullptr;
RendererRD::ToneMapper *tone_mapper = nullptr;
RendererRD::FSR *fsr = nullptr;
RendererRD::VRS *vrs = nullptr;
@@ -114,7 +116,6 @@ protected:
/* ENVIRONMENT */
bool glow_bicubic_upscale = false;
- bool glow_high_quality = false;
bool use_physical_light_units = false;
@@ -181,9 +182,6 @@ private:
/* RENDER BUFFERS */
- // TODO move into effects/luminance.h/cpp
- void _allocate_luminance_textures(Ref<RenderSceneBuffersRD> rb);
-
/* GI */
bool screen_space_roughness_limiter = false;
float screen_space_roughness_limiter_amount = 0.25;
@@ -206,9 +204,9 @@ public:
/* LIGHTING */
- virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_extents){};
+ virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_size){};
virtual void setup_added_light(const RS::LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture){};
- virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_extents){};
+ virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_size){};
/* GI */
@@ -218,14 +216,6 @@ public:
RendererRD::SkyRD *get_sky() { return &sky; }
- /* SDFGI UPDATE */
-
- virtual void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override;
- virtual int sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const override;
- virtual AABB sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override;
- virtual uint32_t sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override;
- RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
-
/* SKY API */
virtual RID sky_allocate() override;
@@ -239,7 +229,6 @@ public:
/* ENVIRONMENT API */
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) override;
- virtual void environment_glow_set_use_high_quality(bool p_enable) override;
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override;
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) override;
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 5e9eadadd9..c85ece6366 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -1,38 +1,40 @@
-/*************************************************************************/
-/* shader_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_rd.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 "shader_rd.h"
#include "core/io/compression.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
+#include "core/object/worker_thread_pool.h"
+#include "core/version.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/rendering_device.h"
#include "thirdparty/misc/smolv.h"
@@ -116,6 +118,10 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
}
StringBuilder tohash;
+ tohash.append("[GodotVersionNumber]");
+ tohash.append(VERSION_NUMBER);
+ tohash.append("[GodotVersionHash]");
+ tohash.append(VERSION_HASH);
tohash.append("[SpirvCacheKey]");
tohash.append(RenderingDevice::get_singleton()->shader_get_spirv_cache_key());
tohash.append("[BinaryCacheKey]");
@@ -160,8 +166,7 @@ void ShaderRD::_clear_version(Version *p_version) {
}
void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template) {
- for (uint32_t i = 0; i < p_template.chunks.size(); i++) {
- const StageTemplate::Chunk &chunk = p_template.chunks[i];
+ for (const StageTemplate::Chunk &chunk : p_template.chunks) {
switch (chunk.type) {
case StageTemplate::Chunk::TYPE_VERSION_DEFINES: {
builder.append("\n"); //make sure defines begin at newline
diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h
index 40b10808c2..d0871ca16c 100644
--- a/servers/rendering/renderer_rd/shader_rd.h
+++ b/servers/rendering/renderer_rd/shader_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_rd.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 SHADER_RD_H
#define SHADER_RD_H
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index 4a18c7c052..1fb8b28b15 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -191,48 +191,6 @@ void main() {
uv += 1e-5;
}
-#ifdef USE_ATTRIBUTES
-#if 0
- if (bool(draw_data.flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone
- //skeleton transform
- ivec4 bone_indicesi = ivec4(bone_indices);
-
- uvec2 tex_ofs = bone_indicesi.x * 2;
-
- mat2x4 m;
- m = mat2x4(
- texelFetch(skeleton_buffer, tex_ofs + 0),
- texelFetch(skeleton_buffer, tex_ofs + 1)) *
- bone_weights.x;
-
- tex_ofs = bone_indicesi.y * 2;
-
- m += mat2x4(
- texelFetch(skeleton_buffer, tex_ofs + 0),
- texelFetch(skeleton_buffer, tex_ofs + 1)) *
- bone_weights.y;
-
- tex_ofs = bone_indicesi.z * 2;
-
- m += mat2x4(
- texelFetch(skeleton_buffer, tex_ofs + 0),
- texelFetch(skeleton_buffer, tex_ofs + 1)) *
- bone_weights.z;
-
- tex_ofs = bone_indicesi.w * 2;
-
- m += mat2x4(
- texelFetch(skeleton_buffer, tex_ofs + 0),
- texelFetch(skeleton_buffer, tex_ofs + 1)) *
- bone_weights.w;
-
- mat4 bone_matrix = skeleton_data.skeleton_transform * transpose(mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))) * skeleton_data.skeleton_transform_inverse;
-
- //outvec = bone_matrix * outvec;
- }
-#endif
-#endif
-
vertex = (canvas_data.canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
vertex_interp = vertex;
@@ -544,6 +502,12 @@ void main() {
if (normal_used || (using_light && bool(draw_data.flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) {
normal.xy = texture(sampler2D(normal_texture, texture_sampler), uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0);
+ if (bool(draw_data.flags & FLAGS_FLIP_H)) {
+ normal.x = -normal.x;
+ }
+ if (bool(draw_data.flags & FLAGS_FLIP_V)) {
+ normal.y = -normal.y;
+ }
normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
normal_used = true;
} else {
@@ -655,20 +619,7 @@ void main() {
if (i >= light_count) {
break;
}
- uint light_base;
- if (i < 8) {
- if (i < 4) {
- light_base = draw_data.lights[0];
- } else {
- light_base = draw_data.lights[1];
- }
- } else {
- if (i < 12) {
- light_base = draw_data.lights[2];
- } else {
- light_base = draw_data.lights[3];
- }
- }
+ uint light_base = draw_data.lights[i >> 2];
light_base >>= (i & 3) * 8;
light_base &= 0xFF;
diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
index 1b627a3e81..a904f4e0a6 100644
--- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
@@ -27,6 +27,9 @@
#define FLAGS_USE_MSDF (1 << 28)
#define FLAGS_USE_LCD (1 << 29)
+#define FLAGS_FLIP_H (1 << 30)
+#define FLAGS_FLIP_V (1 << 31)
+
#define SAMPLER_NEAREST_CLAMP 0
#define SAMPLER_LINEAR_CLAMP 1
#define SAMPLER_NEAREST_WITH_MIPMAPS_CLAMP 2
@@ -134,7 +137,7 @@ layout(set = 0, binding = 4) uniform texture2D shadow_atlas_texture;
layout(set = 0, binding = 5) uniform sampler shadow_sampler;
-layout(set = 0, binding = 6) uniform texture2D screen_texture;
+layout(set = 0, binding = 6) uniform texture2D color_buffer;
layout(set = 0, binding = 7) uniform texture2D sdf_texture;
layout(set = 0, binding = 8) uniform sampler material_samplers[12];
diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
index 2fe230f0bf..8c26a67926 100644
--- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl
+++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
@@ -64,7 +64,7 @@ void main() {
#version 450
#VERSION_DEFINES
-
+#ifndef MOLTENVK_USED // Metal will corrupt GPU state otherwise
#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) && defined(has_GL_KHR_shader_subgroup_vote)
#extension GL_KHR_shader_subgroup_ballot : enable
@@ -73,6 +73,7 @@ void main() {
#define USE_SUBGROUPS
#endif
+#endif
layout(location = 0) in float depth_interp;
layout(location = 1) in flat uint element_index;
@@ -141,7 +142,11 @@ void main() {
}
}
#else
- if (!gl_HelperInvocation) {
+// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs
+#ifndef MOLTENVK_USED
+ if (!gl_HelperInvocation)
+#endif
+ {
atomicOr(cluster_render.data[usage_write_offset], usage_write_bit);
}
#endif
@@ -161,7 +166,11 @@ void main() {
}
}
#else
- if (!gl_HelperInvocation) {
+// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs
+#ifndef MOLTENVK_USED
+ if (!gl_HelperInvocation)
+#endif
+ {
atomicOr(cluster_render.data[z_write_offset], z_write_bit);
}
#endif
diff --git a/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl
index cb06250cf2..31aabbe9d2 100644
--- a/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl
@@ -53,30 +53,31 @@ void main() {
#ifdef MODE_GAUSSIAN_BLUR
- // Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
-
- // note, for blur blur.luminance_multiplier is irrelavant, we would be multiplying and then dividing by this amount.
-
- if (bool(blur.flags & FLAG_HORIZONTAL)) {
- vec2 pix_size = blur.pixel_size;
- pix_size *= 0.5; //reading from larger buffer, so use more samples
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607;
- color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879;
- color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514;
- color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303;
- color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879;
- color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514;
- color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303;
- frag_color = color;
- } else {
- vec2 pix_size = blur.pixel_size;
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774;
- color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477;
- color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136;
- color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477;
- color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136;
- frag_color = color;
- }
+ // For Gaussian Blur we use 13 taps in a single pass instead of 12 taps over 2 passes.
+ // This minimizes the number of times we change framebuffers which is very important for mobile.
+ // Source: http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare
+ vec4 A = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, -1.0));
+ vec4 B = texture(source_color, uv_interp + blur.pixel_size * vec2(0.0, -1.0));
+ vec4 C = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, -1.0));
+ vec4 D = texture(source_color, uv_interp + blur.pixel_size * vec2(-0.5, -0.5));
+ vec4 E = texture(source_color, uv_interp + blur.pixel_size * vec2(0.5, -0.5));
+ vec4 F = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, 0.0));
+ vec4 G = texture(source_color, uv_interp);
+ vec4 H = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, 0.0));
+ vec4 I = texture(source_color, uv_interp + blur.pixel_size * vec2(-0.5, 0.5));
+ vec4 J = texture(source_color, uv_interp + blur.pixel_size * vec2(0.5, 0.5));
+ vec4 K = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, 1.0));
+ vec4 L = texture(source_color, uv_interp + blur.pixel_size * vec2(0.0, 1.0));
+ vec4 M = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, 1.0));
+
+ float base_weight = 0.5 / 4.0;
+ float lesser_weight = 0.125 / 4.0;
+
+ frag_color = (D + E + I + J) * base_weight;
+ frag_color += (A + B + G + F) * lesser_weight;
+ frag_color += (B + C + H + G) * lesser_weight;
+ frag_color += (F + G + L + K) * lesser_weight;
+ frag_color += (G + H + M + L) * lesser_weight;
#endif
#ifdef MODE_GAUSSIAN_GLOW
diff --git a/servers/rendering/renderer_rd/shaders/effects/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl
index bfe329b8ec..3a82861057 100644
--- a/servers/rendering/renderer_rd/shaders/effects/copy.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl
@@ -14,8 +14,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#define FLAG_FLIP_Y (1 << 5)
#define FLAG_FORCE_LUMINANCE (1 << 6)
#define FLAG_COPY_ALL_SOURCE (1 << 7)
-#define FLAG_HIGH_QUALITY_GLOW (1 << 8)
-#define FLAG_ALPHA_TO_ONE (1 << 9)
+#define FLAG_ALPHA_TO_ONE (1 << 8)
layout(push_constant, std430) uniform Params {
ivec4 section;
@@ -93,25 +92,14 @@ void main() {
#ifdef MODE_GAUSSIAN_BLUR
// First pass copy texture into 16x16 local memory for every 8x8 thread block
- vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
+ vec2 quad_center_uv = clamp(vec2(params.section.xy + gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16;
-#ifdef MODE_GLOW
- if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) {
- vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
-
- local_cache[dest_index] = (textureLod(source_color, quad_center_uv, 0) + textureLod(source_color, quad_offset_uv, 0)) * 0.5;
- local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5;
- local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5;
- local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5;
- } else
-#endif
- {
- local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0);
- local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0);
- local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0);
- local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0);
- }
+ local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0);
+ local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0);
+ local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0);
+ local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0);
+
#ifdef MODE_GLOW
if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
// Tonemap initial samples to reduce weight of fireflies: https://graphicrants.blogspot.com/2013/12/tone-mapping.html
@@ -194,10 +182,10 @@ void main() {
color = min(color * feedback, vec4(params.glow_luminance_cap));
}
-#endif
+#endif // MODE_GLOW
imageStore(dest_buffer, pos + params.target, color);
-#endif
+#endif // MODE_GAUSSIAN_BLUR
#ifdef MODE_SIMPLE_COPY
@@ -227,7 +215,7 @@ void main() {
imageStore(dest_buffer, pos + params.target, color);
-#endif
+#endif // MODE_SIMPLE_COPY
#ifdef MODE_SIMPLE_COPY_DEPTH
@@ -239,7 +227,7 @@ void main() {
imageStore(dest_buffer, pos + params.target, vec4(color.r));
-#endif
+#endif // MODE_SIMPLE_COPY_DEPTH
#ifdef MODE_LINEARIZE_DEPTH_COPY
@@ -253,7 +241,7 @@ void main() {
}
imageStore(dest_buffer, pos + params.target, color);
-#endif
+#endif // MODE_LINEARIZE_DEPTH_COPY
#if defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA)
@@ -276,7 +264,7 @@ void main() {
vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne
#endif
imageStore(dest_buffer, pos + params.target, color);
-#endif
+#endif // defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA)
#ifdef MODE_SET_COLOR
imageStore(dest_buffer, pos + params.target, params.set_color);
diff --git a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
index 1c17eabb56..6137224162 100644
--- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
@@ -13,6 +13,14 @@
#endif // has_VK_KHR_multiview
#endif //MULTIVIEW
+#define FLAG_FLIP_Y (1 << 0)
+#define FLAG_USE_SECTION (1 << 1)
+#define FLAG_FORCE_LUMINANCE (1 << 2)
+#define FLAG_ALPHA_TO_ZERO (1 << 3)
+#define FLAG_SRGB (1 << 4)
+#define FLAG_ALPHA_TO_ONE (1 << 5)
+#define FLAG_LINEAR (1 << 6)
+
#ifdef MULTIVIEW
layout(location = 0) out vec3 uv_interp;
#else
@@ -22,11 +30,10 @@ layout(location = 0) out vec2 uv_interp;
layout(push_constant, std430) uniform Params {
vec4 section;
vec2 pixel_size;
- bool flip_y;
- bool use_section;
+ float luminance_multiplier;
+ uint flags;
- bool force_luminance;
- uint pad[3];
+ vec4 color;
}
params;
@@ -37,13 +44,13 @@ void main() {
uv_interp.z = ViewIndex;
#endif
vec2 vpos = uv_interp.xy;
- if (params.use_section) {
+ if (bool(params.flags & FLAG_USE_SECTION)) {
vpos = params.section.xy + vpos * params.section.zw;
}
gl_Position = vec4(vpos * 2.0 - 1.0, 0.0, 1.0);
- if (params.flip_y) {
+ if (bool(params.flags & FLAG_FLIP_Y)) {
uv_interp.y = 1.0 - uv_interp.y;
}
}
@@ -63,19 +70,25 @@ void main() {
#endif // has_VK_KHR_multiview
#endif //MULTIVIEW
+#define FLAG_FLIP_Y (1 << 0)
+#define FLAG_USE_SECTION (1 << 1)
+#define FLAG_FORCE_LUMINANCE (1 << 2)
+#define FLAG_ALPHA_TO_ZERO (1 << 3)
+#define FLAG_SRGB (1 << 4)
+#define FLAG_ALPHA_TO_ONE (1 << 5)
+#define FLAG_LINEAR (1 << 6)
+
layout(push_constant, std430) uniform Params {
vec4 section;
vec2 pixel_size;
- bool flip_y;
- bool use_section;
+ float luminance_multiplier;
+ uint flags;
- bool force_luminance;
- bool alpha_to_zero;
- bool srgb;
- uint pad;
+ vec4 color;
}
params;
+#ifndef MODE_SET_COLOR
#ifdef MULTIVIEW
layout(location = 0) in vec3 uv_interp;
#else
@@ -94,6 +107,7 @@ layout(set = 0, binding = 0) uniform sampler2D source_color;
layout(set = 1, binding = 0) uniform sampler2D source_color2;
#endif /* MODE_TWO_SOURCES */
#endif /* MULTIVIEW */
+#endif /* !SET_COLOR */
layout(location = 0) out vec4 frag_color;
@@ -104,7 +118,15 @@ vec3 linear_to_srgb(vec3 color) {
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
}
+vec3 srgb_to_linear(vec3 color) {
+ return mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045)));
+}
+
void main() {
+#ifdef MODE_SET_COLOR
+ frag_color = params.color;
+#else
+
#ifdef MULTIVIEW
vec3 uv = uv_interp;
#else
@@ -155,15 +177,22 @@ void main() {
#endif /* MODE_TWO_SOURCES */
#endif /* MULTIVIEW */
- if (params.force_luminance) {
+ if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
color.rgb = vec3(max(max(color.r, color.g), color.b));
}
- if (params.alpha_to_zero) {
+ if (bool(params.flags & FLAG_ALPHA_TO_ZERO)) {
color.rgb *= color.a;
}
- if (params.srgb) {
+ if (bool(params.flags & FLAG_SRGB)) {
color.rgb = linear_to_srgb(color.rgb);
}
+ if (bool(params.flags & FLAG_ALPHA_TO_ONE)) {
+ color.a = 1.0;
+ }
+ if (bool(params.flags & FLAG_LINEAR)) {
+ color.rgb = srgb_to_linear(color.rgb);
+ }
- frag_color = color;
+ frag_color = color / params.luminance_multiplier;
+#endif // MODE_SET_COLOR
}
diff --git a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
index 1bee428a6f..c0597fe3f3 100644
--- a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
@@ -70,17 +70,6 @@ float DistributionGGX(float NdotH, float roughness4) {
return roughness4 / denom;
}
-// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float GGX(float NdotV, float a) {
- float k = a / 2.0;
- return NdotV / (NdotV * (1.0 - k) + k);
-}
-
-// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float G_Smith(float a, float nDotV, float nDotL) {
- return GGX(nDotL, a * a) * GGX(nDotV, a * a);
-}
-
float radicalInverse_VdC(uint bits) {
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
diff --git a/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl b/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl
index c8eb78a2f0..221e97bece 100644
--- a/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* fsr_upscale.glsl */
-/*************************************************************************/
-/* 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. */
-/*************************************************************************/
+/**************************************************************************/
+/* fsr_upscale.glsl */
+/**************************************************************************/
+/* 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. */
+/**************************************************************************/
#[compute]
diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce.glsl
index 0ee4cf6e31..0ee4cf6e31 100644
--- a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce.glsl
diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster.glsl
index 29ebd74a90..29ebd74a90 100644
--- a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster.glsl
diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster_inc.glsl
index b8860f6518..b8860f6518 100644
--- a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster_inc.glsl
diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
index 9d8294a7da..631d1968b0 100644
--- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
@@ -66,6 +66,19 @@ void main() {
vec4 normal_roughness = imageLoad(source_normal_roughness, ssC);
vec3 normal = normal_roughness.xyz * 2.0 - 1.0;
+ float roughness = normal_roughness.w;
+
+ // The roughness cutoff of 0.6 is chosen to match the roughness fadeout from GH-69828.
+ if (roughness > 0.6) {
+ // Do not compute SSR for rough materials to improve performance at the cost of
+ // subtle artifacting.
+#ifdef MODE_ROUGH
+ imageStore(blur_radius_image, ssC, vec4(0.0));
+#endif
+ imageStore(ssr_image, ssC, vec4(0.0));
+ return;
+ }
+
normal = normalize(normal);
normal.y = -normal.y; //because this code reads flipped
@@ -81,8 +94,6 @@ void main() {
imageStore(ssr_image, ssC, vec4(0.0));
return;
}
- //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
- //ray_dir = normalize(vec3(1.0, 1.0, -1.0));
////////////////
@@ -212,6 +223,9 @@ void main() {
float grad = (steps_taken + 1.0) / float(params.num_steps);
float initial_fade = params.curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), params.curve_fade_in);
float fade = pow(clamp(1.0 - grad, 0.0, 1.0), params.distance_fade) * initial_fade;
+ // This is an ad-hoc term to fade out the SSR as roughness increases. Values used
+ // are meant to match the visual appearance of a ReflectionProbe.
+ float roughness_fade = smoothstep(0.4, 0.7, 1.0 - normal_roughness.w);
final_pos = pos;
vec4 final_color;
@@ -220,7 +234,6 @@ void main() {
// if roughness is enabled, do screen space cone tracing
float blur_radius = 0.0;
- float roughness = normal_roughness.w;
if (roughness > 0.001) {
float cone_angle = min(roughness, 0.999) * M_PI * 0.5;
@@ -246,7 +259,7 @@ void main() {
#endif // MODE_ROUGH
- final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend);
+ final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend * roughness_fade);
// Schlick term.
float metallic = texelFetch(source_metallic, ssC << 1, 0).w;
diff --git a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
index 134aae5ce7..b1ff46dd3b 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
@@ -56,7 +56,7 @@ vec4 screen_space_to_view_space_depth(vec4 p_depth) {
float depth_linearize_mul = params.z_near;
float depth_linearize_add = params.z_far;
- // Optimised version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar"
+ // Optimized version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar"
// Set your depth_linearize_mul and depth_linearize_add to:
// depth_linearize_mul = ( cameraClipFar * cameraClipNear) / ( cameraClipFar - cameraClipNear );
diff --git a/servers/rendering/renderer_rd/shaders/effects/ssao.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl
index 2a87e273bc..ffaa6872c9 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ssao.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl
@@ -221,7 +221,7 @@ void SSAOTap(const int p_quality_level, inout float r_obscurance_sum, inout floa
// snap to pixel center (more correct obscurance math, avoids artifacts)
sample_offset = round(sample_offset);
- // calculate MIP based on the sample distance from the centre, similar to as described
+ // calculate MIP based on the sample distance from the center, similar to as described
// in http://graphics.cs.williams.edu/papers/SAOHPG12/.
float mip_level = (p_quality_level < SSAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (sample_pow_2_len + p_mip_offset);
@@ -259,7 +259,7 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o
// get this pixel's viewspace depth
pix_z = valuesUL.y;
- // get left right top bottom neighbouring pixels for edge detection (gets compiled out on quality_level == 0)
+ // get left right top bottom neighboring pixels for edge detection (gets compiled out on quality_level == 0)
pix_left_z = valuesUL.x;
pix_top_z = valuesUL.z;
pix_right_z = valuesBR.z;
@@ -304,7 +304,7 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o
float obscurance_sum = 0.0;
float weight_sum = 0.0;
- // edge mask for between this and left/right/top/bottom neighbour pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge)
+ // edge mask for between this and left/right/top/bottom neighbor pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge)
vec4 edgesLRTB = vec4(1.0, 1.0, 1.0, 1.0);
// Move center pixel slightly towards camera to avoid imprecision artifacts due to using of 16bit depth buffer; a lot smaller offsets needed when using 32bit floats
@@ -318,7 +318,7 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o
if (!p_adaptive_base && (p_quality_level >= SSAO_DETAIL_AO_ENABLE_AT_QUALITY_PRESET)) {
// disable in case of quality level 4 (reference)
if (p_quality_level != 4) {
- //approximate neighbouring pixels positions (actually just deltas or "positions - pix_center_pos" )
+ //approximate neighboring pixels positions (actually just deltas or "positions - pix_center_pos" )
vec3 normalized_viewspace_dir = vec3(pix_center_pos.xy / pix_center_pos.zz, 1.0);
vec3 pixel_left_delta = vec3(-pixel_size_at_center.x, 0.0, 0.0) + normalized_viewspace_dir * (pix_left_z - pix_center_pos.z);
vec3 pixel_right_delta = vec3(+pixel_size_at_center.x, 0.0, 0.0) + normalized_viewspace_dir * (pix_right_z - pix_center_pos.z);
diff --git a/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
index 04f98964e8..d234ab4417 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
@@ -80,7 +80,7 @@ void main() {
#ifdef PROCESS_MAPA
vec2 uv = (vec2(ssC) + 0.5f) * params.half_screen_pixel_size * 2.0;
- float centre = textureLod(source_importance, uv, 0.0).x;
+ float center = textureLod(source_importance, uv, 0.0).x;
vec2 half_pixel = params.half_screen_pixel_size;
@@ -98,7 +98,7 @@ void main() {
#ifdef PROCESS_MAPB
vec2 uv = (vec2(ssC) + 0.5f) * params.half_screen_pixel_size * 2.0;
- float centre = textureLod(source_importance, uv, 0.0).x;
+ float center = textureLod(source_importance, uv, 0.0).x;
vec2 half_pixel = params.half_screen_pixel_size;
diff --git a/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
index f6a9a92fac..45cc62d361 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
@@ -60,8 +60,8 @@ void main() {
int mx = int(pix_pos.x % 2);
int my = int(pix_pos.y % 2);
int index_center = mx + my * 2; // center index
- int index_horizontal = (1 - mx) + my * 2; // neighbouring, horizontal
- int index_vertical = mx + (1 - my) * 2; // neighbouring, vertical
+ int index_horizontal = (1 - mx) + my * 2; // neighboring, horizontal
+ int index_vertical = mx + (1 - my) * 2; // neighboring, vertical
int index_diagonal = (1 - mx) + (1 - my) * 2; // diagonal
vec2 center_val = texelFetch(source_texture, ivec3(pix_pos / uvec2(params.size_modifier), index_center), 0).xy;
diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl
index 513791dfbf..de7b97953f 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ssil.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl
@@ -234,7 +234,7 @@ void SSILTap(const int p_quality_level, inout vec3 r_color_sum, inout float r_ob
// snap to pixel center (more correct obscurance math, avoids artifacts)
sample_offset = round(sample_offset);
- // calculate MIP based on the sample distance from the centre, similar to as described
+ // calculate MIP based on the sample distance from the center, similar to as described
// in http://graphics.cs.williams.edu/papers/SAOHPG12/.
float mip_level = (p_quality_level < SSIL_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (sample_pow_2_len + p_mip_offset);
@@ -272,7 +272,7 @@ void generate_SSIL(out vec3 r_color, out vec4 r_edges, out float r_obscurance, o
// get this pixel's viewspace depth
pix_z = valuesUL.y;
- // get left right top bottom neighbouring pixels for edge detection (gets compiled out on quality_level == 0)
+ // get left right top bottom neighboring pixels for edge detection (gets compiled out on quality_level == 0)
pix_left_z = valuesUL.x;
pix_top_z = valuesUL.z;
pix_right_z = valuesBR.z;
@@ -318,7 +318,7 @@ void generate_SSIL(out vec3 r_color, out vec4 r_edges, out float r_obscurance, o
float obscurance_sum = 0.0;
float weight_sum = 0.0;
- // edge mask for between this and left/right/top/bottom neighbour pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge)
+ // edge mask for between this and left/right/top/bottom neighbor pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge)
vec4 edgesLRTB = vec4(1.0, 1.0, 1.0, 1.0);
// Move center pixel slightly towards camera to avoid imprecision artifacts due to using of 16bit depth buffer; a lot smaller offsets needed when using 32bit floats
diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
index 47c56571f6..f48e6c4341 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
@@ -124,14 +124,14 @@ void main() {
vec2 uv = (vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size;
- vec4 centre = textureLod(source_ssil, uv, 0.0);
+ vec4 center = textureLod(source_ssil, uv, 0.0);
vec4 value = textureLod(source_ssil, vec2(uv + vec2(-half_pixel.x * 3, -half_pixel.y)), 0.0) * 0.2;
value += textureLod(source_ssil, vec2(uv + vec2(+half_pixel.x, -half_pixel.y * 3)), 0.0) * 0.2;
value += textureLod(source_ssil, vec2(uv + vec2(-half_pixel.x, +half_pixel.y * 3)), 0.0) * 0.2;
value += textureLod(source_ssil, vec2(uv + vec2(+half_pixel.x * 3, +half_pixel.y)), 0.0) * 0.2;
- vec4 sampled = value + centre * 0.2;
+ vec4 sampled = value + center * 0.2;
#else
#ifdef MODE_SMART
diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
index 6b6b02739d..193e3458ab 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
@@ -82,7 +82,7 @@ void main() {
#ifdef PROCESS_MAPA
vec2 uv = (vec2(ssC) + 0.5) * params.half_screen_pixel_size * 2.0;
- float centre = textureLod(source_importance, uv, 0.0).x;
+ float center = textureLod(source_importance, uv, 0.0).x;
vec2 half_pixel = params.half_screen_pixel_size;
@@ -100,7 +100,7 @@ void main() {
#ifdef PROCESS_MAPB
vec2 uv = (vec2(ssC) + 0.5f) * params.half_screen_pixel_size * 2.0;
- float centre = textureLod(source_importance, uv, 0.0).x;
+ float center = textureLod(source_importance, uv, 0.0).x;
vec2 half_pixel = params.half_screen_pixel_size;
diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
index 9e86ac0cf0..ed85b8ee4c 100644
--- a/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
@@ -62,8 +62,8 @@ void main() {
int mx = int(pix_pos.x % 2);
int my = int(pix_pos.y % 2);
int index_center = mx + my * 2; // center index
- int index_horizontal = (1 - mx) + my * 2; // neighbouring, horizontal
- int index_vertical = mx + (1 - my) * 2; // neighbouring, vertical
+ int index_horizontal = (1 - mx) + my * 2; // neighboring, horizontal
+ int index_vertical = mx + (1 - my) * 2; // neighboring, vertical
int index_diagonal = (1 - mx) + (1 - my) * 2; // diagonal
vec4 color = texelFetch(source_texture, ivec3(pix_pos / uvec2(params.size_modifier), index_center), 0);
diff --git a/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl
index b0a0839836..02566d8e35 100644
--- a/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl
@@ -32,7 +32,9 @@
// Based on Spartan Engine's TAA implementation (without TAA upscale).
// <https://github.com/PanosK92/SpartanEngine/blob/a8338d0609b85dc32f3732a5c27fb4463816a3b9/Data/shaders/temporal_antialiasing.hlsl>
+#ifndef MOLTENVK_USED
#define USE_SUBGROUPS
+#endif // MOLTENVK_USED
#define GROUP_SIZE 8
#define FLT_MIN 0.00000001
diff --git a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl
index 5ef83c0b44..b450bb9fe9 100644
--- a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl
@@ -63,10 +63,18 @@ void main() {
#ifdef MULTIVIEW
vec4 color = textureLod(source_color, uv, 0.0);
+ frag_color = uint(color.r * 255.0);
#else /* MULTIVIEW */
vec4 color = textureLod(source_color, uv, 0.0);
-#endif /* MULTIVIEW */
- // See if we can change the sampler to one that returns int...
- frag_color = uint(color.r * 256.0);
+ // for user supplied VRS map we do a color mapping
+ color.r *= 3.0;
+ frag_color = int(color.r) << 2;
+
+ color.g *= 3.0;
+ frag_color += int(color.g);
+
+ // note 1x4, 4x1, 1x8, 8x1, 2x8 and 8x2 are not supported
+ // 4x8, 8x4 and 8x8 are only available on some GPUs
+#endif /* MULTIVIEW */
}
diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
index ab927df678..459c4dcb1d 100644
--- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
@@ -108,7 +108,9 @@ layout(set = 0, binding = 18, std140) uniform SceneData {
}
scene_data;
+#ifdef USE_VRS
layout(r8ui, set = 0, binding = 19) uniform restrict readonly uimage2D vrs_buffer;
+#endif
layout(push_constant, std430) uniform Params {
uint max_voxel_gi_instances;
@@ -661,6 +663,7 @@ void main() {
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
uint vrs_x, vrs_y;
+#ifdef USE_VRS
if (sc_use_vrs) {
ivec2 vrs_pos;
@@ -684,6 +687,7 @@ void main() {
return;
}
}
+#endif
if (sc_half_res) {
pos <<= 1;
@@ -708,6 +712,7 @@ void main() {
imageStore(ambient_buffer, pos, ambient_light);
imageStore(reflection_buffer, pos, reflection_light);
+#ifdef USE_VRS
if (sc_use_vrs) {
if (vrs_x > 1) {
imageStore(ambient_buffer, pos + ivec2(1, 0), ambient_light);
@@ -766,4 +771,5 @@ void main() {
imageStore(reflection_buffer, pos + ivec2(3, 3), reflection_light);
}
}
+#endif
}
diff --git a/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
index 9f7449b8aa..06709f65d3 100644
--- a/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
@@ -24,7 +24,7 @@ struct ProcessVoxel {
uint albedo; // rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors.
uint light; // rgbe8985 encoded total saved light, extra 2 bits for neighbors.
uint light_aniso; // 55555 light anisotropy, extra 2 bits for neighbors.
- //total neighbours: 26
+ //total neighbors: 26
};
#ifdef MODE_PROCESS_STATIC
@@ -443,10 +443,10 @@ void main() {
imageStore(dst_aniso1, positioni, vec4(aniso1, 0.0, 0.0));
imageStore(dst_light, positioni, uvec4(light_total_rgbe));
- //also fill neighbours, so light interpolation during the indirect pass works
+ //also fill neighbors, so light interpolation during the indirect pass works
- //recover the neighbour list from the leftover bits
- uint neighbours = (voxel_albedo >> 21) | ((voxel_position >> 21) << 11) | ((process_voxels.data[voxel_index].light >> 30) << 22) | ((process_voxels.data[voxel_index].light_aniso >> 30) << 24);
+ //recover the neighbor list from the leftover bits
+ uint neighbors = (voxel_albedo >> 21) | ((voxel_position >> 21) << 11) | ((process_voxels.data[voxel_index].light >> 30) << 22) | ((process_voxels.data[voxel_index].light_aniso >> 30) << 24);
const uint max_neighbours = 26;
const ivec3 neighbour_positions[max_neighbours] = ivec3[](
@@ -478,7 +478,7 @@ void main() {
ivec3(1, 1, 1));
for (uint i = 0; i < max_neighbours; i++) {
- if (bool(neighbours & (1 << i))) {
+ if (bool(neighbors & (1 << i))) {
ivec3 neighbour_pos = positioni + neighbour_positions[i];
imageStore(dst_light, neighbour_pos, uvec4(light_total_rgbe));
imageStore(dst_aniso0, neighbour_pos, aniso0);
diff --git a/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
index bce98f4054..dd35ae3b73 100644
--- a/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
@@ -102,10 +102,10 @@ dispatch_data;
struct ProcessVoxel {
uint position; // xyz 7 bit packed, extra 11 bits for neighbors.
- uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbours
- uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours
- uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours
- //total neighbours: 26
+ uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors
+ uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbors
+ uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbors
+ //total neighbors: 26
};
layout(set = 0, binding = 11, std430) restrict buffer writeonly ProcessVoxels {
@@ -135,10 +135,10 @@ dispatch_data;
struct ProcessVoxel {
uint position; // xyz 7 bit packed, extra 11 bits for neighbors.
- uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbours
- uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours
- uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours
- //total neighbours: 26
+ uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors
+ uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbors
+ uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbors
+ //total neighbors: 26
};
layout(set = 0, binding = 6, std430) restrict buffer readonly ProcessVoxels {
@@ -1016,14 +1016,14 @@ void main() {
store_positions[index].albedo = rgb >> 1; //store as it comes (555) to avoid precision loss (and move away the alpha bit)
store_positions[index].albedo |= (facing & 0x3F) << 15; // store facing in bits 15-21
- store_positions[index].albedo |= neighbour_bits << 21; //store lower 11 bits of neighbours with remaining albedo
- store_positions[index].position |= (neighbour_bits >> 11) << 21; //store 11 bits more of neighbours with position
+ store_positions[index].albedo |= neighbour_bits << 21; //store lower 11 bits of neighbors with remaining albedo
+ store_positions[index].position |= (neighbour_bits >> 11) << 21; //store 11 bits more of neighbors with position
store_positions[index].light = imageLoad(src_light, pos).r;
store_positions[index].light_aniso = imageLoad(src_light_aniso, pos).r;
- //add neighbours
- store_positions[index].light |= (neighbour_bits >> 22) << 30; //store 2 bits more of neighbours with light
- store_positions[index].light_aniso |= (neighbour_bits >> 24) << 30; //store 2 bits more of neighbours with aniso
+ //add neighbors
+ store_positions[index].light |= (neighbour_bits >> 22) << 30; //store 2 bits more of neighbors with light
+ store_positions[index].light_aniso |= (neighbour_bits >> 24) << 30; //store 2 bits more of neighbors with aniso
}
groupMemoryBarrier();
diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl
index d523461600..bf974a3fd5 100644
--- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl
@@ -14,7 +14,7 @@ layout(location = 0) out vec2 uv_interp;
layout(push_constant, std430) uniform Params {
mat3 orientation;
- vec4 projections[MAX_VIEWS];
+ vec4 projection; // only applicable if not multiview
vec3 position;
float time;
vec3 pad;
@@ -54,7 +54,7 @@ layout(location = 0) in vec2 uv_interp;
layout(push_constant, std430) uniform Params {
mat3 orientation;
- vec4 projections[MAX_VIEWS];
+ vec4 projection; // only applicable if not multiview
vec3 position;
float time;
vec3 pad;
@@ -82,7 +82,10 @@ layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUnifor
}
global_shader_uniforms;
-layout(set = 0, binding = 2, std140) uniform SceneData {
+layout(set = 0, binding = 2, std140) uniform SkySceneData {
+ mat4 view_inv_projections[2];
+ vec4 view_eye_offsets[2];
+
bool volumetric_fog_enabled; // 4 - 4
float volumetric_fog_inv_length; // 4 - 8
float volumetric_fog_detail_spread; // 4 - 12
@@ -101,7 +104,7 @@ layout(set = 0, binding = 2, std140) uniform SceneData {
uint pad1; // 4 - 60
uint pad2; // 4 - 64
}
-scene_data;
+sky_scene_data;
struct DirectionalLightData {
vec4 direction_energy;
@@ -124,6 +127,9 @@ layout(set = 2, binding = 0) uniform textureCube radiance;
#ifdef USE_CUBEMAP_PASS
layout(set = 2, binding = 1) uniform textureCube half_res;
layout(set = 2, binding = 2) uniform textureCube quarter_res;
+#elif defined(USE_MULTIVIEW)
+layout(set = 2, binding = 1) uniform texture2DArray half_res;
+layout(set = 2, binding = 2) uniform texture2DArray quarter_res;
#else
layout(set = 2, binding = 1) uniform texture2D half_res;
layout(set = 2, binding = 2) uniform texture2D quarter_res;
@@ -169,15 +175,15 @@ vec4 volumetric_fog_process(vec2 screen_uv) {
}
vec4 fog_process(vec3 view, vec3 sky_color) {
- vec3 fog_color = mix(scene_data.fog_light_color, sky_color, scene_data.fog_aerial_perspective);
+ vec3 fog_color = mix(sky_scene_data.fog_light_color, sky_color, sky_scene_data.fog_aerial_perspective);
- if (scene_data.fog_sun_scatter > 0.001) {
+ if (sky_scene_data.fog_sun_scatter > 0.001) {
vec4 sun_scatter = vec4(0.0);
float sun_total = 0.0;
- for (uint i = 0; i < scene_data.directional_light_count; i++) {
+ for (uint i = 0; i < sky_scene_data.directional_light_count; i++) {
vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w;
float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0);
- fog_color += light_color * light_amount * scene_data.fog_sun_scatter;
+ fog_color += light_color * light_amount * sky_scene_data.fog_sun_scatter;
}
}
@@ -186,9 +192,17 @@ vec4 fog_process(vec3 view, vec3 sky_color) {
void main() {
vec3 cube_normal;
+#ifdef USE_MULTIVIEW
+ // In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject.
+ vec4 unproject = vec4(uv_interp.x, -uv_interp.y, 1.0, 1.0);
+ vec4 unprojected = sky_scene_data.view_inv_projections[ViewIndex] * unproject;
+ cube_normal = unprojected.xyz / unprojected.w;
+ cube_normal += sky_scene_data.view_eye_offsets[ViewIndex].xyz;
+#else
cube_normal.z = -1.0;
- cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projections[ViewIndex].x)) / params.projections[ViewIndex].y;
- cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projections[ViewIndex].z)) / params.projections[ViewIndex].w;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projection.x)) / params.projection.y;
+ cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projection.z)) / params.projection.w;
+#endif
cube_normal = mat3(params.orientation) * cube_normal;
cube_normal = normalize(cube_normal);
@@ -209,20 +223,33 @@ void main() {
vec4 custom_fog = vec4(0.0);
#ifdef USE_CUBEMAP_PASS
+
#ifdef USES_HALF_RES_COLOR
half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier;
#endif
#ifdef USES_QUARTER_RES_COLOR
quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier;
#endif
+
#else
+
#ifdef USES_HALF_RES_COLOR
+#ifdef USE_MULTIVIEW
+ half_res_color = textureLod(sampler2DArray(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier;
+#else
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier;
-#endif
+#endif // USE_MULTIVIEW
+#endif // USES_HALF_RES_COLOR
+
#ifdef USES_QUARTER_RES_COLOR
+#ifdef USE_MULTIVIEW
+ quarter_res_color = textureLod(sampler2DArray(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier;
+#else
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier;
-#endif
-#endif
+#endif // USE_MULTIVIEW
+#endif // USES_QUARTER_RES_COLOR
+
+#endif //USE_CUBEMAP_PASS
{
@@ -236,14 +263,14 @@ void main() {
#if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
- if (scene_data.fog_enabled) {
+ if (sky_scene_data.fog_enabled) {
vec4 fog = fog_process(cube_normal, frag_color.rgb);
- frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.fog_sky_affect);
+ frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.fog_sky_affect);
}
- if (scene_data.volumetric_fog_enabled) {
+ if (sky_scene_data.volumetric_fog_enabled) {
vec4 fog = volumetric_fog_process(uv);
- frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.volumetric_fog_sky_affect);
+ frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.volumetric_fog_sky_affect);
}
if (custom_fog.a > 0.0) {
diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl
index 4658afd02d..8e4f5762fd 100644
--- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl
@@ -37,7 +37,7 @@ layout(push_constant, std430) uniform Params {
vec3 position;
float pad;
- vec3 extents;
+ vec3 size;
float pad2;
ivec3 corner;
@@ -184,36 +184,37 @@ void main() {
vec4 local_pos = params.transform * world;
local_pos.xyz /= local_pos.w;
+ vec3 half_size = params.size / 2.0;
float sdf = -1.0;
if (params.shape == 0) {
// Ellipsoid
// https://www.shadertoy.com/view/tdS3DG
- float k0 = length(local_pos.xyz / params.extents);
- float k1 = length(local_pos.xyz / (params.extents * params.extents));
+ float k0 = length(local_pos.xyz / half_size);
+ float k1 = length(local_pos.xyz / (half_size * half_size));
sdf = k0 * (k0 - 1.0) / k1;
} else if (params.shape == 1) {
// Cone
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
- // Compute the cone angle automatically to fit within the volume's extents.
- float inv_height = 1.0 / max(0.001, params.extents.y);
- float radius = 1.0 / max(0.001, (min(params.extents.x, params.extents.z) * 0.5));
+ // Compute the cone angle automatically to fit within the volume's size.
+ float inv_height = 1.0 / max(0.001, half_size.y);
+ float radius = 1.0 / max(0.001, (min(half_size.x, half_size.z) * 0.5));
float hypotenuse = sqrt(radius * radius + inv_height * inv_height);
float rsin = radius / hypotenuse;
float rcos = inv_height / hypotenuse;
vec2 c = vec2(rsin, rcos);
float q = length(local_pos.xz);
- sdf = max(dot(c, vec2(q, local_pos.y - params.extents.y)), -params.extents.y - local_pos.y);
+ sdf = max(dot(c, vec2(q, local_pos.y - half_size.y)), -half_size.y - local_pos.y);
} else if (params.shape == 2) {
// Cylinder
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
- vec2 d = abs(vec2(length(local_pos.xz), local_pos.y)) - vec2(min(params.extents.x, params.extents.z), params.extents.y);
+ vec2 d = abs(vec2(length(local_pos.xz), local_pos.y)) - vec2(min(half_size.x, half_size.z), half_size.y);
sdf = min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
} else if (params.shape == 3) {
// Box
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
- vec3 q = abs(local_pos.xyz) - params.extents;
+ vec3 q = abs(local_pos.xyz) - half_size;
sdf = length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
}
@@ -222,7 +223,7 @@ void main() {
#ifndef SDF_USED
cull_mask = 1.0 - smoothstep(-0.1, 0.0, sdf);
#endif
- uvw = clamp((local_pos.xyz + params.extents) / (2.0 * params.extents), 0.0, 1.0);
+ uvw = clamp((local_pos.xyz + half_size) / params.size, 0.0, 1.0);
}
if (cull_mask > 0.0) {
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
index 1a8a1f3aa3..c8ad1f0312 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
@@ -62,7 +62,7 @@ vec3 oct_to_vec3(vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
float t = max(-v.z, 0.0);
v.xy += t * -sign(v.xy);
- return v;
+ return normalize(v);
}
/* Varyings */
@@ -97,9 +97,7 @@ layout(location = 8) out vec4 prev_screen_position;
#ifdef MATERIAL_UNIFORMS_USED
layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
-
#MATERIAL_UNIFORMS
-
} material;
#endif
@@ -120,9 +118,15 @@ layout(location = 10) out flat uint instance_index_interp;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif // has_VK_KHR_multiview
+vec3 multiview_uv(vec2 uv) {
+ return vec3(uv, ViewIndex);
+}
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
+vec2 multiview_uv(vec2 uv) {
+ return uv;
+}
#endif //USE_MULTIVIEW
invariant gl_Position;
@@ -311,9 +315,11 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
#ifdef USE_MULTIVIEW
mat4 projection_matrix = scene_data.projection_matrix_view[ViewIndex];
mat4 inv_projection_matrix = scene_data.inv_projection_matrix_view[ViewIndex];
+ vec3 eye_offset = scene_data.eye_offset[ViewIndex].xyz;
#else
mat4 projection_matrix = scene_data.projection_matrix;
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
+ vec3 eye_offset = vec3(0.0, 0.0, 0.0);
#endif //USE_MULTIVIEW
//using world coordinates
@@ -546,9 +552,15 @@ layout(location = 10) in flat uint instance_index_interp;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif // has_VK_KHR_multiview
+vec3 multiview_uv(vec2 uv) {
+ return vec3(uv, ViewIndex);
+}
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
+vec2 multiview_uv(vec2 uv) {
+ return uv;
+}
#endif //USE_MULTIVIEW
//defines to keep compatibility with vertex
@@ -691,7 +703,7 @@ vec4 fog_process(vec3 vertex) {
void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) {
uint item_min_max = cluster_buffer.data[p_offset];
- item_min = item_min_max & 0xFFFF;
+ item_min = item_min_max & 0xFFFFu;
item_max = item_min_max >> 16;
item_from = item_min >> 5;
@@ -712,8 +724,10 @@ void fragment_shader(in SceneData scene_data) {
//lay out everything, whatever is unused is optimized away anyway
vec3 vertex = vertex_interp;
#ifdef USE_MULTIVIEW
- vec3 view = -normalize(vertex_interp - scene_data.eye_offset[ViewIndex].xyz);
+ vec3 eye_offset = scene_data.eye_offset[ViewIndex].xyz;
+ vec3 view = -normalize(vertex_interp - eye_offset);
#else
+ vec3 eye_offset = vec3(0.0, 0.0, 0.0);
vec3 view = -normalize(vertex_interp);
#endif
vec3 albedo = vec3(1.0);
@@ -828,7 +842,8 @@ void fragment_shader(in SceneData scene_data) {
// alpha hash can be used in unison with alpha antialiasing
#ifdef ALPHA_HASH_USED
- if (alpha < compute_alpha_hash_threshold(vertex, alpha_hash_scale)) {
+ vec3 object_pos = (inverse(read_model_matrix) * inv_view_matrix * vec4(vertex, 1.0)).xyz;
+ if (alpha < compute_alpha_hash_threshold(object_pos, alpha_hash_scale)) {
discard;
}
#endif // ALPHA_HASH_USED
@@ -958,9 +973,9 @@ void fragment_shader(in SceneData scene_data) {
while (merged_mask != 0) {
uint bit = findMSB(merged_mask);
- merged_mask &= ~(1 << bit);
+ merged_mask &= ~(1u << bit);
#ifdef USE_SUBGROUPS
- if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ if (((1u << bit) & mask) == 0) { //do not process if not originally here
continue;
}
#endif
@@ -1085,12 +1100,13 @@ void fragment_shader(in SceneData scene_data) {
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
- blend = modf(roughness * MAX_ROUGHNESS_LOD, lod);
+
+ blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod);
specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb;
specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend);
#else
- specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;
+ specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
specular_light *= scene_data.IBL_exposure_normalization;
@@ -1138,7 +1154,7 @@ void fragment_shader(in SceneData scene_data) {
ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness);
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
- float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD;
+ float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
@@ -1293,24 +1309,26 @@ void fragment_shader(in SceneData scene_data) {
}
if (sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances
-
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
- vec3 ref_vec = normalize(reflect(-view, normal));
- ref_vec = mix(ref_vec, normal, roughness * roughness);
+ // Make vertex orientation the world one, but still align to camera.
+ vec3 cam_pos = mat3(scene_data.inv_view_matrix) * vertex;
+ vec3 cam_normal = mat3(scene_data.inv_view_matrix) * normal;
+ vec3 ref_vec = mat3(scene_data.inv_view_matrix) * normalize(reflect(-view, normal));
+
//find arbitrary tangent and bitangent, then build a matrix
- vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
- vec3 tangent = normalize(cross(v0, normal));
- vec3 bitangent = normalize(cross(tangent, normal));
- mat3 normal_mat = mat3(tangent, bitangent, normal);
+ vec3 v0 = abs(cam_normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+ vec3 tangent = normalize(cross(v0, cam_normal));
+ vec3 bitangent = normalize(cross(tangent, cam_normal));
+ mat3 normal_mat = mat3(tangent, bitangent, cam_normal);
vec4 amb_accum = vec4(0.0);
vec4 spec_accum = vec4(0.0);
- voxel_gi_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
+ voxel_gi_compute(index1, cam_pos, cam_normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
uint index2 = instances.data[instance_index].gi_offset >> 16;
if (index2 != 0xFFFF) {
- voxel_gi_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
+ voxel_gi_compute(index2, cam_pos, cam_normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
}
if (amb_accum.a > 0.0) {
@@ -1339,8 +1357,8 @@ void fragment_shader(in SceneData scene_data) {
#endif // USE_MULTIVIEW
for (int i = 0; i < 4; i++) {
- const vec2 neighbours[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1));
- vec2 neighbour_coord = base_coord + neighbours[i] * scene_data.screen_pixel_size;
+ const vec2 neighbors[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1));
+ vec2 neighbour_coord = base_coord + neighbors[i] * scene_data.screen_pixel_size;
#ifdef USE_MULTIVIEW
float neighbour_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(neighbour_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0);
#else // USE_MULTIVIEW
@@ -1372,7 +1390,11 @@ void fragment_shader(in SceneData scene_data) {
#endif // !USE_LIGHTMAP
if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) {
+#ifdef USE_MULTIVIEW
+ float ssao = texture(sampler2DArray(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(screen_uv, ViewIndex)).r;
+#else
float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
+#endif
ao = min(ao, ssao);
ao_light_affect = mix(ao_light_affect, max(ao_light_affect, implementation_data.ssao_light_affect), implementation_data.ssao_ao_affect);
}
@@ -1419,9 +1441,9 @@ void fragment_shader(in SceneData scene_data) {
while (merged_mask != 0) {
uint bit = findMSB(merged_mask);
- merged_mask &= ~(1 << bit);
+ merged_mask &= ~(1u << bit);
#ifdef USE_SUBGROUPS
- if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ if (((1u << bit) & mask) == 0) { //do not process if not originally here
continue;
}
#endif
@@ -1447,18 +1469,28 @@ void fragment_shader(in SceneData scene_data) {
}
//finalize ambient light here
- ambient_light *= albedo.rgb;
- ambient_light *= ao;
+ {
+#if defined(AMBIENT_LIGHT_DISABLED)
+ ambient_light = vec3(0.0, 0.0, 0.0);
+#else
+ ambient_light *= albedo.rgb;
+ ambient_light *= ao;
+
+ if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) {
+#ifdef USE_MULTIVIEW
+ vec4 ssil = textureLod(sampler2DArray(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(screen_uv, ViewIndex), 0.0);
+#else
+ vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0);
+#endif // USE_MULTIVIEW
+ ambient_light *= 1.0 - ssil.a;
+ ambient_light += ssil.rgb * albedo.rgb;
+ }
+#endif // AMBIENT_LIGHT_DISABLED
+ }
// convert ao to direct light ao
ao = mix(1.0, ao, ao_light_affect);
- if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) {
- vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0);
- ambient_light *= 1.0 - ssil.a;
- ambient_light += ssil.rgb * albedo.rgb;
- }
-
//this saves some VGPRs
vec3 f0 = F0(metallic, specular, albedo);
@@ -1479,7 +1511,7 @@ void fragment_shader(in SceneData scene_data) {
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0);
+ specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0);
#endif
}
@@ -1775,12 +1807,12 @@ void fragment_shader(in SceneData scene_data) {
float shadow = 1.0;
#ifndef SHADOWS_DISABLED
if (i < 4) {
- shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0;
+ shadow = float(shadow0 >> (i * 8u) & 0xFFu) / 255.0;
} else {
- shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
+ shadow = float(shadow1 >> ((i - 4u) * 8u) & 0xFFu) / 255.0;
}
- shadow = shadow * directional_lights.data[i].shadow_opacity + 1.0 - directional_lights.data[i].shadow_opacity;
+ shadow = mix(1.0, shadow, directional_lights.data[i].shadow_opacity);
#endif
blur_shadow(shadow);
@@ -1839,9 +1871,9 @@ void fragment_shader(in SceneData scene_data) {
while (merged_mask != 0) {
uint bit = findMSB(merged_mask);
- merged_mask &= ~(1 << bit);
+ merged_mask &= ~(1u << bit);
#ifdef USE_SUBGROUPS
- if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ if (((1u << bit) & mask) == 0) { //do not process if not originally here
continue;
}
#endif
@@ -1910,9 +1942,9 @@ void fragment_shader(in SceneData scene_data) {
while (merged_mask != 0) {
uint bit = findMSB(merged_mask);
- merged_mask &= ~(1 << bit);
+ merged_mask &= ~(1u << bit);
#ifdef USE_SUBGROUPS
- if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ if (((1u << bit) & mask) == 0) { //do not process if not originally here
continue;
}
#endif
@@ -2064,8 +2096,8 @@ void fragment_shader(in SceneData scene_data) {
float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
- //store as 8985 to have 2 extra neighbour bits
- uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
+ //store as 8985 to have 2 extra neighbor bits
+ uint light_rgbe = ((uint(sRed) & 0x1FFu) >> 1) | ((uint(sGreen) & 0x1FFu) << 8) | (((uint(sBlue) & 0x1FFu) >> 1) << 17) | ((uint(exps) & 0x1Fu) << 25);
imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
@@ -2099,8 +2131,8 @@ void fragment_shader(in SceneData scene_data) {
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
uint index2 = instances.data[instance_index].gi_offset >> 16;
- voxel_gi_buffer.x = index1 & 0xFF;
- voxel_gi_buffer.y = index2 & 0xFF;
+ voxel_gi_buffer.x = index1 & 0xFFu;
+ voxel_gi_buffer.y = index2 & 0xFFu;
} else {
voxel_gi_buffer.x = 0xFF;
voxel_gi_buffer.y = 0xFF;
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl
index 0d36b98645..043bba1e4e 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl
@@ -4,14 +4,15 @@
#define MAX_VOXEL_GI_INSTANCES 8
#define MAX_VIEWS 2
+#ifndef MOLTENVK_USED
#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic)
#extension GL_KHR_shader_subgroup_ballot : enable
#extension GL_KHR_shader_subgroup_arithmetic : enable
#define USE_SUBGROUPS
-
#endif
+#endif // MOLTENVK_USED
#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
#extension GL_EXT_multiview : enable
@@ -267,21 +268,26 @@ layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid;
#define color_buffer shadow_atlas
#define normal_roughness_buffer shadow_atlas
+#define multiviewSampler sampler2D
#else
-layout(set = 1, binding = 10) uniform texture2D depth_buffer;
-layout(set = 1, binding = 11) uniform texture2D color_buffer;
-
#ifdef USE_MULTIVIEW
+layout(set = 1, binding = 10) uniform texture2DArray depth_buffer;
+layout(set = 1, binding = 11) uniform texture2DArray color_buffer;
layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer;
+layout(set = 1, binding = 13) uniform texture2DArray ao_buffer;
layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer;
layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer;
+#define multiviewSampler sampler2DArray
#else // USE_MULTIVIEW
+layout(set = 1, binding = 10) uniform texture2D depth_buffer;
+layout(set = 1, binding = 11) uniform texture2D color_buffer;
layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer;
+layout(set = 1, binding = 13) uniform texture2D ao_buffer;
layout(set = 1, binding = 14) uniform texture2D ambient_buffer;
layout(set = 1, binding = 15) uniform texture2D reflection_buffer;
+#define multiviewSampler sampler2D
#endif
-layout(set = 1, binding = 13) uniform texture2D ao_buffer;
layout(set = 1, binding = 16) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 17) uniform texture3D sdfgi_occlusion_cascades;
@@ -307,7 +313,11 @@ voxel_gi_instances;
layout(set = 1, binding = 19) uniform texture3D volumetric_fog_texture;
+#ifdef USE_MULTIVIEW
+layout(set = 1, binding = 20) uniform texture2DArray ssil_buffer;
+#else
layout(set = 1, binding = 20) uniform texture2D ssil_buffer;
+#endif // USE_MULTIVIEW
#endif
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
index 33fd4c35b1..a8b28bbd4f 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
@@ -63,7 +63,7 @@ vec3 oct_to_vec3(vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
float t = max(-v.z, 0.0);
v.xy += t * -sign(v.xy);
- return v;
+ return normalize(v);
}
/* Varyings */
@@ -112,9 +112,15 @@ layout(location = 9) out highp float dp_clip;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif
+vec3 multiview_uv(vec2 uv) {
+ return vec3(uv, ViewIndex);
+}
#else
// Set to zero, not supported in non stereo
#define ViewIndex 0
+vec2 multiview_uv(vec2 uv) {
+ return uv;
+}
#endif //USE_MULTIVIEW
invariant gl_Position;
@@ -308,9 +314,11 @@ void main() {
#ifdef USE_MULTIVIEW
mat4 projection_matrix = scene_data.projection_matrix_view[ViewIndex];
mat4 inv_projection_matrix = scene_data.inv_projection_matrix_view[ViewIndex];
+ vec3 eye_offset = scene_data.eye_offset[ViewIndex].xyz;
#else
mat4 projection_matrix = scene_data.projection_matrix;
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
+ vec3 eye_offset = vec3(0.0, 0.0, 0.0);
#endif //USE_MULTIVIEW
//using world coordinates
@@ -523,9 +531,15 @@ layout(location = 9) highp in float dp_clip;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif
+vec3 multiview_uv(vec2 uv) {
+ return vec3(uv, ViewIndex);
+}
#else
// Set to zero, not supported in non stereo
#define ViewIndex 0
+vec2 multiview_uv(vec2 uv) {
+ return uv;
+}
#endif //USE_MULTIVIEW
//defines to keep compatibility with vertex
@@ -659,8 +673,10 @@ void main() {
//lay out everything, whatever is unused is optimized away anyway
vec3 vertex = vertex_interp;
#ifdef USE_MULTIVIEW
- vec3 view = -normalize(vertex_interp - scene_data.eye_offset[ViewIndex].xyz);
+ vec3 eye_offset = scene_data.eye_offset[ViewIndex].xyz;
+ vec3 view = -normalize(vertex_interp - eye_offset);
#else
+ vec3 eye_offset = vec3(0.0, 0.0, 0.0);
vec3 view = -normalize(vertex_interp);
#endif
vec3 albedo = vec3(1.0);
@@ -779,7 +795,8 @@ void main() {
// alpha hash can be used in unison with alpha antialiasing
#ifdef ALPHA_HASH_USED
- if (alpha < compute_alpha_hash_threshold(vertex, alpha_hash_scale)) {
+ vec3 object_pos = (inverse(read_model_matrix) * inv_view_matrix * vec4(vertex, 1.0)).xyz;
+ if (alpha < compute_alpha_hash_threshold(object_pos, alpha_hash_scale)) {
discard;
}
#endif // ALPHA_HASH_USED
@@ -865,7 +882,7 @@ void main() {
uint decal_indices = draw_call.decals.x;
for (uint i = 0; i < 8; i++) {
uint decal_index = decal_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
decal_indices = draw_call.decals.y;
} else {
decal_indices = decal_indices >> 8;
@@ -986,12 +1003,12 @@ void main() {
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
- blend = modf(roughness * MAX_ROUGHNESS_LOD, lod);
+ blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod);
specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb;
specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend);
#else // USE_RADIANCE_CUBEMAP_ARRAY
- specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;
+ specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
specular_light *= sc_luminance_multiplier;
@@ -1041,7 +1058,7 @@ void main() {
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
- float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD;
+ float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
@@ -1147,7 +1164,7 @@ void main() {
for (uint i = 0; i < 8; i++) {
uint reflection_index = reflection_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
reflection_indices = draw_call.reflection_probes.y;
} else {
reflection_indices = reflection_indices >> 8;
@@ -1172,8 +1189,14 @@ void main() {
} //Reflection probes
// finalize ambient light here
- ambient_light *= albedo.rgb;
- ambient_light *= ao;
+ {
+#if defined(AMBIENT_LIGHT_DISABLED)
+ ambient_light = vec3(0.0, 0.0, 0.0);
+#else
+ ambient_light *= albedo.rgb;
+ ambient_light *= ao;
+#endif // AMBIENT_LIGHT_DISABLED
+ }
// convert ao to direct light ao
ao = mix(1.0, ao, ao_light_affect);
@@ -1198,7 +1221,7 @@ void main() {
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- specular_light *= env.x * f0 + env.y;
+ specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0);
#endif
}
@@ -1508,6 +1531,8 @@ void main() {
} else {
shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
}
+
+ shadow = mix(1.0, shadow, directional_lights.data[i].shadow_opacity);
#endif
blur_shadow(shadow);
@@ -1544,7 +1569,7 @@ void main() {
uint light_indices = draw_call.omni_lights.x;
for (uint i = 0; i < 8; i++) {
uint light_index = light_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
light_indices = draw_call.omni_lights.y;
} else {
light_indices = light_indices >> 8;
@@ -1589,7 +1614,7 @@ void main() {
uint light_indices = draw_call.spot_lights.x;
for (uint i = 0; i < 8; i++) {
uint light_index = light_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
light_indices = draw_call.spot_lights.y;
} else {
light_indices = light_indices >> 8;
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl
index 631ff0575b..78b39a356d 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl
@@ -154,8 +154,15 @@ layout(set = 1, binding = 5) uniform highp texture2D directional_shadow_atlas;
// this needs to change to providing just the lightmap we're using..
layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
+#ifdef USE_MULTIVIEW
+layout(set = 1, binding = 9) uniform highp texture2DArray depth_buffer;
+layout(set = 1, binding = 10) uniform mediump texture2DArray color_buffer;
+#define multiviewSampler sampler2DArray
+#else
layout(set = 1, binding = 9) uniform highp texture2D depth_buffer;
layout(set = 1, binding = 10) uniform mediump texture2D color_buffer;
+#define multiviewSampler sampler2D
+#endif // USE_MULTIVIEW
/* Set 2 Skeleton & Instancing (can change per item) */
diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index 3a6dd579b9..a609076e2c 100644
--- a/servers/rendering/renderer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -243,8 +243,14 @@ void main() {
if (params.trail_size > 1) {
if (params.trail_pass) {
+ if (particle >= params.total_particles * (params.trail_size - 1)) {
+ return;
+ }
particle += (particle / (params.trail_size - 1)) + 1;
} else {
+ if (particle >= params.total_particles) {
+ return;
+ }
particle *= params.trail_size;
}
}
@@ -298,12 +304,17 @@ void main() {
PARTICLE.flags = PARTICLE_FLAG_TRAILED | ((frame_history.data[0].frame & PARTICLE_FRAME_MASK) << PARTICLE_FRAME_SHIFT); //mark it as trailed, save in which frame it will start
PARTICLE.xform = particles.data[src_idx].xform;
}
-
+ if (!bool(particles.data[src_idx].flags & PARTICLE_FLAG_ACTIVE)) {
+ // Disable the entire trail if the parent is no longer active.
+ PARTICLE.flags = 0;
+ return;
+ }
if (bool(PARTICLE.flags & PARTICLE_FLAG_TRAILED) && ((PARTICLE.flags >> PARTICLE_FRAME_SHIFT) == (FRAME.frame & PARTICLE_FRAME_MASK))) { //check this is trailed and see if it should start now
// we just assume that this is the first frame of the particle, the rest is deterministic
PARTICLE.flags = PARTICLE_FLAG_ACTIVE | (particles.data[src_idx].flags & (PARTICLE_FRAME_MASK << PARTICLE_FRAME_SHIFT));
return; //- this appears like it should be correct, but it seems not to be.. wonder why.
}
+
} else {
PARTICLE.flags &= ~PARTICLE_FLAG_STARTED;
}
@@ -462,7 +473,7 @@ void main() {
if (any(lessThan(uvw_pos, vec3(0.0))) || any(greaterThan(uvw_pos, vec3(1.0)))) {
continue;
}
- vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * 2.0 - 1.0;
+ vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * -2.0 + 1.0;
dir = mat3(FRAME.attractors[i].transform) * safe_normalize(s); //revert direction
amount = length(s);
diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
index 048257e9ef..b57ee18521 100644
--- a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
@@ -63,7 +63,7 @@ struct SceneData {
float IBL_exposure_normalization;
bool pancake_shadows;
- uint pad1;
+ uint camera_visible_layers;
uint pad2;
uint pad3;
};
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl
index 97c913d489..71510ee06a 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl
@@ -11,7 +11,8 @@ float hash_3d(vec3 p) {
float compute_alpha_hash_threshold(vec3 pos, float hash_scale) {
vec3 dx = dFdx(pos);
- vec3 dy = dFdx(pos);
+ vec3 dy = dFdy(pos);
+
float delta_max_sqr = max(length(dx), length(dy));
float pix_scale = 1.0 / (hash_scale * delta_max_sqr);
@@ -32,9 +33,9 @@ float compute_alpha_hash_threshold(vec3 pos, float hash_scale) {
1.0 - ((1.0 - a_interp) * (1.0 - a_interp) / (2.0 * min_lerp * (1.0 - min_lerp))));
float alpha_hash_threshold =
- (lerp_factor < (1.0 - min_lerp)) ? ((lerp_factor < min_lerp) ? cases.x : cases.y) : cases.z;
+ (a_interp < (1.0 - min_lerp)) ? ((a_interp < min_lerp) ? cases.x : cases.y) : cases.z;
- return clamp(alpha_hash_threshold, 0.0, 1.0);
+ return clamp(alpha_hash_threshold, 0.00001, 1.0);
}
#endif // ALPHA_HASH_USED
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
index 2fba1351f7..9dda62c28d 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -134,7 +134,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
#endif
#if defined(LIGHT_RIM_USED)
- float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
+ // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior.
+ float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color;
#endif
@@ -202,7 +203,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
float cLdotH5 = SchlickFresnel(cLdotH);
// Calculate Fresnel using specular occlusion term from Filament:
// https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion
- float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), 0.0, 1.0);
+ float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), metallic, 1.0);
vec3 F = f0 + (f90 - f0) * cLdotH5;
vec3 specular_brdf_NL = cNdotL * D * F * G;
@@ -793,8 +794,13 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
float light_length = length(light_rel_vec);
float spot_attenuation = get_omni_attenuation(light_length, spot_lights.data[idx].inv_radius, spot_lights.data[idx].attenuation);
vec3 spot_dir = spot_lights.data[idx].direction;
- float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[idx].cone_angle);
- float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[idx].cone_angle));
+
+ // This conversion to a highp float is crucial to prevent light leaking
+ // due to precision errors in the following calculations (cone angle is mediump).
+ highp float cone_angle = spot_lights.data[idx].cone_angle;
+ float scos = max(dot(-normalize(light_rel_vec), spot_dir), cone_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cone_angle));
+
spot_attenuation *= 1.0 - pow(spot_rim, spot_lights.data[idx].cone_attenuation);
float light_attenuation = spot_attenuation;
vec3 color = spot_lights.data[idx].color;
diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl
index 75bea9300b..59c161548c 100644
--- a/servers/rendering/renderer_rd/shaders/skeleton.glsl
+++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl
@@ -51,6 +51,15 @@ layout(push_constant, std430) uniform Params {
bool normalized_blend_shapes;
uint pad0;
uint pad1;
+
+ vec2 skeleton_transform_x;
+ vec2 skeleton_transform_y;
+
+ vec2 skeleton_transform_offset;
+ vec2 inverse_transform_x;
+
+ vec2 inverse_transform_y;
+ vec2 inverse_transform_offset;
}
params;
@@ -63,7 +72,7 @@ vec3 oct_to_vec3(vec2 oct) {
vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y));
float t = max(-v.z, 0.0);
v.xy += t * -sign(v.xy);
- return v;
+ return normalize(v);
}
vec3 decode_uint_oct_to_norm(uint base) {
@@ -143,8 +152,8 @@ void main() {
uint skin_offset = params.skin_stride * index;
uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
- uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset
- uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3;
+ uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 2; //pre-add xform offset
+ uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 2;
skin_offset += params.skin_weight_offset;
@@ -158,9 +167,20 @@ void main() {
m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.x;
m += mat4(bone_transforms.data[bones_23.y], bone_transforms.data[bones_23.y + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y;
- //reverse order because its transposed
- vertex = (vec4(vertex, 0.0, 1.0) * m).xy;
+ mat4 skeleton_matrix = mat4(vec4(params.skeleton_transform_x, 0.0, 0.0), vec4(params.skeleton_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(params.skeleton_transform_offset, 0.0, 1.0));
+ mat4 inverse_matrix = mat4(vec4(params.inverse_transform_x, 0.0, 0.0), vec4(params.inverse_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(params.inverse_transform_offset, 0.0, 1.0));
+
+ m = skeleton_matrix * transpose(m) * inverse_matrix;
+
+ vertex = (m * vec4(vertex, 0.0, 1.0)).xy;
}
+
+ uint dst_offset = index * params.vertex_stride;
+
+ uvec2 uvertex = floatBitsToUint(vertex);
+ dst_vertices.data[dst_offset + 0] = uvertex.x;
+ dst_vertices.data[dst_offset + 1] = uvertex.y;
+
#else
vec3 vertex;
vec3 normal;
diff --git a/servers/rendering/renderer_rd/spirv-reflect/SCsub b/servers/rendering/renderer_rd/spirv-reflect/SCsub
new file mode 100644
index 0000000000..4c27e5bef7
--- /dev/null
+++ b/servers/rendering/renderer_rd/spirv-reflect/SCsub
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+Import("env")
+
+# Thirdparty source files
+
+thirdparty_dir = "#thirdparty/spirv-reflect/"
+thirdparty_sources = [
+ "spirv_reflect.c",
+]
+
+thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+
+env_thirdparty = env.Clone()
+env_thirdparty.disable_warnings()
+
+env_thirdparty.add_source_files(env.servers_sources, thirdparty_sources)
diff --git a/servers/rendering/renderer_rd/storage_rd/forward_id_storage.cpp b/servers/rendering/renderer_rd/storage_rd/forward_id_storage.cpp
index c7f106eba0..3782d343c2 100644
--- a/servers/rendering/renderer_rd/storage_rd/forward_id_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/forward_id_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* forward_id_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* forward_id_storage.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 "forward_id_storage.h"
diff --git a/servers/rendering/renderer_rd/storage_rd/forward_id_storage.h b/servers/rendering/renderer_rd/storage_rd/forward_id_storage.h
index f6a74383d4..bedf5e80c7 100644
--- a/servers/rendering/renderer_rd/storage_rd/forward_id_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/forward_id_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* forward_id_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* forward_id_storage.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 FORWARD_ID_STORAGE_H
#define FORWARD_ID_STORAGE_H
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
index c83473ef07..e65d842a67 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* light_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* light_storage.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 "light_storage.h"
#include "core/config/project_settings.h"
@@ -232,6 +232,8 @@ void LightStorage::light_set_projector(RID p_light, RID p_texture) {
return;
}
+ ERR_FAIL_COND(p_texture.is_valid() && !texture_storage->owns_texture(p_texture));
+
if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
@@ -387,6 +389,13 @@ uint64_t LightStorage::light_get_version(RID p_light) const {
return light->version;
}
+uint32_t LightStorage::light_get_cull_mask(RID p_light) const {
+ const Light *light = light_owner.get_or_null(p_light);
+ ERR_FAIL_COND_V(!light, 0);
+
+ return light->cull_mask;
+}
+
AABB LightStorage::light_get_aabb(RID p_light) const {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, AABB());
@@ -568,8 +577,6 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
r_directional_light_count = 0;
r_positional_light_count = 0;
- Plane camera_plane(-p_camera_transform.basis.get_column(Vector3::AXIS_Z).normalized(), p_camera_transform.origin);
-
omni_light_count = 0;
spot_light_count = 0;
@@ -653,6 +660,14 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
if (light_data.shadow_opacity > 0.001) {
RS::LightDirectionalShadowMode smode = light->directional_shadow_mode;
+ light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR];
+ light_data.softshadow_angle = angular_diameter;
+ light_data.bake_mode = light->bake_mode;
+
+ if (angular_diameter <= 0.0) {
+ light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->directional_shadow_quality_radius_get(); // Only use quality radius for PCF
+ }
+
int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light->directional_blend_splits;
for (int j = 0; j < 4; j++) {
@@ -669,7 +684,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
Projection shadow_mtx = rectm * bias * matrix * modelview;
light_data.shadow_split_offsets[j] = split;
- float bias_scale = light_instance->shadow_transform[j].bias_scale;
+ float bias_scale = light_instance->shadow_transform[j].bias_scale * light_data.soft_shadow_scale;
light_data.shadow_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_BIAS] / 100.0 * bias_scale;
light_data.shadow_normal_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[j].shadow_texel_size;
light_data.shadow_transmittance_bias[j] = light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] * bias_scale;
@@ -702,14 +717,6 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
float fade_start = light->param[RS::LIGHT_PARAM_SHADOW_FADE_START];
light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep
light_data.fade_to = -light_data.shadow_split_offsets[3];
-
- light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR];
- light_data.softshadow_angle = angular_diameter;
- light_data.bake_mode = light->bake_mode;
-
- if (angular_diameter <= 0.0) {
- light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->directional_shadow_quality_radius_get(); // Only use quality radius for PCF
- }
}
r_directional_light_count++;
@@ -720,7 +727,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
}
Transform3D light_transform = light_instance->transform;
- const real_t distance = camera_plane.distance_to(light_transform.origin);
+ const real_t distance = p_camera_transform.origin.distance_to(light_transform.origin);
if (light->distance_fade) {
const float fade_begin = light->distance_fade_begin;
@@ -745,7 +752,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
}
Transform3D light_transform = light_instance->transform;
- const real_t distance = camera_plane.distance_to(light_transform.origin);
+ const real_t distance = p_camera_transform.origin.distance_to(light_transform.origin);
if (light->distance_fade) {
const float fade_begin = light->distance_fade_begin;
@@ -787,6 +794,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
RS::LightType type = (i < omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT;
LightInstance *light_instance = (i < omni_light_count) ? omni_light_sort[index].light_instance : spot_light_sort[index].light_instance;
Light *light = (i < omni_light_count) ? omni_light_sort[index].light : spot_light_sort[index].light;
+ real_t distance = (i < omni_light_count) ? omni_light_sort[index].depth : spot_light_sort[index].depth;
if (using_forward_ids) {
forward_id_storage->map_forward_id(type == RS::LIGHT_OMNI ? RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT : RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT, light_instance->forward_id, index);
@@ -803,7 +811,6 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
float fade_begin = 0.0;
float fade_shadow = 0.0;
float fade_length = 0.0;
- real_t distance = 0.0;
float fade = 1.0;
float shadow_opacity_fade = 1.0;
@@ -811,7 +818,6 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
fade_begin = light->distance_fade_begin;
fade_shadow = light->distance_fade_shadow;
fade_length = light->distance_fade_length;
- distance = camera_plane.distance_to(light_transform.origin);
// Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
if (distance > fade_begin) {
@@ -978,6 +984,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
light_data.soft_shadow_size = 0.0;
light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->shadows_quality_radius_get(); // Only use quality radius for PCF
}
+ light_data.shadow_bias *= light_data.soft_shadow_scale;
}
} else {
light_data.shadow_opacity = 0.0;
@@ -1066,14 +1073,14 @@ void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distan
reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
+void LightStorage::reflection_probe_set_size(RID p_probe, const Vector3 &p_size) {
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
ERR_FAIL_COND(!reflection_probe);
- if (reflection_probe->extents == p_extents) {
+ if (reflection_probe->size == p_size) {
return;
}
- reflection_probe->extents = p_extents;
+ reflection_probe->size = p_size;
reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
@@ -1145,8 +1152,8 @@ AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
ERR_FAIL_COND_V(!reflection_probe, AABB());
AABB aabb;
- aabb.position = -reflection_probe->extents;
- aabb.size = reflection_probe->extents * 2.0;
+ aabb.position = -reflection_probe->size / 2;
+ aabb.size = reflection_probe->size;
return aabb;
}
@@ -1165,11 +1172,11 @@ uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {
return reflection_probe->cull_mask;
}
-Vector3 LightStorage::reflection_probe_get_extents(RID p_probe) const {
+Vector3 LightStorage::reflection_probe_get_size(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Vector3());
- return reflection_probe->extents;
+ return reflection_probe->size;
}
Vector3 LightStorage::reflection_probe_get_origin_offset(RID p_probe) const {
@@ -1314,6 +1321,10 @@ void LightStorage::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_s
ra->reflections.clear();
}
+
+ if (ra->render_buffers.is_valid()) {
+ ra->render_buffers->cleanup();
+ }
}
int LightStorage::reflection_atlas_get_size(RID p_ref_atlas) const {
@@ -1359,6 +1370,9 @@ void LightStorage::reflection_probe_release_atlas_index(RID p_instance) {
ERR_FAIL_COND(!atlas);
ERR_FAIL_INDEX(rpi->atlas_index, atlas->reflections.size());
atlas->reflections.write[rpi->atlas_index].owner = RID();
+
+ // TODO investigate if this is enough? shouldn't we be freeing our textures and framebuffers?
+
rpi->atlas_index = -1;
rpi->atlas = RID();
}
@@ -1397,6 +1411,10 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
ERR_FAIL_COND_V(!rpi, false);
+ if (atlas->render_buffers.is_null()) {
+ atlas->render_buffers.instantiate();
+ }
+
RD::get_singleton()->draw_command_begin_label("Reflection probe render");
if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->size != 256) {
@@ -1454,6 +1472,8 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
Vector<RID> fb;
fb.push_back(atlas->depth_buffer);
atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb);
+
+ atlas->render_buffers->configure_for_reflections(Size2i(atlas->size, atlas->size));
}
if (rpi->atlas_index == -1) {
@@ -1493,6 +1513,13 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
return true;
}
+Ref<RenderSceneBuffers> LightStorage::reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) {
+ ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas);
+ ERR_FAIL_COND_V(!atlas, Ref<RenderSceneBuffersRD>());
+
+ return atlas->render_buffers;
+}
+
bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
ERR_FAIL_COND_V(!rpi, false);
@@ -1534,6 +1561,11 @@ bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) {
if (rpi->processing_side == 6) {
rpi->processing_side = 0;
rpi->processing_layer++;
+ if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) {
+ rpi->rendering = false;
+ rpi->processing_layer = 1;
+ return true;
+ }
}
return false;
@@ -1649,7 +1681,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c
ReflectionData &reflection_ubo = reflections[i];
- Vector3 extents = probe->extents;
+ Vector3 extents = probe->size / 2;
rpi->cull_mask = probe->cull_mask;
@@ -1725,13 +1757,13 @@ void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_use
//erase lightmap users
if (lm->light_texture.is_valid()) {
- TextureStorage::Texture *t = texture_storage->get_singleton()->get_texture(lm->light_texture);
+ TextureStorage::Texture *t = texture_storage->get_texture(lm->light_texture);
if (t) {
t->lightmap_users.erase(p_lightmap);
}
}
- TextureStorage::Texture *t = texture_storage->get_singleton()->get_texture(p_light);
+ TextureStorage::Texture *t = texture_storage->get_texture(p_light);
lm->light_texture = p_light;
lm->uses_spherical_harmonics = p_uses_spherical_haromics;
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h
index 79006ad982..c36d1ef503 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* light_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* light_storage.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 LIGHT_STORAGE_RD_H
#define LIGHT_STORAGE_RD_H
@@ -38,6 +38,7 @@
#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
#include "servers/rendering/renderer_rd/environment/sky.h"
#include "servers/rendering/renderer_rd/storage_rd/forward_id_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/storage/light_storage.h"
#include "servers/rendering/storage/utilities.h"
@@ -225,7 +226,7 @@ private:
Color ambient_color;
float ambient_color_energy = 1.0;
float max_distance = 0;
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(20, 20, 20);
Vector3 origin_offset;
bool interior = false;
bool box_projection = false;
@@ -256,6 +257,8 @@ private:
Vector<Reflection> reflections;
+ Ref<RenderSceneBuffersRD> render_buffers; // Further render buffers used.
+
ClusterBuilderRD *cluster_builder = nullptr; // only used if cluster builder is supported by the renderer.
};
@@ -514,13 +517,6 @@ public:
return light->color;
}
- _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
- const Light *light = light_owner.get_or_null(p_light);
- ERR_FAIL_COND_V(!light, 0);
-
- return light->cull_mask;
- }
-
_FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) {
const Light *light = light_owner.get_or_null(p_light);
return light->distance_fade;
@@ -572,6 +568,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override;
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override;
virtual uint64_t light_get_version(RID p_light) const override;
+ virtual uint32_t light_get_cull_mask(RID p_light) const override;
Dependency *light_get_dependency(RID p_light) const;
@@ -788,7 +785,7 @@ public:
virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override;
virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override;
virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) override;
- virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override;
+ virtual void reflection_probe_set_size(RID p_probe, const Vector3 &p_size) override;
virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override;
virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override;
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override;
@@ -802,7 +799,7 @@ public:
virtual AABB reflection_probe_get_aabb(RID p_probe) const override;
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override;
- virtual Vector3 reflection_probe_get_extents(RID p_probe) const override;
+ virtual Vector3 reflection_probe_get_size(RID p_probe) const override;
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override;
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override;
virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override;
@@ -846,6 +843,7 @@ public:
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
+ virtual Ref<RenderSceneBuffers> reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) override;
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override;
uint32_t reflection_probe_instance_get_resolution(RID p_instance);
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index f0b8d006cb..d631a89dd2 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* material_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* material_storage.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 "material_storage.h"
#include "core/config/engine.h"
@@ -85,7 +85,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored
}
} else {
- int v = value;
+ uint32_t v = value;
gui[0] = v & 1 ? 1 : 0;
gui[1] = v & 2 ? 1 : 0;
}
@@ -112,7 +112,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored
}
} else {
- int v = value;
+ uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0;
@@ -141,7 +141,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
}
}
} else {
- int v = value;
+ uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0;
@@ -734,7 +734,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
switch (type) {
case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data;
- *gui = value[0].boolean ? 1 : 0;
+ gui[0] = value[0].boolean ? 1 : 0;
} break;
case ShaderLanguage::TYPE_BVEC2: {
uint32_t *gui = (uint32_t *)data;
@@ -928,6 +928,104 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
}
///////////////////////////////////////////////////////////////////////////
+// MaterialStorage::ShaderData
+
+void MaterialStorage::ShaderData::set_path_hint(const String &p_hint) {
+ path = p_hint;
+}
+
+void MaterialStorage::ShaderData::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;
+ }
+}
+
+Variant MaterialStorage::ShaderData::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();
+}
+
+void MaterialStorage::ShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const {
+ SortArray<Pair<StringName, int>, ShaderLanguage::UniformOrderComparator> sorter;
+ LocalVector<Pair<StringName, int>> filtered_uniforms;
+
+ for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
+ if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
+ continue;
+ }
+ if (E.value.texture_order >= 0) {
+ filtered_uniforms.push_back(Pair<StringName, int>(E.key, E.value.texture_order + 100000));
+ } else {
+ filtered_uniforms.push_back(Pair<StringName, int>(E.key, E.value.order));
+ }
+ }
+ int uniform_count = filtered_uniforms.size();
+ sorter.sort(filtered_uniforms.ptr(), uniform_count);
+
+ String last_group;
+ for (int i = 0; i < uniform_count; i++) {
+ const StringName &uniform_name = filtered_uniforms[i].first;
+ const ShaderLanguage::ShaderNode::Uniform &uniform = uniforms[uniform_name];
+
+ String group = uniform.group;
+ if (!uniform.subgroup.is_empty()) {
+ group += "::" + uniform.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(uniform);
+ pi.name = uniform_name;
+ p_param_list->push_back(pi);
+ }
+}
+
+void MaterialStorage::ShaderData::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 MaterialStorage::ShaderData::is_parameter_texture(const StringName &p_param) const {
+ if (!uniforms.has(p_param)) {
+ return false;
+ }
+
+ return uniforms[p_param].texture_order >= 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
// MaterialStorage::MaterialData
void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) {
@@ -1221,6 +1319,10 @@ void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Va
roughness_detect_texture = tex;
roughness_channel = RS::TextureDetectRoughnessChannel(p_texture_uniforms[i].hint - ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_R);
}
+ if (tex->render_target) {
+ tex->render_target->was_used = true;
+ render_target_cache.push_back(tex->render_target);
+ }
#endif
}
if (rd_texture.is_null()) {
@@ -1307,6 +1409,7 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<
if ((uint32_t)texture_cache.size() != tex_uniform_count || p_textures_dirty) {
texture_cache.resize(tex_uniform_count);
+ render_target_cache.clear();
p_textures_dirty = true;
//clear previous uniform set
@@ -1367,6 +1470,12 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<
return true;
}
+void MaterialStorage::MaterialData::set_as_used() {
+ for (int i = 0; i < render_target_cache.size(); i++) {
+ render_target_cache[i]->was_used = true;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////
// MaterialStorage
@@ -2113,7 +2222,7 @@ void MaterialStorage::global_shader_parameters_load_settings(bool p_load_texture
for (const PropertyInfo &E : settings) {
if (E.name.begins_with("shader_globals/")) {
StringName name = E.name.get_slice("/", 1);
- Dictionary d = ProjectSettings::get_singleton()->get(E.name);
+ Dictionary d = GLOBAL_GET(E.name);
ERR_CONTINUE(!d.has("type"));
ERR_CONTINUE(!d.has("value"));
@@ -2213,7 +2322,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) {
global_shader_uniforms.instance_buffer_pos.erase(p_instance);
}
-void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) {
+void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count) {
if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore
}
@@ -2223,7 +2332,9 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
return; //again, not allocated, ignore
}
ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
- ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
+
+ Variant::Type value_type = p_value.get_type();
+ ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
const ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = {
ShaderLanguage::TYPE_MAX, //nil
@@ -2249,9 +2360,23 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
ShaderLanguage::TYPE_VEC4 //color
};
- ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_type()];
-
- ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
+ ShaderLanguage::DataType datatype = ShaderLanguage::TYPE_MAX;
+ if (value_type == Variant::INT && p_flags_count > 0) {
+ switch (p_flags_count) {
+ case 1:
+ datatype = ShaderLanguage::TYPE_BVEC2;
+ break;
+ case 2:
+ datatype = ShaderLanguage::TYPE_BVEC3;
+ break;
+ case 3:
+ datatype = ShaderLanguage::TYPE_BVEC4;
+ break;
+ }
+ } else {
+ datatype = datatype_from_value[value_type];
+ }
+ ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
pos += p_index;
@@ -2560,6 +2685,14 @@ void MaterialStorage::material_free(RID p_rid) {
Material *material = material_owner.get_or_null(p_rid);
ERR_FAIL_COND(!material);
+ // Need to clear texture arrays to prevent spin locking of their RID's.
+ // This happens when the app is being closed.
+ for (KeyValue<StringName, Variant> &E : material->params) {
+ if (E.value.get_type() == Variant::ARRAY) {
+ Array(E.value).clear();
+ }
+ }
+
material_set_shader(p_rid, RID()); //clean up shader
material->dependency.deleted_notify(p_rid);
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h
index 19c2f39553..ac217d9a49 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h
@@ -1,36 +1,38 @@
-/*************************************************************************/
-/* material_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* material_storage.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 MATERIAL_STORAGE_RD_H
#define MATERIAL_STORAGE_RD_H
+#include "texture_storage.h"
+
#include "core/math/projection.h"
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
@@ -54,24 +56,30 @@ public:
};
struct ShaderData {
- virtual void set_code(const String &p_Code) = 0;
- virtual void set_path_hint(const String &p_hint) = 0;
- virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) = 0;
- virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0;
+ String path;
+ HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ HashMap<StringName, HashMap<int, RID>> default_texture_params;
- virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0;
- virtual bool is_parameter_texture(const StringName &p_param) const = 0;
+ 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 Variant get_default_parameter(const StringName &p_parameter) const;
+ 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 void set_code(const String &p_Code) = 0;
virtual bool is_animated() const = 0;
virtual bool casts_shadows() const = 0;
- virtual Variant get_default_parameter(const StringName &p_parameter) const = 0;
virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); }
virtual ~ShaderData() {}
};
struct MaterialData {
+ Vector<RendererRD::TextureStorage::RenderTarget *> render_target_cache;
void update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
void update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
+ void set_as_used();
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
@@ -79,7 +87,7 @@ public:
virtual ~MaterialData();
//to be used internally by update_parameters, in the most common configuration of material parameters
- bool update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ bool update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
void free_parameters_uniform_set(RID p_uniform_set);
private:
@@ -315,13 +323,13 @@ public:
// http://andrewthall.org/papers/df64_qf128.pdf
#ifdef REAL_T_IS_DOUBLE
- static _FORCE_INLINE_ void split_double(double a, float *ahi, float *alo) {
+ static _FORCE_INLINE_ void split_double(double a, float *a_hi, float *a_lo) {
const double SPLITTER = (1 << 29) + 1;
double t = a * SPLITTER;
- double thi = t - (t - a);
- double tlo = a - thi;
- *ahi = (float)thi;
- *alo = (float)tlo;
+ double t_hi = t - (t - a);
+ double t_lo = a - t_hi;
+ *a_hi = (float)t_hi;
+ *a_lo = (float)t_lo;
}
#endif
@@ -361,7 +369,7 @@ public:
virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override;
virtual void global_shader_parameters_instance_free(RID p_instance) override;
- virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override;
+ virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override;
RID global_shader_uniforms_get_storage_buffer() const;
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index 1e74d31383..96618c3352 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* mesh_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* mesh_storage.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 "mesh_storage.h"
#include "../../rendering_server_globals.h"
@@ -434,20 +434,8 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
}
if (mesh->surface_count == 0) {
- mesh->bone_aabbs = p_surface.bone_aabbs;
mesh->aabb = p_surface.aabb;
} else {
- if (mesh->bone_aabbs.size() < p_surface.bone_aabbs.size()) {
- // ArrayMesh::_surface_set_data only allocates bone_aabbs up to max_bone
- // Each surface may affect different numbers of bones.
- mesh->bone_aabbs.resize(p_surface.bone_aabbs.size());
- }
- for (int i = 0; i < p_surface.bone_aabbs.size(); i++) {
- const AABB &bone = p_surface.bone_aabbs[i];
- if (bone.has_volume()) {
- mesh->bone_aabbs.write[i].merge_with(bone);
- }
- }
mesh->aabb.merge_with(p_surface.aabb);
}
@@ -598,6 +586,8 @@ void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
Mesh *mesh = mesh_owner.get_or_null(p_mesh);
ERR_FAIL_COND(!mesh);
mesh->custom_aabb = p_aabb;
+
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const {
@@ -616,7 +606,7 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
- if (!skeleton || skeleton->size == 0) {
+ if (!skeleton || skeleton->size == 0 || mesh->skeleton_aabb_version == skeleton->version) {
return mesh->aabb;
}
@@ -708,6 +698,9 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
}
}
+ mesh->aabb = aabb;
+
+ mesh->skeleton_aabb_version = skeleton->version;
return aabb;
}
@@ -851,15 +844,15 @@ void MeshStorage::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int
}
void MeshStorage::_mesh_instance_clear(MeshInstance *mi) {
- for (uint32_t i = 0; i < mi->surfaces.size(); i++) {
- if (mi->surfaces[i].versions) {
- for (uint32_t j = 0; j < mi->surfaces[i].version_count; j++) {
- RD::get_singleton()->free(mi->surfaces[i].versions[j].vertex_array);
+ for (const RendererRD::MeshStorage::MeshInstance::Surface &surface : mi->surfaces) {
+ if (surface.versions) {
+ for (uint32_t j = 0; j < surface.version_count; j++) {
+ RD::get_singleton()->free(surface.versions[j].vertex_array);
}
- memfree(mi->surfaces[i].versions);
+ memfree(surface.versions);
}
- if (mi->surfaces[i].vertex_buffer.is_valid()) {
- RD::get_singleton()->free(mi->surfaces[i].vertex_buffer);
+ if (surface.vertex_buffer.is_valid()) {
+ RD::get_singleton()->free(surface.vertex_buffer);
}
}
mi->surfaces.clear();
@@ -875,8 +868,8 @@ void MeshStorage::_mesh_instance_clear(MeshInstance *mi) {
void MeshStorage::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface) {
if (mesh->blend_shape_count > 0 && mi->blend_weights_buffer.is_null()) {
mi->blend_weights.resize(mesh->blend_shape_count);
- for (uint32_t i = 0; i < mi->blend_weights.size(); i++) {
- mi->blend_weights[i] = 0;
+ for (float &weight : mi->blend_weights) {
+ weight = 0;
}
mi->blend_weights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(float) * mi->blend_weights.size(), mi->blend_weights.to_byte_array());
mi->weights_dirty = true;
@@ -939,6 +932,11 @@ void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) {
}
}
+void MeshStorage::mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) {
+ MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
+ mi->canvas_item_transform_2d = p_transform;
+}
+
void MeshStorage::update_mesh_instances() {
while (dirty_mesh_instance_weights.first()) {
MeshInstance *mi = dirty_mesh_instance_weights.first()->self();
@@ -990,6 +988,25 @@ void MeshStorage::update_mesh_instances() {
push_constant.skin_stride = (mi->mesh->surfaces[i]->skin_buffer_size / mi->mesh->surfaces[i]->vertex_count) / 4;
push_constant.skin_weight_offset = (mi->mesh->surfaces[i]->format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 4 : 2;
+ Transform2D transform = Transform2D();
+ if (sk && sk->use_2d) {
+ transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;
+ }
+ push_constant.skeleton_transform_x[0] = transform.columns[0][0];
+ push_constant.skeleton_transform_x[1] = transform.columns[0][1];
+ push_constant.skeleton_transform_y[0] = transform.columns[1][0];
+ push_constant.skeleton_transform_y[1] = transform.columns[1][1];
+ push_constant.skeleton_transform_offset[0] = transform.columns[2][0];
+ push_constant.skeleton_transform_offset[1] = transform.columns[2][1];
+
+ Transform2D inverse_transform = transform.affine_inverse();
+ push_constant.inverse_transform_x[0] = inverse_transform.columns[0][0];
+ push_constant.inverse_transform_x[1] = inverse_transform.columns[0][1];
+ push_constant.inverse_transform_y[0] = inverse_transform.columns[1][0];
+ push_constant.inverse_transform_y[1] = inverse_transform.columns[1][1];
+ push_constant.inverse_transform_offset[0] = inverse_transform.columns[2][0];
+ push_constant.inverse_transform_offset[1] = inverse_transform.columns[2][1];
+
push_constant.blend_shape_count = mi->mesh->blend_shape_count;
push_constant.normalized_blend_shapes = mi->mesh->blend_shape_mode == RS::BLEND_SHAPE_MODE_NORMALIZED;
push_constant.pad0 = 0;
@@ -1788,8 +1805,12 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible
}
if (multimesh->data_cache.size()) {
- //there is a data cache..
+ // There is a data cache, but we may need to update some sections.
_multimesh_mark_all_dirty(multimesh, false, true);
+ int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
+ for (int i = start; i < p_visible; i++) {
+ _multimesh_mark_dirty(multimesh, i, true);
+ }
}
multimesh->visible_instances = p_visible;
@@ -1841,7 +1862,7 @@ void MeshStorage::_update_dirty_multimeshes() {
RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float) + offset, MIN(region_size, size - offset), &data[region_start_index], RD::BARRIER_MASK_NO_BARRIER);
}
}
- RD::get_singleton()->barrier(RD::BARRIER_MASK_NO_BARRIER, RD::BARRIER_MASK_ALL);
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_NO_BARRIER, RD::BARRIER_MASK_ALL_BARRIERS);
}
memcpy(multimesh->previous_data_cache_dirty_regions, multimesh->data_cache_dirty_regions, data_cache_dirty_region_count * sizeof(bool));
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
index c8a33bd4d7..c921523941 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* mesh_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* mesh_storage.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 MESH_STORAGE_RD_H
#define MESH_STORAGE_RD_H
@@ -138,12 +138,11 @@ private:
Surface **surfaces = nullptr;
uint32_t surface_count = 0;
- Vector<AABB> bone_aabbs;
-
bool has_bone_weights = false;
AABB aabb;
AABB custom_aabb;
+ uint64_t skeleton_aabb_version = 0;
Vector<RID> material_cache;
@@ -179,6 +178,7 @@ private:
bool weights_dirty = false;
SelfList<MeshInstance> weight_update_list;
SelfList<MeshInstance> array_update_list;
+ Transform2D canvas_item_transform_2d;
MeshInstance() :
weight_update_list(this), array_update_list(this) {}
};
@@ -257,6 +257,14 @@ private:
uint32_t normalized_blend_shapes;
uint32_t pad0;
uint32_t pad1;
+ float skeleton_transform_x[2];
+ float skeleton_transform_y[2];
+
+ float skeleton_transform_offset[2];
+ float inverse_transform_x[2];
+
+ float inverse_transform_y[2];
+ float inverse_transform_offset[2];
};
enum {
@@ -398,13 +406,11 @@ public:
return s->index_count ? s->index_count : s->vertex_count;
}
- _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_mesh_lod_threshold, uint32_t *r_index_count = nullptr) const {
+ _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_mesh_lod_threshold, uint32_t &r_index_count) const {
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
int32_t current_lod = -1;
- if (r_index_count) {
- *r_index_count = s->index_count;
- }
+ r_index_count = s->index_count;
for (uint32_t i = 0; i < s->lod_count; i++) {
float screen_size = s->lods[i].edge_length * p_model_scale / p_distance_threshold;
if (screen_size > p_mesh_lod_threshold) {
@@ -415,9 +421,7 @@ public:
if (current_lod == -1) {
return 0;
} else {
- if (r_index_count) {
- *r_index_count = s->lods[current_lod].index_count;
- }
+ r_index_count = s->lods[current_lod].index_count;
return current_lod + 1;
}
}
@@ -553,6 +557,7 @@ public:
virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override;
virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override;
virtual void mesh_instance_check_for_update(RID p_mesh_instance) override;
+ virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) override;
virtual void update_mesh_instances() override;
/* MULTIMESH API */
@@ -668,7 +673,6 @@ public:
virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override;
- void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform3D &p_world_transform);
virtual int skeleton_get_bone_count(RID p_skeleton) const override;
virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) override;
virtual Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override;
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index 240f743387..00fb8acca8 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* particles_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* particles_storage.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 "particles_storage.h"
@@ -425,7 +425,7 @@ void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, doub
p_length = MIN(10.0, p_length);
particles->trails_enabled = p_enable;
- particles->trail_length = p_length;
+ particles->trail_lifetime = p_length;
_particles_free_data(particles);
@@ -810,6 +810,15 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
//2D collision
Transform2D xform = p_particles->sdf_collision_transform; //will use dotproduct manually so invert beforehand
+
+ if (!p_particles->use_local_coords) {
+ Transform2D emission;
+ emission.columns[0] = Vector2(p_particles->emission_transform.basis.get_column(0).x, p_particles->emission_transform.basis.get_column(0).y);
+ emission.columns[1] = Vector2(p_particles->emission_transform.basis.get_column(1).x, p_particles->emission_transform.basis.get_column(1).y);
+ emission.set_origin(Vector2(p_particles->emission_transform.origin.x, p_particles->emission_transform.origin.y));
+ xform = xform * emission.affine_inverse();
+ }
+
Transform2D revert = xform.affine_inverse();
frame_params.collider_count = 1;
frame_params.colliders[0].transform[0] = xform.columns[0][0];
@@ -842,9 +851,9 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
collision_heightmap_texture = p_particles->sdf_collision_texture;
//replace in all other history frames where used because parameters are no longer valid if screen moves
- for (uint32_t i = 1; i < p_particles->frame_history.size(); i++) {
- if (p_particles->frame_history[i].collider_count > 0 && p_particles->frame_history[i].colliders[0].type == ParticlesFrameParams::COLLISION_TYPE_2D_SDF) {
- p_particles->frame_history[i].colliders[0] = frame_params.colliders[0];
+ for (ParticlesFrameParams &params : p_particles->frame_history) {
+ if (params.collider_count > 0 && params.colliders[0].type == ParticlesFrameParams::COLLISION_TYPE_2D_SDF) {
+ params.colliders[0] = frame_params.colliders[0];
}
}
}
@@ -1027,6 +1036,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
uniforms.push_back(u);
}
p_particles->collision_textures_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.default_shader_rd, 2);
+ p_particles->collision_heightmap_texture = collision_heightmap_texture;
}
}
@@ -1106,6 +1116,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
if (m->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(m->uniform_set)) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, m->uniform_set, 3);
+ m->set_as_used();
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ParticlesShader::PushConstant));
@@ -1134,7 +1145,7 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p
return;
}
- if (particles->particle_buffer.is_null()) {
+ if (particles->particle_buffer.is_null() || particles->trail_bind_pose_uniform_set.is_null()) {
return; //particles have not processed yet
}
@@ -1220,7 +1231,9 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p
RendererCompositorRD::singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
}
- copy_push_constant.total_particles *= copy_push_constant.total_particles;
+ if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) {
+ copy_push_constant.total_particles *= particles->trail_bind_poses.size();
+ }
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
uint32_t copy_pipeline = do_sort ? ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : ParticlesShader::COPY_MODE_FILL_INSTANCES;
@@ -1349,7 +1362,7 @@ void ParticlesStorage::update_particles() {
int history_size = 1;
int trail_steps = 1;
if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) {
- history_size = MAX(1, int(particles->trail_length * fixed_fps));
+ history_size = MAX(1, int(particles->trail_lifetime * fixed_fps));
trail_steps = particles->trail_bind_poses.size();
}
@@ -1437,7 +1450,7 @@ void ParticlesStorage::update_particles() {
}
double todo = particles->frame_remainder + delta;
- while (todo >= frame_time) {
+ while (todo >= frame_time || particles->clear) {
_particles_process(particles, frame_time);
todo -= decr;
}
@@ -1452,8 +1465,10 @@ void ParticlesStorage::update_particles() {
}
}
- //copy particles to instance buffer
+ // Ensure that memory is initialized (the code above should ensure that _particles_process is always called at least once upon clearing).
+ DEV_ASSERT(!particles->clear);
+ // Copy particles to instance buffer.
if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) {
//does not need view dependent operation, do copy here
ParticlesShader::CopyPushConstant copy_push_constant;
@@ -1531,9 +1546,6 @@ bool ParticlesStorage::particles_is_inactive(RID p_particles) const {
/* Particles SHADER */
-void ParticlesStorage::ParticlesShaderData::set_path_hint(const String &p_path) {
- path = p_path;
-}
void ParticlesStorage::ParticlesShaderData::set_code(const String &p_code) {
ParticlesStorage *particles_storage = ParticlesStorage::get_singleton();
//compile
@@ -1599,83 +1611,6 @@ void ParticlesStorage::ParticlesShaderData::set_code(const String &p_code) {
valid = true;
}
-void ParticlesStorage::ParticlesShaderData::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 ParticlesStorage::ParticlesShaderData::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 ParticlesStorage::ParticlesShaderData::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 ParticlesStorage::ParticlesShaderData::is_parameter_texture(const StringName &p_param) const {
- if (!uniforms.has(p_param)) {
- return false;
- }
-
- return uniforms[p_param].texture_order >= 0;
-}
-
bool ParticlesStorage::ParticlesShaderData::is_animated() const {
return false;
}
@@ -1684,15 +1619,6 @@ bool ParticlesStorage::ParticlesShaderData::casts_shadows() const {
return false;
}
-Variant ParticlesStorage::ParticlesShaderData::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 ParticlesStorage::ParticlesShaderData::get_native_source_code() const {
return ParticlesStorage::get_singleton()->particles_shader.shader.version_get_native_source_code(version);
}
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
index 017844626f..9308d3ce9e 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* particles_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* particles_storage.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 PARTICLES_STORAGE_RD_H
#define PARTICLES_STORAGE_RD_H
@@ -54,8 +54,7 @@ private:
float velocity[3];
uint32_t active;
float color[4];
- float custom[3];
- float lifetime;
+ float custom[4];
};
struct ParticlesFrameParams {
@@ -97,7 +96,7 @@ private:
uint32_t type;
uint32_t texture_index; //texture index for vector field
- real_t scale;
+ float scale;
uint32_t pad[2];
};
@@ -106,8 +105,8 @@ private:
float prev_system_phase;
uint32_t cycle;
- real_t explosiveness;
- real_t randomness;
+ float explosiveness;
+ float randomness;
float time;
float delta;
@@ -127,9 +126,6 @@ private:
Collider colliders[MAX_COLLIDERS];
};
- struct ParticleEmissionBufferData {
- };
-
struct ParticleEmissionBuffer {
struct Data {
float xform[16];
@@ -232,7 +228,7 @@ private:
Dependency dependency;
- double trail_length = 1.0;
+ double trail_lifetime = 0.3;
bool trails_enabled = false;
LocalVector<ParticlesFrameParams> frame_history;
LocalVector<ParticlesFrameParams> trail_params;
@@ -317,15 +313,12 @@ private:
RID version;
bool uses_collision = false;
- 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;
RID pipeline;
@@ -335,14 +328,8 @@ private:
uint32_t userdata_count = 0;
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;
ParticlesShaderData() {}
@@ -412,7 +399,7 @@ public:
bool owns_particles(RID p_rid) { return particles_owner.owns(p_rid); }
virtual RID particles_allocate() override;
- virtual void particles_initialize(RID p_particles_collision) override;
+ virtual void particles_initialize(RID p_rid) override;
virtual void particles_free(RID p_rid) override;
virtual void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) override;
@@ -468,6 +455,12 @@ public:
return particles->mode;
}
+ _FORCE_INLINE_ uint32_t particles_get_frame_counter(RID p_particles) {
+ Particles *particles = particles_owner.get_or_null(p_particles);
+ ERR_FAIL_COND_V(!particles, false);
+ return particles->frame_counter;
+ }
+
_FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles, uint32_t &r_trail_divisor) {
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_COND_V(!particles, 0);
@@ -498,9 +491,8 @@ public:
_FORCE_INLINE_ RID particles_get_instance_buffer_uniform_set(RID p_particles, RID p_shader, uint32_t p_set) {
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_COND_V(!particles, RID());
- if (particles->particles_transforms_buffer_uniform_set.is_null()) {
+ if (particles->particles_transforms_buffer_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(particles->particles_transforms_buffer_uniform_set)) {
_particles_update_buffers(particles);
-
Vector<RD::Uniform> uniforms;
{
@@ -519,7 +511,7 @@ public:
virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) override;
virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) override;
- virtual void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) override;
+ void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture);
virtual void update_particles() override;
@@ -546,7 +538,7 @@ public:
virtual AABB particles_collision_get_aabb(RID p_particles_collision) const override;
Vector3 particles_collision_get_extents(RID p_particles_collision) const;
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override;
- virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override;
+ RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
Dependency *particles_collision_get_dependency(RID p_particles) const;
diff --git a/servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h
index d904012914..c0b3f09842 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_buffer_custom_data_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_buffer_custom_data_rd.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 RENDER_BUFFER_CUSTOM_DATA_RD_H
#define RENDER_BUFFER_CUSTOM_DATA_RD_H
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
index 0c2092f03e..f5d6404f01 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_scene_buffers_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_scene_buffers_rd.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 "render_scene_buffers_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
@@ -50,25 +50,19 @@ void RenderSceneBuffersRD::_bind_methods() {
// ClassDB::bind_method(D_METHOD("create_texture_view", "context", "name", "view_name", "view"), &RenderSceneBuffersRD::has_texture);
ClassDB::bind_method(D_METHOD("get_texture", "context", "name"), &RenderSceneBuffersRD::get_texture);
// ClassDB::bind_method(D_METHOD("get_texture_format", "context", "name"), &RenderSceneBuffersRD::get_texture_format);
- ClassDB::bind_method(D_METHOD("get_texture_slice", "context", "name", "layer", "mipmap"), &RenderSceneBuffersRD::get_texture_slice);
- ClassDB::bind_method(D_METHOD("get_texture_slice_size", "context", "name", "layer", "mipmap"), &RenderSceneBuffersRD::get_texture_slice_size);
+ ClassDB::bind_method(D_METHOD("get_texture_slice", "context", "name", "layer", "mipmap", "layers", "mipmaps"), &RenderSceneBuffersRD::get_texture_slice);
+ ClassDB::bind_method(D_METHOD("get_texture_slice_size", "context", "name", "mipmap"), &RenderSceneBuffersRD::get_texture_slice_size);
ClassDB::bind_method(D_METHOD("clear_context", "context"), &RenderSceneBuffersRD::clear_context);
}
void RenderSceneBuffersRD::update_sizes(NamedTexture &p_named_texture) {
ERR_FAIL_COND(p_named_texture.texture.is_null());
- uint32_t size = p_named_texture.format.array_layers * p_named_texture.format.mipmaps;
- p_named_texture.sizes.resize(size);
+ p_named_texture.sizes.resize(p_named_texture.format.mipmaps);
Size2i mipmap_size = Size2i(p_named_texture.format.width, p_named_texture.format.height);
-
for (uint32_t mipmap = 0; mipmap < p_named_texture.format.mipmaps; mipmap++) {
- for (uint32_t layer = 0; layer < p_named_texture.format.array_layers; layer++) {
- uint32_t index = layer * p_named_texture.format.mipmaps + mipmap;
-
- p_named_texture.sizes.ptrw()[index] = mipmap_size;
- }
+ p_named_texture.sizes.ptrw()[mipmap] = mipmap_size;
mipmap_size.width = MAX(1, mipmap_size.width >> 1);
mipmap_size.height = MAX(1, mipmap_size.height >> 1);
@@ -94,31 +88,9 @@ void RenderSceneBuffersRD::cleanup() {
free_named_texture(E.value);
}
named_textures.clear();
-
- // old stuff, to be re-evaluated...
-
- for (int i = 0; i < luminance.fb.size(); i++) {
- RD::get_singleton()->free(luminance.fb[i]);
- }
- luminance.fb.clear();
-
- for (int i = 0; i < luminance.reduce.size(); i++) {
- RD::get_singleton()->free(luminance.reduce[i]);
- }
- luminance.reduce.clear();
-
- if (luminance.current_fb.is_valid()) {
- RD::get_singleton()->free(luminance.current_fb);
- luminance.current_fb = RID();
- }
-
- if (luminance.current.is_valid()) {
- RD::get_singleton()->free(luminance.current);
- luminance.current = RID();
- }
}
-void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
+void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
@@ -126,12 +98,7 @@ void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_interna
target_size = p_target_size;
internal_size = p_internal_size;
-
- // FIXME, right now we do this because only our clustered renderer supports FSR upscale
- // this does mean that with linear upscale if we use subpasses, we could get into trouble.
- if (!can_be_storage) {
- internal_size = target_size;
- }
+ scaling_3d_mode = p_scaling_3d_mode;
if (p_use_taa) {
// Use negative mipmap LOD bias when TAA is enabled to compensate for loss of sharpness.
@@ -202,6 +169,31 @@ void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_interna
vrs_texture = create_texture(RB_SCOPE_VRS, RB_TEXTURE, RD::DATA_FORMAT_R8_UINT, usage_bits, RD::TEXTURE_SAMPLES_1, vrs->get_vrs_texture_size(internal_size));
}
+ // (re-)configure any named buffers
+ for (KeyValue<StringName, Ref<RenderBufferCustomDataRD>> &E : data_buffers) {
+ E.value->configure(this);
+ }
+}
+
+void RenderSceneBuffersRD::configure_for_reflections(const Size2i p_reflection_size) {
+ // For now our render buffers for reflections are only used for effects/environment (Sky/Fog/Etc)
+ // Possibly at some point move our entire reflection atlas buffer management into this class
+
+ target_size = p_reflection_size;
+ internal_size = p_reflection_size;
+ render_target = RID();
+ scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
+ fsr_sharpness = 0.0;
+ msaa_3d = RS::VIEWPORT_MSAA_DISABLED;
+ screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;
+ use_taa = false;
+ use_debanding = false;
+ view_count = 1;
+
+ // cleanout any old buffers we had.
+ cleanup();
+
+ // (re-)configure any named buffers
for (KeyValue<StringName, Ref<RenderBufferCustomDataRD>> &E : data_buffers) {
E.value->configure(this);
}
@@ -253,7 +245,7 @@ RID RenderSceneBuffersRD::create_texture(const StringName &p_context, const Stri
}
RID RenderSceneBuffersRD::create_texture_from_format(const StringName &p_context, const StringName &p_texture_name, const RD::TextureFormat &p_texture_format, RD::TextureView p_view, bool p_unique) {
- // TODO p_unique, if p_unique is true, this is a texture that can be shared. This will be implemented later as an optimisation.
+ // TODO p_unique, if p_unique is true, this is a texture that can be shared. This will be implemented later as an optimization.
NTKey key(p_context, p_texture_name);
@@ -326,7 +318,7 @@ const RD::TextureFormat RenderSceneBuffersRD::get_texture_format(const StringNam
return named_textures[key].format;
}
-RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap) {
+RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers, const uint32_t p_mipmaps) {
NTKey key(p_context, p_texture_name);
// check if this is a known texture
@@ -336,36 +328,41 @@ RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const S
// check if we're in bounds
ERR_FAIL_UNSIGNED_INDEX_V(p_layer, named_texture.format.array_layers, RID());
+ ERR_FAIL_COND_V(p_layers == 0, RID());
+ ERR_FAIL_COND_V(p_layer + p_layers > named_texture.format.array_layers, RID());
ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, named_texture.format.mipmaps, RID());
+ ERR_FAIL_COND_V(p_mipmaps == 0, RID());
+ ERR_FAIL_COND_V(p_mipmap + p_mipmaps > named_texture.format.mipmaps, RID());
- // if we don't have multiple layers or mipmaps, we can just return our texture as is
- if (named_texture.format.array_layers == 1 && named_texture.format.mipmaps == 1) {
+ // asking the whole thing? just return the original
+ if (p_layer == 0 && p_mipmap == 0 && named_texture.format.array_layers == p_layers && named_texture.format.mipmaps == p_mipmaps) {
return named_texture.texture;
}
- // get our index and make sure we have enough entries in our slices vector
- uint32_t index = p_layer * named_texture.format.mipmaps + p_mipmap;
- while (named_texture.slices.size() <= int(index)) {
- named_texture.slices.push_back(RID());
+ // see if we have this
+ NTSliceKey slice_key(p_layer, p_layers, p_mipmap, p_mipmaps);
+ if (named_texture.slices.has(slice_key)) {
+ return named_texture.slices[slice_key];
}
- // create our slice if we don't have it already
- if (named_texture.slices[index].is_null()) {
- named_texture.slices.ptrw()[index] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), named_texture.texture, p_layer, p_mipmap);
+ // create our slice
+ RID &slice = named_texture.slices[slice_key];
+ slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), named_texture.texture, p_layer, p_mipmap, p_mipmaps, p_layers > 1 ? RD::TEXTURE_SLICE_2D_ARRAY : RD::TEXTURE_SLICE_2D, p_layers);
- Array arr;
- arr.push_back(p_context);
- arr.push_back(p_texture_name);
- arr.push_back(itos(p_layer));
- arr.push_back(itos(p_mipmap));
- RD::get_singleton()->set_resource_name(named_texture.slices[index], String("RenderBuffer {0}/{1} slice {2}/{3}").format(arr));
- }
+ Array arr;
+ arr.push_back(p_context);
+ arr.push_back(p_texture_name);
+ arr.push_back(itos(p_layer));
+ arr.push_back(itos(p_layers));
+ arr.push_back(itos(p_mipmap));
+ arr.push_back(itos(p_mipmaps));
+ RD::get_singleton()->set_resource_name(slice, String("RenderBuffer {0}/{1}, layer {2}/{3}, mipmap {4}/{5}").format(arr));
// and return our slice
- return named_texture.slices[index];
+ return slice;
}
-Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap) {
+Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_mipmap) {
NTKey key(p_context, p_texture_name);
// check if this is a known texture
@@ -374,14 +371,10 @@ Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context,
ERR_FAIL_COND_V(named_texture.texture.is_null(), Size2i());
// check if we're in bounds
- ERR_FAIL_UNSIGNED_INDEX_V(p_layer, named_texture.format.array_layers, Size2i());
ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, named_texture.format.mipmaps, Size2i());
- // get our index
- uint32_t index = p_layer * named_texture.format.mipmaps + p_mipmap;
-
- // and return our size
- return named_texture.sizes[index];
+ // return our size
+ return named_texture.sizes[p_mipmap];
}
void RenderSceneBuffersRD::clear_context(const StringName &p_context) {
@@ -492,6 +485,16 @@ Ref<RenderBufferCustomDataRD> RenderSceneBuffersRD::get_custom_data(const String
// Depth texture
+bool RenderSceneBuffersRD::has_depth_texture() {
+ RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+ RID depth = texture_storage->render_target_get_override_depth(render_target);
+ if (depth.is_valid()) {
+ return true;
+ } else {
+ return has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH);
+ }
+}
+
RID RenderSceneBuffersRD::get_depth_texture() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RID depth = texture_storage->render_target_get_override_depth(render_target);
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
index 6907f69b93..9a299a3415 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_scene_buffers_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_scene_buffers_rd.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 RENDER_SCENE_BUFFERS_RD_H
#define RENDER_SCENE_BUFFERS_RD_H
@@ -73,6 +73,7 @@ private:
// The internal size of the textures we render 3D to in case we render at a lower resolution and upscale
Size2i internal_size = Size2i(0, 0);
+ RS::ViewportScaling3DMode scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
float fsr_sharpness = 0.2f;
// Aliassing settings
@@ -92,7 +93,6 @@ private:
}
static uint32_t hash(const NTKey &p_val) {
- // FIXME, properly hash two stringnames together
uint32_t h = p_val.context.hash();
h = hash_murmur3_one_32(p_val.buffer_name.hash(), h);
return hash_fmix32(h);
@@ -105,6 +105,33 @@ private:
}
};
+ struct NTSliceKey {
+ uint32_t layer;
+ uint32_t layers;
+ uint32_t mipmap;
+ uint32_t mipmaps;
+
+ bool operator==(const NTSliceKey &p_val) const {
+ return (layer == p_val.layer) && (layers == p_val.layers) && (mipmap == p_val.mipmap) && (mipmaps == p_val.mipmaps);
+ }
+
+ static uint32_t hash(const NTSliceKey &p_val) {
+ uint32_t h = hash_murmur3_one_32(p_val.layer);
+ h = hash_murmur3_one_32(p_val.layers, h);
+ h = hash_murmur3_one_32(p_val.mipmap, h);
+ h = hash_murmur3_one_32(p_val.mipmaps, h);
+ return hash_fmix32(h);
+ }
+
+ NTSliceKey() {}
+ NTSliceKey(uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) {
+ layer = p_layer;
+ layers = p_layers;
+ mipmap = p_mipmap;
+ mipmaps = p_mipmaps;
+ }
+ };
+
struct NamedTexture {
// Cache the data used to create our texture
RD::TextureFormat format;
@@ -112,7 +139,7 @@ private:
// Our texture objects, slices are lazy (i.e. only created when requested).
RID texture;
- Vector<RID> slices;
+ mutable HashMap<NTSliceKey, RID, NTSliceKey> slices;
Vector<Size2i> sizes;
};
@@ -139,7 +166,8 @@ public:
void set_vrs(RendererRD::VRS *p_vrs) { vrs = p_vrs; }
void cleanup();
- virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override;
+ virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override;
+ void configure_for_reflections(const Size2i p_reflection_size);
virtual void set_fsr_sharpness(float p_fsr_sharpness) override;
virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override;
virtual void set_use_debanding(bool p_use_debanding) override;
@@ -152,8 +180,8 @@ public:
RID create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName p_view_name, RD::TextureView p_view = RD::TextureView());
RID get_texture(const StringName &p_context, const StringName &p_texture_name) const;
const RD::TextureFormat get_texture_format(const StringName &p_context, const StringName &p_texture_name) const;
- RID get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap);
- Size2i get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap);
+ RID get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers = 1, const uint32_t p_mipmaps = 1);
+ Size2i get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_mipmap);
void clear_context(const StringName &p_context);
@@ -171,6 +199,7 @@ public:
_FORCE_INLINE_ uint32_t get_view_count() const { return view_count; }
_FORCE_INLINE_ Size2i get_internal_size() const { return internal_size; }
_FORCE_INLINE_ Size2i get_target_size() const { return target_size; }
+ _FORCE_INLINE_ RS::ViewportScaling3DMode get_scaling_3d_mode() const { return scaling_3d_mode; }
_FORCE_INLINE_ float get_fsr_sharpness() const { return fsr_sharpness; }
_FORCE_INLINE_ RS::ViewportMSAA get_msaa_3d() const { return msaa_3d; }
_FORCE_INLINE_ RS::ViewportScreenSpaceAA get_screen_space_aa() const { return screen_space_aa; }
@@ -182,6 +211,9 @@ public:
// For our internal textures we provide some easy access methods.
+ _FORCE_INLINE_ bool has_internal_texture() const {
+ return has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR);
+ }
_FORCE_INLINE_ RID get_internal_texture() const {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR);
}
@@ -189,6 +221,7 @@ public:
return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR, p_layer, 0);
}
+ bool has_depth_texture();
RID get_depth_texture();
RID get_depth_texture(const uint32_t p_layer);
@@ -212,15 +245,6 @@ public:
// 2 full size, 2 half size
WeightBuffers weight_buffers[4]; // Only used in raster
-
- struct Luminance {
- Vector<RID> reduce;
- RID current;
-
- // used only on mobile renderer
- Vector<RID> fb;
- RID current_fb;
- } luminance;
};
#endif // RENDER_SCENE_BUFFERS_RD_H
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
index 7dd790d1da..a7b8f985d9 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_scene_data_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_scene_data_rd.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 "render_scene_data_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
@@ -88,6 +88,7 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->penumbra_shadow_kernel_get(), ubo.penumbra_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->soft_shadow_kernel_get(), ubo.soft_shadow_kernel);
+ ubo.camera_visible_layers = camera_visible_layers;
ubo.viewport_size[0] = p_screen_size.x;
ubo.viewport_size[1] = p_screen_size.y;
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
index 9c031acc1e..7546998a9b 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_scene_data_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_scene_data_rd.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 RENDER_SCENE_DATA_RD_H
#define RENDER_SCENE_DATA_RD_H
@@ -45,6 +45,7 @@ public:
Transform3D cam_transform;
Projection cam_projection;
Vector2 taa_jitter;
+ uint32_t camera_visible_layers;
bool cam_orthogonal = false;
// For stereo rendering
@@ -142,7 +143,7 @@ private:
float IBL_exposure_normalization; // Adjusts for baked exposure.
uint32_t pancake_shadows;
- uint32_t pad1;
+ uint32_t camera_visible_layers;
uint32_t pad2;
uint32_t pad3;
};
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index bc70c57b69..0ee9b28826 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* texture_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* texture_storage.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 "texture_storage.h"
@@ -419,11 +419,11 @@ TextureStorage::TextureStorage() {
tformat.format = RD::DATA_FORMAT_R8_UINT;
tformat.width = 4;
tformat.height = 4;
- tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
- if (RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS)) {
- tformat.usage_bits |= RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT;
- }
+ tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT;
tformat.texture_type = RD::TEXTURE_TYPE_2D;
+ if (!RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS)) {
+ tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ }
Vector<uint8_t> pv;
pv.resize(4 * 4);
@@ -560,6 +560,7 @@ void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS:
void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
ERR_FAIL_NULL(ct);
+
ct->texture_repeat = p_repeat;
ct->clear_sets();
}
@@ -580,6 +581,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
}
ct = t->canvas_texture;
+ if (t->render_target) {
+ t->render_target->was_used = true;
+ }
} else {
ct = canvas_texture_owner.get_or_null(p_texture);
}
@@ -610,6 +614,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
} else {
u.append_id(t->rd_texture);
ct->size_cache = Size2i(t->width_2d, t->height_2d);
+ if (t->render_target) {
+ t->render_target->was_used = true;
+ }
}
uniforms.push_back(u);
}
@@ -625,6 +632,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
} else {
u.append_id(t->rd_texture);
ct->use_normal_cache = true;
+ if (t->render_target) {
+ t->render_target->was_used = true;
+ }
}
uniforms.push_back(u);
}
@@ -640,6 +650,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte
} else {
u.append_id(t->rd_texture);
ct->use_specular_cache = true;
+ if (t->render_target) {
+ t->render_target->was_used = true;
+ }
}
uniforms.push_back(u);
}
@@ -1336,6 +1349,13 @@ Size2 TextureStorage::texture_size_with_proxy(RID p_proxy) {
return texture_2d_get_size(p_proxy);
}
+RID TextureStorage::texture_get_rd_texture_rid(RID p_texture, bool p_srgb) const {
+ Texture *tex = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_COND_V(!tex, RID());
+
+ return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture;
+}
+
Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
Ref<Image> image = p_image->duplicate();
@@ -1756,6 +1776,46 @@ Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, T
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
+ case Image::FORMAT_ASTC_4x4:
+ case Image::FORMAT_ASTC_4x4_HDR: {
+ if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
+ r_format.format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK;
+ if (p_image->get_format() == Image::FORMAT_ASTC_4x4) {
+ r_format.format_srgb = RD::DATA_FORMAT_ASTC_4x4_SRGB_BLOCK;
+ }
+ } else {
+ //not supported, reconvert
+ r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
+ image->decompress();
+ image->convert(Image::FORMAT_RGBA8);
+ }
+ r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
+ r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
+ r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
+ r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
+
+ } break; // astc 4x4
+ case Image::FORMAT_ASTC_8x8:
+ case Image::FORMAT_ASTC_8x8_HDR: {
+ if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
+ r_format.format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK;
+ if (p_image->get_format() == Image::FORMAT_ASTC_8x8) {
+ r_format.format_srgb = RD::DATA_FORMAT_ASTC_8x8_SRGB_BLOCK;
+ }
+ } else {
+ //not supported, reconvert
+ r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
+ image->decompress();
+ image->convert(Image::FORMAT_RGBA8);
+ }
+ r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
+ r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
+ r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
+ r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
+
+ } break; // astc 8x8
default: {
}
@@ -1793,10 +1853,10 @@ void TextureStorage::decal_free(RID p_rid) {
decal_owner.free(p_rid);
}
-void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
+void TextureStorage::decal_set_size(RID p_decal, const Vector3 &p_size) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
- decal->extents = p_extents;
+ decal->size = p_size;
decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
@@ -1846,7 +1906,7 @@ void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->cull_mask = p_layers;
- decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+ decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL);
}
void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
@@ -1889,7 +1949,14 @@ AABB TextureStorage::decal_get_aabb(RID p_decal) const {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND_V(!decal, AABB());
- return AABB(-decal->extents, decal->extents * 2.0);
+ return AABB(-decal->size / 2, decal->size);
+}
+
+uint32_t TextureStorage::decal_get_cull_mask(RID p_decal) const {
+ Decal *decal = decal_owner.get_or_null(p_decal);
+ ERR_FAIL_COND_V(!decal, 0);
+
+ return decal->cull_mask;
}
Dependency *TextureStorage::decal_get_dependency(RID p_decal) {
@@ -2145,6 +2212,12 @@ void TextureStorage::decal_instance_set_transform(RID p_decal_instance, const Tr
di->transform = p_transform;
}
+void TextureStorage::decal_instance_set_sorting_offset(RID p_decal_instance, float p_sorting_offset) {
+ DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
+ ERR_FAIL_COND(!di);
+ di->sorting_offset = p_sorting_offset;
+}
+
/* DECAL DATA API */
void TextureStorage::free_decal_data() {
@@ -2172,7 +2245,7 @@ void TextureStorage::set_max_decals(const uint32_t p_max_decals) {
decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size);
}
-void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) {
+void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const Transform3D &p_camera_xform) {
ForwardIDStorage *forward_id_storage = ForwardIDStorage::get_singleton();
Transform3D uv_xform;
@@ -2196,7 +2269,7 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const
Transform3D xform = decal_instance->transform;
- real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
+ real_t distance = p_camera_xform.origin.distance_to(xform.origin);
if (decal->distance_fade) {
float fade_begin = decal->distance_fade_begin;
@@ -2211,7 +2284,7 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const
decal_sort[decal_count].decal_instance = decal_instance;
decal_sort[decal_count].decal = decal;
- decal_sort[decal_count].depth = distance;
+ decal_sort[decal_count].depth = distance - decal_instance->sorting_offset;
decal_count++;
}
@@ -2231,11 +2304,10 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const
decal_instance->cull_mask = decal->cull_mask;
- Transform3D xform = decal_instance->transform;
float fade = 1.0;
if (decal->distance_fade) {
- const real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
+ const real_t distance = decal_sort[i].depth + decal_instance->sorting_offset;
const float fade_begin = decal->distance_fade_begin;
const float fade_length = decal->distance_fade_length;
@@ -2247,15 +2319,20 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const
DecalData &dd = decals[i];
- Vector3 decal_extents = decal->extents;
+ Vector3 decal_extents = decal->size / 2;
Transform3D scale_xform;
scale_xform.basis.scale(decal_extents);
- Transform3D to_decal_xform = (p_camera_inverse_xform * xform * scale_xform * uv_xform).affine_inverse();
+
+ Transform3D xform = decal_instance->transform;
+
+ Transform3D camera_inverse_xform = p_camera_xform.affine_inverse();
+
+ Transform3D to_decal_xform = (camera_inverse_xform * xform * scale_xform * uv_xform).affine_inverse();
MaterialStorage::store_transform(to_decal_xform, dd.xform);
Vector3 normal = xform.basis.get_column(Vector3::AXIS_Y).normalized();
- normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
+ normal = camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
dd.normal[0] = normal.x;
dd.normal[1] = normal.y;
@@ -2289,7 +2366,7 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const
dd.normal_rect[2] = rect.size.x;
dd.normal_rect[3] = rect.size.y;
- Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized();
+ Basis normal_xform = camera_inverse_xform.basis * xform.basis.orthonormalized();
MaterialStorage::store_basis_3x4(normal_xform, dd.normal_xform);
} else {
dd.normal_rect[0] = 0;
@@ -2390,6 +2467,10 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
rt->color = RID();
rt->color_multisample = RID();
+ if (rt->texture.is_valid()) {
+ Texture *tex = get_texture(rt->texture);
+ tex->render_target = nullptr;
+ }
}
void TextureStorage::_update_render_target(RenderTarget *rt) {
@@ -2470,6 +2551,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
tex->rd_texture = RID();
tex->rd_texture_srgb = RID();
+ tex->render_target = rt;
//create shared textures to the color buffer,
//so transparent can be supported
@@ -2594,11 +2676,13 @@ RID TextureStorage::render_target_get_texture(RID p_render_target) {
return rt->texture;
}
-void TextureStorage::render_target_set_override_color(RID p_render_target, RID p_texture) {
+void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
- rt->overridden.color = p_texture;
+ rt->overridden.color = p_color_texture;
+ rt->overridden.depth = p_depth_texture;
+ rt->overridden.velocity = p_velocity_texture;
}
RID TextureStorage::render_target_get_override_color(RID p_render_target) const {
@@ -2608,13 +2692,6 @@ RID TextureStorage::render_target_get_override_color(RID p_render_target) const
return rt->overridden.color;
}
-void TextureStorage::render_target_set_override_depth(RID p_render_target, RID p_texture) {
- RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND(!rt);
-
- rt->overridden.depth = p_texture;
-}
-
RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@@ -2641,13 +2718,6 @@ RID TextureStorage::render_target_get_override_depth_slice(RID p_render_target,
}
}
-void TextureStorage::render_target_set_override_velocity(RID p_render_target, RID p_texture) {
- RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND(!rt);
-
- rt->overridden.velocity = p_texture;
-}
-
RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@@ -3124,9 +3194,11 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons
// TODO figure out stereo support here
- //single texture copy for backbuffer
- //RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
- copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true);
+ if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
+ copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true);
+ } else {
+ copy_effects->copy_to_fb_rect(rt->color, rt->backbuffer_fb, region, false, false, false, false, RID(), false, true);
+ }
if (!p_gen_mipmaps) {
return;
@@ -3135,14 +3207,22 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons
//then mipmap blur
RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
+ Size2i texture_size = rt->size;
+
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
region.position.x >>= 1;
region.position.y >>= 1;
region.size.x = MAX(1, region.size.x >> 1);
region.size.y = MAX(1, region.size.y >> 1);
+ texture_size.x = MAX(1, texture_size.x >> 1);
+ texture_size.y = MAX(1, texture_size.y >> 1);
RID mipmap = rt->backbuffer_mipmaps[i];
- copy_effects->gaussian_blur(prev_texture, mipmap, region, true);
+ if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
+ copy_effects->gaussian_blur(prev_texture, mipmap, region, texture_size, true);
+ } else {
+ copy_effects->gaussian_blur_raster(prev_texture, mipmap, region, texture_size);
+ }
prev_texture = mipmap;
}
RD::get_singleton()->draw_command_end_label();
@@ -3170,7 +3250,11 @@ void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const
}
//single texture copy for backbuffer
- copy_effects->set_color(rt->backbuffer_mipmap0, p_color, region, true);
+ if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
+ copy_effects->set_color(rt->backbuffer_mipmap0, p_color, region, true);
+ } else {
+ copy_effects->set_color_raster(rt->backbuffer_mipmap0, p_color, region);
+ }
}
void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
@@ -3196,15 +3280,23 @@ void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target,
RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2");
//then mipmap blur
RID prev_texture = rt->backbuffer_mipmap0;
+ Size2i texture_size = rt->size;
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
region.position.x >>= 1;
region.position.y >>= 1;
region.size.x = MAX(1, region.size.x >> 1);
region.size.y = MAX(1, region.size.y >> 1);
+ texture_size.x = MAX(1, texture_size.x >> 1);
+ texture_size.y = MAX(1, texture_size.y >> 1);
RID mipmap = rt->backbuffer_mipmaps[i];
- copy_effects->gaussian_blur(prev_texture, mipmap, region, true);
+
+ if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
+ copy_effects->gaussian_blur(prev_texture, mipmap, region, texture_size, true);
+ } else {
+ copy_effects->gaussian_blur_raster(prev_texture, mipmap, region, texture_size);
+ }
prev_texture = mipmap;
}
RD::get_singleton()->draw_command_end_label();
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 00b4e50737..c16f5274ad 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* texture_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* texture_storage.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 TEXTURE_STORAGE_RD_H
#define TEXTURE_STORAGE_RD_H
@@ -108,6 +108,8 @@ private:
/* Texture API */
+ struct RenderTarget;
+
class Texture {
public:
TextureType type;
@@ -141,6 +143,7 @@ private:
Vector<BufferSlice3D> buffer_slices_3d;
uint32_t buffer_size_3d = 0;
+ RenderTarget *render_target = nullptr;
bool is_render_target;
bool is_proxy;
@@ -232,7 +235,7 @@ private:
} decal_atlas;
struct Decal {
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(2, 2, 2);
RID textures[RS::DECAL_TEXTURE_MAX];
float emission_energy = 1.0;
float albedo_mix = 1.0;
@@ -255,6 +258,7 @@ private:
struct DecalInstance {
RID decal;
Transform3D transform;
+ float sorting_offset = 0.0;
uint32_t cull_mask = 0;
RendererRD::ForwardID forward_id = -1;
};
@@ -491,6 +495,8 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) override;
+ virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override;
+
//internal usage
_FORCE_INLINE_ TextureType texture_get_type(RID p_texture) {
RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture);
@@ -555,7 +561,7 @@ public:
virtual void decal_initialize(RID p_decal) override;
virtual void decal_free(RID p_rid) override;
- virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
+ virtual void decal_set_size(RID p_decal, const Vector3 &p_size) override;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
@@ -571,9 +577,9 @@ public:
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
- _FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
+ _FORCE_INLINE_ Vector3 decal_get_size(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
- return decal->extents;
+ return decal->size;
}
_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
@@ -632,6 +638,7 @@ public:
}
virtual AABB decal_get_aabb(RID p_decal) const override;
+ virtual uint32_t decal_get_cull_mask(RID p_decal) const override;
Dependency *decal_get_dependency(RID p_decal);
/* DECAL INSTANCE API */
@@ -641,6 +648,7 @@ public:
virtual RID decal_instance_create(RID p_decal) override;
virtual void decal_instance_free(RID p_decal_instance) override;
virtual void decal_instance_set_transform(RID p_decal_instance, const Transform3D &p_transform) override;
+ virtual void decal_instance_set_sorting_offset(RID p_decal_instance, float p_sorting_offset) override;
_FORCE_INLINE_ RID decal_instance_get_base(RID p_decal_instance) const {
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
@@ -672,7 +680,7 @@ public:
void free_decal_data();
void set_max_decals(const uint32_t p_max_decals);
RID get_decal_buffer() { return decal_buffer; }
- void update_decal_buffer(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform);
+ void update_decal_buffer(const PagedArray<RID> &p_decals, const Transform3D &p_camera_xform);
/* RENDER TARGET API */
@@ -718,12 +726,10 @@ public:
virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override;
virtual RID render_target_get_vrs_texture(RID p_render_target) const override;
- virtual void render_target_set_override_color(RID p_render_target, RID p_texture) override;
+ virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override;
virtual RID render_target_get_override_color(RID p_render_target) const override;
- virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) override;
virtual RID render_target_get_override_depth(RID p_render_target) const override;
RID render_target_get_override_depth_slice(RID p_render_target, const uint32_t p_layer) const;
- virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) override;
virtual RID render_target_get_override_velocity(RID p_render_target) const override;
RID render_target_get_override_velocity_slice(RID p_render_target, const uint32_t p_layer) const;
diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
index e517186955..cabac4e9ee 100644
--- a/servers/rendering/renderer_rd/storage_rd/utilities.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* utilities.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* utilities.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 "utilities.h"
#include "../environment/fog.h"
@@ -200,7 +200,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de
if (p_enter) {
if (!vn->enter_callback.is_null()) {
if (p_deferred) {
- vn->enter_callback.call_deferredp(nullptr, 0);
+ vn->enter_callback.call_deferred();
} else {
Variant r;
Callable::CallError ce;
@@ -210,7 +210,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de
} else {
if (!vn->exit_callback.is_null()) {
if (p_deferred) {
- vn->exit_callback.call_deferredp(nullptr, 0);
+ vn->exit_callback.call_deferred();
} else {
Variant r;
Callable::CallError ce;
@@ -286,6 +286,10 @@ bool Utilities::has_os_feature(const String &p_feature) const {
return true;
}
+ if (p_feature == "astc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
return false;
}
@@ -321,3 +325,11 @@ RenderingDevice::DeviceType Utilities::get_video_adapter_type() const {
String Utilities::get_video_adapter_api_version() const {
return RenderingDevice::get_singleton()->get_device_api_version();
}
+
+Size2i Utilities::get_maximum_viewport_size() const {
+ RenderingDevice *device = RenderingDevice::get_singleton();
+
+ int max_x = device->limit_get(RenderingDevice::LIMIT_MAX_VIEWPORT_DIMENSIONS_X);
+ int max_y = device->limit_get(RenderingDevice::LIMIT_MAX_VIEWPORT_DIMENSIONS_Y);
+ return Size2i(max_x, max_y);
+}
diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.h b/servers/rendering/renderer_rd/storage_rd/utilities.h
index a80eb8510e..2ba3da7515 100644
--- a/servers/rendering/renderer_rd/storage_rd/utilities.h
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* utilities.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* utilities.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 UTILITIES_RD_H
#define UTILITIES_RD_H
@@ -115,6 +115,8 @@ public:
virtual String get_video_adapter_vendor() const override;
virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
virtual String get_video_adapter_api_version() const override;
+
+ virtual Size2i get_maximum_viewport_size() const override;
};
} // namespace RendererRD
diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp
index 84529ca400..1f67d5e258 100644
--- a/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* uniform_set_cache_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* uniform_set_cache_rd.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 "uniform_set_cache_rd.h"
diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.h b/servers/rendering/renderer_rd/uniform_set_cache_rd.h
index bca8b02178..50243e715d 100644
--- a/servers/rendering/renderer_rd/uniform_set_cache_rd.h
+++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* uniform_set_cache_rd.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* uniform_set_cache_rd.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 UNIFORM_SET_CACHE_RD_H
#define UNIFORM_SET_CACHE_RD_H
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index d0cb46dee9..813c1fa4ff 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -1,36 +1,37 @@
-/*************************************************************************/
-/* renderer_scene_cull.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_cull.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 "renderer_scene_cull.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "core/os/os.h"
#include "rendering_server_default.h"
#include "rendering_server_globals.h"
@@ -646,6 +647,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
geom->geometry_instance->set_surface_materials(instance->materials);
geom->geometry_instance->set_transform(instance->transform, instance->aabb, instance->transformed_aabb);
geom->geometry_instance->set_layer_mask(instance->layer_mask);
+ geom->geometry_instance->set_pivot_data(instance->sorting_offset, instance->use_aabb_center);
geom->geometry_instance->set_lod_bias(instance->lod_bias);
geom->geometry_instance->set_transparency(instance->transparency);
geom->geometry_instance->set_use_baked_light(instance->baked_light);
@@ -693,6 +695,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
instance->base_data = decal;
decal->instance = RSG::texture_storage->decal_instance_create(p_base);
+ RSG::texture_storage->decal_instance_set_sorting_offset(decal->instance, instance->sorting_offset);
} break;
case RS::INSTANCE_LIGHTMAP: {
InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
@@ -747,6 +750,10 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) {
switch (instance->base_type) {
case RS::INSTANCE_LIGHT: {
InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
+ if (instance->visible && RSG::light_storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ instance->scenario->dynamic_lights.erase(light->instance);
+ }
+
#ifdef DEBUG_ENABLED
if (light->geometries.size()) {
ERR_PRINT("BUG, indexing did not unpair geometries from light.");
@@ -832,6 +839,10 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
Instance *instance = instance_owner.get_or_null(p_instance);
ERR_FAIL_COND(!instance);
+ if (instance->layer_mask == p_mask) {
+ return;
+ }
+
instance->layer_mask = p_mask;
if (instance->scenario && instance->array_index >= 0) {
instance->scenario->instance_data[instance->array_index].layer_mask = p_mask;
@@ -841,6 +852,30 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
ERR_FAIL_NULL(geom->geometry_instance);
geom->geometry_instance->set_layer_mask(p_mask);
+
+ if (geom->can_cast_shadows) {
+ for (HashSet<RendererSceneCull::Instance *>::Iterator I = geom->lights.begin(); I != geom->lights.end(); ++I) {
+ InstanceLightData *light = static_cast<InstanceLightData *>((*I)->base_data);
+ light->shadow_dirty = true;
+ }
+ }
+ }
+}
+
+void RendererSceneCull::instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center) {
+ Instance *instance = instance_owner.get_or_null(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->sorting_offset = p_sorting_offset;
+ instance->use_aabb_center = p_use_aabb_center;
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ ERR_FAIL_NULL(geom->geometry_instance);
+ geom->geometry_instance->set_pivot_data(p_sorting_offset, p_use_aabb_center);
+ } else if (instance->base_type == RS::INSTANCE_DECAL && instance->base_data) {
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
+ RSG::texture_storage->decal_instance_set_sorting_offset(decal->instance, instance->sorting_offset);
}
}
@@ -1449,8 +1484,23 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c
} else {
E->value.value = p_value;
if (E->value.index >= 0 && instance->instance_allocated_shader_uniforms) {
+ int flags_count = 0;
+ if (E->value.info.hint == PROPERTY_HINT_FLAGS) {
+ // A small hack to detect boolean flags count and prevent overhead.
+ switch (E->value.info.hint_string.length()) {
+ case 3: // "x,y"
+ flags_count = 1;
+ break;
+ case 5: // "x,y,z"
+ flags_count = 2;
+ break;
+ case 7: // "x,y,z,w"
+ flags_count = 3;
+ break;
+ }
+ }
//update directly
- RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value);
+ RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value, flags_count);
}
}
}
@@ -1738,6 +1788,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_allocator = &pair_allocator;
pair.pair_pass = pair_pass;
pair.pair_mask = 0;
+ pair.cull_mask = 0xFFFFFFFF;
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
pair.pair_mask |= 1 << RS::INSTANCE_LIGHT;
@@ -1758,12 +1809,14 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI);
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
}
+ pair.cull_mask = RSG::light_storage->light_get_cull_mask(p_instance->base);
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) {
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) {
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
+ pair.cull_mask = RSG::texture_storage->decal_get_cull_mask(p_instance->base);
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
pair.pair_mask = (1 << RS::INSTANCE_PARTICLES);
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
@@ -2223,7 +2276,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in
}
}
-bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold) {
+bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold, uint32_t p_visible_layers) {
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
Transform3D light_transform = p_instance->transform;
@@ -2279,7 +2332,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
+ if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
continue;
} else {
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
@@ -2357,7 +2410,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
+ if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
continue;
} else {
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
@@ -2420,7 +2473,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
+ if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
continue;
} else {
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
@@ -2497,7 +2550,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
} break;
}
- camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter);
+ camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, camera->visible_layers);
} else {
// Setup our camera for our XR interface.
// We can support multiple views here each with their own camera
@@ -2505,7 +2558,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
Projection projections[RendererSceneRender::MAX_RENDER_VIEWS];
uint32_t view_count = p_xr_interface->get_view_count();
- ERR_FAIL_COND_MSG(view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported");
+ ERR_FAIL_COND_MSG(view_count == 0 || view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported");
float aspect = p_viewport_size.width / (float)p_viewport_size.height;
@@ -2519,7 +2572,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
}
if (view_count == 1) {
- camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter);
+ camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, camera->visible_layers);
} else if (view_count == 2) {
camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect);
} else {
@@ -2779,7 +2832,9 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
ERR_FAIL_NULL(geom->geometry_instance);
+ cull_data.cull->lock.lock();
geom->geometry_instance->set_softshadow_projector_pairing(geom->softshadow_count > 0, geom->projector_count > 0);
+ cull_data.cull->lock.unlock();
idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY);
}
@@ -2846,7 +2901,9 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
}
ERR_FAIL_NULL(geom->geometry_instance);
+ cull_data.cull->lock.lock();
geom->geometry_instance->set_lightmap_capture(sh);
+ cull_data.cull->lock.unlock();
idata.instance->last_frame_pass = frame_number;
}
@@ -2861,7 +2918,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
if (IN_FRUSTUM(cull_data.cull->shadows[j].cascades[k].frustum) && VIS_CHECK) {
uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
- if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) {
+ if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS && LAYER_CHECK) {
cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry);
mesh_visible = true;
}
@@ -2911,11 +2968,13 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
+ ERR_FAIL_COND(p_render_buffers.is_null());
+
render_pass++;
scene_render->set_scene_pass(render_pass);
- if (p_render_buffers.is_valid()) {
+ if (p_reflection_probe.is_null()) {
//no rendering code here, this is only to set up what needs to be done, request regions, etc.
scene_render->sdfgi_update(p_render_buffers, p_environment, p_camera_data->main_transform.origin); //update conditions for SDFGI (whether its used or not)
}
@@ -2997,7 +3056,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
{ //sdfgi
cull.sdfgi.region_count = 0;
- if (p_render_buffers.is_valid()) {
+ if (p_reflection_probe.is_null()) {
cull.sdfgi.cascade_light_count = 0;
uint32_t prev_cascade = 0xFFFFFFFF;
@@ -3043,15 +3102,15 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
#endif
if (cull_to > thread_cull_threshold) {
//multiple threads
- for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) {
- scene_cull_result_threads[i].clear();
+ for (InstanceCullResult &thread : scene_cull_result_threads) {
+ thread.clear();
}
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RendererSceneCull::_scene_cull_threaded, &cull_data, scene_cull_result_threads.size(), -1, true, SNAME("RenderCullInstances"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
- for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) {
- scene_cull_result.append_from(scene_cull_result_threads[i]);
+ for (InstanceCullResult &thread : scene_cull_result_threads) {
+ scene_cull_result.append_from(thread);
}
} else {
@@ -3188,7 +3247,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) {
//must redraw!
RENDER_TIMESTAMP("> Render Light3D " + itos(i));
- light->shadow_dirty = _light_instance_update_shadow(ins, p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_orthogonal, p_camera_data->vaspect, p_shadow_atlas, scenario, p_screen_mesh_lod_threshold);
+ light->shadow_dirty = _light_instance_update_shadow(ins, p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_orthogonal, p_camera_data->vaspect, p_shadow_atlas, scenario, p_screen_mesh_lod_threshold, p_visible_layers);
RENDER_TIMESTAMP("< Render Light3D " + itos(i));
} else {
light->shadow_dirty = redraw;
@@ -3199,6 +3258,8 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
//render SDFGI
{
+ // Q: Should this whole block be skipped if we're rendering our reflection probe?
+
sdfgi_update_data.update_static = false;
if (cull.sdfgi.region_count > 0) {
@@ -3224,7 +3285,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
}
}
- if (p_render_buffers.is_valid()) {
+ if (p_reflection_probe.is_null()) {
sdfgi_update_data.directional_lights = &directional_lights;
sdfgi_update_data.positional_light_instances = scenario->dynamic_lights.ptr();
sdfgi_update_data.positional_light_count = scenario->dynamic_lights.size();
@@ -3304,7 +3365,7 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), Projection(), true, false);
- scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
+ scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
}
@@ -3339,13 +3400,13 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
Vector3(0, -1, 0)
};
- Vector3 extents = RSG::light_storage->reflection_probe_get_extents(p_instance->base);
+ Vector3 probe_size = RSG::light_storage->reflection_probe_get_size(p_instance->base);
Vector3 origin_offset = RSG::light_storage->reflection_probe_get_origin_offset(p_instance->base);
float max_distance = RSG::light_storage->reflection_probe_get_origin_max_distance(p_instance->base);
- float size = RSG::light_storage->reflection_atlas_get_size(scenario->reflection_atlas);
- float mesh_lod_threshold = RSG::light_storage->reflection_probe_get_mesh_lod_threshold(p_instance->base) / size;
+ float atlas_size = RSG::light_storage->reflection_atlas_get_size(scenario->reflection_atlas);
+ float mesh_lod_threshold = RSG::light_storage->reflection_probe_get_mesh_lod_threshold(p_instance->base) / atlas_size;
- Vector3 edge = view_normals[p_step] * extents;
+ Vector3 edge = view_normals[p_step] * probe_size / 2;
float distance = ABS(view_normals[p_step].dot(edge) - view_normals[p_step].dot(origin_offset)); //distance from origin offset to actual view distance limit
max_distance = MAX(max_distance, distance);
@@ -3377,7 +3438,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(xform, cm, false, false);
- Ref<RenderSceneBuffers> render_buffers;
+ Ref<RenderSceneBuffers> render_buffers = RSG::light_storage->reflection_probe_atlas_get_render_buffers(scenario->reflection_atlas);
_render_scene(&camera_data, render_buffers, environment, RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
} else {
@@ -3884,7 +3945,22 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) {
if (E.value.value.get_type() != Variant::NIL) {
- RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value);
+ int flags_count = 0;
+ if (E.value.info.hint == PROPERTY_HINT_FLAGS) {
+ // A small hack to detect boolean flags count and prevent overhead.
+ switch (E.value.info.hint_string.length()) {
+ case 3: // "x,y"
+ flags_count = 1;
+ break;
+ case 5: // "x,y,z"
+ flags_count = 2;
+ break;
+ case 7: // "x,y,z,w"
+ flags_count = 3;
+ break;
+ }
+ }
+ RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value, flags_count);
}
}
} else {
@@ -4064,8 +4140,8 @@ RendererSceneCull::RendererSceneCull() {
scene_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
scene_cull_result_threads.resize(WorkerThreadPool::get_singleton()->get_thread_count());
- for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) {
- scene_cull_result_threads[i].init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
+ for (InstanceCullResult &thread : scene_cull_result_threads) {
+ thread.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
}
indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame");
@@ -4093,8 +4169,8 @@ RendererSceneCull::~RendererSceneCull() {
}
scene_cull_result.reset();
- for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) {
- scene_cull_result_threads[i].reset();
+ for (InstanceCullResult &thread : scene_cull_result_threads) {
+ thread.reset();
}
scene_cull_result_threads.clear();
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index d085b84a8c..b3874ee7ae 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_scene_cull.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_cull.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 RENDERER_SCENE_CULL_H
#define RENDERER_SCENE_CULL_H
@@ -459,6 +459,10 @@ public:
float extra_margin;
ObjectID object_id;
+ // sorting
+ float sorting_offset = 0.0;
+ bool use_aabb_center = true;
+
Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior
uint64_t last_frame_pass;
@@ -476,10 +480,12 @@ public:
Instance *instance = (Instance *)tracker->userdata;
switch (p_notification) {
case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_BONES:
case Dependency::DEPENDENCY_CHANGED_AABB: {
singleton->_instance_queue_update(instance, true, false);
} break;
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
case Dependency::DEPENDENCY_CHANGED_MATERIAL: {
singleton->_instance_queue_update(instance, false, true);
} break;
@@ -491,10 +497,6 @@ public:
case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
singleton->_instance_queue_update(instance, true, true);
} break;
- case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
- case Dependency::DEPENDENCY_CHANGED_SKELETON_BONES: {
- //ignored
- } break;
case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
//requires repairing
if (instance->indexer_id.is_valid()) {
@@ -731,11 +733,12 @@ public:
DynamicBVH *bvh2 = nullptr; //some may need to cull in two
uint32_t pair_mask;
uint64_t pair_pass;
+ uint32_t cull_mask = 0xFFFFFFFF; // Needed for decals and lights in the mobile and compatibility renderers.
_FORCE_INLINE_ bool operator()(void *p_data) {
Instance *p_instance = (Instance *)p_data;
- if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type))) {
+ if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type)) && (cull_mask & p_instance->layer_mask)) {
//test is more coarse in indexer
p_instance->pair_check = pair_pass;
InstancePair *pair = pair_allocator->alloc();
@@ -933,6 +936,7 @@ public:
virtual void instance_set_base(RID p_instance, RID p_base);
virtual void instance_set_scenario(RID p_instance, RID p_scenario);
virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask);
+ virtual void instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center);
virtual void instance_set_transform(RID p_instance, const Transform3D &p_transform);
virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id);
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight);
@@ -983,7 +987,7 @@ public:
void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect);
- _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold);
+ _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold, uint32_t p_visible_layers = 0xFFFFFF);
RID _render_get_environment(RID p_camera, RID p_scenario);
@@ -1173,7 +1177,6 @@ public:
PASS1RC(RID, environment_get_glow_map, RID)
PASS1(environment_glow_set_use_bicubic_upscale, bool)
- PASS1(environment_glow_set_use_high_quality, bool)
// SSR
PASS6(environment_set_ssr, RID, bool, int, float, float, float)
diff --git a/servers/rendering/renderer_scene_occlusion_cull.cpp b/servers/rendering/renderer_scene_occlusion_cull.cpp
index e1ca5a7103..c4f0177c73 100644
--- a/servers/rendering/renderer_scene_occlusion_cull.cpp
+++ b/servers/rendering/renderer_scene_occlusion_cull.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_scene_occlusion_cull.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_occlusion_cull.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 "renderer_scene_occlusion_cull.h"
@@ -60,6 +60,8 @@ void RendererSceneOcclusionCull::HZBuffer::clear() {
if (debug_image.is_valid()) {
debug_image.unref();
}
+
+ ERR_FAIL_NULL(RenderingServer::get_singleton());
RS::get_singleton()->free(debug_texture);
}
diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h
index 0d466e8a32..565b393094 100644
--- a/servers/rendering/renderer_scene_occlusion_cull.h
+++ b/servers/rendering/renderer_scene_occlusion_cull.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_scene_occlusion_cull.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_occlusion_cull.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 RENDERER_SCENE_OCCLUSION_CULL_H
#define RENDERER_SCENE_OCCLUSION_CULL_H
diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp
index f085168df3..a389e3e767 100644
--- a/servers/rendering/renderer_scene_render.cpp
+++ b/servers/rendering/renderer_scene_render.cpp
@@ -1,39 +1,39 @@
-/*************************************************************************/
-/* renderer_scene_render.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_render.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 "renderer_scene_render.h"
/////////////////////////////////////////////////////////////////////////////
// CameraData
-void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) {
+void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter, const uint32_t p_visible_layers) {
view_count = 1;
is_orthogonal = p_is_orthogonal;
vaspect = p_vaspect;
@@ -41,6 +41,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform,
main_transform = p_transform;
main_projection = p_projection;
+ visible_layers = p_visible_layers;
view_offset[0] = Transform3D();
view_projection[0] = p_projection;
taa_jitter = p_taa_jitter;
@@ -49,6 +50,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform,
void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) {
ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view");
+ visible_layers = 0xFFFFFFFF;
view_count = p_view_count;
is_orthogonal = p_is_orthogonal;
vaspect = p_vaspect;
@@ -82,7 +84,7 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count
Transform3D main_transform_inv = main_transform.inverse();
// 5. figure out far plane, this could use some improvement, we may have our far plane too close like this, not sure if this matters
- Vector3 far_center = (planes[0][Projection::PLANE_FAR].center() + planes[1][Projection::PLANE_FAR].center()) * 0.5;
+ Vector3 far_center = (planes[0][Projection::PLANE_FAR].get_center() + planes[1][Projection::PLANE_FAR].get_center()) * 0.5;
Plane far(-z, far_center);
/////////////////////////////////////////////////////////////////////////////
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index a8df897077..9007383641 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_scene_render.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_scene_render.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 RENDERER_SCENE_RENDER_H
#define RENDERER_SCENE_RENDER_H
@@ -162,7 +162,6 @@ public:
RID environment_get_glow_map(RID p_env) const;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
- virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
// SSR
void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance);
@@ -268,6 +267,7 @@ public:
// flags
uint32_t view_count;
bool is_orthogonal;
+ uint32_t visible_layers;
bool vaspect;
// Main/center projection
@@ -278,7 +278,7 @@ public:
Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
Vector2 taa_jitter;
- void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2());
+ void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), uint32_t p_visible_layers = 0xFFFFFFFF);
void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect);
};
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 4f7683493b..0e2a3c682d 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -1,36 +1,37 @@
-/*************************************************************************/
-/* renderer_viewport.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_viewport.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 "renderer_viewport.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "renderer_canvas_cull.h"
#include "renderer_scene_cull.h"
#include "rendering_server_globals.h"
@@ -115,9 +116,8 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
if (p_viewport->size.width == 0 || p_viewport->size.height == 0) {
p_viewport->render_buffers.unref();
} else {
- const float scaling_3d_scale = p_viewport->scaling_3d_scale;
+ float scaling_3d_scale = p_viewport->scaling_3d_scale;
RS::ViewportScaling3DMode scaling_3d_mode = p_viewport->scaling_3d_mode;
- bool scaling_enabled = true;
if ((scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) && (scaling_3d_scale > 1.0)) {
// FSR is not designed for downsampling.
@@ -133,7 +133,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
}
if (scaling_3d_scale == 1.0) {
- scaling_enabled = false;
+ scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
}
int width;
@@ -141,36 +141,37 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
int render_width;
int render_height;
- if (scaling_enabled) {
- switch (scaling_3d_mode) {
- case RS::VIEWPORT_SCALING_3D_MODE_BILINEAR:
- // Clamp 3D rendering resolution to reasonable values supported on most hardware.
- // This prevents freezing the engine or outright crashing on lower-end GPUs.
- width = CLAMP(p_viewport->size.width * scaling_3d_scale, 1, 16384);
- height = CLAMP(p_viewport->size.height * scaling_3d_scale, 1, 16384);
- render_width = width;
- render_height = height;
- break;
- case RS::VIEWPORT_SCALING_3D_MODE_FSR:
- width = p_viewport->size.width;
- height = p_viewport->size.height;
- render_width = MAX(width * scaling_3d_scale, 1.0); // width / (width * scaling)
- render_height = MAX(height * scaling_3d_scale, 1.0);
- break;
- default:
- // This is an unknown mode.
- WARN_PRINT_ONCE(vformat("Unknown scaling mode: %d. Disabling 3D resolution scaling.", scaling_3d_mode));
- width = p_viewport->size.width;
- height = p_viewport->size.height;
- render_width = width;
- render_height = height;
- break;
- }
- } else {
- width = p_viewport->size.width;
- height = p_viewport->size.height;
- render_width = width;
- render_height = height;
+ switch (scaling_3d_mode) {
+ case RS::VIEWPORT_SCALING_3D_MODE_BILINEAR:
+ // Clamp 3D rendering resolution to reasonable values supported on most hardware.
+ // This prevents freezing the engine or outright crashing on lower-end GPUs.
+ width = CLAMP(p_viewport->size.width * scaling_3d_scale, 1, 16384);
+ height = CLAMP(p_viewport->size.height * scaling_3d_scale, 1, 16384);
+ render_width = width;
+ render_height = height;
+ break;
+ case RS::VIEWPORT_SCALING_3D_MODE_FSR:
+ width = p_viewport->size.width;
+ height = p_viewport->size.height;
+ render_width = MAX(width * scaling_3d_scale, 1.0); // width / (width * scaling)
+ render_height = MAX(height * scaling_3d_scale, 1.0);
+ break;
+ case RS::VIEWPORT_SCALING_3D_MODE_OFF:
+ width = p_viewport->size.width;
+ height = p_viewport->size.height;
+ render_width = width;
+ render_height = height;
+ break;
+ default:
+ // This is an unknown mode.
+ WARN_PRINT_ONCE(vformat("Unknown scaling mode: %d. Disabling 3D resolution scaling.", scaling_3d_mode));
+ scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
+ scaling_3d_scale = 1.0;
+ width = p_viewport->size.width;
+ height = p_viewport->size.height;
+ render_width = width;
+ render_height = height;
+ break;
}
p_viewport->internal_size = Size2(render_width, render_height);
@@ -179,7 +180,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
// to compensate for the loss of sharpness.
const float texture_mipmap_bias = log2f(MIN(scaling_3d_scale, 1.0)) + p_viewport->texture_mipmap_bias;
- p_viewport->render_buffers->configure(p_viewport->render_target, Size2i(render_width, render_height), Size2(width, height), p_viewport->fsr_sharpness, texture_mipmap_bias, p_viewport->msaa_3d, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->view_count);
+ p_viewport->render_buffers->configure(p_viewport->render_target, Size2i(render_width, render_height), Size2(width, height), scaling_3d_mode, p_viewport->fsr_sharpness, texture_mipmap_bias, p_viewport->msaa_3d, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->view_count);
}
}
}
@@ -229,6 +230,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front
int scenario_canvas_max_layer = 0;
+ bool force_clear_render_target = false;
for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_TYPE_MAX; i++) {
for (int j = 0; j < RS::VIEWPORT_RENDER_INFO_MAX; j++) {
@@ -236,11 +238,16 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
}
}
- if (!p_viewport->disable_2d && !p_viewport->disable_environment && RSG::scene->is_scenario(p_viewport->scenario)) {
+ if (RSG::scene->is_scenario(p_viewport->scenario)) {
RID environment = RSG::scene->scenario_get_environment(p_viewport->scenario);
if (RSG::scene->is_environment(environment)) {
- scenario_draw_canvas_bg = RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS;
- scenario_canvas_max_layer = RSG::scene->environment_get_canvas_max_layer(environment);
+ if (!p_viewport->disable_2d && !viewport_is_environment_disabled(p_viewport)) {
+ scenario_draw_canvas_bg = RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS;
+ scenario_canvas_max_layer = RSG::scene->environment_get_canvas_max_layer(environment);
+ } else if (RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS) {
+ // The scene renderer will still copy over the last frame, so we need to clear the render target.
+ force_clear_render_target = true;
+ }
}
}
@@ -263,6 +270,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
}
if (!scenario_draw_canvas_bg && can_draw_3d) {
+ if (force_clear_render_target) {
+ RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
+ }
_draw_3d(p_viewport);
}
@@ -496,6 +506,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
}
if (scenario_draw_canvas_bg && canvas_map.begin() && canvas_map.begin()->key.get_layer() > scenario_canvas_max_layer) {
+ // There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn.
+ // Clear now otherwise we copy over garbage from the render target.
+ RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
if (!can_draw_3d) {
RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas);
} else {
@@ -530,12 +543,15 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
ptr = ptr->filter_next_ptr;
}
- RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel);
+ RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel, p_viewport->canvas_cull_mask);
if (RSG::canvas->was_sdf_used()) {
p_viewport->sdf_active = true;
}
if (scenario_draw_canvas_bg && E.key.get_layer() >= scenario_canvas_max_layer) {
+ // There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn.
+ // Clear now otherwise we copy over garbage from the render target.
+ RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
if (!can_draw_3d) {
RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas);
} else {
@@ -547,6 +563,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
}
if (scenario_draw_canvas_bg) {
+ // There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn.
+ // Clear now otherwise we copy over garbage from the render target.
+ RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
if (!can_draw_3d) {
RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas);
} else {
@@ -614,32 +633,32 @@ void RendererViewport::draw_viewports() {
if (vp->use_xr) {
if (xr_interface.is_valid()) {
+ // Ignore update mode we have to commit frames to our XR interface
+ visible = true;
+
// Override our size, make sure it matches our required size and is created as a stereo target
Size2 xr_size = xr_interface->get_render_target_size();
_viewport_set_size(vp, xr_size.width, xr_size.height, xr_interface->get_view_count());
-
- // Inform xr interface we're about to render its viewport, if this returns false we don't render
- visible = xr_interface->pre_draw_viewport(vp->render_target);
} else {
// don't render anything
visible = false;
vp->size = Size2();
}
- }
-
- if (vp->update_mode == RS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == RS::VIEWPORT_UPDATE_ONCE) {
- visible = true;
- }
-
- if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::texture_storage->render_target_was_used(vp->render_target)) {
- visible = true;
- }
+ } else {
+ if (vp->update_mode == RS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == RS::VIEWPORT_UPDATE_ONCE) {
+ visible = true;
+ }
- if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE) {
- Viewport *parent = viewport_owner.get_or_null(vp->parent);
- if (parent && parent->last_pass == draw_viewports_pass) {
+ if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::texture_storage->render_target_was_used(vp->render_target)) {
visible = true;
}
+
+ if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE) {
+ Viewport *parent = viewport_owner.get_or_null(vp->parent);
+ if (parent && parent->last_pass == draw_viewports_pass) {
+ visible = true;
+ }
+ }
}
visible = visible && vp->size.x > 1 && vp->size.y > 1;
@@ -664,40 +683,43 @@ void RendererViewport::draw_viewports() {
RSG::texture_storage->render_target_set_as_unused(vp->render_target);
if (vp->use_xr && xr_interface.is_valid()) {
- RSG::texture_storage->render_target_set_override_color(vp->render_target, xr_interface->get_color_texture());
- RSG::texture_storage->render_target_set_override_depth(vp->render_target, xr_interface->get_depth_texture());
- RSG::texture_storage->render_target_set_override_velocity(vp->render_target, xr_interface->get_velocity_texture());
-
- // render...
- RSG::scene->set_debug_draw_mode(vp->debug_draw);
-
- // and draw viewport
- _draw_viewport(vp);
-
- // measure
-
- // commit our eyes
- Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect);
- if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID) {
- if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") {
- if (blits.size() > 0) {
- RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size());
- }
- RSG::rasterizer->end_frame(true);
- } else if (blits.size() > 0) {
- if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
- blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
- }
+ // Inform XR interface we're about to render its viewport,
+ // if this returns false we don't render.
+ // This usually is a result of the player taking off their headset and OpenXR telling us to skip
+ // rendering frames.
+ if (xr_interface->pre_draw_viewport(vp->render_target)) {
+ RSG::texture_storage->render_target_set_override(vp->render_target,
+ xr_interface->get_color_texture(),
+ xr_interface->get_depth_texture(),
+ xr_interface->get_velocity_texture());
+
+ // render...
+ RSG::scene->set_debug_draw_mode(vp->debug_draw);
+
+ // and draw viewport
+ _draw_viewport(vp);
+
+ // commit our eyes
+ Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect);
+ if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID) {
+ if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") {
+ if (blits.size() > 0) {
+ RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size());
+ }
+ RSG::rasterizer->end_frame(true);
+ } else if (blits.size() > 0) {
+ if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
+ blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
+ }
- for (int b = 0; b < blits.size(); b++) {
- blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
+ for (int b = 0; b < blits.size(); b++) {
+ blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
+ }
}
}
}
} else {
- RSG::texture_storage->render_target_set_override_color(vp->render_target, RID()); // TODO if fullscreen output, we can set this to our texture chain
- RSG::texture_storage->render_target_set_override_depth(vp->render_target, RID());
- RSG::texture_storage->render_target_set_override_velocity(vp->render_target, RID());
+ RSG::texture_storage->render_target_set_override(vp->render_target, RID(), RID(), RID());
RSG::scene->set_debug_draw_mode(vp->debug_draw);
@@ -832,7 +854,7 @@ void RendererViewport::viewport_set_scaling_3d_scale(RID p_viewport, float p_sca
}
void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
- ERR_FAIL_COND(p_width < 0 && p_height < 0);
+ ERR_FAIL_COND(p_width < 0 || p_height < 0);
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -980,11 +1002,21 @@ void RendererViewport::viewport_set_disable_2d(RID p_viewport, bool p_disable) {
viewport->disable_2d = p_disable;
}
-void RendererViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) {
+void RendererViewport::viewport_set_environment_mode(RID p_viewport, RS::ViewportEnvironmentMode p_mode) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
- viewport->disable_environment = p_disable;
+ viewport->disable_environment = p_mode;
+}
+
+bool RendererViewport::viewport_is_environment_disabled(Viewport *viewport) {
+ ERR_FAIL_COND_V(!viewport, false);
+
+ if (viewport->parent.is_valid() && viewport->disable_environment == RS::VIEWPORT_ENVIRONMENT_INHERIT) {
+ Viewport *parent = viewport_owner.get_or_null(viewport->parent);
+ return viewport_is_environment_disabled(parent);
+ }
+ return viewport->disable_environment == RS::VIEWPORT_ENVIRONMENT_DISABLED;
}
void RendererViewport::viewport_set_disable_3d(RID p_viewport, bool p_disable) {
@@ -1126,6 +1158,7 @@ void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::Viewport
void RendererViewport::viewport_set_use_taa(RID p_viewport, bool p_use_taa) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
+ ERR_FAIL_COND_EDMSG(OS::get_singleton()->get_current_rendering_method() != "forward_plus", "TAA is only available when using the Forward+ renderer.");
if (viewport->use_taa == p_use_taa) {
return;
@@ -1349,6 +1382,12 @@ void RendererViewport::set_default_clear_color(const Color &p_color) {
RSG::texture_storage->set_default_clear_color(p_color);
}
+void RendererViewport::viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) {
+ Viewport *viewport = viewport_owner.get_or_null(p_viewport);
+ ERR_FAIL_COND(!viewport);
+ viewport->canvas_cull_mask = p_canvas_cull_mask;
+}
+
// Workaround for setting this on thread.
void RendererViewport::call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window) {
DisplayServer::get_singleton()->window_set_vsync_mode(p_mode, p_window);
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index 55058a30b8..c24275de6e 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* renderer_viewport.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* renderer_viewport.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 RENDERER_VIEWPORT_H
#define RENDERER_VIEWPORT_H
@@ -85,7 +85,7 @@ public:
bool viewport_render_direct_to_screen;
bool disable_2d = false;
- bool disable_environment = false;
+ RS::ViewportEnvironmentMode disable_environment = RS::VIEWPORT_ENVIRONMENT_INHERIT;
bool disable_3d = false;
bool measure_render_time = false;
@@ -117,6 +117,8 @@ public:
bool transparent_bg = false;
+ uint32_t canvas_cull_mask = 0xffffffff;
+
struct CanvasKey {
int64_t stacking;
RID canvas;
@@ -236,9 +238,11 @@ public:
const RendererSceneRender::CameraData *viewport_get_prev_camera_data(RID p_viewport);
void viewport_set_disable_2d(RID p_viewport, bool p_disable);
- void viewport_set_disable_environment(RID p_viewport, bool p_disable);
+ void viewport_set_environment_mode(RID p_viewport, RS::ViewportEnvironmentMode p_mode);
void viewport_set_disable_3d(RID p_viewport, bool p_disable);
+ bool viewport_is_environment_disabled(Viewport *viewport);
+
void viewport_attach_camera(RID p_viewport, RID p_camera);
void viewport_set_scenario(RID p_viewport, RID p_scenario);
void viewport_attach_canvas(RID p_viewport, RID p_canvas);
@@ -249,6 +253,8 @@ public:
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
+ void viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask);
+
void viewport_set_positional_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true);
void viewport_set_positional_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index dd190437a3..286d1b683f 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -1,39 +1,49 @@
-/*************************************************************************/
-/* rendering_device.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_device.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 "rendering_device.h"
#include "rendering_device_binds.h"
+#include "thirdparty/spirv-reflect/spirv_reflect.h"
+
RenderingDevice *RenderingDevice::singleton = nullptr;
+const char *RenderingDevice::shader_stage_names[RenderingDevice::SHADER_STAGE_MAX] = {
+ "Vertex",
+ "Fragment",
+ "TesselationControl",
+ "TesselationEvaluation",
+ "Compute",
+};
+
RenderingDevice *RenderingDevice::get_singleton() {
return singleton;
}
@@ -170,10 +180,16 @@ RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const Typ
return vertex_format_create(descriptions);
}
-RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) {
+RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers, const Vector<int64_t> &p_offsets) {
Vector<RID> buffers = Variant(p_src_buffers);
- return vertex_array_create(p_vertex_count, p_vertex_format, buffers);
+ Vector<uint64_t> offsets;
+ offsets.resize(p_offsets.size());
+ for (int i = 0; i < p_offsets.size(); i++) {
+ offsets.write[i] = p_offsets[i];
+ }
+
+ return vertex_array_create(p_vertex_count, p_vertex_format, buffers, offsets);
}
Ref<RDShaderSPIRV> RenderingDevice::_shader_compile_spirv_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) {
@@ -246,7 +262,7 @@ RID RenderingDevice::_uniform_set_create(const TypedArray<RDUniform> &p_uniforms
return uniform_set_create(uniforms, p_shader, p_shader_set);
}
-Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier) {
+Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier) {
return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier);
}
@@ -280,7 +296,7 @@ static Vector<RenderingDevice::PipelineSpecializationConstant> _get_spec_constan
return ret;
}
-RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants) {
+RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants) {
PipelineRasterizationState rasterization_state;
if (p_rasterization_state.is_valid()) {
rasterization_state = p_rasterization_state->base;
@@ -362,12 +378,329 @@ void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, cons
compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
}
+Error RenderingDevice::_reflect_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, SpirvReflectionData &r_reflection_data) {
+ r_reflection_data = {};
+
+ for (int i = 0; i < p_spirv.size(); i++) {
+ ShaderStage stage = p_spirv[i].shader_stage;
+ ShaderStage stage_flag = (ShaderStage)(1 << p_spirv[i].shader_stage);
+
+ if (p_spirv[i].shader_stage == SHADER_STAGE_COMPUTE) {
+ r_reflection_data.is_compute = true;
+ ERR_FAIL_COND_V_MSG(p_spirv.size() != 1, FAILED,
+ "Compute shaders can only receive one stage, dedicated to compute.");
+ }
+ ERR_FAIL_COND_V_MSG(r_reflection_data.stages_mask.has_flag(stage_flag), FAILED,
+ "Stage " + String(shader_stage_names[p_spirv[i].shader_stage]) + " submitted more than once.");
+
+ {
+ SpvReflectShaderModule module;
+ const uint8_t *spirv = p_spirv[i].spir_v.ptr();
+ SpvReflectResult result = spvReflectCreateShaderModule(p_spirv[i].spir_v.size(), spirv, &module);
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed parsing shader.");
+
+ if (r_reflection_data.is_compute) {
+ r_reflection_data.compute_local_size[0] = module.entry_points->local_size.x;
+ r_reflection_data.compute_local_size[1] = module.entry_points->local_size.y;
+ r_reflection_data.compute_local_size[2] = module.entry_points->local_size.z;
+ }
+ uint32_t binding_count = 0;
+ result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr);
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating descriptor bindings.");
+
+ if (binding_count > 0) {
+ // Parse bindings.
+
+ Vector<SpvReflectDescriptorBinding *> bindings;
+ bindings.resize(binding_count);
+ result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.ptrw());
+
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings.");
+
+ for (uint32_t j = 0; j < binding_count; j++) {
+ const SpvReflectDescriptorBinding &binding = *bindings[j];
+
+ SpirvReflectionData::Uniform info{};
+
+ bool need_array_dimensions = false;
+ bool need_block_size = false;
+ bool may_be_writable = false;
+
+ switch (binding.descriptor_type) {
+ case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: {
+ info.type = UNIFORM_TYPE_SAMPLER;
+ need_array_dimensions = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
+ info.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ need_array_dimensions = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
+ info.type = UNIFORM_TYPE_TEXTURE;
+ need_array_dimensions = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
+ info.type = UNIFORM_TYPE_IMAGE;
+ need_array_dimensions = true;
+ may_be_writable = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
+ info.type = UNIFORM_TYPE_TEXTURE_BUFFER;
+ need_array_dimensions = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
+ info.type = UNIFORM_TYPE_IMAGE_BUFFER;
+ need_array_dimensions = true;
+ may_be_writable = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
+ info.type = UNIFORM_TYPE_UNIFORM_BUFFER;
+ need_block_size = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
+ info.type = UNIFORM_TYPE_STORAGE_BUFFER;
+ need_block_size = true;
+ may_be_writable = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
+ ERR_PRINT("Dynamic uniform buffer not supported.");
+ continue;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
+ ERR_PRINT("Dynamic storage buffer not supported.");
+ continue;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
+ info.type = UNIFORM_TYPE_INPUT_ATTACHMENT;
+ need_array_dimensions = true;
+ } break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
+ ERR_PRINT("Acceleration structure not supported.");
+ continue;
+ } break;
+ }
+
+ if (need_array_dimensions) {
+ if (binding.array.dims_count == 0) {
+ info.length = 1;
+ } else {
+ for (uint32_t k = 0; k < binding.array.dims_count; k++) {
+ if (k == 0) {
+ info.length = binding.array.dims[0];
+ } else {
+ info.length *= binding.array.dims[k];
+ }
+ }
+ }
+
+ } else if (need_block_size) {
+ info.length = binding.block.size;
+ } else {
+ info.length = 0;
+ }
+
+ if (may_be_writable) {
+ info.writable = !(binding.type_description->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
+ } else {
+ info.writable = false;
+ }
+
+ info.binding = binding.binding;
+ uint32_t set = binding.set;
+
+ ERR_FAIL_COND_V_MSG(set >= MAX_UNIFORM_SETS, FAILED,
+ "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ").");
+
+ if (set < (uint32_t)r_reflection_data.uniforms.size()) {
+ // Check if this already exists.
+ bool exists = false;
+ for (int k = 0; k < r_reflection_data.uniforms[set].size(); k++) {
+ if (r_reflection_data.uniforms[set][k].binding == (uint32_t)info.binding) {
+ // Already exists, verify that it's the same type.
+ ERR_FAIL_COND_V_MSG(r_reflection_data.uniforms[set][k].type != info.type, FAILED,
+ "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform type.");
+
+ // Also, verify that it's the same size.
+ ERR_FAIL_COND_V_MSG(r_reflection_data.uniforms[set][k].length != info.length, FAILED,
+ "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform size.");
+
+ // Also, verify that it has the same writability.
+ ERR_FAIL_COND_V_MSG(r_reflection_data.uniforms[set][k].writable != info.writable, FAILED,
+ "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different writability.");
+
+ // Just append stage mask and return.
+ r_reflection_data.uniforms.write[set].write[k].stages_mask.set_flag(stage_flag);
+ exists = true;
+ break;
+ }
+ }
+
+ if (exists) {
+ continue; // Merged.
+ }
+ }
+
+ info.stages_mask.set_flag(stage_flag);
+
+ if (set >= (uint32_t)r_reflection_data.uniforms.size()) {
+ r_reflection_data.uniforms.resize(set + 1);
+ }
+
+ r_reflection_data.uniforms.write[set].push_back(info);
+ }
+ }
+
+ {
+ // Specialization constants.
+
+ uint32_t sc_count = 0;
+ result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr);
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating specialization constants.");
+
+ if (sc_count) {
+ Vector<SpvReflectSpecializationConstant *> spec_constants;
+ spec_constants.resize(sc_count);
+
+ result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw());
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining specialization constants.");
+
+ for (uint32_t j = 0; j < sc_count; j++) {
+ int32_t existing = -1;
+ SpirvReflectionData::SpecializationConstant sconst{};
+ SpvReflectSpecializationConstant *spc = spec_constants[j];
+
+ sconst.constant_id = spc->constant_id;
+ sconst.int_value = 0; // Clear previous value JIC.
+ switch (spc->constant_type) {
+ case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: {
+ sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ sconst.bool_value = spc->default_value.int_bool_value != 0;
+ } break;
+ case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: {
+ sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
+ sconst.int_value = spc->default_value.int_bool_value;
+ } break;
+ case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: {
+ sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
+ sconst.float_value = spc->default_value.float_value;
+ } break;
+ }
+ sconst.stages_mask.set_flag(stage_flag);
+
+ for (int k = 0; k < r_reflection_data.specialization_constants.size(); k++) {
+ if (r_reflection_data.specialization_constants[k].constant_id == sconst.constant_id) {
+ ERR_FAIL_COND_V_MSG(r_reflection_data.specialization_constants[k].type != sconst.type, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their types differ.");
+ ERR_FAIL_COND_V_MSG(r_reflection_data.specialization_constants[k].int_value != sconst.int_value, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their default values differ.");
+ existing = k;
+ break;
+ }
+ }
+
+ if (existing > 0) {
+ r_reflection_data.specialization_constants.write[existing].stages_mask.set_flag(stage_flag);
+ } else {
+ r_reflection_data.specialization_constants.push_back(sconst);
+ }
+ }
+ }
+ }
+
+ if (stage == SHADER_STAGE_VERTEX) {
+ uint32_t iv_count = 0;
+ result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr);
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating input variables.");
+
+ if (iv_count) {
+ Vector<SpvReflectInterfaceVariable *> input_vars;
+ input_vars.resize(iv_count);
+
+ result = spvReflectEnumerateInputVariables(&module, &iv_count, input_vars.ptrw());
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining input variables.");
+
+ for (uint32_t j = 0; j < iv_count; j++) {
+ if (input_vars[j] && input_vars[j]->decoration_flags == 0) { // Regular input.
+ r_reflection_data.vertex_input_mask |= (1 << uint32_t(input_vars[j]->location));
+ }
+ }
+ }
+ }
+
+ if (stage == SHADER_STAGE_FRAGMENT) {
+ uint32_t ov_count = 0;
+ result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr);
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating output variables.");
+
+ if (ov_count) {
+ Vector<SpvReflectInterfaceVariable *> output_vars;
+ output_vars.resize(ov_count);
+
+ result = spvReflectEnumerateOutputVariables(&module, &ov_count, output_vars.ptrw());
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining output variables.");
+
+ for (uint32_t j = 0; j < ov_count; j++) {
+ const SpvReflectInterfaceVariable *refvar = output_vars[j];
+ if (refvar != nullptr && refvar->built_in != SpvBuiltInFragDepth) {
+ r_reflection_data.fragment_output_mask |= 1 << refvar->location;
+ }
+ }
+ }
+ }
+
+ uint32_t pc_count = 0;
+ result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr);
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating push constants.");
+
+ if (pc_count) {
+ ERR_FAIL_COND_V_MSG(pc_count > 1, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "': Only one push constant is supported, which should be the same across shader stages.");
+
+ Vector<SpvReflectBlockVariable *> pconstants;
+ pconstants.resize(pc_count);
+ result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, pconstants.ptrw());
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining push constants.");
+#if 0
+ if (pconstants[0] == nullptr) {
+ Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE);
+ f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t));
+ }
+#endif
+
+ ERR_FAIL_COND_V_MSG(r_reflection_data.push_constant_size && r_reflection_data.push_constant_size != pconstants[0]->size, FAILED,
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "': Push constant block must be the same across shader stages.");
+
+ r_reflection_data.push_constant_size = pconstants[0]->size;
+ r_reflection_data.push_constant_stages_mask.set_flag(stage_flag);
+
+ //print_line("Stage: " + String(shader_stage_names[stage]) + " push constant of size=" + itos(push_constant.push_constant_size));
+ }
+
+ // Destroy the reflection data when no longer required.
+ spvReflectDestroyShaderModule(&module);
+ }
+
+ r_reflection_data.stages_mask.set_flag(stage_flag);
+ }
+
+ return OK;
+}
+
void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared);
ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "mipmaps", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(1), DEFVAL(TEXTURE_SLICE_2D));
- ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::texture_update, DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::texture_update, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data);
ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage);
@@ -375,9 +708,9 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared);
ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid);
- ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "post_barrier"), &RenderingDevice::texture_copy, DEFVAL(BARRIER_MASK_ALL));
- ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL));
- ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "post_barrier"), &RenderingDevice::texture_copy, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
+ ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
+ ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments", "view_count"), &RenderingDevice::_framebuffer_format_create, DEFVAL(1));
ClassDB::bind_method(D_METHOD("framebuffer_format_create_multipass", "attachments", "passes", "view_count"), &RenderingDevice::_framebuffer_format_create_multipass, DEFVAL(1));
@@ -393,6 +726,7 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data", "use_as_storage"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create);
+ ClassDB::bind_method(D_METHOD("vertex_array_create", "vertex_count", "vertex_format", "src_buffers", "offsets"), &RenderingDevice::_vertex_array_create, DEFVAL(Vector<int64_t>()));
ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data", "use_restart_indices"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create);
@@ -410,9 +744,9 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create);
ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid);
- ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update, DEFVAL(BARRIER_MASK_ALL));
- ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL));
- ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
+ ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
+ ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
+ ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer", "offset_bytes", "size_bytes"), &RenderingDevice::buffer_get_data, DEFVAL(0), DEFVAL(0));
ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass", "specialization_constants"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0), DEFVAL(TypedArray<RDPipelineSpecializationConstant>()));
ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
@@ -444,7 +778,7 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_list_switch_to_next_pass"), &RenderingDevice::draw_list_switch_to_next_pass);
ClassDB::bind_method(D_METHOD("draw_list_switch_to_next_pass_split", "splits"), &RenderingDevice::_draw_list_switch_to_next_pass_split);
- ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
ClassDB::bind_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::compute_list_begin, DEFVAL(false));
ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline);
@@ -452,7 +786,7 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set);
ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch);
ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier);
- ClassDB::bind_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::compute_list_end, DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::compute_list_end, DEFVAL(BARRIER_MASK_ALL_BARRIERS));
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingDevice::free);
@@ -468,7 +802,7 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit);
ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync);
- ClassDB::bind_method(D_METHOD("barrier", "from", "to"), &RenderingDevice::barrier, DEFVAL(BARRIER_MASK_ALL), DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("barrier", "from", "to"), &RenderingDevice::barrier, DEFVAL(BARRIER_MASK_ALL_BARRIERS), DEFVAL(BARRIER_MASK_ALL_BARRIERS));
ClassDB::bind_method(D_METHOD("full_barrier"), &RenderingDevice::full_barrier);
ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device);
@@ -487,12 +821,6 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_driver_resource", "resource", "rid", "index"), &RenderingDevice::get_driver_resource);
- BIND_CONSTANT(BARRIER_MASK_RASTER);
- BIND_CONSTANT(BARRIER_MASK_COMPUTE);
- BIND_CONSTANT(BARRIER_MASK_TRANSFER);
- BIND_CONSTANT(BARRIER_MASK_ALL);
- BIND_CONSTANT(BARRIER_MASK_NO_BARRIER);
-
BIND_ENUM_CONSTANT(DEVICE_TYPE_OTHER);
BIND_ENUM_CONSTANT(DEVICE_TYPE_INTEGRATED_GPU);
BIND_ENUM_CONSTANT(DEVICE_TYPE_DISCRETE_GPU);
@@ -734,6 +1062,12 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM);
BIND_ENUM_CONSTANT(DATA_FORMAT_MAX);
+ BIND_BITFIELD_FLAG(BARRIER_MASK_RASTER);
+ BIND_BITFIELD_FLAG(BARRIER_MASK_COMPUTE);
+ BIND_BITFIELD_FLAG(BARRIER_MASK_TRANSFER);
+ BIND_BITFIELD_FLAG(BARRIER_MASK_ALL_BARRIERS);
+ BIND_BITFIELD_FLAG(BARRIER_MASK_NO_BARRIER);
+
BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D);
BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D);
BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D);
@@ -752,16 +1086,16 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64);
BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_INPUT_ATTACHMENT_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_SAMPLING_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CPU_READ_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_UPDATE_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_COPY_FROM_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_COPY_TO_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_INPUT_ATTACHMENT_BIT);
BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY);
BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO);
@@ -799,7 +1133,7 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16);
BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32);
- BIND_ENUM_CONSTANT(STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);
+ BIND_BITFIELD_FLAG(STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);
BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type)
BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture
@@ -899,13 +1233,13 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM);
BIND_ENUM_CONSTANT(BLEND_OP_MAX);
- BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH);
- BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS);
- BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS);
- BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS);
- BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK);
- BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK);
- BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE);
+ BIND_BITFIELD_FLAG(DYNAMIC_STATE_LINE_WIDTH);
+ BIND_BITFIELD_FLAG(DYNAMIC_STATE_DEPTH_BIAS);
+ BIND_BITFIELD_FLAG(DYNAMIC_STATE_BLEND_CONSTANTS);
+ BIND_BITFIELD_FLAG(DYNAMIC_STATE_DEPTH_BOUNDS);
+ BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_COMPARE_MASK);
+ BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_WRITE_MASK);
+ BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_REFERENCE);
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params)
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params)
@@ -974,6 +1308,8 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X);
BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y);
BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VIEWPORT_DIMENSIONS_X);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VIEWPORT_DIMENSIONS_Y);
BIND_ENUM_CONSTANT(MEMORY_TEXTURES);
BIND_ENUM_CONSTANT(MEMORY_BUFFERS);
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index ca30a30786..447627b08e 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rendering_device.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_device.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 RENDERING_DEVICE_H
#define RENDERING_DEVICE_H
@@ -396,8 +396,8 @@ public:
BARRIER_MASK_RASTER = 1,
BARRIER_MASK_COMPUTE = 2,
BARRIER_MASK_TRANSFER = 4,
+ BARRIER_MASK_ALL_BARRIERS = BARRIER_MASK_RASTER | BARRIER_MASK_COMPUTE | BARRIER_MASK_TRANSFER, // 7
BARRIER_MASK_NO_BARRIER = 8,
- BARRIER_MASK_ALL = BARRIER_MASK_RASTER | BARRIER_MASK_COMPUTE | BARRIER_MASK_TRANSFER
};
/*****************/
@@ -530,19 +530,19 @@ public:
TEXTURE_SLICE_2D_ARRAY,
};
- virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0;
+ virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D, uint32_t p_layers = 0) = 0;
- virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
- virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0;
+ virtual bool texture_is_format_supported_for_usage(DataFormat p_format, BitField<RenderingDevice::TextureUsageBits> p_usage) const = 0;
virtual bool texture_is_shared(RID p_texture) = 0;
virtual bool texture_is_valid(RID p_texture) = 0;
virtual Size2i texture_size(RID p_texture) = 0;
- virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
- virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
- virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
+ virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
+ virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
/*********************/
/**** FRAMEBUFFER ****/
@@ -683,7 +683,7 @@ public:
// This ID is warranted to be unique for the same formats, does not need to be freed
virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0;
- virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0;
+ virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers, const Vector<uint64_t> &p_offsets = Vector<uint64_t>()) = 0;
enum IndexBufferFormat {
INDEX_BUFFER_FORMAT_UINT16,
@@ -749,11 +749,11 @@ public:
};
enum StorageBufferUsage {
- STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT = 1
+ STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT = 1,
};
virtual RID uniform_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>()) = 0;
- virtual RID storage_buffer_create(uint32_t p_size, const Vector<uint8_t> &p_data = Vector<uint8_t>(), uint32_t p_usage = 0) = 0;
+ virtual RID storage_buffer_create(uint32_t p_size, const Vector<uint8_t> &p_data = Vector<uint8_t>(), BitField<StorageBufferUsage> p_usage = 0) = 0;
virtual RID texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>()) = 0;
struct Uniform {
@@ -826,9 +826,9 @@ public:
virtual bool uniform_set_is_valid(RID p_uniform_set) = 0;
virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata) = 0;
- virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
- virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
- virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving
+ virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
+ virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
+ virtual Vector<uint8_t> buffer_get_data(RID p_buffer, uint32_t p_offset = 0, uint32_t p_size = 0) = 0; // This causes stall, only use to retrieve large buffers for saving.
/******************************************/
/**** PIPELINE SPECIALIZATION CONSTANT ****/
@@ -1112,7 +1112,7 @@ public:
};
virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
- virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0;
+ virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0;
/**************************/
/**** COMPUTE PIPELINE ****/
@@ -1173,7 +1173,7 @@ public:
virtual DrawListID draw_list_switch_to_next_pass() = 0;
virtual Error draw_list_switch_to_next_pass_split(uint32_t p_splits, DrawListID *r_split_ids) = 0;
- virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual void draw_list_end(BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
/***********************/
/**** COMPUTE LISTS ****/
@@ -1190,9 +1190,9 @@ public:
virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) = 0;
virtual void compute_list_add_barrier(ComputeListID p_list) = 0;
- virtual void compute_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual void compute_list_end(BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
- virtual void barrier(uint32_t p_from = BARRIER_MASK_ALL, uint32_t p_to = BARRIER_MASK_ALL) = 0;
+ virtual void barrier(BitField<BarrierMask> p_from = BARRIER_MASK_ALL_BARRIERS, BitField<BarrierMask> p_to = BARRIER_MASK_ALL_BARRIERS) = 0;
virtual void full_barrier() = 0;
/***************/
@@ -1252,9 +1252,13 @@ public:
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X,
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y,
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z,
+ LIMIT_MAX_VIEWPORT_DIMENSIONS_X,
+ LIMIT_MAX_VIEWPORT_DIMENSIONS_Y,
LIMIT_SUBGROUP_SIZE,
LIMIT_SUBGROUP_IN_SHADERS, // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
LIMIT_SUBGROUP_OPERATIONS,
+ LIMIT_VRS_TEXEL_WIDTH,
+ LIMIT_VRS_TEXEL_HEIGHT,
};
virtual uint64_t limit_get(Limit p_limit) const = 0;
@@ -1297,6 +1301,10 @@ public:
RenderingDevice();
protected:
+ static const char *shader_stage_names[RenderingDevice::SHADER_STAGE_MAX];
+
+ static const uint32_t MAX_UNIFORM_SETS = 16;
+
//binders to script API
RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array());
RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture);
@@ -1308,7 +1316,7 @@ protected:
RID _framebuffer_create_multipass(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
RID _sampler_create(const Ref<RDSamplerState> &p_state);
VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats);
- RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers);
+ RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers, const Vector<int64_t> &p_offsets = Vector<int64_t>());
Ref<RDShaderSPIRV> _shader_compile_spirv_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true);
Vector<uint8_t> _shader_compile_binary_from_spirv(const Ref<RDShaderSPIRV> &p_bytecode, const String &p_shader_name = "");
@@ -1316,15 +1324,48 @@ protected:
RID _uniform_set_create(const TypedArray<RDUniform> &p_uniforms, RID p_shader, uint32_t p_shader_set);
- Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
+ Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS);
- RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
+ RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
RID _compute_pipeline_create(RID p_shader, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>());
void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
Vector<int64_t> _draw_list_switch_to_next_pass_split(uint32_t p_splits);
+
+ struct SpirvReflectionData {
+ BitField<ShaderStage> stages_mask;
+ uint32_t vertex_input_mask;
+ uint32_t fragment_output_mask;
+ bool is_compute;
+ uint32_t compute_local_size[3];
+ uint32_t push_constant_size;
+ BitField<ShaderStage> push_constant_stages_mask;
+
+ struct Uniform {
+ UniformType type;
+ uint32_t binding;
+ BitField<ShaderStage> stages_mask;
+ uint32_t length; // Size of arrays (in total elements), or ubos (in bytes * total elements).
+ bool writable;
+ };
+ Vector<Vector<Uniform>> uniforms;
+
+ struct SpecializationConstant {
+ PipelineSpecializationConstantType type;
+ uint32_t constant_id;
+ union {
+ uint32_t int_value;
+ float float_value;
+ bool bool_value;
+ };
+ BitField<ShaderStage> stages_mask;
+ };
+ Vector<SpecializationConstant> specialization_constants;
+ };
+
+ Error _reflect_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, SpirvReflectionData &r_reflection_data);
};
VARIANT_ENUM_CAST(RenderingDevice::DeviceType)
@@ -1333,9 +1374,10 @@ VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage)
VARIANT_ENUM_CAST(RenderingDevice::CompareOperator)
VARIANT_ENUM_CAST(RenderingDevice::DataFormat)
+VARIANT_BITFIELD_CAST(RenderingDevice::BarrierMask);
VARIANT_ENUM_CAST(RenderingDevice::TextureType)
VARIANT_ENUM_CAST(RenderingDevice::TextureSamples)
-VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits)
+VARIANT_BITFIELD_CAST(RenderingDevice::TextureUsageBits)
VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle)
VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType)
VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter)
@@ -1343,7 +1385,7 @@ VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode)
VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor)
VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency)
VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat)
-VARIANT_ENUM_CAST(RenderingDevice::StorageBufferUsage)
+VARIANT_BITFIELD_CAST(RenderingDevice::StorageBufferUsage)
VARIANT_ENUM_CAST(RenderingDevice::UniformType)
VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive)
VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode)
@@ -1352,7 +1394,7 @@ VARIANT_ENUM_CAST(RenderingDevice::StencilOperation)
VARIANT_ENUM_CAST(RenderingDevice::LogicOperation)
VARIANT_ENUM_CAST(RenderingDevice::BlendFactor)
VARIANT_ENUM_CAST(RenderingDevice::BlendOperation)
-VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags)
+VARIANT_BITFIELD_CAST(RenderingDevice::PipelineDynamicStateFlags)
VARIANT_ENUM_CAST(RenderingDevice::PipelineSpecializationConstantType)
VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp
index d03c4e0427..3678b70254 100644
--- a/servers/rendering/rendering_device_binds.cpp
+++ b/servers/rendering/rendering_device_binds.cpp
@@ -1,36 +1,38 @@
-/*************************************************************************/
-/* rendering_device_binds.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_device_binds.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 "rendering_device_binds.h"
Error RDShaderFile::parse_versions_from_text(const String &p_text, const String p_defines, OpenIncludeFunction p_include_func, void *p_include_func_userdata) {
+ ERR_FAIL_NULL_V(RenderingDevice::get_singleton(), ERR_UNAVAILABLE);
+
Vector<String> lines = p_text.split("\n");
bool reading_versions = false;
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index c710bd0a10..01d0f178c7 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rendering_device_binds.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_device_binds.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 RENDERING_DEVICE_BINDS_H
#define RENDERING_DEVICE_BINDS_H
@@ -66,7 +66,7 @@ public:
RD_SETGET(uint32_t, mipmaps)
RD_SETGET(RD::TextureType, texture_type)
RD_SETGET(RD::TextureSamples, samples)
- RD_SETGET(uint32_t, usage_bits)
+ RD_SETGET(BitField<RenderingDevice::TextureUsageBits>, usage_bits)
void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); }
void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); }
diff --git a/servers/rendering/rendering_method.cpp b/servers/rendering/rendering_method.cpp
index 16a4e35ad3..d4737966c6 100644
--- a/servers/rendering/rendering_method.cpp
+++ b/servers/rendering/rendering_method.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rendering_method.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_method.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 "rendering_method.h"
diff --git a/servers/rendering/rendering_method.h b/servers/rendering/rendering_method.h
index c4d9e25ecd..f705603a1c 100644
--- a/servers/rendering/rendering_method.h
+++ b/servers/rendering/rendering_method.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rendering_method.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_method.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 RENDERING_METHOD_H
#define RENDERING_METHOD_H
@@ -72,6 +72,7 @@ public:
virtual void instance_set_base(RID p_instance, RID p_base) = 0;
virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0;
virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask) = 0;
+ virtual void instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center) = 0;
virtual void instance_set_transform(RID p_instance, const Transform3D &p_transform) = 0;
virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id) = 0;
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0;
@@ -203,7 +204,6 @@ public:
virtual RID environment_get_glow_map(RID p_env) const = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
- virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
// SSR
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 9103b0cf56..6017eff55e 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rendering_server_default.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_server_default.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 "rendering_server_default.h"
@@ -291,6 +291,10 @@ void RenderingServerDefault::set_boot_image(const Ref<Image> &p_image, const Col
RSG::rasterizer->set_boot_image(p_image, p_color, p_scale, p_use_filter);
}
+Color RenderingServerDefault::get_default_clear_color() {
+ return RSG::texture_storage->get_default_clear_color();
+}
+
void RenderingServerDefault::set_default_clear_color(const Color &p_color) {
RSG::viewport->set_default_clear_color(p_color);
}
@@ -331,6 +335,14 @@ bool RenderingServerDefault::is_low_end() const {
return RendererCompositor::is_low_end();
}
+Size2i RenderingServerDefault::get_maximum_viewport_size() const {
+ if (RSG::utilities) {
+ return RSG::utilities->get_maximum_viewport_size();
+ } else {
+ return Size2i();
+ }
+}
+
void RenderingServerDefault::_thread_exit() {
exit.set();
}
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index fe212151e3..a3bdf7d146 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -1,36 +1,37 @@
-/*************************************************************************/
-/* rendering_server_default.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_server_default.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 RENDERING_SERVER_DEFAULT_H
#define RENDERING_SERVER_DEFAULT_H
+#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
#include "core/templates/hash_map.h"
#include "renderer_canvas_cull.h"
@@ -212,6 +213,7 @@ public:
FUNC1(texture_debug_usage, List<TextureInfo> *)
FUNC2(texture_set_force_redraw_if_visible, RID, bool)
+ FUNC2RC(RID, texture_get_rd_texture_rid, RID, bool)
/* SHADER API */
@@ -386,7 +388,7 @@ public:
FUNC2(reflection_probe_set_ambient_energy, RID, float)
FUNC2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode)
FUNC2(reflection_probe_set_max_distance, RID, float)
- FUNC2(reflection_probe_set_extents, RID, const Vector3 &)
+ FUNC2(reflection_probe_set_size, RID, const Vector3 &)
FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &)
FUNC2(reflection_probe_set_as_interior, RID, bool)
FUNC2(reflection_probe_set_enable_box_projection, RID, bool)
@@ -427,7 +429,7 @@ public:
FUNCRIDSPLIT(decal)
- FUNC2(decal_set_extents, RID, const Vector3 &)
+ FUNC2(decal_set_size, RID, const Vector3 &)
FUNC3(decal_set_texture, RID, DecalTexture, RID)
FUNC2(decal_set_emission_energy, RID, float)
FUNC2(decal_set_albedo_mix, RID, float)
@@ -539,7 +541,7 @@ public:
FUNCRIDSPLIT(fog_volume)
FUNC2(fog_volume_set_shape, RID, FogVolumeShape)
- FUNC2(fog_volume_set_extents, RID, const Vector3 &)
+ FUNC2(fog_volume_set_size, RID, const Vector3 &)
FUNC2(fog_volume_set_material, RID, RID)
/* VISIBILITY_NOTIFIER */
@@ -607,9 +609,11 @@ public:
FUNC1RC(RID, viewport_get_texture, RID)
FUNC2(viewport_set_disable_2d, RID, bool)
- FUNC2(viewport_set_disable_environment, RID, bool)
+ FUNC2(viewport_set_environment_mode, RID, ViewportEnvironmentMode)
FUNC2(viewport_set_disable_3d, RID, bool)
+ FUNC2(viewport_set_canvas_cull_mask, RID, uint32_t)
+
FUNC2(viewport_attach_camera, RID, RID)
FUNC2(viewport_set_scenario, RID, RID)
FUNC2(viewport_attach_canvas, RID, RID)
@@ -695,7 +699,6 @@ public:
FUNC13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float, float, RID)
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
- FUNC1(environment_glow_set_use_high_quality, bool)
FUNC4(environment_set_tonemap, RID, EnvironmentToneMapper, float, float)
@@ -760,6 +763,7 @@ public:
FUNC2(instance_set_base, RID, RID)
FUNC2(instance_set_scenario, RID, RID)
FUNC2(instance_set_layer_mask, RID, uint32_t)
+ FUNC3(instance_set_pivot_data, RID, float, bool)
FUNC2(instance_set_transform, RID, const Transform3D &)
FUNC2(instance_attach_object_instance_id, RID, ObjectID)
FUNC3(instance_set_blend_shape_weight, RID, int, float)
@@ -828,6 +832,8 @@ public:
FUNC2(canvas_item_set_visible, RID, bool)
FUNC2(canvas_item_set_light_mask, RID, int)
+ FUNC2(canvas_item_set_visibility_layer, RID, uint32_t)
+
FUNC2(canvas_item_set_update_when_visible, RID, bool)
FUNC2(canvas_item_set_transform, RID, const Transform2D &)
@@ -846,10 +852,10 @@ public:
FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool)
- FUNC7(canvas_item_add_msdf_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, int, float)
+ FUNC8(canvas_item_add_msdf_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, int, float, float)
FUNC5(canvas_item_add_lcd_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &)
FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
- FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
+ FUNC5(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int)
FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID)
@@ -981,6 +987,7 @@ public:
virtual double get_frame_setup_time_cpu() const override;
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override;
+ virtual Color get_default_clear_color() override;
virtual void set_default_clear_color(const Color &p_color) override;
virtual bool has_feature(Features p_feature) const override;
@@ -994,6 +1001,8 @@ public:
virtual void set_print_gpu_profile(bool p_enable) override;
+ virtual Size2i get_maximum_viewport_size() const override;
+
RenderingServerDefault(bool p_create_thread = false);
~RenderingServerDefault();
};
diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp
index ca24042ef9..1d1de2bfaf 100644
--- a/servers/rendering/rendering_server_globals.cpp
+++ b/servers/rendering/rendering_server_globals.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rendering_server_globals.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_server_globals.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 "rendering_server_globals.h"
diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h
index 23f3810ce8..f5b4941b3b 100644
--- a/servers/rendering/rendering_server_globals.h
+++ b/servers/rendering/rendering_server_globals.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* rendering_server_globals.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* rendering_server_globals.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 RENDERING_SERVER_GLOBALS_H
#define RENDERING_SERVER_GLOBALS_H
diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp
index 54cc7a011a..8737d3b217 100644
--- a/servers/rendering/shader_compiler.cpp
+++ b/servers/rendering/shader_compiler.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_compiler.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_compiler.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 "shader_compiler.h"
@@ -134,6 +134,8 @@ static String _interpstr(SL::DataInterpolation p_interp) {
return "flat ";
case SL::INTERPOLATION_SMOOTH:
return "";
+ case SL::INTERPOLATION_DEFAULT:
+ return "";
}
return "";
}
@@ -373,16 +375,16 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str
static String _get_global_shader_uniform_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) {
switch (p_type) {
case ShaderLanguage::TYPE_BOOL: {
- return "(" + p_buffer + "[" + p_index + "].x != 0.0)";
+ return "bool(floatBitsToUint(" + p_buffer + "[" + p_index + "].x))";
}
case ShaderLanguage::TYPE_BVEC2: {
- return "(notEqual(" + p_buffer + "[" + p_index + "].xy, vec2(0.0)))";
+ return "bvec2(floatBitsToUint(" + p_buffer + "[" + p_index + "].xy))";
}
case ShaderLanguage::TYPE_BVEC3: {
- return "(notEqual(" + p_buffer + "[" + p_index + "].xyz, vec3(0.0)))";
+ return "bvec3(floatBitsToUint(" + p_buffer + "[" + p_index + "].xyz))";
}
case ShaderLanguage::TYPE_BVEC4: {
- return "(notEqual(" + p_buffer + "[" + p_index + "].xyzw, vec4(0.0)))";
+ return "bvec4(floatBitsToUint(" + p_buffer + "[" + p_index + "].xyzw))";
}
case ShaderLanguage::TYPE_INT: {
return "floatBitsToInt(" + p_buffer + "[" + p_index + "].x)";
@@ -667,6 +669,9 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
fragment_varyings.insert(varying_name);
continue;
}
+ if (varying.type < SL::TYPE_INT) {
+ continue; // Ignore boolean types to prevent crashing (if varying is just declared).
+ }
String vcode;
String interp_mode = _interpstr(varying.interpolation);
@@ -904,9 +909,6 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
if (p_default_actions.renames.has(vnode->name)) {
code = p_default_actions.renames[vnode->name];
- if (vnode->name == "SCREEN_TEXTURE") {
- r_gen_code.uses_screen_texture_mipmaps = true;
- }
} else {
if (shader->uniforms.has(vnode->name)) {
//its a uniform!
@@ -914,29 +916,22 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
if (u.texture_order >= 0) {
StringName name = vnode->name;
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) {
- name = "SCREEN_TEXTURE";
+ name = "color_buffer";
if (u.filter >= ShaderLanguage::FILTER_NEAREST_MIPMAP) {
r_gen_code.uses_screen_texture_mipmaps = true;
}
+ r_gen_code.uses_screen_texture = true;
} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
- name = "NORMAL_ROUGHNESS_TEXTURE";
+ name = "normal_roughness_buffer";
+ r_gen_code.uses_normal_roughness_texture = true;
} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
- name = "DEPTH_TEXTURE";
+ name = "depth_buffer";
+ r_gen_code.uses_depth_texture = true;
} else {
name = _mkid(vnode->name); //texture, use as is
}
- if (p_default_actions.renames.has(name)) {
- code = p_default_actions.renames[name];
- } else {
- code = name;
- }
-
- if (p_actions.usage_flag_pointers.has(name) && !used_flag_pointers.has(name)) {
- *p_actions.usage_flag_pointers[name] = true;
- used_flag_pointers.insert(name);
- }
-
+ code = name;
} else {
//a scalar or vector
if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
@@ -1141,11 +1136,24 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
case SL::OP_STRUCT:
case SL::OP_CONSTRUCT: {
ERR_FAIL_COND_V(onode->arguments[0]->type != SL::Node::TYPE_VARIABLE, String());
-
- SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0];
+ const SL::VariableNode *vnode = static_cast<const SL::VariableNode *>(onode->arguments[0]);
+ const SL::FunctionNode *func = nullptr;
+ const bool is_internal_func = internal_functions.has(vnode->name);
+
+ if (!is_internal_func) {
+ for (int i = 0; i < shader->functions.size(); i++) {
+ if (shader->functions[i].name == vnode->name) {
+ func = shader->functions[i].function;
+ break;
+ }
+ }
+ }
bool is_texture_func = false;
bool is_screen_texture = false;
+ bool texture_func_no_uv = false;
+ bool texture_func_returns_data = false;
+
if (onode->op == SL::OP_STRUCT) {
code += _mkid(vnode->name);
} else if (onode->op == SL::OP_CONSTRUCT) {
@@ -1156,9 +1164,11 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
used_flag_pointers.insert(vnode->name);
}
- if (internal_functions.has(vnode->name)) {
+ if (is_internal_func) {
code += vnode->name;
is_texture_func = texture_functions.has(vnode->name);
+ texture_func_no_uv = (vnode->name == "textureSize" || vnode->name == "textureQueryLevels");
+ texture_func_returns_data = texture_func_no_uv || vnode->name == "textureQueryLod";
} else if (p_default_actions.renames.has(vnode->name)) {
code += p_default_actions.renames[vnode->name];
} else {
@@ -1168,13 +1178,56 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
code += "(";
+ // if color backbuffer, depth backbuffer or normal roughness texture is used,
+ // we will add logic to automatically switch between
+ // sampler2D and sampler2D array and vec2 UV and vec3 UV.
+ bool multiview_uv_needed = false;
+
for (int i = 1; i < onode->arguments.size(); i++) {
if (i > 1) {
code += ", ";
}
+
+ bool is_out_qualifier = false;
+ if (is_internal_func) {
+ is_out_qualifier = SL::is_builtin_func_out_parameter(vnode->name, i - 1);
+ } else if (func != nullptr) {
+ const SL::ArgumentQualifier qualifier = func->arguments[i - 1].qualifier;
+ is_out_qualifier = qualifier == SL::ARGUMENT_QUALIFIER_OUT || qualifier == SL::ARGUMENT_QUALIFIER_INOUT;
+ }
+
+ if (is_out_qualifier) {
+ StringName name;
+ bool found = false;
+ {
+ const SL::Node *node = onode->arguments[i];
+
+ bool done = false;
+ do {
+ switch (node->type) {
+ case SL::Node::TYPE_VARIABLE: {
+ name = static_cast<const SL::VariableNode *>(node)->name;
+ done = true;
+ found = true;
+ } break;
+ case SL::Node::TYPE_MEMBER: {
+ node = static_cast<const SL::MemberNode *>(node)->owner;
+ } break;
+ default: {
+ done = true;
+ } break;
+ }
+ } while (!done);
+ }
+
+ if (found && p_actions.write_flag_pointers.has(name)) {
+ *p_actions.write_flag_pointers[name] = true;
+ }
+ }
+
String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- if (!RS::get_singleton()->is_low_end() && is_texture_func && i == 1) {
- //need to map from texture to sampler in order to sample when using Vulkan GLSL
+ if (is_texture_func && i == 1) {
+ // If we're doing a texture lookup we need to check our texture argument
StringName texture_uniform;
bool correct_texture_uniform = false;
@@ -1193,17 +1246,25 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
break;
}
- if (correct_texture_uniform) {
- //TODO Needs to detect screen_texture hint as well
- is_screen_texture = (texture_uniform == "SCREEN_TEXTURE");
-
+ if (correct_texture_uniform && !RS::get_singleton()->is_low_end()) {
+ // Need to map from texture to sampler in order to sample when using Vulkan GLSL.
String sampler_name;
+ bool is_depth_texture = false;
+ bool is_normal_roughness_texture = false;
if (actions.custom_samplers.has(texture_uniform)) {
sampler_name = actions.custom_samplers[texture_uniform];
} else {
if (shader->uniforms.has(texture_uniform)) {
- sampler_name = _get_sampler_name(shader->uniforms[texture_uniform].filter, shader->uniforms[texture_uniform].repeat);
+ const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[texture_uniform];
+ if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) {
+ is_screen_texture = true;
+ } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
+ is_depth_texture = true;
+ } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
+ is_normal_roughness_texture = true;
+ }
+ sampler_name = _get_sampler_name(u.filter, u.repeat);
} else {
bool found = false;
@@ -1229,17 +1290,46 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
}
}
- code += ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype()) + "(" + node_code + ", " + sampler_name + ")";
+ String data_type_name = "";
+ if (actions.check_multiview_samplers && (is_screen_texture || is_depth_texture || is_normal_roughness_texture)) {
+ data_type_name = "multiviewSampler";
+ multiview_uv_needed = true;
+ } else {
+ data_type_name = ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype());
+ }
+
+ code += data_type_name + "(" + node_code + ", " + sampler_name + ")";
+ } else if (actions.check_multiview_samplers && correct_texture_uniform && RS::get_singleton()->is_low_end()) {
+ // Texture function on low end hardware (i.e. OpenGL).
+ // We just need to know if the texture supports multiview.
+
+ if (shader->uniforms.has(texture_uniform)) {
+ const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[texture_uniform];
+ if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) {
+ multiview_uv_needed = true;
+ } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
+ multiview_uv_needed = true;
+ } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
+ multiview_uv_needed = true;
+ }
+ }
+
+ code += node_code;
} else {
code += node_code;
}
+ } else if (multiview_uv_needed && !texture_func_no_uv && i == 2) {
+ // UV coordinate after using color, depth or normal roughness texture.
+ node_code = "multiview_uv(" + node_code + ".xy)";
+
+ code += node_code;
} else {
code += node_code;
}
}
code += ")";
- if (is_screen_texture && actions.apply_luminance_multiplier) {
- code = "(" + code + " / vec4(vec3(sc_luminance_multiplier), 1.0))";
+ if (is_screen_texture && !texture_func_returns_data && actions.apply_luminance_multiplier) {
+ code = "(" + code + " * vec4(vec3(sc_luminance_multiplier), 1.0))";
}
} break;
case SL::OP_INDEX: {
@@ -1445,6 +1535,9 @@ Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, Ident
r_gen_code.uses_vertex_time = false;
r_gen_code.uses_global_textures = false;
r_gen_code.uses_screen_texture_mipmaps = false;
+ r_gen_code.uses_screen_texture = false;
+ r_gen_code.uses_depth_texture = false;
+ r_gen_code.uses_normal_roughness_texture = false;
used_name_defines.clear();
used_rmode_defines.clear();
diff --git a/servers/rendering/shader_compiler.h b/servers/rendering/shader_compiler.h
index 4cbe93afb2..3bb29a545b 100644
--- a/servers/rendering/shader_compiler.h
+++ b/servers/rendering/shader_compiler.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_compiler.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_compiler.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 SHADER_COMPILER_H
#define SHADER_COMPILER_H
@@ -81,6 +81,9 @@ public:
bool uses_fragment_time;
bool uses_vertex_time;
bool uses_screen_texture_mipmaps;
+ bool uses_screen_texture;
+ bool uses_depth_texture;
+ bool uses_normal_roughness_texture;
};
struct DefaultIdentifierActions {
@@ -98,6 +101,7 @@ public:
String instance_uniform_index_variable;
uint32_t base_varying_index = 0;
bool apply_luminance_multiplier = false;
+ bool check_multiview_samplers = false;
};
private:
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index a92292209f..a727e83513 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_language.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_language.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 "shader_language.h"
@@ -90,8 +90,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"IDENTIFIER",
"TRUE",
"FALSE",
- "REAL_CONSTANT",
+ "FLOAT_CONSTANT",
"INT_CONSTANT",
+ "UINT_CONSTANT",
"TYPE_VOID",
"TYPE_BOOL",
"TYPE_BVEC2",
@@ -126,6 +127,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"INTERPOLATION_FLAT",
"INTERPOLATION_SMOOTH",
"CONST",
+ "STRUCT",
"PRECISION_LOW",
"PRECISION_MID",
"PRECISION_HIGH",
@@ -169,6 +171,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"CF_DO",
"CF_SWITCH",
"CF_CASE",
+ "CF_DEFAULT",
"CF_BREAK",
"CF_CONTINUE",
"CF_RETURN",
@@ -185,19 +188,26 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"SEMICOLON",
"PERIOD",
"UNIFORM",
+ "UNIFORM_GROUP",
"INSTANCE",
"GLOBAL",
"VARYING",
- "IN",
- "OUT",
- "INOUT",
+ "ARG_IN",
+ "ARG_OUT",
+ "ARG_INOUT",
"RENDER_MODE",
- "SOURCE_COLOR",
"HINT_DEFAULT_WHITE_TEXTURE",
"HINT_DEFAULT_BLACK_TEXTURE",
"HINT_DEFAULT_TRANSPARENT_TEXTURE",
"HINT_NORMAL_TEXTURE",
+ "HINT_ROUGHNESS_NORMAL_TEXTURE",
+ "HINT_ROUGHNESS_R",
+ "HINT_ROUGHNESS_G",
+ "HINT_ROUGHNESS_B",
+ "HINT_ROUGHNESS_A",
+ "HINT_ROUGHNESS_GRAY",
"HINT_ANISOTROPY_TEXTURE",
+ "HINT_SOURCE_COLOR",
"HINT_RANGE",
"HINT_INSTANCE_INDEX",
"HINT_SCREEN_TEXTURE",
@@ -612,7 +622,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
char_idx += 2;
include_positions.resize(include_positions.size() - 1); // Pop back.
- tk_line = include_positions[include_positions.size() - 1].line; // Restore line.
+ tk_line = include_positions[include_positions.size() - 1].line - 1; // Restore line.
} else {
return _make_token(TK_ERROR, "Invalid include enter/exit hint token (@@> and @@<)");
@@ -989,6 +999,18 @@ String ShaderLanguage::get_precision_name(DataPrecision p_type) {
return "";
}
+String ShaderLanguage::get_interpolation_name(DataInterpolation p_interpolation) {
+ switch (p_interpolation) {
+ case INTERPOLATION_FLAT:
+ return "flat";
+ case INTERPOLATION_SMOOTH:
+ return "smooth";
+ default:
+ break;
+ }
+ return "";
+}
+
String ShaderLanguage::get_datatype_name(DataType p_type) {
switch (p_type) {
case TYPE_VOID:
@@ -1203,7 +1225,7 @@ void ShaderLanguage::clear() {
char_idx = 0;
error_set = false;
error_str = "";
- last_const = false;
+ is_const_decl = false;
while (nodes) {
Node *n = nodes;
nodes = nodes->next;
@@ -1251,7 +1273,7 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
if (is_shader_inc) {
for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
for (const KeyValue<StringName, FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) {
- if ((current_function == E.key || E.key == "global") && E.value.built_ins.has(p_identifier)) {
+ if ((current_function == E.key || E.key == "global" || E.key == "constants") && E.value.built_ins.has(p_identifier)) {
if (r_data_type) {
*r_data_type = E.value.built_ins[p_identifier].type;
}
@@ -2815,6 +2837,20 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
{ "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ // dFdxCoarse
+
+ { "dFdxCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdxCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdxCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdxCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+
+ // dFdxFine
+
+ { "dFdxFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdxFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdxFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdxFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+
// dFdy
{ "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
@@ -2822,6 +2858,20 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
{ "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ // dFdyCoarse
+
+ { "dFdyCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdyCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdyCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdyCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+
+ // dFdyFine
+
+ { "dFdyFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdyFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdyFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdyFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+
// fwidth
{ "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
@@ -2829,6 +2879,20 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
{ "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ // fwidthCoarse
+
+ { "fwidthCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "fwidthCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "fwidthCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "fwidthCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+
+ // fwidthFine
+
+ { "fwidthFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "fwidthFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "fwidthFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "fwidthFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+
// Sub-functions.
// array
@@ -2837,10 +2901,10 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
// Modern functions.
// fma
- { "fma", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, false },
- { "fma", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, false },
- { "fma", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, false },
- { "fma", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, false },
+ { "fma", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
+ { "fma", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
+ { "fma", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
+ { "fma", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
// Packing/Unpacking functions.
@@ -3497,6 +3561,14 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Functio
return false;
}
+ if (is_const_decl && arg->type == Node::TYPE_VARIABLE) {
+ const VariableNode *var = static_cast<const VariableNode *>(arg);
+ if (!var->is_const) {
+ _set_error(RTR("Expected constant expression."));
+ return false;
+ }
+ }
+
p_func->arguments.push_back(arg);
tk = _get_token();
@@ -3645,7 +3717,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
switch (p_type) {
case ShaderLanguage::TYPE_BOOL:
if (array_size > 0) {
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].boolean);
}
@@ -3658,7 +3730,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
array_size *= 2;
if (array_size > 0) {
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].boolean);
}
@@ -3671,7 +3743,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
array_size *= 3;
if (array_size > 0) {
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].boolean);
}
@@ -3684,7 +3756,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
array_size *= 4;
if (array_size > 0) {
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].boolean);
}
@@ -3695,7 +3767,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
break;
case ShaderLanguage::TYPE_INT:
if (array_size > 0) {
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].sint);
}
@@ -3708,7 +3780,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 2;
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].sint);
}
@@ -3721,7 +3793,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 3;
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].sint);
}
@@ -3734,7 +3806,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 4;
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].sint);
}
@@ -3745,7 +3817,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
break;
case ShaderLanguage::TYPE_UINT:
if (array_size > 0) {
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].uint);
}
@@ -3758,7 +3830,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 2;
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].uint);
}
@@ -3771,7 +3843,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 3;
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].uint);
}
@@ -3784,7 +3856,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 4;
- PackedInt32Array array = PackedInt32Array();
+ PackedInt32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].uint);
}
@@ -3795,7 +3867,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
break;
case ShaderLanguage::TYPE_FLOAT:
if (array_size > 0) {
- PackedFloat32Array array = PackedFloat32Array();
+ PackedFloat32Array array;
for (int i = 0; i < array_size; i++) {
array.push_back(p_value[i].real);
}
@@ -3808,7 +3880,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 2;
- PackedVector2Array array = PackedVector2Array();
+ PackedVector2Array array;
for (int i = 0; i < array_size; i += 2) {
array.push_back(Vector2(p_value[i].real, p_value[i + 1].real));
}
@@ -3822,13 +3894,13 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
array_size *= 3;
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
- PackedColorArray array = PackedColorArray();
+ PackedColorArray array;
for (int i = 0; i < array_size; i += 3) {
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
}
value = Variant(array);
} else {
- PackedVector3Array array = PackedVector3Array();
+ PackedVector3Array array;
for (int i = 0; i < array_size; i += 3) {
array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
}
@@ -3847,13 +3919,13 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
array_size *= 4;
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
- PackedColorArray array = PackedColorArray();
+ PackedColorArray array;
for (int i = 0; i < array_size; i += 4) {
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
}
value = Variant(array);
} else {
- PackedFloat32Array array = PackedFloat32Array();
+ PackedFloat32Array array;
for (int i = 0; i < array_size; i += 4) {
array.push_back(p_value[i].real);
array.push_back(p_value[i + 1].real);
@@ -3874,7 +3946,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 4;
- PackedFloat32Array array = PackedFloat32Array();
+ PackedFloat32Array array;
for (int i = 0; i < array_size; i += 4) {
array.push_back(p_value[i].real);
array.push_back(p_value[i + 1].real);
@@ -3890,7 +3962,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 9;
- PackedFloat32Array array = PackedFloat32Array();
+ PackedFloat32Array array;
for (int i = 0; i < array_size; i += 9) {
for (int j = 0; j < 9; j++) {
array.push_back(p_value[i + j].real);
@@ -3916,7 +3988,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 16;
- PackedFloat32Array array = PackedFloat32Array();
+ PackedFloat32Array array;
for (int i = 0; i < array_size; i += 16) {
for (int j = 0; j < 16; j++) {
array.push_back(p_value[i + j].real);
@@ -4110,43 +4182,41 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
case ShaderLanguage::TYPE_USAMPLER2D: {
if (p_uniform.array_size > 0) {
pi.type = Variant::ARRAY;
+ pi.hint = PROPERTY_HINT_ARRAY_TYPE;
+ pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture2D");
} else {
pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "Texture2D";
}
- pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "Texture2D";
} break;
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
- case ShaderLanguage::TYPE_USAMPLER2DARRAY: {
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_SAMPLERCUBE:
+ case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
if (p_uniform.array_size > 0) {
pi.type = Variant::ARRAY;
+ pi.hint = PROPERTY_HINT_ARRAY_TYPE;
+ pi.hint_string = MAKE_RESOURCE_TYPE_HINT("TextureLayered");
} else {
pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "TextureLayered";
}
- pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "TextureLayered";
} break;
case ShaderLanguage::TYPE_SAMPLER3D:
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D: {
if (p_uniform.array_size > 0) {
pi.type = Variant::ARRAY;
+ pi.hint = PROPERTY_HINT_ARRAY_TYPE;
+ pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture3D");
} else {
pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "Texture3D";
}
- pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "Texture3D";
- } break;
- case ShaderLanguage::TYPE_SAMPLERCUBE:
- case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
- if (p_uniform.array_size > 0) {
- pi.type = Variant::ARRAY;
- } else {
- pi.type = Variant::OBJECT;
- }
- pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "TextureLayered";
} break;
case ShaderLanguage::TYPE_STRUCT: {
// FIXME: Implement this.
@@ -4309,8 +4379,18 @@ ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) {
TYPE_INT,
TYPE_UINT,
TYPE_FLOAT,
+ TYPE_INT,
+ TYPE_UINT,
+ TYPE_FLOAT,
+ TYPE_INT,
+ TYPE_UINT,
+ TYPE_FLOAT,
+ TYPE_FLOAT,
+ TYPE_VOID,
};
+ static_assert(sizeof(scalar_types) / sizeof(*scalar_types) == TYPE_MAX);
+
return scalar_types[p_type];
}
@@ -4340,8 +4420,18 @@ int ShaderLanguage::get_cardinality(DataType p_type) {
1,
1,
1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
};
+ static_assert(sizeof(cardinality_table) / sizeof(*cardinality_table) == TYPE_MAX);
+
return cardinality_table[p_type];
}
@@ -4399,13 +4489,17 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
}
bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) {
- if (current_function != String("vertex") && current_function != String("fragment")) {
+ if (current_function != "vertex" && current_function != "fragment") {
*r_message = vformat(RTR("Varying may not be assigned in the '%s' function."), current_function);
return false;
}
switch (p_varying.stage) {
case ShaderNode::Varying::STAGE_UNKNOWN: // first assign
if (current_function == varying_function_names.vertex) {
+ if (p_varying.type < TYPE_INT) {
+ *r_message = vformat(RTR("Varying with '%s' data type may only be assigned in the 'fragment' function."), get_datatype_name(p_varying.type));
+ return false;
+ }
p_varying.stage = ShaderNode::Varying::STAGE_VERTEX;
} else if (current_function == varying_function_names.fragment) {
p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT;
@@ -4444,14 +4538,14 @@ bool ShaderLanguage::_check_node_constness(const Node *p_node) const {
case Node::TYPE_CONSTANT:
break;
case Node::TYPE_VARIABLE: {
- const VariableNode *varn = static_cast<const VariableNode *>(p_node);
- if (!varn->is_const) {
+ const VariableNode *var_node = static_cast<const VariableNode *>(p_node);
+ if (!var_node->is_const) {
return false;
}
} break;
case Node::TYPE_ARRAY: {
- const ArrayNode *arrn = static_cast<const ArrayNode *>(p_node);
- if (!arrn->is_const) {
+ const ArrayNode *arr_node = static_cast<const ArrayNode *>(p_node);
+ if (!arr_node->is_const) {
return false;
}
} break;
@@ -5098,6 +5192,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = func;
} else { //a function call
+ if (p_block == nullptr) { // Non-constructor function call in global space is forbidden.
+ if (is_const_decl) {
+ _set_error(RTR("Expected constant expression."));
+ }
+ return nullptr;
+ }
const StringName &name = identifier;
@@ -5205,7 +5305,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (shader->varyings.has(varname)) {
switch (shader->varyings[varname].stage) {
case ShaderNode::Varying::STAGE_UNKNOWN: {
- _set_error(vformat(RTR("Varying '%s' must be assigned in the vertex or fragment function first."), varname));
+ _set_error(vformat(RTR("Varying '%s' must be assigned in the 'vertex' or 'fragment' function first."), varname));
return nullptr;
}
case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT:
@@ -5365,9 +5465,19 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
} else {
if (!_find_identifier(p_block, false, p_function_info, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
+ if (identifier == "SCREEN_TEXTURE" || identifier == "DEPTH_TEXTURE" || identifier == "NORMAL_ROUGHNESS_TEXTURE") {
+ String name = String(identifier);
+ String name_lower = name.to_lower();
+ _set_error(vformat(RTR("%s has been removed in favor of using hint_%s with a uniform.\nTo continue with minimal code changes add 'uniform sampler2D %s : hint_%s, filter_linear_mipmap;' near the top of your shader."), name, name_lower, name, name_lower));
+ return nullptr;
+ }
_set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier)));
return nullptr;
}
+ if (is_const_decl && !is_const) {
+ _set_error(RTR("Expected constant expression."));
+ return nullptr;
+ }
if (ident_type == IDENTIFIER_VARYING) {
TkPos prev_pos = _get_tkpos();
Token next_token = _get_token();
@@ -5389,6 +5499,16 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
} else {
switch (var.stage) {
+ case ShaderNode::Varying::STAGE_UNKNOWN: {
+ if (var.type < TYPE_INT) {
+ if (current_function == varying_function_names.vertex) {
+ _set_error(vformat(RTR("Varying with '%s' data type may only be used in the 'fragment' function."), get_datatype_name(var.type)));
+ } else {
+ _set_error(vformat(RTR("Varying '%s' must be assigned in the 'fragment' function first."), identifier));
+ }
+ return nullptr;
+ }
+ } break;
case ShaderNode::Varying::STAGE_VERTEX:
if (current_function == varying_function_names.fragment || current_function == varying_function_names.light) {
var.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT;
@@ -6433,7 +6553,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_function_info)) {
- _set_error(RTR("Can't use increment/decrement operator in a constant expression."));
+ _set_error(RTR("Invalid use of increment/decrement operator in a constant expression."));
return nullptr;
}
op->arguments.push_back(expression[i + 1].node);
@@ -6875,6 +6995,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
}
#endif // DEBUG_ENABLED
+ is_const_decl = is_const;
BlockNode::Variable var;
var.type = type;
@@ -7131,6 +7252,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
vdnode->declarations.push_back(decl);
p_block->variables[name] = var;
+ is_const_decl = false;
if (!fixed_array_size) {
array_size = 0;
@@ -7570,7 +7692,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_BUG;
}
- if (b && b->parent_function && p_function_info.main_function) {
+ if (b->parent_function && p_function_info.main_function) {
_set_error(vformat(RTR("Using '%s' in the '%s' processor function is incorrect."), "return", b->parent_function->name));
return ERR_PARSE_ERROR;
}
@@ -8170,21 +8292,31 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
};
[[fallthrough]];
case TK_INSTANCE: {
+ if (tk.type == TK_INSTANCE) {
#ifdef DEBUG_ENABLED
- keyword_completion_context = CF_UNIFORM_KEYWORD;
- if (_lookup_next(next)) {
- if (next.type == TK_UNIFORM) {
- keyword_completion_context ^= CF_UNIFORM_KEYWORD;
+ keyword_completion_context = CF_UNIFORM_KEYWORD;
+ if (_lookup_next(next)) {
+ if (next.type == TK_UNIFORM) {
+ keyword_completion_context ^= CF_UNIFORM_KEYWORD;
+ }
}
- }
#endif // DEBUG_ENABLED
- if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) {
- tk = _get_token();
- if (tk.type != TK_UNIFORM) {
- _set_expected_after_error("uniform", "instance");
+ if (String(shader_type_identifier) != "spatial") {
+ _set_error(vformat(RTR("Uniform instances are not yet implemented for '%s' shaders."), shader_type_identifier));
+ return ERR_PARSE_ERROR;
+ }
+ if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
+ _set_error(RTR("Uniform instances are not supported in gl_compatibility shaders."));
return ERR_PARSE_ERROR;
}
- uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE;
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) {
+ tk = _get_token();
+ if (tk.type != TK_UNIFORM) {
+ _set_expected_after_error("uniform", "instance");
+ return ERR_PARSE_ERROR;
+ }
+ uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE;
+ }
}
};
[[fallthrough]];
@@ -8201,7 +8333,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
}
}
DataPrecision precision = PRECISION_DEFAULT;
- DataInterpolation interpolation = INTERPOLATION_SMOOTH;
+ DataInterpolation interpolation = INTERPOLATION_DEFAULT;
DataType type;
StringName name;
int array_size = 0;
@@ -8289,7 +8421,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
_set_error(vformat(RTR("The '%s' data type is not supported for uniforms."), "struct"));
return ERR_PARSE_ERROR;
} else {
- _set_error(vformat(RTR("The '%s' data type not allowed here."), "struct"));
+ _set_error(vformat(RTR("The '%s' data type is not allowed here."), "struct"));
return ERR_PARSE_ERROR;
}
}
@@ -8310,6 +8442,11 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
return ERR_PARSE_ERROR;
}
+ if (!is_uniform && interpolation != INTERPOLATION_DEFAULT && type < TYPE_INT) {
+ _set_error(vformat(RTR("Interpolation modifier '%s' cannot be used with boolean types."), get_interpolation_name(interpolation)));
+ return ERR_PARSE_ERROR;
+ }
+
if (!is_uniform && type > TYPE_MAT4) {
_set_error(RTR("Invalid data type for varying."));
return ERR_PARSE_ERROR;
@@ -8635,12 +8772,22 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
} break;
case TK_HINT_SCREEN_TEXTURE: {
new_hint = ShaderNode::Uniform::HINT_SCREEN_TEXTURE;
+ --texture_uniforms;
+ --texture_binding;
} break;
case TK_HINT_NORMAL_ROUGHNESS_TEXTURE: {
new_hint = ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE;
+ --texture_uniforms;
+ --texture_binding;
+ if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
+ _set_error(RTR("'hint_normal_roughness_texture is not supported in gl_compatibility shaders."));
+ return ERR_PARSE_ERROR;
+ }
} break;
case TK_HINT_DEPTH_TEXTURE: {
new_hint = ShaderNode::Uniform::HINT_DEPTH_TEXTURE;
+ --texture_uniforms;
+ --texture_binding;
} break;
case TK_FILTER_NEAREST: {
new_filter = FILTER_NEAREST;
@@ -8851,7 +8998,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
_set_error(RTR("Expected an uniform group identifier or `;`."));
}
return ERR_PARSE_ERROR;
- } else if (tk.type == TK_SEMICOLON && current_uniform_group_name.is_empty()) {
+ } else if (current_uniform_group_name.is_empty()) {
_set_error(RTR("Group needs to be opened before."));
return ERR_PARSE_ERROR;
} else {
@@ -8974,6 +9121,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
constant.precision = precision;
constant.initializer = nullptr;
constant.array_size = array_size;
+ is_const_decl = true;
if (tk.type == TK_BRACKET_OPEN) {
Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size);
@@ -9233,6 +9381,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
unknown_size = false;
} else if (tk.type == TK_SEMICOLON) {
+ is_const_decl = false;
break;
} else {
_set_expected_error(",", ";");
@@ -9710,6 +9859,25 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
return String();
}
+bool ShaderLanguage::is_builtin_func_out_parameter(const String &p_name, int p_param) {
+ int i = 0;
+ while (builtin_func_out_args[i].name) {
+ if (p_name == builtin_func_out_args[i].name) {
+ for (int j = 0; j < BuiltinFuncOutArgs::MAX_ARGS; j++) {
+ int arg = builtin_func_out_args[i].arguments[j];
+ if (arg == p_param) {
+ return true;
+ }
+ if (arg < 0) {
+ return false;
+ }
+ }
+ }
+ i++;
+ }
+ return false;
+}
+
#ifdef DEBUG_ENABLED
void ShaderLanguage::_check_warning_accums() {
for (const KeyValue<ShaderWarning::Code, HashMap<StringName, HashMap<StringName, Usage>> *> &E : warnings_check_map2) {
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 1e302f5805..aea61e42c3 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_language.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_language.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 SHADER_LANGUAGE_H
#define SHADER_LANGUAGE_H
@@ -247,6 +247,7 @@ public:
enum DataInterpolation {
INTERPOLATION_FLAT,
INTERPOLATION_SMOOTH,
+ INTERPOLATION_DEFAULT,
};
enum Operator {
@@ -720,6 +721,12 @@ public:
Node(TYPE_SHADER) {}
};
+ struct UniformOrderComparator {
+ _FORCE_INLINE_ bool operator()(const Pair<StringName, int> &A, const Pair<StringName, int> &B) const {
+ return A.second < B.second;
+ }
+ };
+
struct Expression {
bool is_op;
union {
@@ -768,6 +775,7 @@ public:
static bool is_token_arg_qual(TokenType p_type);
static DataPrecision get_token_precision(TokenType p_type);
static String get_precision_name(DataPrecision p_type);
+ static String get_interpolation_name(DataInterpolation p_interpolation);
static String get_datatype_name(DataType p_type);
static String get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint);
static String get_texture_filter_name(TextureFilter p_filter);
@@ -945,7 +953,7 @@ private:
StringName shader_type_identifier;
StringName current_function;
- bool last_const = false;
+ bool is_const_decl = false;
StringName last_name;
bool is_shader_inc = false;
@@ -1119,6 +1127,7 @@ public:
void clear();
static String get_shader_type(const String &p_code);
+ static bool is_builtin_func_out_parameter(const String &p_name, int p_param);
struct ShaderCompileInfo {
HashMap<StringName, FunctionInfo> functions;
diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp
index 46e76fbe92..b45a7c0db3 100644
--- a/servers/rendering/shader_preprocessor.cpp
+++ b/servers/rendering/shader_preprocessor.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_preprocessor.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_preprocessor.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 "shader_preprocessor.h"
#include "core/math/expression.h"
@@ -78,19 +78,46 @@ char32_t ShaderPreprocessor::Tokenizer::peek() {
return 0;
}
+int ShaderPreprocessor::Tokenizer::consume_line_continuations(int p_offset) {
+ int skips = 0;
+
+ for (int i = index + p_offset; i < size; i++) {
+ char32_t c = code[i];
+ if (c == '\\') {
+ if (i + 1 < size && code[i + 1] == '\n') {
+ // This line ends with "\" and "\n" continuation.
+ add_generated(Token('\n', line));
+ line++;
+ skips++;
+
+ i = i + 2;
+ index = i;
+ } else {
+ break;
+ }
+ } else if (!is_whitespace(c)) {
+ break;
+ }
+ }
+ return skips;
+}
+
LocalVector<ShaderPreprocessor::Token> ShaderPreprocessor::Tokenizer::advance(char32_t p_what) {
LocalVector<ShaderPreprocessor::Token> tokens;
while (index < size) {
char32_t c = code[index++];
-
- tokens.push_back(ShaderPreprocessor::Token(c, line));
+ if (c == '\\' && consume_line_continuations(-1) > 0) {
+ continue;
+ }
if (c == '\n') {
add_generated(ShaderPreprocessor::Token('\n', line));
line++;
}
+ tokens.push_back(ShaderPreprocessor::Token(c, line));
+
if (c == p_what || c == 0) {
return tokens;
}
@@ -104,6 +131,11 @@ void ShaderPreprocessor::Tokenizer::skip_whitespace() {
}
}
+bool ShaderPreprocessor::Tokenizer::consume_empty_line() {
+ // Read until newline and return true if the content was all whitespace/empty.
+ return tokens_to_string(advance('\n')).strip_edges().size() == 0;
+}
+
String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_started) {
if (r_is_cursor != nullptr) {
*r_is_cursor = false;
@@ -113,6 +145,10 @@ String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_s
while (true) {
char32_t c = peek();
+ if (c == '\\' && consume_line_continuations(0) > 0) {
+ continue;
+ }
+
if (is_char_end(c) || c == '(' || c == ')' || c == ',' || c == ';') {
break;
}
@@ -146,8 +182,10 @@ String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_s
String ShaderPreprocessor::Tokenizer::peek_identifier() {
const int original = index;
+ const int original_line = line;
String id = get_identifier();
index = original;
+ line = original_line;
return id;
}
@@ -330,8 +368,8 @@ String ShaderPreprocessor::vector_to_string(const LocalVector<char32_t> &p_v, in
String ShaderPreprocessor::tokens_to_string(const LocalVector<Token> &p_tokens) {
LocalVector<char32_t> result;
- for (uint32_t i = 0; i < p_tokens.size(); i++) {
- result.push_back(p_tokens[i].text);
+ for (const Token &token : p_tokens) {
+ result.push_back(token.text);
}
return vector_to_string(result);
}
@@ -485,7 +523,9 @@ void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) {
state->previous_region->to_line = line - 1;
}
- p_tokenizer->advance('\n');
+ if (!p_tokenizer->consume_empty_line()) {
+ set_error(RTR("Invalid else."), p_tokenizer->get_line());
+ }
bool skip = false;
for (int i = 0; i < state->current_branch->conditions.size(); i++) {
@@ -508,17 +548,21 @@ void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) {
}
void ShaderPreprocessor::process_endif(Tokenizer *p_tokenizer) {
+ const int line = p_tokenizer->get_line();
+
state->condition_depth--;
if (state->condition_depth < 0) {
- set_error(RTR("Unmatched endif."), p_tokenizer->get_line());
+ set_error(RTR("Unmatched endif."), line);
return;
}
if (state->previous_region != nullptr) {
- state->previous_region->to_line = p_tokenizer->get_line() - 1;
+ state->previous_region->to_line = line - 1;
state->previous_region = state->previous_region->parent;
}
- p_tokenizer->advance('\n');
+ if (!p_tokenizer->consume_empty_line()) {
+ set_error(RTR("Invalid endif."), line);
+ }
state->current_branch = state->current_branch->parent;
state->branches.pop_back();
@@ -574,12 +618,10 @@ void ShaderPreprocessor::process_ifdef(Tokenizer *p_tokenizer) {
return;
}
- p_tokenizer->skip_whitespace();
- if (!is_char_end(p_tokenizer->peek())) {
+ if (!p_tokenizer->consume_empty_line()) {
set_error(RTR("Invalid ifdef."), line);
return;
}
- p_tokenizer->advance('\n');
bool success = state->defines.has(label);
start_branch_condition(p_tokenizer, success);
@@ -598,12 +640,10 @@ void ShaderPreprocessor::process_ifndef(Tokenizer *p_tokenizer) {
return;
}
- p_tokenizer->skip_whitespace();
- if (!is_char_end(p_tokenizer->peek())) {
+ if (!p_tokenizer->consume_empty_line()) {
set_error(RTR("Invalid ifndef."), line);
return;
}
- p_tokenizer->advance('\n');
bool success = !state->defines.has(label);
start_branch_condition(p_tokenizer, success);
@@ -628,13 +668,17 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {
}
}
path = path.substr(0, path.length() - 1);
- p_tokenizer->skip_whitespace();
- if (path.is_empty() || !is_char_end(p_tokenizer->peek())) {
+ if (path.is_empty() || !p_tokenizer->consume_empty_line()) {
set_error(RTR("Invalid path."), line);
return;
}
+ path = path.simplify_path();
+ if (path.is_relative_path()) {
+ path = state->current_filename.get_base_dir().path_join(path);
+ }
+
Ref<Resource> res = ResourceLoader::load(path);
if (res.is_null()) {
set_error(RTR("Shader include load failed. Does the shader include exist? Is there a cyclic dependency?"), line);
@@ -728,25 +772,24 @@ void ShaderPreprocessor::process_pragma(Tokenizer *p_tokenizer) {
return;
}
- p_tokenizer->advance('\n');
+ if (!p_tokenizer->consume_empty_line()) {
+ set_error(RTR("Invalid pragma directive."), line);
+ return;
+ }
}
void ShaderPreprocessor::process_undef(Tokenizer *p_tokenizer) {
const int line = p_tokenizer->get_line();
const String label = p_tokenizer->get_identifier();
- if (label.is_empty() || !state->defines.has(label)) {
- set_error(RTR("Invalid name."), line);
- return;
- }
-
- p_tokenizer->skip_whitespace();
- if (!is_char_end(p_tokenizer->peek())) {
+ if (label.is_empty() || !p_tokenizer->consume_empty_line()) {
set_error(RTR("Invalid undef."), line);
return;
}
- memdelete(state->defines[label]);
- state->defines.erase(label);
+ if (state->defines.has(label)) {
+ memdelete(state->defines[label]);
+ state->defines.erase(label);
+ }
}
void ShaderPreprocessor::add_region(int p_line, bool p_enabled, Region *p_parent_region) {
@@ -957,15 +1000,57 @@ bool ShaderPreprocessor::expand_macros_once(const String &p_line, int p_line_num
String body = define->body;
if (define->arguments.size() > 0) {
// Complex macro with arguments.
- int args_start = index + key.length();
- int args_end = p_line.find(")", args_start);
- if (args_start == -1 || args_end == -1) {
- set_error(RTR("Missing macro argument parenthesis."), p_line_number);
- return false;
+
+ int args_start = -1;
+ int args_end = -1;
+ int brackets_open = 0;
+ Vector<String> args;
+ for (int i = index_start - 1; i < p_line.length(); i++) {
+ bool add_argument = false;
+ bool reached_end = false;
+ char32_t c = p_line[i];
+
+ if (c == '(') {
+ brackets_open++;
+ if (brackets_open == 1) {
+ args_start = i + 1;
+ args_end = -1;
+ }
+ } else if (c == ')') {
+ brackets_open--;
+ if (brackets_open == 0) {
+ args_end = i;
+ add_argument = true;
+ reached_end = true;
+ }
+ } else if (c == ',') {
+ if (brackets_open == 1) {
+ args_end = i;
+ add_argument = true;
+ }
+ }
+
+ if (add_argument) {
+ if (args_start == -1 || args_end == -1) {
+ set_error(RTR("Invalid macro argument list."), p_line_number);
+ return false;
+ }
+
+ String arg = p_line.substr(args_start, args_end - args_start).strip_edges();
+ if (arg.is_empty()) {
+ set_error(RTR("Invalid macro argument."), p_line_number);
+ return false;
+ }
+ args.append(arg);
+
+ args_start = args_end + 1;
+ }
+
+ if (reached_end) {
+ break;
+ }
}
- String values = result.substr(args_start + 1, args_end - (args_start + 1));
- Vector<String> args = values.split(",");
if (args.size() != define->arguments.size()) {
set_error(RTR("Invalid macro argument count."), p_line_number);
return false;
@@ -987,9 +1072,6 @@ bool ShaderPreprocessor::expand_macros_once(const String &p_line, int p_line_num
result = result.substr(0, index) + " " + body + " " + result.substr(args_end + 1, result.length());
} else {
result = result.substr(0, index) + body + result.substr(index + key.length(), result.length() - (index + key.length()));
- // Manually reset index_start to where the body value of the define finishes.
- // This ensures we don't skip another instance of this macro in the string.
- index_start = index + body.length() + 1;
}
r_expanded = result;
@@ -1081,21 +1163,17 @@ ShaderPreprocessor::Define *ShaderPreprocessor::create_define(const String &p_bo
return define;
}
-void ShaderPreprocessor::clear() {
- if (state_owner && state != nullptr) {
+void ShaderPreprocessor::clear_state() {
+ if (state != nullptr) {
for (const RBMap<String, Define *>::Element *E = state->defines.front(); E; E = E->next()) {
memdelete(E->get());
}
-
- memdelete(state);
+ state->defines.clear();
}
- state_owner = false;
state = nullptr;
}
Error ShaderPreprocessor::preprocess(State *p_state, const String &p_code, String &r_result) {
- clear();
-
output.clear();
state = p_state;
@@ -1242,6 +1320,9 @@ Error ShaderPreprocessor::preprocess(const String &p_code, const String &p_filen
}
}
}
+
+ clear_state();
+
return err;
}
@@ -1273,5 +1354,4 @@ ShaderPreprocessor::ShaderPreprocessor() {
}
ShaderPreprocessor::~ShaderPreprocessor() {
- clear();
}
diff --git a/servers/rendering/shader_preprocessor.h b/servers/rendering/shader_preprocessor.h
index f1b2876891..f198af66f0 100644
--- a/servers/rendering/shader_preprocessor.h
+++ b/servers/rendering/shader_preprocessor.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_preprocessor.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_preprocessor.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 SHADER_PREPROCESSOR_H
#define SHADER_PREPROCESSOR_H
@@ -93,11 +93,13 @@ private:
int get_line() const;
int get_index() const;
char32_t peek();
+ int consume_line_continuations(int p_offset);
void get_and_clear_generated(Vector<Token> *r_out);
void backtrack(char32_t p_what);
LocalVector<Token> advance(char32_t p_what);
void skip_whitespace();
+ bool consume_empty_line();
String get_identifier(bool *r_is_cursor = nullptr, bool p_started = false);
String peek_identifier();
Token get_token();
@@ -167,7 +169,6 @@ private:
private:
LocalVector<char32_t> output;
State *state = nullptr;
- bool state_owner = false;
private:
static bool is_char_word(char32_t p_char);
@@ -181,7 +182,7 @@ private:
}
void _set_unexpected_token_error(const String &p_what, int p_line) {
- set_error(vformat(RTR("Unexpected token '%s'."), p_what), p_line);
+ set_error(vformat(RTR("Unexpected token: '%s'."), p_what), p_line);
}
void process_directive(Tokenizer *p_tokenizer);
@@ -211,7 +212,7 @@ private:
static Define *create_define(const String &p_body);
- void clear();
+ void clear_state();
Error preprocess(State *p_state, const String &p_code, String &r_result);
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 5e1da7c15d..56d00fa1bb 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_types.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_types.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 "shader_types.h"
#include "core/math/math_defs.h"
@@ -100,11 +100,13 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_VISIBLE_LAYERS"] = ShaderLanguage::TYPE_UINT;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_MONO_LEFT"] = constt(ShaderLanguage::TYPE_INT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_RIGHT"] = constt(ShaderLanguage::TYPE_INT);
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["EYE_OFFSET"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
@@ -137,9 +139,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO_LIGHT_AFFECT"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL_ROUGHNESS_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2);
@@ -147,11 +146,13 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_VISIBLE_LAYERS"] = ShaderLanguage::TYPE_UINT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_MONO_LEFT"] = constt(ShaderLanguage::TYPE_INT);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_RIGHT"] = constt(ShaderLanguage::TYPE_INT);
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["EYE_OFFSET"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
@@ -265,7 +266,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["AT_LIGHT_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].can_discard = true;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].main_function = true;
@@ -466,7 +466,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["WORLD_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["OBJECT_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["UVW"] = constt(ShaderLanguage::TYPE_VEC3);
- shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["EXTENTS"] = constt(ShaderLanguage::TYPE_VEC3);
+ shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["SIZE"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["SDF"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["ALBEDO"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["DENSITY"] = ShaderLanguage::TYPE_FLOAT;
diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h
index dfec3a7111..5a7423b661 100644
--- a/servers/rendering/shader_types.h
+++ b/servers/rendering/shader_types.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_types.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_types.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 SHADER_TYPES_H
#define SHADER_TYPES_H
diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp
index 855dc23d94..dce8f6cff1 100644
--- a/servers/rendering/shader_warnings.cpp
+++ b/servers/rendering/shader_warnings.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_warnings.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_warnings.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 "shader_warnings.h"
#include "core/variant/variant.h"
diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h
index d5c6a4b1a6..ed28ebdd2b 100644
--- a/servers/rendering/shader_warnings.h
+++ b/servers/rendering/shader_warnings.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* shader_warnings.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* shader_warnings.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 SHADER_WARNINGS_H
#define SHADER_WARNINGS_H
diff --git a/servers/rendering/storage/camera_attributes_storage.cpp b/servers/rendering/storage/camera_attributes_storage.cpp
index 570fefb9de..151ae4ccfe 100644
--- a/servers/rendering/storage/camera_attributes_storage.cpp
+++ b/servers/rendering/storage/camera_attributes_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* camera_attributes_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* camera_attributes_storage.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 "camera_attributes_storage.h"
diff --git a/servers/rendering/storage/camera_attributes_storage.h b/servers/rendering/storage/camera_attributes_storage.h
index 6c7b364b10..6fbcd3da7d 100644
--- a/servers/rendering/storage/camera_attributes_storage.h
+++ b/servers/rendering/storage/camera_attributes_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* camera_attributes_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* camera_attributes_storage.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 CAMERA_ATTRIBUTES_STORAGE_H
#define CAMERA_ATTRIBUTES_STORAGE_H
diff --git a/servers/rendering/storage/environment_storage.cpp b/servers/rendering/storage/environment_storage.cpp
index 9b1842f1d9..30a6a616bb 100644
--- a/servers/rendering/storage/environment_storage.cpp
+++ b/servers/rendering/storage/environment_storage.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* environment_storage.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* environment_storage.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 "environment_storage.h"
@@ -283,7 +283,7 @@ void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool
env->volumetric_fog_scattering = p_albedo;
env->volumetric_fog_emission = p_emission;
env->volumetric_fog_emission_energy = p_emission_energy;
- env->volumetric_fog_anisotropy = p_anisotropy,
+ env->volumetric_fog_anisotropy = p_anisotropy;
env->volumetric_fog_length = p_length;
env->volumetric_fog_detail_spread = p_detail_spread;
env->volumetric_fog_gi_inject = p_gi_inject;
diff --git a/servers/rendering/storage/environment_storage.h b/servers/rendering/storage/environment_storage.h
index 17bde94902..d677dfc57b 100644
--- a/servers/rendering/storage/environment_storage.h
+++ b/servers/rendering/storage/environment_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* environment_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* environment_storage.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 ENVIRONMENT_STORAGE_H
#define ENVIRONMENT_STORAGE_H
@@ -98,7 +98,7 @@ private:
float glow_hdr_luminance_cap = 12.0;
float glow_hdr_bleed_scale = 2.0;
float glow_map_strength = 0.0f; // 1.0f in GLES3 ??
- RID glow_map = RID();
+ RID glow_map;
// SSR
bool ssr_enabled = false;
@@ -143,7 +143,7 @@ private:
float adjustments_contrast = 1.0f;
float adjustments_saturation = 1.0f;
bool use_1d_color_correction = false;
- RID color_correction = RID();
+ RID color_correction;
};
mutable RID_Owner<Environment, true> environment_owner;
diff --git a/servers/rendering/storage/light_storage.h b/servers/rendering/storage/light_storage.h
index df5b893cd5..5bd4297179 100644
--- a/servers/rendering/storage/light_storage.h
+++ b/servers/rendering/storage/light_storage.h
@@ -1,36 +1,37 @@
-/*************************************************************************/
-/* light_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* light_storage.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 LIGHT_STORAGE_H
#define LIGHT_STORAGE_H
+#include "render_scene_buffers.h"
#include "servers/rendering_server.h"
class RendererLightStorage {
@@ -83,6 +84,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0;
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0;
virtual uint64_t light_get_version(RID p_light) const = 0;
+ virtual uint32_t light_get_cull_mask(RID p_light) const = 0;
/* LIGHT INSTANCE API */
@@ -109,7 +111,7 @@ public:
virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) = 0;
virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) = 0;
virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) = 0;
- virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) = 0;
+ virtual void reflection_probe_set_size(RID p_probe, const Vector3 &p_size) = 0;
virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) = 0;
virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) = 0;
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0;
@@ -120,7 +122,7 @@ public:
virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0;
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0;
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0;
- virtual Vector3 reflection_probe_get_extents(RID p_probe) const = 0;
+ virtual Vector3 reflection_probe_get_size(RID p_probe) const = 0;
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const = 0;
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const = 0;
virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0;
@@ -142,6 +144,7 @@ public:
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0;
virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0;
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0;
+ virtual Ref<RenderSceneBuffers> reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) = 0;
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
/* LIGHTMAP */
diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h
index 396668c9ed..03feda8abb 100644
--- a/servers/rendering/storage/material_storage.h
+++ b/servers/rendering/storage/material_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* material_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* material_storage.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 MATERIAL_STORAGE_H
#define MATERIAL_STORAGE_H
@@ -53,7 +53,7 @@ public:
virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) = 0;
virtual void global_shader_parameters_instance_free(RID p_instance) = 0;
- virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0;
+ virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) = 0;
/* SHADER API */
virtual RID shader_allocate() = 0;
diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h
index 5b3738dfd7..76e46a696a 100644
--- a/servers/rendering/storage/mesh_storage.h
+++ b/servers/rendering/storage/mesh_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* mesh_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* mesh_storage.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 MESH_STORAGE_H
#define MESH_STORAGE_H
@@ -83,6 +83,7 @@ public:
virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) = 0;
virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) = 0;
virtual void mesh_instance_check_for_update(RID p_mesh_instance) = 0;
+ virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) = 0;
virtual void update_mesh_instances() = 0;
/* MULTIMESH API */
diff --git a/servers/rendering/storage/particles_storage.h b/servers/rendering/storage/particles_storage.h
index ee4b8679b3..78c616f6d5 100644
--- a/servers/rendering/storage/particles_storage.h
+++ b/servers/rendering/storage/particles_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* particles_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* particles_storage.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 PARTICLES_STORAGE_H
#define PARTICLES_STORAGE_H
@@ -94,8 +94,6 @@ public:
virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) = 0;
virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) = 0;
- virtual void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) = 0;
-
virtual void update_particles() = 0;
/* PARTICLES COLLISION */
@@ -116,7 +114,6 @@ public:
virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field
virtual AABB particles_collision_get_aabb(RID p_particles_collision) const = 0;
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0;
- virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0;
//used from 2D and 3D
virtual RID particles_collision_instance_create(RID p_collision) = 0;
diff --git a/servers/rendering/storage/render_scene_buffers.cpp b/servers/rendering/storage/render_scene_buffers.cpp
index 104700090f..6369139aa6 100644
--- a/servers/rendering/storage/render_scene_buffers.cpp
+++ b/servers/rendering/storage/render_scene_buffers.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_scene_buffers.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_scene_buffers.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 "render_scene_buffers.h"
@@ -34,8 +34,8 @@ void RenderSceneBuffers::_bind_methods() {
ClassDB::bind_method(D_METHOD("configure", "render_target", "internal_size", "target_size", "fsr_sharpness", "texture_mipmap_bias", "msaa", "screen_space_aa", "use_taa", "use_debanding", "view_count"), &RenderSceneBuffers::configure);
}
-void RenderSceneBuffers::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
- GDVIRTUAL_CALL(_configure, p_render_target, p_internal_size, p_target_size, p_fsr_sharpness, p_texture_mipmap_bias, p_msaa, p_screen_space_aa, p_use_taa, p_use_debanding, p_view_count);
+void RenderSceneBuffers::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
+ GDVIRTUAL_CALL(_configure, p_render_target, p_internal_size, p_target_size, p_scaling_3d_mode, p_fsr_sharpness, p_texture_mipmap_bias, p_msaa, p_screen_space_aa, p_use_taa, p_use_debanding, p_view_count);
};
void RenderSceneBuffers::set_fsr_sharpness(float p_fsr_sharpness) {
diff --git a/servers/rendering/storage/render_scene_buffers.h b/servers/rendering/storage/render_scene_buffers.h
index e28e3201ae..cf96a9f372 100644
--- a/servers/rendering/storage/render_scene_buffers.h
+++ b/servers/rendering/storage/render_scene_buffers.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* render_scene_buffers.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* render_scene_buffers.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 RENDER_SCENE_BUFFERS_H
#define RENDER_SCENE_BUFFERS_H
@@ -40,7 +40,7 @@ class RenderSceneBuffers : public RefCounted {
protected:
static void _bind_methods();
- GDVIRTUAL10(_configure, RID, Size2i, Size2i, float, float, RS::ViewportMSAA, RenderingServer::ViewportScreenSpaceAA, bool, bool, uint32_t)
+ GDVIRTUAL11(_configure, RID, Size2i, Size2i, RS::ViewportScaling3DMode, float, float, RS::ViewportMSAA, RenderingServer::ViewportScreenSpaceAA, bool, bool, uint32_t)
GDVIRTUAL1(_set_fsr_sharpness, float)
GDVIRTUAL1(_set_texture_mipmap_bias, float)
GDVIRTUAL1(_set_use_debanding, bool)
@@ -49,7 +49,7 @@ public:
RenderSceneBuffers(){};
virtual ~RenderSceneBuffers(){};
- virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count);
+ virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, RS::ViewportScaling3DMode p_scaling_3d_mode, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count);
// for those settings that are unlikely to require buffers to be recreated, we'll add setters
virtual void set_fsr_sharpness(float p_fsr_sharpness);
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index 635f44786c..227d44aa27 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* texture_storage.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* texture_storage.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 TEXTURE_STORAGE_H
#define TEXTURE_STORAGE_H
@@ -100,12 +100,14 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) = 0;
+ virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const = 0;
+
/* Decal API */
virtual RID decal_allocate() = 0;
virtual void decal_initialize(RID p_rid) = 0;
virtual void decal_free(RID p_rid) = 0;
- virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
+ virtual void decal_set_size(RID p_decal, const Vector3 &p_size) = 0;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
@@ -116,6 +118,7 @@ public:
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
virtual AABB decal_get_aabb(RID p_decal) const = 0;
+ virtual uint32_t decal_get_cull_mask(RID p_decal) const = 0;
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
@@ -125,6 +128,7 @@ public:
virtual RID decal_instance_create(RID p_decal) = 0;
virtual void decal_instance_free(RID p_decal_instance) = 0;
virtual void decal_instance_set_transform(RID p_decal_instance, const Transform3D &p_transform) = 0;
+ virtual void decal_instance_set_sorting_offset(RID p_decal_instance, float p_sorting_offset) = 0;
/* RENDER TARGET */
@@ -160,11 +164,9 @@ public:
virtual RID render_target_get_vrs_texture(RID p_render_target) const = 0;
// override color, depth and velocity buffers (depth and velocity only for 3D)
- virtual void render_target_set_override_color(RID p_render_target, RID p_texture) = 0;
+ virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) = 0;
virtual RID render_target_get_override_color(RID p_render_target) const = 0;
- virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) = 0;
virtual RID render_target_get_override_depth(RID p_render_target) const = 0;
- virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) = 0;
virtual RID render_target_get_override_velocity(RID p_render_target) const = 0;
// get textures
diff --git a/servers/rendering/storage/utilities.cpp b/servers/rendering/storage/utilities.cpp
index 7cc6417a25..c607d7741f 100644
--- a/servers/rendering/storage/utilities.cpp
+++ b/servers/rendering/storage/utilities.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* utilities.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* utilities.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 "utilities.h"
diff --git a/servers/rendering/storage/utilities.h b/servers/rendering/storage/utilities.h
index d240d58917..8fb4907a43 100644
--- a/servers/rendering/storage/utilities.h
+++ b/servers/rendering/storage/utilities.h
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* utilities.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. */
-/*************************************************************************/
+/**************************************************************************/
+/* utilities.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 RENDERER_UTILITIES_H
#define RENDERER_UTILITIES_H
@@ -181,6 +181,8 @@ public:
virtual String get_video_adapter_vendor() const = 0;
virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
virtual String get_video_adapter_api_version() const = 0;
+
+ virtual Size2i get_maximum_viewport_size() const = 0;
};
#endif // RENDERER_UTILITIES_H