summaryrefslogtreecommitdiff
path: root/servers/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering')
-rw-r--r--servers/rendering/SCsub2
-rw-r--r--servers/rendering/rasterizer.h1413
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h602
-rw-r--r--servers/rendering/rasterizer_rd/shaders/ssao.glsl249
-rw-r--r--servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl153
-rw-r--r--servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl45
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp (renamed from servers/rendering/rendering_server_canvas.cpp)507
-rw-r--r--servers/rendering/renderer_canvas_cull.h (renamed from servers/rendering/rendering_server_canvas.h)48
-rw-r--r--servers/rendering/renderer_canvas_render.cpp31
-rw-r--r--servers/rendering/renderer_canvas_render.h604
-rw-r--r--servers/rendering/renderer_compositor.cpp42
-rw-r--r--servers/rendering/renderer_compositor.h78
-rw-r--r--servers/rendering/renderer_rd/SCsub (renamed from servers/rendering/rasterizer_rd/SCsub)0
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp (renamed from servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp)678
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h (renamed from servers/rendering/rasterizer_rd/rasterizer_effects_rd.h)230
-rw-r--r--servers/rendering/renderer_rd/light_cluster_builder.cpp (renamed from servers/rendering/rasterizer_rd/light_cluster_builder.cpp)6
-rw-r--r--servers/rendering/renderer_rd/light_cluster_builder.h (renamed from servers/rendering/rasterizer_rd/light_cluster_builder.h)6
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.cpp (renamed from servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp)22
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.h (renamed from servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h)16
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp (renamed from servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp)280
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h (renamed from servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h)53
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp (renamed from servers/rendering/rasterizer_rd/rasterizer_rd.cpp)38
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h (renamed from servers/rendering/rasterizer_rd/rasterizer_rd.h)44
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_forward.cpp (renamed from servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp)2101
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_forward.h745
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp (renamed from servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp)1601
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h (renamed from servers/rendering/rasterizer_rd/rasterizer_scene_rd.h)188
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp (renamed from servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp)1679
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h (renamed from servers/rendering/rasterizer_rd/rasterizer_storage_rd.h)332
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.cpp (renamed from servers/rendering/rasterizer_rd/shader_compiler_rd.cpp)35
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.h (renamed from servers/rendering/rasterizer_rd/shader_compiler_rd.h)4
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp (renamed from servers/rendering/rasterizer_rd/shader_rd.cpp)153
-rw-r--r--servers/rendering/renderer_rd/shader_rd.h (renamed from servers/rendering/rasterizer_rd/shader_rd.h)12
-rw-r--r--servers/rendering/renderer_rd/shaders/SCsub (renamed from servers/rendering/rasterizer_rd/shaders/SCsub)7
-rw-r--r--servers/rendering/renderer_rd/shaders/bokeh_dof.glsl (renamed from servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl (renamed from servers/rendering/rasterizer_rd/shaders/canvas.glsl)25
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl (renamed from servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_sdf.glsl (renamed from servers/rendering/rasterizer_rd/shaders/canvas_sdf.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl (renamed from servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl (renamed from servers/rendering/rasterizer_rd/shaders/cluster_data_inc.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/copy.glsl (renamed from servers/rendering/rasterizer_rd/shaders/copy.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/copy_to_fb.glsl (renamed from servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/cube_to_dp.glsl (renamed from servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl (renamed from servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_filter.glsl (renamed from servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl (renamed from servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/gi.glsl (renamed from servers/rendering/rasterizer_rd/shaders/gi.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe.glsl (renamed from servers/rendering/rasterizer_rd/shaders/giprobe.glsl)11
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_debug.glsl (renamed from servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl (renamed from servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_write.glsl (renamed from servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/luminance_reduce.glsl (renamed from servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl (renamed from servers/rendering/rasterizer_rd/shaders/particles.glsl)2
-rw-r--r--servers/rendering/renderer_rd/shaders/particles_copy.glsl (renamed from servers/rendering/rasterizer_rd/shaders/particles_copy.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/resolve.glsl (renamed from servers/rendering/rasterizer_rd/shaders/resolve.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/roughness_limiter.glsl (renamed from servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward.glsl (renamed from servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl)234
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl (renamed from servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl)100
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl (renamed from servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl (renamed from servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl (renamed from servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sdfgi_debug.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sdfgi_debug_probes.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl)14
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sdfgi_fields.glsl)2
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/shadow_reduce.glsl (renamed from servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/skeleton.glsl199
-rw-r--r--servers/rendering/renderer_rd/shaders/sky.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sky.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/sort.glsl (renamed from servers/rendering/rasterizer_rd/shaders/sort.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/specular_merge.glsl (renamed from servers/rendering/rasterizer_rd/shaders/specular_merge.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao.glsl486
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_blur.glsl154
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_downsample.glsl206
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl126
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_interleave.glsl119
-rw-r--r--servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl (renamed from servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/tonemap.glsl (renamed from servers/rendering/rasterizer_rd/shaders/tonemap.glsl)24
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl (renamed from servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl)21
-rw-r--r--servers/rendering/renderer_scene.cpp37
-rw-r--r--servers/rendering/renderer_scene.h203
-rw-r--r--servers/rendering/renderer_scene_cull.cpp3508
-rw-r--r--servers/rendering/renderer_scene_cull.h1045
-rw-r--r--servers/rendering/renderer_scene_render.cpp31
-rw-r--r--servers/rendering/renderer_scene_render.h230
-rw-r--r--servers/rendering/renderer_storage.cpp (renamed from servers/rendering/rasterizer.cpp)46
-rw-r--r--servers/rendering/renderer_storage.h623
-rw-r--r--servers/rendering/renderer_thread_pool.cpp42
-rw-r--r--servers/rendering/renderer_thread_pool.h45
-rw-r--r--servers/rendering/renderer_viewport.cpp (renamed from servers/rendering/rendering_server_viewport.cpp)218
-rw-r--r--servers/rendering/renderer_viewport.h (renamed from servers/rendering/rendering_server_viewport.h)18
-rw-r--r--servers/rendering/rendering_device.cpp10
-rw-r--r--servers/rendering/rendering_device.h15
-rw-r--r--servers/rendering/rendering_device_binds.cpp6
-rw-r--r--servers/rendering/rendering_device_binds.h12
-rw-r--r--servers/rendering/rendering_server_default.cpp (renamed from servers/rendering/rendering_server_raster.cpp)112
-rw-r--r--servers/rendering/rendering_server_default.h (renamed from servers/rendering/rendering_server_raster.h)49
-rw-r--r--servers/rendering/rendering_server_globals.cpp17
-rw-r--r--servers/rendering/rendering_server_globals.h27
-rw-r--r--servers/rendering/rendering_server_scene.cpp3040
-rw-r--r--servers/rendering/rendering_server_scene.h476
-rw-r--r--servers/rendering/rendering_server_wrap_mt.cpp4
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h29
-rw-r--r--servers/rendering/shader_language.cpp469
-rw-r--r--servers/rendering/shader_language.h16
-rw-r--r--servers/rendering/shader_types.cpp20
-rw-r--r--servers/rendering/shader_types.h4
108 files changed, 14466 insertions, 9613 deletions
diff --git a/servers/rendering/SCsub b/servers/rendering/SCsub
index 5ea0d40486..0939b68482 100644
--- a/servers/rendering/SCsub
+++ b/servers/rendering/SCsub
@@ -4,4 +4,4 @@ Import("env")
env.add_source_files(env.servers_sources, "*.cpp")
-SConscript("rasterizer_rd/SCsub")
+SConscript("renderer_rd/SCsub")
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
deleted file mode 100644
index 4df140f8c3..0000000000
--- a/servers/rendering/rasterizer.h
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*************************************************************************/
-/* rasterizer.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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. */
-/*************************************************************************/
-
-#ifndef RASTERIZER_H
-#define RASTERIZER_H
-
-#include "core/math/camera_matrix.h"
-#include "core/templates/pair.h"
-#include "core/templates/self_list.h"
-#include "servers/rendering_server.h"
-
-class RasterizerScene {
-public:
- /* SHADOW ATLAS API */
-
- virtual RID shadow_atlas_create() = 0;
- virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
- virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
- virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
-
- virtual void directional_shadow_atlas_set_size(int p_size) = 0;
- virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
- virtual void set_directional_shadow_count(int p_count) = 0;
-
- /* SDFGI UPDATE */
-
- struct InstanceBase;
-
- virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0;
- virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0;
- virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0;
- virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0;
- virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0;
-
- /* SKY API */
-
- virtual RID sky_create() = 0;
- virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
- virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0;
- virtual void sky_set_material(RID p_sky, RID p_material) = 0;
- virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
-
- /* ENVIRONMENT API */
-
- virtual RID environment_create() = 0;
-
- virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0;
- virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
- virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0;
- virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0;
- virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
- virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
- virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) = 0;
-// FIXME: Disabled during Vulkan refactoring, should be ported.
-#if 0
- virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
-#endif
-
- virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 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;
-
- virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
-
- virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
- virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
- virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
- virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
-
- virtual 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) = 0;
- virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
-
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
-
- virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) = 0;
-
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
-
- virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
- virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
-
- virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
-
- virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
-
- virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
-
- virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
-
- virtual bool is_environment(RID p_env) const = 0;
- virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0;
- virtual int environment_get_canvas_max_layer(RID p_env) const = 0;
-
- virtual RID camera_effects_create() = 0;
-
- virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0;
- virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0;
-
- virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0;
- virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0;
-
- virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
- virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
-
- struct InstanceDependency {
- void instance_notify_changed(bool p_aabb, bool p_dependencies);
- void instance_notify_deleted(RID p_deleted);
-
- ~InstanceDependency();
-
- private:
- friend struct InstanceBase;
- Map<InstanceBase *, uint32_t> instances;
- };
-
- struct InstanceBase {
- RS::InstanceType base_type;
- RID base;
-
- RID skeleton;
- RID material_override;
-
- RID instance_data;
-
- Transform transform;
-
- int depth_layer;
- uint32_t layer_mask;
- uint32_t instance_version;
-
- //RID sampled_light;
-
- Vector<RID> materials;
- Vector<RID> light_instances;
- Vector<RID> reflection_probe_instances;
- Vector<RID> gi_probe_instances;
-
- Vector<float> blend_values;
-
- RS::ShadowCastingSetting cast_shadows;
-
- //fit in 32 bits
- bool mirror : 8;
- bool receive_shadows : 8;
- bool visible : 8;
- bool baked_light : 2; //this flag is only to know if it actually did use baked light
- bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light
- bool redraw_if_visible : 4;
-
- float depth; //used for sorting
-
- SelfList<InstanceBase> dependency_item;
-
- InstanceBase *lightmap;
- Rect2 lightmap_uv_scale;
- int lightmap_slice_index;
- uint32_t lightmap_cull_index;
- Vector<Color> lightmap_sh; //spherical harmonic
-
- AABB aabb;
- AABB transformed_aabb;
-
- struct InstanceShaderParameter {
- int32_t index = -1;
- Variant value;
- Variant default_value;
- PropertyInfo info;
- };
-
- Map<StringName, InstanceShaderParameter> instance_shader_parameters;
- bool instance_allocated_shader_parameters = false;
- int32_t instance_allocated_shader_parameters_offset = -1;
-
- virtual void dependency_deleted(RID p_dependency) {}
- virtual void dependency_changed(bool p_aabb, bool p_dependencies) {}
-
- Set<InstanceDependency *> dependencies;
-
- void instance_increase_version() {
- instance_version++;
- }
-
- void update_dependency(InstanceDependency *p_dependency) {
- dependencies.insert(p_dependency);
- p_dependency->instances[this] = instance_version;
- }
-
- void clean_up_dependencies() {
- List<Pair<InstanceDependency *, Map<InstanceBase *, uint32_t>::Element *>> to_clean_up;
- for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) {
- InstanceDependency *dep = E->get();
- Map<InstanceBase *, uint32_t>::Element *F = dep->instances.find(this);
- ERR_CONTINUE(!F);
- if (F->get() != instance_version) {
- Pair<InstanceDependency *, Map<InstanceBase *, uint32_t>::Element *> p;
- p.first = dep;
- p.second = F;
- to_clean_up.push_back(p);
- }
- }
-
- while (to_clean_up.size()) {
- to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second);
- to_clean_up.pop_front();
- }
- }
-
- void clear_dependencies() {
- for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) {
- InstanceDependency *dep = E->get();
- dep->instances.erase(this);
- }
- dependencies.clear();
- }
-
- InstanceBase() :
- dependency_item(this) {
- base_type = RS::INSTANCE_NONE;
- cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
- receive_shadows = true;
- visible = true;
- depth_layer = 0;
- layer_mask = 1;
- instance_version = 0;
- baked_light = false;
- dynamic_gi = false;
- redraw_if_visible = false;
- lightmap_slice_index = 0;
- lightmap = nullptr;
- lightmap_cull_index = 0;
- }
-
- virtual ~InstanceBase() {
- clear_dependencies();
- }
- };
-
- virtual RID light_instance_create(RID p_light) = 0;
- virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
- virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0;
- virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0;
- virtual void light_instance_mark_visible(RID p_light_instance) = 0;
- virtual bool light_instances_can_render_shadow_cube() const {
- return true;
- }
-
- virtual RID reflection_atlas_create() = 0;
- virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0;
-
- virtual RID reflection_probe_instance_create(RID p_probe) = 0;
- virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) = 0;
- virtual void reflection_probe_release_atlas_index(RID p_instance) = 0;
- 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 bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
-
- virtual RID decal_instance_create(RID p_decal) = 0;
- virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0;
-
- virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
- virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
- virtual bool gi_probe_needs_update(RID p_probe) const = 0;
- virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0;
-
- virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
-
- virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
-
- virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
- virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
- virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) = 0;
- virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) = 0;
- virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) = 0;
-
- virtual void set_scene_pass(uint64_t p_pass) = 0;
- virtual void set_time(double p_time, double p_step) = 0;
- virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
-
- virtual RID render_buffers_create() = 0;
- virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0;
-
- virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0;
- virtual bool screen_space_roughness_limiter_is_active() const = 0;
-
- virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0;
- virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0;
-
- virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0;
-
- virtual bool free(RID p_rid) = 0;
-
- virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0;
-
- virtual void update() = 0;
- virtual ~RasterizerScene() {}
-};
-
-class RasterizerStorage {
- Color default_clear_color;
-
-public:
- /* TEXTURE API */
-
- virtual RID texture_2d_create(const Ref<Image> &p_image) = 0;
- virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0;
- virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0;
- virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent
-
- virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming
- virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
- virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
- virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0;
-
- //these two APIs can be used together or in combination with the others.
- virtual RID texture_2d_placeholder_create() = 0;
- virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0;
- virtual RID texture_3d_placeholder_create() = 0;
-
- virtual Ref<Image> texture_2d_get(RID p_texture) const = 0;
- virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0;
- virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0;
-
- virtual void texture_replace(RID p_texture, RID p_by_texture) = 0;
- virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
-
- virtual void texture_set_path(RID p_texture, const String &p_path) = 0;
- virtual String texture_get_path(RID p_texture) const = 0;
-
- virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0;
- virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0;
- virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) = 0;
-
- virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) = 0;
-
- virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
-
- virtual Size2 texture_size_with_proxy(RID p_proxy) = 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;
-
- /* CANVAS TEXTURE API */
-
- virtual RID canvas_texture_create() = 0;
- virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
- virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
-
- virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0;
- virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0;
-
- /* SHADER API */
-
- virtual RID shader_create() = 0;
-
- virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
- virtual String shader_get_code(RID p_shader) const = 0;
- virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0;
-
- virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0;
- virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0;
- virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0;
-
- /* COMMON MATERIAL API */
-
- virtual RID material_create() = 0;
-
- virtual void material_set_render_priority(RID p_material, int priority) = 0;
- virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
-
- virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0;
- virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
-
- virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0;
-
- virtual bool material_is_animated(RID p_material) = 0;
- virtual bool material_casts_shadows(RID p_material) = 0;
-
- struct InstanceShaderParam {
- PropertyInfo info;
- int index;
- Variant default_value;
- };
-
- virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
-
- virtual void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) = 0;
-
- /* MESH API */
-
- virtual RID mesh_create() = 0;
-
- /// Returns stride
- virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) = 0;
-
- virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0;
-
- virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) = 0;
- virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0;
-
- virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
-
- virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0;
- virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0;
-
- virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const = 0;
-
- virtual int mesh_get_surface_count(RID p_mesh) const = 0;
-
- virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0;
- virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0;
-
- virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) = 0;
-
- virtual void mesh_clear(RID p_mesh) = 0;
-
- /* MULTIMESH API */
-
- virtual RID multimesh_create() = 0;
-
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0;
-
- virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
-
- virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0;
- virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0;
- virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0;
- virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0;
- virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0;
-
- virtual RID multimesh_get_mesh(RID p_multimesh) const = 0;
-
- virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0;
- virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0;
- virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0;
- virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0;
-
- virtual void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) = 0;
- virtual Vector<float> multimesh_get_buffer(RID p_multimesh) const = 0;
-
- virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
- virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
-
- virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0;
-
- /* IMMEDIATE API */
-
- virtual RID immediate_create() = 0;
- virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0;
- virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0;
- virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0;
- virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) = 0;
- virtual void immediate_color(RID p_immediate, const Color &p_color) = 0;
- virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) = 0;
- virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) = 0;
- virtual void immediate_end(RID p_immediate) = 0;
- virtual void immediate_clear(RID p_immediate) = 0;
- virtual void immediate_set_material(RID p_immediate, RID p_material) = 0;
- virtual RID immediate_get_material(RID p_immediate) const = 0;
- virtual AABB immediate_get_aabb(RID p_immediate) const = 0;
-
- /* SKELETON API */
-
- virtual RID skeleton_create() = 0;
- virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0;
- virtual int skeleton_get_bone_count(RID p_skeleton) const = 0;
- virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0;
- virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0;
- virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
- virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
- virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
-
- /* Light API */
-
- virtual RID light_create(RS::LightType p_type) = 0;
-
- RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); }
- RID omni_light_create() { return light_create(RS::LIGHT_OMNI); }
- RID spot_light_create() { return light_create(RS::LIGHT_SPOT); }
-
- virtual void light_set_color(RID p_light, const Color &p_color) = 0;
- virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0;
- virtual void light_set_shadow(RID p_light, bool p_enabled) = 0;
- virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0;
- virtual void light_set_projector(RID p_light, RID p_texture) = 0;
- virtual void light_set_negative(RID p_light, bool p_enable) = 0;
- virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0;
- virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0;
- virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) = 0;
- virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0;
-
- virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) = 0;
-
- virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) = 0;
- virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
- virtual bool light_directional_get_blend_splits(RID p_light) const = 0;
- virtual void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) = 0;
- virtual RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const = 0;
-
- virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0;
- virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0;
-
- virtual bool light_has_shadow(RID p_light) const = 0;
-
- virtual RS::LightType light_get_type(RID p_light) const = 0;
- virtual AABB light_get_aabb(RID p_light) const = 0;
- virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0;
- virtual Color light_get_color(RID p_light) = 0;
- 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;
-
- /* PROBE API */
-
- virtual RID reflection_probe_create() = 0;
-
- virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0;
- virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
- virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) = 0;
- virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) = 0;
- 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_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;
- virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0;
- virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
-
- 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_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;
-
- virtual void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0;
- virtual void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0;
-
- /* DECAL API */
-
- virtual RID decal_create() = 0;
- virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 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;
- virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
- virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
- virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
- virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
- virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
-
- virtual AABB decal_get_aabb(RID p_decal) const = 0;
-
- /* GI PROBE API */
-
- virtual RID gi_probe_create() = 0;
-
- virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
-
- virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0;
- virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0;
- virtual Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const = 0;
- virtual Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const = 0;
- virtual Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const = 0;
-
- virtual Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const = 0;
- virtual Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) = 0;
- virtual float gi_probe_get_dynamic_range(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_propagation(RID p_gi_probe, float p_range) = 0;
- virtual float gi_probe_get_propagation(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_energy(RID p_gi_probe, float p_energy) = 0;
- virtual float gi_probe_get_energy(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_ao(RID p_gi_probe, float p_ao) = 0;
- virtual float gi_probe_get_ao(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) = 0;
- virtual float gi_probe_get_ao_size(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_bias(RID p_gi_probe, float p_bias) = 0;
- virtual float gi_probe_get_bias(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) = 0;
- virtual float gi_probe_get_normal_bias(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_interior(RID p_gi_probe, bool p_enable) = 0;
- virtual bool gi_probe_is_interior(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) = 0;
- virtual bool gi_probe_is_using_two_bounces(RID p_gi_probe) const = 0;
-
- virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0;
- virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0;
-
- virtual uint32_t gi_probe_get_version(RID p_probe) = 0;
-
- /* LIGHTMAP CAPTURE */
-
- virtual RID lightmap_create() = 0;
-
- virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0;
- virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0;
- virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0;
- virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0;
- virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0;
- virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0;
- virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0;
- virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0;
- virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0;
- virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0;
- virtual bool lightmap_is_interior(RID p_lightmap) const = 0;
- virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0;
- virtual float lightmap_get_probe_capture_update_speed() const = 0;
-
- /* PARTICLES */
-
- virtual RID particles_create() = 0;
-
- virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
- virtual bool particles_get_emitting(RID p_particles) = 0;
-
- virtual void particles_set_amount(RID p_particles, int p_amount) = 0;
- virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0;
- virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0;
- virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0;
- virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0;
- virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0;
- virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0;
- virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0;
- virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0;
- virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
- virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
- virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
- virtual void particles_set_collision_base_size(RID p_particles, float p_size) = 0;
- virtual void particles_restart(RID p_particles) = 0;
- virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0;
- virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) = 0;
-
- virtual bool particles_is_inactive(RID p_particles) const = 0;
-
- virtual void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) = 0;
-
- virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0;
- virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0;
-
- virtual void particles_request_process(RID p_particles) = 0;
- virtual AABB particles_get_current_aabb(RID p_particles) = 0;
- virtual AABB particles_get_aabb(RID p_particles) const = 0;
-
- virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0;
-
- virtual int particles_get_draw_passes(RID p_particles) const = 0;
- virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0;
-
- virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0;
-
- virtual void particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) = 0;
- virtual void particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) = 0;
-
- virtual void update_particles() = 0;
-
- /* PARTICLES COLLISION */
-
- virtual RID particles_collision_create() = 0;
- virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) = 0;
- virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0;
- virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) = 0; //for spheres
- virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; //for non-spheres
- virtual void particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) = 0;
- virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) = 0;
- virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) = 0;
- virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; //for SDF and vector field, heightfield is dynamic
- virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; //for SDF and vector field
- 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;
-
- /* GLOBAL VARIABLES */
-
- virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
- virtual void global_variable_remove(const StringName &p_name) = 0;
- virtual Vector<StringName> global_variable_get_list() const = 0;
-
- virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0;
- virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0;
- virtual Variant global_variable_get(const StringName &p_name) const = 0;
- virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0;
-
- virtual void global_variables_load_settings(bool p_load_textures = true) = 0;
- virtual void global_variables_clear() = 0;
-
- virtual int32_t global_variables_instance_allocate(RID p_instance) = 0;
- virtual void global_variables_instance_free(RID p_instance) = 0;
- virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0;
-
- /* RENDER TARGET */
-
- enum RenderTargetFlags {
- RENDER_TARGET_TRANSPARENT,
- RENDER_TARGET_DIRECT_TO_SCREEN,
- RENDER_TARGET_FLAG_MAX
- };
-
- virtual RID render_target_create() = 0;
- virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
- virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0;
- virtual RID render_target_get_texture(RID p_render_target) = 0;
- virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
- virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
- virtual bool render_target_was_used(RID p_render_target) = 0;
- virtual void render_target_set_as_unused(RID p_render_target) = 0;
-
- virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0;
- virtual bool render_target_is_clear_requested(RID p_render_target) = 0;
- virtual Color render_target_get_clear_request_color(RID p_render_target) = 0;
- virtual void render_target_disable_clear_request(RID p_render_target) = 0;
- virtual void render_target_do_clear_request(RID p_render_target) = 0;
-
- virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0;
- virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0;
-
- virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
- virtual bool free(RID p_rid) = 0;
-
- virtual bool has_os_feature(const String &p_feature) const = 0;
-
- virtual void update_dirty_resources() = 0;
-
- virtual void set_debug_generate_wireframes(bool p_generate) = 0;
-
- virtual void render_info_begin_capture() = 0;
- virtual void render_info_end_capture() = 0;
- virtual int get_captured_render_info(RS::RenderInfo p_info) = 0;
-
- virtual int get_render_info(RS::RenderInfo p_info) = 0;
- virtual String get_video_adapter_name() const = 0;
- virtual String get_video_adapter_vendor() const = 0;
-
- static RasterizerStorage *base_singleton;
-
- void set_default_clear_color(const Color &p_color) {
- default_clear_color = p_color;
- }
-
- Color get_default_clear_color() const {
- return default_clear_color;
- }
-#define TIMESTAMP_BEGIN() \
- { \
- if (RSG::storage->capturing_timestamps) \
- RSG::storage->capture_timestamps_begin(); \
- }
-
-#define RENDER_TIMESTAMP(m_text) \
- { \
- if (RSG::storage->capturing_timestamps) \
- RSG::storage->capture_timestamp(m_text); \
- }
-
- bool capturing_timestamps = false;
-
- virtual void capture_timestamps_begin() = 0;
- virtual void capture_timestamp(const String &p_name) = 0;
- virtual uint32_t get_captured_timestamps_count() const = 0;
- virtual uint64_t get_captured_timestamps_frame() const = 0;
- virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0;
- virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0;
- virtual String get_captured_timestamp_name(uint32_t p_index) const = 0;
-
- RasterizerStorage();
- virtual ~RasterizerStorage() {}
-};
-
-class RasterizerCanvas {
-public:
- static RasterizerCanvas *singleton;
-
- enum CanvasRectFlags {
- CANVAS_RECT_REGION = 1,
- CANVAS_RECT_TILE = 2,
- CANVAS_RECT_FLIP_H = 4,
- CANVAS_RECT_FLIP_V = 8,
- CANVAS_RECT_TRANSPOSE = 16,
- CANVAS_RECT_CLIP_UV = 32,
- CANVAS_RECT_IS_GROUP = 64,
- };
-
- struct Light {
- bool enabled;
- Color color;
- Transform2D xform;
- float height;
- float energy;
- float scale;
- int z_min;
- int z_max;
- int layer_min;
- int layer_max;
- int item_mask;
- int item_shadow_mask;
- float directional_distance;
- RS::CanvasLightMode mode;
- RS::CanvasLightBlendMode blend_mode;
- RID texture;
- Vector2 texture_offset;
- RID canvas;
- bool use_shadow;
- int shadow_buffer_size;
- RS::CanvasLightShadowFilter shadow_filter;
- Color shadow_color;
- float shadow_smooth;
-
- //void *texture_cache; // implementation dependent
- Rect2 rect_cache;
- Transform2D xform_cache;
- float radius_cache; //used for shadow far plane
- //CameraMatrix shadow_matrix_cache;
-
- Transform2D light_shader_xform;
- //Vector2 light_shader_pos;
-
- Light *shadows_next_ptr;
- Light *filter_next_ptr;
- Light *next_ptr;
- Light *directional_next_ptr;
-
- RID light_internal;
- uint64_t version;
-
- int32_t render_index_cache;
-
- Light() {
- version = 0;
- enabled = true;
- color = Color(1, 1, 1);
- shadow_color = Color(0, 0, 0, 0);
- height = 0;
- z_min = -1024;
- z_max = 1024;
- layer_min = 0;
- layer_max = 0;
- item_mask = 1;
- scale = 1.0;
- energy = 1.0;
- item_shadow_mask = 1;
- mode = RS::CANVAS_LIGHT_MODE_POINT;
- blend_mode = RS::CANVAS_LIGHT_BLEND_MODE_ADD;
- // texture_cache = nullptr;
- next_ptr = nullptr;
- directional_next_ptr = nullptr;
- filter_next_ptr = nullptr;
- use_shadow = false;
- shadow_buffer_size = 2048;
- shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE;
- shadow_smooth = 0.0;
- render_index_cache = -1;
- directional_distance = 10000.0;
- }
- };
-
- //easier wrap to avoid mistakes
-
- struct Item;
-
- typedef uint64_t PolygonID;
- virtual PolygonID request_polygon(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>()) = 0;
- virtual void free_polygon(PolygonID p_polygon) = 0;
-
- //also easier to wrap to avoid mistakes
- struct Polygon {
- PolygonID polygon_id;
- Rect2 rect_cache;
-
- _FORCE_INLINE_ void create(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>()) {
- ERR_FAIL_COND(polygon_id != 0);
- {
- uint32_t pc = p_points.size();
- const Vector2 *v2 = p_points.ptr();
- rect_cache.position = *v2;
- for (uint32_t i = 1; i < pc; i++) {
- rect_cache.expand_to(v2[i]);
- }
- }
- polygon_id = singleton->request_polygon(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights);
- }
-
- _FORCE_INLINE_ Polygon() { polygon_id = 0; }
- _FORCE_INLINE_ ~Polygon() {
- if (polygon_id) {
- singleton->free_polygon(polygon_id);
- }
- }
- };
-
- //item
-
- struct Item {
- //commands are allocated in blocks of 4k to improve performance
- //and cache coherence.
- //blocks always grow but never shrink.
-
- struct CommandBlock {
- enum {
- MAX_SIZE = 4096
- };
- uint32_t usage;
- uint8_t *memory;
- };
-
- struct Command {
- enum Type {
- TYPE_RECT,
- TYPE_NINEPATCH,
- TYPE_POLYGON,
- TYPE_PRIMITIVE,
- TYPE_MESH,
- TYPE_MULTIMESH,
- TYPE_PARTICLES,
- TYPE_TRANSFORM,
- TYPE_CLIP_IGNORE,
- };
-
- Command *next;
- Type type;
- virtual ~Command() {}
- };
-
- struct CommandRect : public Command {
- Rect2 rect;
- Color modulate;
- Rect2 source;
- uint8_t flags;
-
- RID texture;
-
- CommandRect() {
- flags = 0;
- type = TYPE_RECT;
- }
- };
-
- struct CommandNinePatch : public Command {
- Rect2 rect;
- Rect2 source;
- float margin[4];
- bool draw_center;
- Color color;
- RS::NinePatchAxisMode axis_x;
- RS::NinePatchAxisMode axis_y;
-
- RID texture;
-
- CommandNinePatch() {
- draw_center = true;
- type = TYPE_NINEPATCH;
- }
- };
-
- struct CommandPolygon : public Command {
- RS::PrimitiveType primitive;
- Polygon polygon;
-
- RID texture;
-
- CommandPolygon() {
- type = TYPE_POLYGON;
- }
- };
-
- struct CommandPrimitive : public Command {
- uint32_t point_count;
- Vector2 points[4];
- Vector2 uvs[4];
- Color colors[4];
-
- RID texture;
-
- CommandPrimitive() {
- type = TYPE_PRIMITIVE;
- }
- };
-
- struct CommandMesh : public Command {
- RID mesh;
- Transform2D transform;
- Color modulate;
-
- RID texture;
-
- CommandMesh() { type = TYPE_MESH; }
- };
-
- struct CommandMultiMesh : public Command {
- RID multimesh;
-
- RID texture;
-
- CommandMultiMesh() { type = TYPE_MULTIMESH; }
- };
-
- struct CommandParticles : public Command {
- RID particles;
-
- RID texture;
-
- CommandParticles() { type = TYPE_PARTICLES; }
- };
-
- struct CommandTransform : public Command {
- Transform2D xform;
- CommandTransform() { type = TYPE_TRANSFORM; }
- };
-
- struct CommandClipIgnore : public Command {
- bool ignore;
- CommandClipIgnore() {
- type = TYPE_CLIP_IGNORE;
- ignore = false;
- }
- };
-
- struct ViewportRender {
- RenderingServer *owner;
- void *udata;
- Rect2 rect;
- };
-
- Transform2D xform;
- bool clip;
- bool visible;
- bool behind;
- bool update_when_visible;
-
- struct CanvasGroup {
- RS::CanvasGroupMode mode;
- bool fit_empty;
- float fit_margin;
- bool blur_mipmaps;
- float clear_margin;
- };
-
- CanvasGroup *canvas_group = nullptr;
- int light_mask;
- int z_final;
-
- mutable bool custom_rect;
- mutable bool rect_dirty;
- mutable Rect2 rect;
- RID material;
- RID skeleton;
-
- Item *next;
-
- struct CopyBackBuffer {
- Rect2 rect;
- Rect2 screen_rect;
- bool full;
- };
- CopyBackBuffer *copy_back_buffer;
-
- Color final_modulate;
- Transform2D final_transform;
- Rect2 final_clip_rect;
- Item *final_clip_owner;
- Item *material_owner;
- Item *canvas_group_owner;
- ViewportRender *vp_render;
- bool distance_field;
- bool light_masked;
-
- Rect2 global_rect_cache;
-
- const Rect2 &get_rect() const {
- if (custom_rect || (!rect_dirty && !update_when_visible)) {
- return rect;
- }
-
- //must update rect
-
- if (commands == nullptr) {
- rect = Rect2();
- rect_dirty = false;
- return rect;
- }
-
- Transform2D xf;
- bool found_xform = false;
- bool first = true;
-
- const Item::Command *c = commands;
-
- while (c) {
- Rect2 r;
-
- switch (c->type) {
- case Item::Command::TYPE_RECT: {
- const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c);
- r = crect->rect;
-
- } break;
- case Item::Command::TYPE_NINEPATCH: {
- const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c);
- r = style->rect;
- } break;
-
- case Item::Command::TYPE_POLYGON: {
- const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
- r = polygon->polygon.rect_cache;
- } break;
- case Item::Command::TYPE_PRIMITIVE: {
- const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
- for (uint32_t j = 0; j < primitive->point_count; j++) {
- if (j == 0) {
- r.position = primitive->points[0];
- } else {
- r.expand_to(primitive->points[j]);
- }
- }
- } break;
- case Item::Command::TYPE_MESH: {
- const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
- AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID());
-
- r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
-
- } break;
- case Item::Command::TYPE_MULTIMESH: {
- const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c);
- AABB aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh);
-
- r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
-
- } break;
- case Item::Command::TYPE_PARTICLES: {
- const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c);
- if (particles_cmd->particles.is_valid()) {
- AABB aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles);
- r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
- }
-
- } break;
- case Item::Command::TYPE_TRANSFORM: {
- const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
- xf = transform->xform;
- found_xform = true;
- [[fallthrough]];
- }
- default: {
- c = c->next;
- continue;
- }
- }
-
- if (found_xform) {
- r = xf.xform(r);
- found_xform = false;
- }
-
- if (first) {
- rect = r;
- first = false;
- } else {
- rect = rect.merge(r);
- }
- c = c->next;
- }
-
- rect_dirty = false;
- return rect;
- }
-
- Command *commands;
- Command *last_command;
- Vector<CommandBlock> blocks;
- uint32_t current_block;
-
- template <class T>
- T *alloc_command() {
- T *command;
- if (commands == nullptr) {
- // As the most common use case of canvas items is to
- // use only one command, the first is done with it's
- // own allocation. The rest of them use blocks.
- command = memnew(T);
- command->next = nullptr;
- commands = command;
- last_command = command;
- } else {
- //Subsequent commands go into a block.
-
- while (true) {
- if (unlikely(current_block == (uint32_t)blocks.size())) {
- // If we need more blocks, we allocate them
- // (they won't be freed until this CanvasItem is
- // deleted, though).
- CommandBlock cb;
- cb.memory = (uint8_t *)memalloc(CommandBlock::MAX_SIZE);
- cb.usage = 0;
- blocks.push_back(cb);
- }
-
- CommandBlock *c = &blocks.write[current_block];
- size_t space_left = CommandBlock::MAX_SIZE - c->usage;
- if (space_left < sizeof(T)) {
- current_block++;
- continue;
- }
-
- //allocate block and add to the linked list
- void *memory = c->memory + c->usage;
- command = memnew_placement(memory, T);
- command->next = nullptr;
- last_command->next = command;
- last_command = command;
- c->usage += sizeof(T);
- break;
- }
- }
-
- rect_dirty = true;
- return command;
- }
-
- void clear() {
- // The first one is always allocated on heap
- // the rest go in the blocks
- Command *c = commands;
- while (c) {
- Command *n = c->next;
- if (c == commands) {
- memdelete(commands);
- commands = nullptr;
- } else {
- c->~Command();
- }
- c = n;
- }
- {
- uint32_t cbc = MIN((current_block + 1), (uint32_t)blocks.size());
- CommandBlock *blockptr = blocks.ptrw();
- for (uint32_t i = 0; i < cbc; i++) {
- blockptr[i].usage = 0;
- }
- }
-
- last_command = nullptr;
- commands = nullptr;
- current_block = 0;
- clip = false;
- rect_dirty = true;
- final_clip_owner = nullptr;
- material_owner = nullptr;
- light_masked = false;
- }
-
- RS::CanvasItemTextureFilter texture_filter;
- RS::CanvasItemTextureRepeat texture_repeat;
-
- Item() {
- commands = nullptr;
- last_command = nullptr;
- current_block = 0;
- light_mask = 1;
- vp_render = nullptr;
- next = nullptr;
- final_clip_owner = nullptr;
- canvas_group_owner = nullptr;
- clip = false;
- final_modulate = Color(1, 1, 1, 1);
- visible = true;
- rect_dirty = true;
- custom_rect = false;
- behind = false;
- material_owner = nullptr;
- copy_back_buffer = nullptr;
- distance_field = false;
- light_masked = false;
- update_when_visible = false;
- z_final = 0;
- texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
- texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
- }
- virtual ~Item() {
- clear();
- for (int i = 0; i < blocks.size(); i++) {
- memfree(blocks[i].memory);
- }
- if (copy_back_buffer) {
- memdelete(copy_back_buffer);
- }
- }
- };
-
- 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;
- RID canvas;
- RID polygon;
- RID occluder;
- Rect2 aabb_cache;
- Transform2D xform;
- Transform2D xform_cache;
- int light_mask;
- bool sdf_collision;
- RS::CanvasOccluderPolygonCullMode cull_cache;
-
- LightOccluderInstance *next;
-
- LightOccluderInstance() {
- enabled = true;
- sdf_collision = false;
- next = nullptr;
- light_mask = 1;
- cull_cache = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
- }
- };
-
- virtual RID light_create() = 0;
- virtual void light_set_texture(RID p_rid, RID p_texture) = 0;
- virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0;
- virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0;
- virtual void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) = 0;
-
- virtual void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) = 0;
-
- virtual RID occluder_polygon_create() = 0;
- virtual void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) = 0;
- virtual void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) = 0;
- virtual void set_shadow_texture_size(int p_size) = 0;
-
- virtual void draw_window_margins(int *p_margins, RID *p_margin_textures) = 0;
-
- virtual bool free(RID p_rid) = 0;
- virtual void update() = 0;
-
- RasterizerCanvas() { singleton = this; }
- virtual ~RasterizerCanvas() {}
-};
-
-class Rasterizer {
-protected:
- static Rasterizer *(*_create_func)();
-
-public:
- static Rasterizer *create();
-
- virtual RasterizerStorage *get_storage() = 0;
- virtual RasterizerCanvas *get_canvas() = 0;
- virtual RasterizerScene *get_scene() = 0;
-
- virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) = 0;
-
- virtual void initialize() = 0;
- virtual void begin_frame(double frame_step) = 0;
-
- struct BlitToScreen {
- RID render_target;
- Rect2i rect;
- //lens distorted parameters for VR should go here
- };
-
- virtual void prepare_for_blitting_render_targets() = 0;
- virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0;
-
- virtual void end_frame(bool p_swap_buffers) = 0;
- virtual void finalize() = 0;
- virtual uint64_t get_frame_number() const = 0;
- virtual float get_frame_delta_time() const = 0;
-
- virtual bool is_low_end() const = 0;
-
- virtual ~Rasterizer() {}
-};
-
-#endif // RASTERIZER_H
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
deleted file mode 100644
index db083a75cc..0000000000
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
+++ /dev/null
@@ -1,602 +0,0 @@
-/*************************************************************************/
-/* rasterizer_scene_high_end_rd.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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. */
-/*************************************************************************/
-
-#ifndef RASTERIZER_SCENE_HIGHEND_RD_H
-#define RASTERIZER_SCENE_HIGHEND_RD_H
-
-#include "servers/rendering/rasterizer_rd/rasterizer_scene_rd.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h"
-#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
-#include "servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl.gen.h"
-
-class RasterizerSceneHighEndRD : public RasterizerSceneRD {
- enum {
- SCENE_UNIFORM_SET = 0,
- RADIANCE_UNIFORM_SET = 1,
- VIEW_DEPENDANT_UNIFORM_SET = 2,
- RENDER_BUFFERS_UNIFORM_SET = 3,
- TRANSFORMS_UNIFORM_SET = 4,
- MATERIAL_UNIFORM_SET = 5
- };
-
- enum {
- SDFGI_MAX_CASCADES = 8,
- MAX_GI_PROBES = 8
- };
-
- /* Scene Shader */
-
- enum ShaderVersion {
- SHADER_VERSION_DEPTH_PASS,
- SHADER_VERSION_DEPTH_PASS_DP,
- SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
- SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE,
- SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
- SHADER_VERSION_DEPTH_PASS_WITH_SDF,
- SHADER_VERSION_COLOR_PASS,
- SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI,
- SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
- SHADER_VERSION_LIGHTMAP_COLOR_PASS,
- SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
- SHADER_VERSION_MAX
- };
-
- struct {
- SceneHighEndShaderRD scene_shader;
- ShaderCompilerRD compiler;
- } shader;
-
- RasterizerStorageRD *storage;
-
- /* Material */
-
- struct ShaderData : public RasterizerStorageRD::ShaderData {
- enum BlendMode { //used internally
- BLEND_MODE_MIX,
- BLEND_MODE_ADD,
- BLEND_MODE_SUB,
- BLEND_MODE_MUL,
- BLEND_MODE_ALPHA_TO_COVERAGE
- };
-
- enum DepthDraw {
- DEPTH_DRAW_DISABLED,
- DEPTH_DRAW_OPAQUE,
- DEPTH_DRAW_ALWAYS
- };
-
- enum DepthTest {
- DEPTH_TEST_DISABLED,
- DEPTH_TEST_ENABLED
- };
-
- enum Cull {
- CULL_DISABLED,
- CULL_FRONT,
- CULL_BACK
- };
-
- enum CullVariant {
- CULL_VARIANT_NORMAL,
- CULL_VARIANT_REVERSED,
- CULL_VARIANT_DOUBLE_SIDED,
- CULL_VARIANT_MAX
-
- };
-
- enum AlphaAntiAliasing {
- ALPHA_ANTIALIASING_OFF,
- ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
- ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
- };
-
- bool valid;
- RID version;
- uint32_t vertex_input_mask;
- RenderPipelineVertexFormatCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
-
- String path;
-
- Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
-
- Vector<uint32_t> ubo_offsets;
- uint32_t ubo_size;
-
- String code;
- Map<StringName, RID> default_texture_params;
-
- DepthDraw depth_draw;
- DepthTest depth_test;
-
- bool uses_point_size;
- bool uses_alpha;
- bool uses_blend_alpha;
- bool uses_alpha_clip;
- bool uses_depth_pre_pass;
- bool uses_discard;
- bool uses_roughness;
- bool uses_normal;
-
- bool unshaded;
- bool uses_vertex;
- bool uses_sss;
- bool uses_transmittance;
- bool uses_screen_texture;
- bool uses_depth_texture;
- bool uses_normal_texture;
- bool uses_time;
- bool writes_modelview_or_projection;
- bool uses_world_coordinates;
-
- uint64_t last_pass = 0;
- uint32_t index = 0;
-
- virtual void set_code(const String &p_Code);
- virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
-
- virtual bool is_param_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;
- ShaderData();
- virtual ~ShaderData();
- };
-
- RasterizerStorageRD::ShaderData *_create_shader_func();
- static RasterizerStorageRD::ShaderData *_create_shader_funcs() {
- return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_shader_func();
- }
-
- struct MaterialData : public RasterizerStorageRD::MaterialData {
- uint64_t last_frame;
- ShaderData *shader_data;
- RID uniform_buffer;
- RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
- uint64_t last_pass = 0;
- uint32_t index = 0;
- RID next_pass;
- uint8_t priority;
- virtual void set_render_priority(int p_priority);
- virtual void set_next_pass(RID p_pass);
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
- virtual ~MaterialData();
- };
-
- RasterizerStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
- static RasterizerStorageRD::MaterialData *_create_material_funcs(RasterizerStorageRD::ShaderData *p_shader) {
- return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
- }
-
- /* Push Constant */
-
- struct PushConstant {
- uint32_t index;
- uint32_t pad;
- float bake_uv2_offset[2];
- };
-
- /* Framebuffer */
-
- struct RenderBufferDataHighEnd : public RenderBufferData {
- //for rendering, may be MSAAd
-
- RID color;
- RID depth;
- RID specular;
- RID normal_roughness_buffer;
- RID giprobe_buffer;
-
- RID ambient_buffer;
- RID reflection_buffer;
-
- RS::ViewportMSAA msaa;
- RD::TextureSamples texture_samples;
-
- RID color_msaa;
- RID depth_msaa;
- RID specular_msaa;
- RID normal_roughness_buffer_msaa;
- RID roughness_buffer_msaa;
- RID giprobe_buffer_msaa;
-
- RID depth_fb;
- RID depth_normal_roughness_fb;
- RID depth_normal_roughness_giprobe_fb;
- RID color_fb;
- RID color_specular_fb;
- RID specular_only_fb;
- int width, height;
-
- RID render_sdfgi_uniform_set;
- void ensure_specular();
- void ensure_gi();
- void ensure_giprobe();
- void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
-
- RID uniform_set;
-
- ~RenderBufferDataHighEnd();
- };
-
- virtual RenderBufferData *_create_render_buffer_data();
- void _allocate_normal_roughness_texture(RenderBufferDataHighEnd *rb);
-
- RID shadow_sampler;
- RID render_base_uniform_set;
- RID view_dependant_uniform_set;
-
- uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
-
- virtual void _base_uniforms_changed();
- void _render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb);
- virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
- virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
- virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers);
- virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers);
-
- void _update_render_base_uniform_set();
- void _setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count);
- void _update_render_buffers_uniform_set(RID p_render_buffers);
-
- struct LightmapData {
- float normal_xform[12];
- };
-
- struct LightmapCaptureData {
- float sh[9 * 4];
- };
-
- enum {
- INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
- INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
- INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
- INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
- INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
- INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11,
- INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
- INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
- INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
- INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
- INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT = 16,
- INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_MASK = 0x7,
- INSTANCE_DATA_FLAG_SKELETON = 1 << 19,
- };
-
- struct InstanceData {
- float transform[16];
- float normal_transform[16];
- uint32_t flags;
- uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer
- uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap)
- uint32_t mask;
- float lightmap_uv_scale[4];
- };
-
- struct SceneState {
- struct UBO {
- float projection_matrix[16];
- float inv_projection_matrix[16];
-
- float camera_matrix[16];
- float inv_camera_matrix[16];
-
- float viewport_size[2];
- float screen_pixel_size[2];
-
- float directional_penumbra_shadow_kernel[128]; //32 vec4s
- float directional_soft_shadow_kernel[128];
- float penumbra_shadow_kernel[128];
- float soft_shadow_kernel[128];
-
- uint32_t directional_penumbra_shadow_samples;
- uint32_t directional_soft_shadow_samples;
- uint32_t penumbra_shadow_samples;
- uint32_t soft_shadow_samples;
-
- float ambient_light_color_energy[4];
-
- float ambient_color_sky_mix;
- uint32_t use_ambient_light;
- uint32_t use_ambient_cubemap;
- uint32_t use_reflection_cubemap;
-
- float radiance_inverse_xform[12];
-
- float shadow_atlas_pixel_size[2];
- float directional_shadow_pixel_size[2];
-
- uint32_t directional_light_count;
- float dual_paraboloid_side;
- float z_far;
- float z_near;
-
- uint32_t ssao_enabled;
- float ssao_light_affect;
- float ssao_ao_affect;
- uint32_t roughness_limiter_enabled;
-
- float roughness_limiter_amount;
- float roughness_limiter_limit;
- uint32_t roughness_limiter_pad[2];
-
- float ao_color[4];
-
- float sdf_to_bounds[16];
-
- int32_t sdf_offset[3];
- uint32_t material_uv2_mode;
-
- int32_t sdf_size[3];
- uint32_t gi_upscale_for_msaa;
-
- uint32_t volumetric_fog_enabled;
- float volumetric_fog_inv_length;
- float volumetric_fog_detail_spread;
- uint32_t volumetric_fog_pad;
-
- // Fog
- uint32_t fog_enabled;
- float fog_density;
- float fog_height;
- float fog_height_density;
-
- float fog_light_color[3];
- float fog_sun_scatter;
-
- float fog_aerial_perspective;
-
- float time;
- float reflection_multiplier;
-
- uint32_t pancake_shadows;
- };
-
- UBO ubo;
-
- RID uniform_buffer;
-
- LightmapData *lightmaps;
- uint32_t max_lightmaps;
- RID lightmap_buffer;
-
- LightmapCaptureData *lightmap_captures;
- uint32_t max_lightmap_captures;
- RID lightmap_capture_buffer;
-
- RID instance_buffer;
- InstanceData *instances;
- uint32_t max_instances;
-
- bool used_screen_texture = false;
- bool used_normal_texture = false;
- bool used_depth_texture = false;
- bool used_sss = false;
- uint32_t current_shader_index = 0;
- uint32_t current_material_index = 0;
-
- } scene_state;
-
- /* Render List */
-
- struct RenderList {
- int max_elements;
-
- struct Element {
- RasterizerScene::InstanceBase *instance;
- MaterialData *material;
- union {
- struct {
- //from least significant to most significant in sort, TODO: should be endian swapped on big endian
- uint64_t geometry_index : 20;
- uint64_t material_index : 15;
- uint64_t shader_index : 12;
- uint64_t uses_instancing : 1;
- uint64_t uses_forward_gi : 1;
- uint64_t uses_lightmap : 1;
- uint64_t depth_layer : 4;
- uint64_t priority : 8;
- };
-
- uint64_t sort_key;
- };
- uint32_t surface_index;
- };
-
- Element *base_elements;
- Element **elements;
-
- int element_count;
- int alpha_element_count;
-
- void clear() {
- element_count = 0;
- alpha_element_count = 0;
- }
-
- //should eventually be replaced by radix
-
- struct SortByKey {
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- return A->sort_key < B->sort_key;
- }
- };
-
- void sort_by_key(bool p_alpha) {
- SortArray<Element *, SortByKey> sorter;
- if (p_alpha) {
- sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
- } else {
- sorter.sort(elements, element_count);
- }
- }
-
- struct SortByDepth {
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- return A->instance->depth < B->instance->depth;
- }
- };
-
- void sort_by_depth(bool p_alpha) { //used for shadows
-
- SortArray<Element *, SortByDepth> sorter;
- if (p_alpha) {
- sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
- } else {
- sorter.sort(elements, element_count);
- }
- }
-
- struct SortByReverseDepthAndPriority {
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- uint32_t layer_A = uint32_t(A->priority);
- uint32_t layer_B = uint32_t(B->priority);
- if (layer_A == layer_B) {
- return A->instance->depth > B->instance->depth;
- } else {
- return layer_A < layer_B;
- }
- }
- };
-
- void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
-
- SortArray<Element *, SortByReverseDepthAndPriority> sorter;
- if (p_alpha) {
- sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
- } else {
- sorter.sort(elements, element_count);
- }
- }
-
- _FORCE_INLINE_ Element *add_element() {
- if (element_count + alpha_element_count >= max_elements) {
- return nullptr;
- }
- elements[element_count] = &base_elements[element_count];
- return elements[element_count++];
- }
-
- _FORCE_INLINE_ Element *add_alpha_element() {
- if (element_count + alpha_element_count >= max_elements) {
- return nullptr;
- }
- int idx = max_elements - alpha_element_count - 1;
- elements[idx] = &base_elements[idx];
- alpha_element_count++;
- return elements[idx];
- }
-
- void init() {
- element_count = 0;
- alpha_element_count = 0;
- elements = memnew_arr(Element *, max_elements);
- base_elements = memnew_arr(Element, max_elements);
- for (int i = 0; i < max_elements; i++) {
- elements[i] = &base_elements[i]; // assign elements
- }
- }
-
- RenderList() {
- max_elements = 0;
- }
-
- ~RenderList() {
- memdelete_arr(elements);
- memdelete_arr(base_elements);
- }
- };
-
- RenderList render_list;
-
- static RasterizerSceneHighEndRD *singleton;
- uint64_t render_pass;
- double time;
- RID default_shader;
- RID default_material;
- RID overdraw_material_shader;
- RID overdraw_material;
- RID wireframe_material_shader;
- RID wireframe_material;
- RID default_shader_rd;
- RID default_shader_sdfgi_rd;
- RID default_radiance_uniform_set;
- RID default_render_buffers_uniform_set;
-
- RID default_vec4_xform_buffer;
- RID default_vec4_xform_uniform_set;
-
- enum PassMode {
- PASS_MODE_COLOR,
- PASS_MODE_COLOR_SPECULAR,
- PASS_MODE_COLOR_TRANSPARENT,
- PASS_MODE_SHADOW,
- PASS_MODE_SHADOW_DP,
- PASS_MODE_DEPTH,
- PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
- PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE,
- PASS_MODE_DEPTH_MATERIAL,
- PASS_MODE_SDF,
- };
-
- void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
- void _setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform);
-
- void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false);
- void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2());
- _FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
- _FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
-
- void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_using_sdfgi = false);
-
- Map<Size2i, RID> sdfgi_framebuffer_size_cache;
-
-protected:
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
- virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &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);
- virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
- virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count);
-
-public:
- virtual void set_time(double p_time, double p_step);
-
- virtual bool free(RID p_rid);
-
- RasterizerSceneHighEndRD(RasterizerStorageRD *p_storage);
- ~RasterizerSceneHighEndRD();
-};
-#endif // RASTERIZER_SCENE_HIGHEND_RD_H
diff --git a/servers/rendering/rasterizer_rd/shaders/ssao.glsl b/servers/rendering/rasterizer_rd/shaders/ssao.glsl
deleted file mode 100644
index 346338181a..0000000000
--- a/servers/rendering/rasterizer_rd/shaders/ssao.glsl
+++ /dev/null
@@ -1,249 +0,0 @@
-#[compute]
-
-#version 450
-
-VERSION_DEFINES
-
-layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-
-#define TWO_PI 6.283185307179586476925286766559
-
-#ifdef SSAO_QUALITY_HIGH
-#define NUM_SAMPLES (20)
-#endif
-
-#ifdef SSAO_QUALITY_ULTRA
-#define NUM_SAMPLES (48)
-#endif
-
-#ifdef SSAO_QUALITY_LOW
-#define NUM_SAMPLES (8)
-#endif
-
-#if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH) && !defined(SSAO_QUALITY_ULTRA)
-#define NUM_SAMPLES (12)
-#endif
-
-// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
-// miplevel to maintain reasonable spatial locality in the cache
-// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
-// If it is too high (> 5), we'll get bad performance because we're not using the MIP levels effectively
-#define LOG_MAX_OFFSET (3)
-
-// This must be less than or equal to the MAX_MIP_LEVEL defined in SSAO.cpp
-#define MAX_MIP_LEVEL (4)
-
-// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent
-// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9
-
-const int ROTATIONS[] = int[](
- 1, 1, 2, 3, 2, 5, 2, 3, 2,
- 3, 3, 5, 5, 3, 4, 7, 5, 5, 7,
- 9, 8, 5, 5, 7, 7, 7, 8, 5, 8,
- 11, 12, 7, 10, 13, 8, 11, 8, 7, 14,
- 11, 11, 13, 12, 13, 19, 17, 13, 11, 18,
- 19, 11, 11, 14, 17, 21, 15, 16, 17, 18,
- 13, 17, 11, 17, 19, 18, 25, 18, 19, 19,
- 29, 21, 19, 27, 31, 29, 21, 18, 17, 29,
- 31, 31, 23, 18, 25, 26, 25, 23, 19, 34,
- 19, 27, 21, 25, 39, 29, 17, 21, 27);
-
-//#define NUM_SPIRAL_TURNS (7)
-const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES - 1];
-
-layout(set = 0, binding = 0) uniform sampler2D source_depth_mipmaps;
-layout(r8, set = 1, binding = 0) uniform restrict writeonly image2D dest_image;
-
-#ifndef USE_HALF_SIZE
-layout(set = 2, binding = 0) uniform sampler2D source_depth;
-#endif
-
-layout(set = 3, binding = 0) uniform sampler2D source_normal;
-
-layout(push_constant, binding = 1, std430) uniform Params {
- ivec2 screen_size;
- float z_far;
- float z_near;
-
- bool orthogonal;
- float intensity_div_r6;
- float radius;
- float bias;
-
- vec4 proj_info;
- vec2 pixel_size;
- float proj_scale;
- uint pad;
-}
-params;
-
-vec3 reconstructCSPosition(vec2 S, float z) {
- if (params.orthogonal) {
- return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z);
- } else {
- return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z);
- }
-}
-
-vec3 getPosition(ivec2 ssP) {
- vec3 P;
-#ifdef USE_HALF_SIZE
- P.z = texelFetch(source_depth_mipmaps, ssP, 0).r;
- P.z = -P.z;
-#else
- P.z = texelFetch(source_depth, ssP, 0).r;
-
- P.z = P.z * 2.0 - 1.0;
- if (params.orthogonal) {
- P.z = ((P.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
- } else {
- P.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - P.z * (params.z_far - params.z_near));
- }
- P.z = -P.z;
-#endif
- // Offset to pixel center
- P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
- return P;
-}
-
-/** Returns a unit vector and a screen-space radius for the tap on a unit disk (the caller should scale by the actual disk radius) */
-vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR) {
- // Radius relative to ssR
- float alpha = (float(sampleNumber) + 0.5) * (1.0 / float(NUM_SAMPLES));
- float angle = alpha * (float(NUM_SPIRAL_TURNS) * 6.28) + spinAngle;
-
- ssR = alpha;
- return vec2(cos(angle), sin(angle));
-}
-
-/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */
-vec3 getOffsetPosition(ivec2 ssP, float ssR) {
- // Derivation:
- // mipLevel = floor(log(ssR / MAX_OFFSET));
-
- int mipLevel = clamp(int(floor(log2(ssR))) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
-
- vec3 P;
-
- // We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
- // Manually clamp to the texture size because texelFetch bypasses the texture unit
- ivec2 mipP = clamp(ssP >> mipLevel, ivec2(0), (params.screen_size >> mipLevel) - ivec2(1));
-
-#ifdef USE_HALF_SIZE
- P.z = texelFetch(source_depth_mipmaps, mipP, mipLevel).r;
- P.z = -P.z;
-#else
- if (mipLevel < 1) {
- //read from depth buffer
- P.z = texelFetch(source_depth, mipP, 0).r;
- P.z = P.z * 2.0 - 1.0;
- if (params.orthogonal) {
- P.z = ((P.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
- } else {
- P.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - P.z * (params.z_far - params.z_near));
- }
- P.z = -P.z;
-
- } else {
- //read from mipmaps
- P.z = texelFetch(source_depth_mipmaps, mipP, mipLevel - 1).r;
- P.z = -P.z;
- }
-#endif
-
- // Offset to pixel center
- P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
-
- return P;
-}
-
-/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds
- to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius
-
- Note that units of H() in the HPG12 paper are meters, not
- unitless. The whole falloff/sampling function is therefore
- unitless. In this implementation, we factor out (9 / radius).
-
- Four versions of the falloff function are implemented below
-*/
-float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in float p_radius, in int tapIndex, in float randomPatternRotationAngle) {
- // Offset on the unit disk, spun for this pixel
- float ssR;
- vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR);
- ssR *= ssDiskRadius;
-
- ivec2 ssP = ivec2(ssR * unitOffset) + ssC;
-
- if (any(lessThan(ssP, ivec2(0))) || any(greaterThanEqual(ssP, params.screen_size))) {
- return 0.0;
- }
-
- // The occluding point in camera space
- vec3 Q = getOffsetPosition(ssP, ssR);
-
- vec3 v = Q - C;
-
- float vv = dot(v, v);
- float vn = dot(v, n_C);
-
- const float epsilon = 0.01;
- float radius2 = p_radius * p_radius;
-
- // A: From the HPG12 paper
- // Note large epsilon to avoid overdarkening within cracks
- //return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6;
-
- // B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
- float f = max(radius2 - vv, 0.0);
- return f * f * f * max((vn - params.bias) / (epsilon + vv), 0.0);
-
- // C: Medium contrast (which looks better at high radii), no division. Note that the
- // contribution still falls off with radius^2, but we've adjusted the rate in a way that is
- // more computationally efficient and happens to be aesthetically pleasing.
- // return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0);
-
- // D: Low contrast, no division operation
- // return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0);
-}
-
-void main() {
- // Pixel being shaded
- ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
- return;
- }
-
- // World space point being shaded
- vec3 C = getPosition(ssC);
-
-#ifdef USE_HALF_SIZE
- vec3 n_C = texelFetch(source_normal, ssC << 1, 0).xyz * 2.0 - 1.0;
-#else
- vec3 n_C = texelFetch(source_normal, ssC, 0).xyz * 2.0 - 1.0;
-#endif
- n_C = normalize(n_C);
- n_C.y = -n_C.y; //because this code reads flipped
-
- // Hash function used in the HPG12 AlchemyAO paper
- float randomPatternRotationAngle = mod(float((3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10), TWO_PI);
-
- // Reconstruct normals from positions. These will lead to 1-pixel black lines
- // at depth discontinuities, however the blur will wipe those out so they are not visible
- // in the final image.
-
- // Choose the screen-space sample radius
- // proportional to the projected area of the sphere
-
- float ssDiskRadius = -params.proj_scale * params.radius;
- if (!params.orthogonal) {
- ssDiskRadius = -params.proj_scale * params.radius / C.z;
- }
- float sum = 0.0;
- for (int i = 0; i < NUM_SAMPLES; ++i) {
- sum += sampleAO(ssC, C, n_C, ssDiskRadius, params.radius, i, randomPatternRotationAngle);
- }
-
- float A = max(0.0, 1.0 - sum * params.intensity_div_r6 * (5.0 / float(NUM_SAMPLES)));
-
- imageStore(dest_image, ssC, vec4(A));
-}
diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl
deleted file mode 100644
index 3e63e3cb59..0000000000
--- a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl
+++ /dev/null
@@ -1,153 +0,0 @@
-#[compute]
-
-#version 450
-
-VERSION_DEFINES
-
-layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-
-layout(set = 0, binding = 0) uniform sampler2D source_ssao;
-layout(set = 1, binding = 0) uniform sampler2D source_depth;
-#ifdef MODE_UPSCALE
-layout(set = 2, binding = 0) uniform sampler2D source_depth_mipmaps;
-#endif
-
-layout(r8, set = 3, binding = 0) uniform restrict writeonly image2D dest_image;
-
-//////////////////////////////////////////////////////////////////////////////////////////////
-// Tunable Parameters:
-
-layout(push_constant, binding = 1, std430) uniform Params {
- float edge_sharpness; /** Increase to make depth edges crisper. Decrease to reduce flicker. */
- int filter_scale;
- float z_far;
- float z_near;
- bool orthogonal;
- uint pad0;
- uint pad1;
- uint pad2;
- ivec2 axis; /** (1, 0) or (0, 1) */
- ivec2 screen_size;
-}
-params;
-
-/** Filter radius in pixels. This will be multiplied by SCALE. */
-#define R (4)
-
-//////////////////////////////////////////////////////////////////////////////////////////////
-
-// Gaussian coefficients
-const float gaussian[R + 1] =
- //float[](0.356642, 0.239400, 0.072410, 0.009869);
- //float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0
- float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0
-//float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
-
-void main() {
- // Pixel being shaded
- ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
- return;
- }
-
-#ifdef MODE_UPSCALE
-
- //closest one should be the same pixel, but check nearby just in case
- float depth = texelFetch(source_depth, ssC, 0).r;
-
- depth = depth * 2.0 - 1.0;
- if (params.orthogonal) {
- depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
- } else {
- depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
- }
-
- vec2 pixel_size = 1.0 / vec2(params.screen_size);
- vec2 closest_uv = vec2(ssC) * pixel_size + pixel_size * 0.5;
- vec2 from_uv = closest_uv;
- vec2 ps2 = pixel_size; // * 2.0;
-
- float closest_depth = abs(textureLod(source_depth_mipmaps, closest_uv, 0.0).r - depth);
-
- vec2 offsets[4] = vec2[](vec2(ps2.x, 0), vec2(-ps2.x, 0), vec2(0, ps2.y), vec2(0, -ps2.y));
- for (int i = 0; i < 4; i++) {
- vec2 neighbour = from_uv + offsets[i];
- float neighbour_depth = abs(textureLod(source_depth_mipmaps, neighbour, 0.0).r - depth);
- if (neighbour_depth < closest_depth) {
- closest_uv = neighbour;
- closest_depth = neighbour_depth;
- }
- }
-
- float visibility = textureLod(source_ssao, closest_uv, 0.0).r;
- imageStore(dest_image, ssC, vec4(visibility));
-#else
-
- float depth = texelFetch(source_depth, ssC, 0).r;
-
-#ifdef MODE_FULL_SIZE
- depth = depth * 2.0 - 1.0;
-
- if (params.orthogonal) {
- depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
- } else {
- depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
- }
-
-#endif
- float depth_divide = 1.0 / params.z_far;
-
- //depth *= depth_divide;
-
- /*
- if (depth > params.z_far * 0.999) {
- discard; //skybox
- }
- */
-
- float sum = texelFetch(source_ssao, ssC, 0).r;
-
- // Base weight for depth falloff. Increase this for more blurriness,
- // decrease it for better edge discrimination
- float BASE = gaussian[0];
- float totalWeight = BASE;
- sum *= totalWeight;
-
- ivec2 clamp_limit = params.screen_size - ivec2(1);
-
- for (int r = -R; r <= R; ++r) {
- // We already handled the zero case above. This loop should be unrolled and the static branch optimized out,
- // so the IF statement has no runtime cost
- if (r != 0) {
- ivec2 ppos = ssC + params.axis * (r * params.filter_scale);
- float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r;
- ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit);
-
- float temp_depth = texelFetch(source_depth, rpos, 0).r;
-#ifdef MODE_FULL_SIZE
- temp_depth = temp_depth * 2.0 - 1.0;
- if (params.orthogonal) {
- temp_depth = ((temp_depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
- } else {
- temp_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - temp_depth * (params.z_far - params.z_near));
- }
- //temp_depth *= depth_divide;
-#endif
- // spatial domain: offset gaussian tap
- float weight = 0.3 + gaussian[abs(r)];
- //weight *= max(0.0, dot(temp_normal, normal));
-
- // range domain (the "bilateral" weight). As depth difference increases, decrease weight.
- weight *= max(0.0, 1.0 - params.edge_sharpness * abs(temp_depth - depth));
-
- sum += value * weight;
- totalWeight += weight;
- }
- }
-
- const float epsilon = 0.0001;
- float visibility = sum / (totalWeight + epsilon);
-
- imageStore(dest_image, ssC, vec4(visibility));
-#endif
-}
diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl
deleted file mode 100644
index 263fca386f..0000000000
--- a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl
+++ /dev/null
@@ -1,45 +0,0 @@
-#[compute]
-
-#version 450
-
-VERSION_DEFINES
-
-layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-
-layout(push_constant, binding = 1, std430) uniform Params {
- vec2 pixel_size;
- float z_far;
- float z_near;
- ivec2 source_size;
- bool orthogonal;
- uint pad;
-}
-params;
-
-#ifdef MINIFY_START
-layout(set = 0, binding = 0) uniform sampler2D source_texture;
-#else
-layout(r32f, set = 0, binding = 0) uniform restrict readonly image2D source_image;
-#endif
-layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_image;
-
-void main() {
- ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
-
- if (any(greaterThan(pos, params.source_size >> 1))) { //too large, do nothing
- return;
- }
-
-#ifdef MINIFY_START
- float depth = texelFetch(source_texture, pos << 1, 0).r * 2.0 - 1.0;
- if (params.orthogonal) {
- depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
- } else {
- depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
- }
-#else
- float depth = imageLoad(source_image, pos << 1).r;
-#endif
-
- imageStore(dest_image, pos, vec4(depth));
-}
diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/renderer_canvas_cull.cpp
index ffc1ec391d..2d2847e6ca 100644
--- a/servers/rendering/rendering_server_canvas.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rendering_server_canvas.cpp */
+/* renderer_canvas_cull.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,20 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rendering_server_canvas.h"
+#include "renderer_canvas_cull.h"
#include "core/math/geometry_2d.h"
+#include "renderer_viewport.h"
+#include "rendering_server_default.h"
#include "rendering_server_globals.h"
-#include "rendering_server_raster.h"
-#include "rendering_server_viewport.h"
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
-void RenderingServerCanvas::_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, RasterizerCanvas::Light *p_lights, RasterizerCanvas::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) {
RENDER_TIMESTAMP("Cull CanvasItem Tree");
- memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *));
- memset(z_last_list, 0, z_range * sizeof(RasterizerCanvas::Item *));
+ 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);
@@ -50,8 +50,8 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can
_cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr);
}
- RasterizerCanvas::Item *list = nullptr;
- RasterizerCanvas::Item *list_end = nullptr;
+ RendererCanvasRender::Item *list = nullptr;
+ RendererCanvasRender::Item *list_end = nullptr;
for (int i = 0; i < z_range; i++) {
if (!z_list[i]) {
@@ -75,9 +75,9 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can
}
}
-void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transform2D p_transform, RenderingServerCanvas::Item *p_material_owner, RenderingServerCanvas::Item **r_items, int &r_index) {
+void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index) {
int child_item_count = p_canvas_item->child_items.size();
- RenderingServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw();
+ RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw();
for (int i = 0; i < child_item_count; i++) {
if (child_items[i]->visible) {
if (r_items) {
@@ -97,14 +97,14 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo
}
}
-void _mark_ysort_dirty(RenderingServerCanvas::Item *ysort_owner, RID_PtrOwner<RenderingServerCanvas::Item> &canvas_item_owner) {
+void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item> &canvas_item_owner) {
do {
ysort_owner->ysort_children_count = -1;
ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr;
} while (ysort_owner && ysort_owner->sort_y);
}
-void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) {
+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 **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) {
Item *ci = p_canvas_item;
if (!ci->visible) {
@@ -144,7 +144,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
if (ci->clip) {
if (p_canvas_clip != nullptr) {
- ci->final_clip_rect = p_canvas_clip->final_clip_rect.clip(global_rect);
+ ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect);
} else {
ci->final_clip_rect = global_rect;
}
@@ -176,7 +176,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
p_z = ci->z_index;
}
- RasterizerCanvas::Item *canvas_group_from = nullptr;
+ RendererCanvasRender::Item *canvas_group_from = nullptr;
bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr);
if (use_canvas_group) {
int zidx = p_z - RS::CANVAS_ITEM_Z_MIN;
@@ -195,7 +195,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
if (ci->copy_back_buffer) {
- ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect);
+ ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).intersection(p_clip_rect);
}
if (use_canvas_group) {
@@ -213,7 +213,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
//compute a global rect (in global coords) for children in the same z layer
Rect2 rect_accum;
- RasterizerCanvas::Item *c = canvas_group_from;
+ RendererCanvasRender::Item *c = canvas_group_from;
while (c) {
if (c == canvas_group_from) {
rect_accum = c->global_rect_cache;
@@ -227,7 +227,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
// We have two choices now, if user has drawn something, we must assume users wants to draw the "mask", so compute the size based on this.
// If nothing has been drawn, we just take it over and draw it ourselves.
if (ci->canvas_group->fit_empty && (ci->commands == nullptr ||
- (ci->commands->next == nullptr && ci->commands->type == Item::Command::TYPE_RECT && (static_cast<Item::CommandRect *>(ci->commands)->flags & RasterizerCanvas::CANVAS_RECT_IS_GROUP)))) {
+ (ci->commands->next == nullptr && ci->commands->type == Item::Command::TYPE_RECT && (static_cast<Item::CommandRect *>(ci->commands)->flags & RendererCanvasRender::CANVAS_RECT_IS_GROUP)))) {
// No commands, or sole command is the one used to draw, so we (re)create the draw command.
ci->clear();
@@ -238,9 +238,9 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
rect_accum = rect_accum.grow(ci->canvas_group->fit_margin);
//draw it?
- RasterizerCanvas::Item::CommandRect *crect = ci->alloc_command<RasterizerCanvas::Item::CommandRect>();
+ RendererCanvasRender::Item::CommandRect *crect = ci->alloc_command<RendererCanvasRender::Item::CommandRect>();
- crect->flags = RasterizerCanvas::CANVAS_RECT_IS_GROUP; // so we can recognize it later
+ crect->flags = RendererCanvasRender::CANVAS_RECT_IS_GROUP; // so we can recognize it later
crect->rect = xform.affine_inverse().xform(rect_accum);
crect->modulate = Color(1, 1, 1, 1);
@@ -256,14 +256,14 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
global_rect.position += p_clip_rect.position;
}
- // Very important that this is cleared after used in RasterizerCanvas to avoid
+ // Very important that this is cleared after used in RendererCanvasRender to avoid
// potential crashes.
canvas_group_from->canvas_group_owner = ci;
}
}
if (ci->update_when_visible) {
- RenderingServerRaster::redraw_request();
+ RenderingServerDefault::redraw_request();
}
if ((ci->commands != nullptr && p_clip_rect.intersects(global_rect, true)) || ci->vp_render || ci->copy_back_buffer) {
@@ -302,7 +302,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
}
-void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::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) {
RENDER_TIMESTAMP(">Render Canvas");
sdf_used = false;
@@ -352,11 +352,11 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas,
RENDER_TIMESTAMP("<End Render Canvas");
}
-bool RenderingServerCanvas::was_sdf_used() {
+bool RendererCanvasCull::was_sdf_used() {
return sdf_used;
}
-RID RenderingServerCanvas::canvas_create() {
+RID RendererCanvasCull::canvas_create() {
Canvas *canvas = memnew(Canvas);
ERR_FAIL_COND_V(!canvas, RID());
RID rid = canvas_owner.make_rid(canvas);
@@ -364,7 +364,7 @@ RID RenderingServerCanvas::canvas_create() {
return rid;
}
-void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) {
+void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) {
Canvas *canvas = canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
Item *canvas_item = canvas_item_owner.getornull(p_item);
@@ -375,17 +375,17 @@ void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item,
canvas->child_items.write[idx].mirror = p_mirroring;
}
-void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) {
+void RendererCanvasCull::canvas_set_modulate(RID p_canvas, const Color &p_color) {
Canvas *canvas = canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
canvas->modulate = p_color;
}
-void RenderingServerCanvas::canvas_set_disable_scale(bool p_disable) {
+void RendererCanvasCull::canvas_set_disable_scale(bool p_disable) {
disable_scale = p_disable;
}
-void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) {
+void RendererCanvasCull::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) {
Canvas *canvas = canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
@@ -393,14 +393,14 @@ void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float
canvas->parent_scale = p_scale;
}
-RID RenderingServerCanvas::canvas_item_create() {
+RID RendererCanvasCull::canvas_item_create() {
Item *canvas_item = memnew(Item);
ERR_FAIL_COND_V(!canvas_item, RID());
return canvas_item_owner.make_rid(canvas_item);
}
-void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
+void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -444,7 +444,7 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
canvas_item->parent = p_parent;
}
-void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) {
+void RendererCanvasCull::canvas_item_set_visible(RID p_item, bool p_visible) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -453,35 +453,35 @@ void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible)
_mark_ysort_dirty(canvas_item, canvas_item_owner);
}
-void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) {
+void RendererCanvasCull::canvas_item_set_light_mask(RID p_item, int p_mask) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->light_mask = p_mask;
}
-void RenderingServerCanvas::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) {
+void RendererCanvasCull::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->xform = p_transform;
}
-void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) {
+void RendererCanvasCull::canvas_item_set_clip(RID p_item, bool p_clip) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->clip = p_clip;
}
-void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) {
+void RendererCanvasCull::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->distance_field = p_enable;
}
-void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) {
+void RendererCanvasCull::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -489,42 +489,42 @@ void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custo
canvas_item->rect = p_rect;
}
-void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) {
+void RendererCanvasCull::canvas_item_set_modulate(RID p_item, const Color &p_color) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->modulate = p_color;
}
-void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) {
+void RendererCanvasCull::canvas_item_set_self_modulate(RID p_item, const Color &p_color) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->self_modulate = p_color;
}
-void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) {
+void RendererCanvasCull::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->behind = p_enable;
}
-void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool p_update) {
+void RendererCanvasCull::canvas_item_set_update_when_visible(RID p_item, bool p_update) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->update_when_visible = p_update;
}
-void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
+void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
Item::CommandPrimitive *line = canvas_item->alloc_command<Item::CommandPrimitive>();
ERR_FAIL_COND(!line);
if (p_width > 1.001) {
- Vector2 t = (p_from - p_to).tangent().normalized();
+ Vector2 t = (p_from - p_to).orthogonal().normalized();
line->points[0] = p_from + t * p_width;
line->points[1] = p_from - t * p_width;
line->points[2] = p_to - t * p_width;
@@ -540,93 +540,146 @@ void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_fro
}
}
-void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
+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.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
+ Color color = Color(1, 1, 1, 1);
+
+ Vector<int> indices;
+ int pc = p_points.size();
+ int pc2 = pc * 2;
+
+ Vector2 prev_t;
+ int j2;
+
Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);
- if (true || p_width <= 1) {
-#define TODO make thick lines possible
- Vector<int> indices;
- int pc = p_points.size();
- indices.resize((pc - 1) * 2);
- {
- int *iptr = indices.ptrw();
- for (int i = 0; i < (pc - 1); i++) {
- iptr[i * 2 + 0] = i;
- iptr[i * 2 + 1] = i + 1;
- }
- }
+ PackedColorArray colors;
+ PackedVector2Array points;
- pline->primitive = RS::PRIMITIVE_LINES;
- pline->polygon.create(indices, p_points, p_colors);
- } else {
-#if 0
- //make a trianglestrip for drawing the line...
- Vector2 prev_t;
- pline->triangles.resize(p_points.size() * 2);
- if (p_antialiased) {
- pline->lines.resize(p_points.size() * 2);
- }
+ colors.resize(pc2);
+ points.resize(pc2);
- if (p_colors.size() == 0) {
- pline->triangle_colors.push_back(Color(1, 1, 1, 1));
- if (p_antialiased) {
- pline->line_colors.push_back(Color(1, 1, 1, 1));
- }
- } else if (p_colors.size() == 1) {
- pline->triangle_colors = p_colors;
- pline->line_colors = p_colors;
- } else {
- if (p_colors.size() != p_points.size()) {
- pline->triangle_colors.push_back(p_colors[0]);
- pline->line_colors.push_back(p_colors[0]);
- } else {
- pline->triangle_colors.resize(pline->triangles.size());
- pline->line_colors.resize(pline->lines.size());
- }
- }
+ Vector2 *points_ptr = points.ptrw();
+ Color *colors_ptr = colors.ptrw();
+
+ if (p_antialiased) {
+ Color color2 = Color(1, 1, 1, 0);
+
+ PackedColorArray colors_top;
+ PackedVector2Array points_top;
+
+ colors_top.resize(pc2);
+ points_top.resize(pc2);
+
+ PackedColorArray colors_bottom;
+ PackedVector2Array points_bottom;
+
+ colors_bottom.resize(pc2);
+ points_bottom.resize(pc2);
+
+ Item::CommandPolygon *pline_top = canvas_item->alloc_command<Item::CommandPolygon>();
+ ERR_FAIL_COND(!pline_top);
+
+ Item::CommandPolygon *pline_bottom = canvas_item->alloc_command<Item::CommandPolygon>();
+ ERR_FAIL_COND(!pline_bottom);
+
+ //make three trianglestrip's for drawing the antialiased line...
+
+ Vector2 *points_top_ptr = points_top.ptrw();
+ Vector2 *points_bottom_ptr = points_bottom.ptrw();
+
+ Color *colors_top_ptr = colors_top.ptrw();
+ Color *colors_bottom_ptr = colors_bottom.ptrw();
- for (int i = 0; i < p_points.size(); i++) {
+ for (int i = 0, j = 0; i < pc; i++, j += 2) {
Vector2 t;
- if (i == p_points.size() - 1) {
+ if (i == pc - 1) {
t = prev_t;
} else {
- t = (p_points[i + 1] - p_points[i]).normalized().tangent();
+ t = (p_points[i + 1] - p_points[i]).normalized().orthogonal();
if (i == 0) {
prev_t = t;
}
}
+ j2 = j + 1;
+
Vector2 tangent = ((t + prev_t).normalized()) * p_width * 0.5;
+ Vector2 pos = p_points[i];
+
+ points_ptr[j] = pos + tangent;
+ points_ptr[j2] = pos - tangent;
+
+ points_top_ptr[j] = pos + tangent + tangent;
+ points_top_ptr[j2] = pos + tangent;
+
+ points_bottom_ptr[j] = pos - tangent;
+ points_bottom_ptr[j2] = pos - tangent - tangent;
+
+ 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;
- if (p_antialiased) {
- pline->lines.write[i] = p_points[i] + tangent;
- pline->lines.write[p_points.size() * 2 - i - 1] = p_points[i] - tangent;
- if (pline->line_colors.size() > 1) {
- pline->line_colors.write[i] = p_colors[i];
- pline->line_colors.write[p_points.size() * 2 - i - 1] = p_colors[i];
+ colors_top_ptr[j] = color2;
+ colors_top_ptr[j2] = color;
+
+ colors_bottom_ptr[j] = color;
+ colors_bottom_ptr[j2] = color2;
+
+ prev_t = t;
+ }
+
+ pline_top->primitive = RS::PRIMITIVE_TRIANGLE_STRIP;
+ pline_top->polygon.create(indices, points_top, colors_top);
+
+ pline_bottom->primitive = RS::PRIMITIVE_TRIANGLE_STRIP;
+ pline_bottom->polygon.create(indices, points_bottom, colors_bottom);
+ } else {
+ //make a trianglestrip 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;
}
}
- pline->triangles.write[i * 2 + 0] = p_points[i] + tangent;
- pline->triangles.write[i * 2 + 1] = p_points[i] - tangent;
+ j2 = j + 1;
- if (pline->triangle_colors.size() > 1) {
- pline->triangle_colors.write[i * 2 + 0] = p_colors[i];
- pline->triangle_colors.write[i * 2 + 1] = p_colors[i];
+ Vector2 tangent = ((t + prev_t).normalized()) * p_width * 0.5;
+ Vector2 pos = p_points[i];
+
+ points_ptr[j] = pos + tangent;
+ points_ptr[j2] = pos - tangent;
+
+ if (i < p_colors.size()) {
+ color = p_colors[i];
}
+ colors_ptr[j] = color;
+ colors_ptr[j2] = color;
+
prev_t = t;
}
-#endif
}
+
+ pline->primitive = RS::PRIMITIVE_TRIANGLE_STRIP;
+ pline->polygon.create(indices, points, colors);
}
-void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
+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.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -643,7 +696,7 @@ void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<P
}
}
-void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) {
+void RendererCanvasCull::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -653,7 +706,7 @@ void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect
rect->rect = p_rect;
}
-void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) {
+void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -687,7 +740,7 @@ void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_p
circle->polygon.create(indices, points, color);
}
-void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) {
+void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -697,28 +750,28 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2
rect->rect = p_rect;
rect->flags = 0;
if (p_tile) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_TILE;
- rect->flags |= RasterizerCanvas::CANVAS_RECT_REGION;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_TILE;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_REGION;
rect->source = Rect2(0, 0, fabsf(p_rect.size.width), fabsf(p_rect.size.height));
}
if (p_rect.size.x < 0) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_H;
rect->rect.size.x = -rect->rect.size.x;
}
if (p_rect.size.y < 0) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_V;
rect->rect.size.y = -rect->rect.size.y;
}
if (p_transpose) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_TRANSPOSE;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_TRANSPOSE;
SWAP(rect->rect.size.x, rect->rect.size.y);
}
rect->texture = p_texture;
}
-void RenderingServerCanvas::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, bool p_transpose, bool p_clip_uv) {
+void RendererCanvasCull::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, bool p_transpose, bool p_clip_uv) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -730,36 +783,36 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons
rect->texture = p_texture;
rect->source = p_src_rect;
- rect->flags = RasterizerCanvas::CANVAS_RECT_REGION;
+ rect->flags = RendererCanvasRender::CANVAS_RECT_REGION;
if (p_rect.size.x < 0) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_H;
rect->rect.size.x = -rect->rect.size.x;
}
if (p_src_rect.size.x < 0) {
- rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_H;
+ rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_H;
rect->source.size.x = -rect->source.size.x;
}
if (p_rect.size.y < 0) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_V;
rect->rect.size.y = -rect->rect.size.y;
}
if (p_src_rect.size.y < 0) {
- rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_V;
+ rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_V;
rect->source.size.y = -rect->source.size.y;
}
if (p_transpose) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_TRANSPOSE;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_TRANSPOSE;
SWAP(rect->rect.size.x, rect->rect.size.y);
}
if (p_clip_uv) {
- rect->flags |= RasterizerCanvas::CANVAS_RECT_CLIP_UV;
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_CLIP_UV;
}
}
-void RenderingServerCanvas::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::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) {
+void RendererCanvasCull::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::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -772,15 +825,15 @@ void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &
style->source = p_source;
style->draw_center = p_draw_center;
style->color = p_modulate;
- style->margin[MARGIN_LEFT] = p_topleft.x;
- style->margin[MARGIN_TOP] = p_topleft.y;
- style->margin[MARGIN_RIGHT] = p_bottomright.x;
- style->margin[MARGIN_BOTTOM] = p_bottomright.y;
+ style->margin[SIDE_LEFT] = p_topleft.x;
+ style->margin[SIDE_TOP] = p_topleft.y;
+ style->margin[SIDE_RIGHT] = p_bottomright.x;
+ style->margin[SIDE_BOTTOM] = p_bottomright.y;
style->axis_x = p_x_axis_mode;
style->axis_y = p_y_axis_mode;
}
-void RenderingServerCanvas::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, float p_width) {
uint32_t pc = p_points.size();
ERR_FAIL_COND(pc == 0 || pc > 4);
@@ -809,7 +862,7 @@ void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<P
prim->texture = p_texture;
}
-void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
+void RendererCanvasCull::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
#ifdef DEBUG_ENABLED
@@ -821,7 +874,7 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi
ERR_FAIL_COND(uv_size != 0 && (uv_size != pointcount));
#endif
Vector<int> indices = Geometry2D::triangulate_polygon(p_points);
- ERR_FAIL_COND_MSG(indices.empty(), "Invalid polygon data, triangulation failed.");
+ ERR_FAIL_COND_MSG(indices.is_empty(), "Invalid polygon data, triangulation failed.");
Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
@@ -830,16 +883,16 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi
polygon->polygon.create(indices, p_points, p_colors, p_uvs);
}
-void RenderingServerCanvas::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, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count) {
+void RendererCanvasCull::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, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
int vertex_count = p_points.size();
ERR_FAIL_COND(vertex_count == 0);
- ERR_FAIL_COND(!p_colors.empty() && p_colors.size() != vertex_count && p_colors.size() != 1);
- ERR_FAIL_COND(!p_uvs.empty() && p_uvs.size() != vertex_count);
- ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != vertex_count * 4);
- ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != vertex_count * 4);
+ ERR_FAIL_COND(!p_colors.is_empty() && p_colors.size() != vertex_count && p_colors.size() != 1);
+ ERR_FAIL_COND(!p_uvs.is_empty() && p_uvs.size() != vertex_count);
+ ERR_FAIL_COND(!p_bones.is_empty() && p_bones.size() != vertex_count * 4);
+ ERR_FAIL_COND(!p_weights.is_empty() && p_weights.size() != vertex_count * 4);
Vector<int> indices = p_indices;
@@ -853,7 +906,7 @@ void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vec
polygon->primitive = RS::PRIMITIVE_TRIANGLES;
}
-void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) {
+void RendererCanvasCull::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -862,7 +915,7 @@ void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Tran
tr->xform = p_transform;
}
-void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture) {
+void RendererCanvasCull::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -876,7 +929,7 @@ void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh,
m->modulate = p_modulate;
}
-void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) {
+void RendererCanvasCull::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -890,7 +943,7 @@ void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particle
RSG::storage->particles_request_process(p_particles);
}
-void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture) {
+void RendererCanvasCull::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -901,7 +954,7 @@ void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RI
mm->texture = p_texture;
}
-void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) {
+void RendererCanvasCull::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -910,7 +963,7 @@ void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignor
ci->ignore = p_ignore;
}
-void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
+void RendererCanvasCull::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -919,7 +972,7 @@ void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool
_mark_ysort_dirty(canvas_item, canvas_item_owner);
}
-void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) {
+void RendererCanvasCull::canvas_item_set_z_index(RID p_item, int p_z) {
ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN || p_z > RS::CANVAS_ITEM_Z_MAX);
Item *canvas_item = canvas_item_owner.getornull(p_item);
@@ -928,25 +981,25 @@ void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) {
canvas_item->z_index = p_z;
}
-void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) {
+void RendererCanvasCull::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->z_relative = p_enable;
}
-void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) {
+void RendererCanvasCull::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->skeleton = p_skeleton;
}
-void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) {
+void RendererCanvasCull::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
if (p_enable && (canvas_item->copy_back_buffer == nullptr)) {
- canvas_item->copy_back_buffer = memnew(RasterizerCanvas::Item::CopyBackBuffer);
+ canvas_item->copy_back_buffer = memnew(RendererCanvasRender::Item::CopyBackBuffer);
}
if (!p_enable && (canvas_item->copy_back_buffer != nullptr)) {
memdelete(canvas_item->copy_back_buffer);
@@ -959,14 +1012,14 @@ void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool
}
}
-void RenderingServerCanvas::canvas_item_clear(RID p_item) {
+void RendererCanvasCull::canvas_item_clear(RID p_item) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->clear();
}
-void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) {
+void RendererCanvasCull::canvas_item_set_draw_index(RID p_item, int p_index) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -985,21 +1038,21 @@ void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index)
}
}
-void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material) {
+void RendererCanvasCull::canvas_item_set_material(RID p_item, RID p_material) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->material = p_material;
}
-void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool p_enable) {
+void RendererCanvasCull::canvas_item_set_use_parent_material(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->use_parent_material = p_enable;
}
-void RenderingServerCanvas::canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin, bool p_fit_empty, float p_fit_margin, bool p_blur_mipmaps) {
+void RendererCanvasCull::canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin, bool p_fit_empty, float p_fit_margin, bool p_blur_mipmaps) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -1010,7 +1063,7 @@ void RenderingServerCanvas::canvas_item_set_canvas_group_mode(RID p_item, RS::Ca
}
} else {
if (canvas_item->canvas_group == nullptr) {
- canvas_item->canvas_group = memnew(RasterizerCanvas::Item::CanvasGroup);
+ canvas_item->canvas_group = memnew(RendererCanvasRender::Item::CanvasGroup);
}
canvas_item->canvas_group->mode = p_mode;
canvas_item->canvas_group->fit_empty = p_fit_empty;
@@ -1020,14 +1073,14 @@ void RenderingServerCanvas::canvas_item_set_canvas_group_mode(RID p_item, RS::Ca
}
}
-RID RenderingServerCanvas::canvas_light_create() {
- RasterizerCanvas::Light *clight = memnew(RasterizerCanvas::Light);
+RID RendererCanvasCull::canvas_light_create() {
+ RendererCanvasRender::Light *clight = memnew(RendererCanvasRender::Light);
clight->light_internal = RSG::canvas_render->light_create();
return canvas_light_owner.make_rid(clight);
}
-void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
if (clight->mode == p_mode) {
@@ -1047,8 +1100,8 @@ void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMo
}
}
-void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
if (clight->canvas.is_valid()) {
@@ -1076,29 +1129,29 @@ void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_can
}
}
-void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_enabled(RID p_light, bool p_enabled) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->enabled = p_enabled;
}
-void RenderingServerCanvas::canvas_light_set_texture_scale(RID p_light, float p_scale) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_texture_scale(RID p_light, float p_scale) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->scale = p_scale;
}
-void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->xform = p_transform;
}
-void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_texture(RID p_light, RID p_texture) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
if (clight->texture == p_texture) {
@@ -1109,80 +1162,80 @@ void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture)
RSG::canvas_render->light_set_texture(clight->light_internal, p_texture);
}
-void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->texture_offset = p_offset;
}
-void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_color(RID p_light, const Color &p_color) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->color = p_color;
}
-void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_height(RID p_light, float p_height) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->height = p_height;
}
-void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_energy(RID p_light, float p_energy) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->energy = p_energy;
}
-void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->z_min = p_min_z;
clight->z_max = p_max_z;
}
-void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->layer_max = p_max_layer;
clight->layer_min = p_min_layer;
}
-void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_item_cull_mask(RID p_light, int p_mask) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->item_mask = p_mask;
}
-void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->item_shadow_mask = p_mask;
}
-void RenderingServerCanvas::canvas_light_set_directional_distance(RID p_light, float p_distance) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_directional_distance(RID p_light, float p_distance) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->directional_distance = p_distance;
}
-void RenderingServerCanvas::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->blend_mode = p_mode;
}
-void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
if (clight->use_shadow == p_enabled) {
@@ -1193,34 +1246,34 @@ void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_
RSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow);
}
-void RenderingServerCanvas::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->shadow_filter = p_filter;
}
-void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_shadow_color(RID p_light, const Color &p_color) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->shadow_color = p_color;
}
-void RenderingServerCanvas::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) {
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+void RendererCanvasCull::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) {
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->shadow_smooth = p_smooth;
}
-RID RenderingServerCanvas::canvas_light_occluder_create() {
- RasterizerCanvas::LightOccluderInstance *occluder = memnew(RasterizerCanvas::LightOccluderInstance);
+RID RendererCanvasCull::canvas_light_occluder_create() {
+ RendererCanvasRender::LightOccluderInstance *occluder = memnew(RendererCanvasRender::LightOccluderInstance);
return canvas_light_occluder_owner.make_rid(occluder);
}
-void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) {
- RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
+void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) {
+ RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
if (occluder->canvas.is_valid()) {
@@ -1240,15 +1293,15 @@ void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occlude
}
}
-void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) {
- RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
+void RendererCanvasCull::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) {
+ RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
occluder->enabled = p_enabled;
}
-void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) {
- RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
+void RendererCanvasCull::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) {
+ RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
if (occluder->polygon.is_valid()) {
@@ -1275,32 +1328,32 @@ void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RI
}
}
-void RenderingServerCanvas::canvas_light_occluder_set_as_sdf_collision(RID p_occluder, bool p_enable) {
- RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
+void RendererCanvasCull::canvas_light_occluder_set_as_sdf_collision(RID p_occluder, bool p_enable) {
+ RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
}
-void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) {
- RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
+void RendererCanvasCull::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) {
+ RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
occluder->xform = p_xform;
}
-void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) {
- RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
+void RendererCanvasCull::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) {
+ RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
occluder->light_mask = p_mask;
}
-RID RenderingServerCanvas::canvas_occluder_polygon_create() {
+RID RendererCanvasCull::canvas_occluder_polygon_create() {
LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon);
occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create();
return canvas_light_occluder_polygon_owner.make_rid(occluder_poly);
}
-void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) {
+void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) {
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon);
ERR_FAIL_COND(!occluder_poly);
@@ -1319,66 +1372,66 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol
RSG::canvas_render->occluder_polygon_set_shape(occluder_poly->occluder, p_shape, p_closed);
- for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) {
+ for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) {
E->get()->aabb_cache = occluder_poly->aabb;
}
}
-void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) {
+void RendererCanvasCull::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) {
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon);
ERR_FAIL_COND(!occluder_poly);
occluder_poly->cull_mode = p_mode;
RSG::canvas_render->occluder_polygon_set_cull_mode(occluder_poly->occluder, p_mode);
- for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) {
+ for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) {
E->get()->cull_cache = p_mode;
}
}
-void RenderingServerCanvas::canvas_set_shadow_texture_size(int p_size) {
+void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) {
RSG::canvas_render->set_shadow_texture_size(p_size);
}
-RID RenderingServerCanvas::canvas_texture_create() {
+RID RendererCanvasCull::canvas_texture_create() {
return RSG::storage->canvas_texture_create();
}
-void RenderingServerCanvas::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
+void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
RSG::storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture);
}
-void RenderingServerCanvas::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) {
+void RendererCanvasCull::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) {
RSG::storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess);
}
-void RenderingServerCanvas::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
+void RendererCanvasCull::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
RSG::storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter);
}
-void RenderingServerCanvas::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
+void RendererCanvasCull::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
RSG::storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat);
}
-void RenderingServerCanvas::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
+void RendererCanvasCull::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
Item *ci = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!ci);
ci->texture_filter = p_filter;
}
-void RenderingServerCanvas::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) {
+void RendererCanvasCull::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) {
Item *ci = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!ci);
ci->texture_repeat = p_repeat;
}
-bool RenderingServerCanvas::free(RID p_rid) {
+bool RendererCanvasCull::free(RID p_rid) {
if (canvas_owner.owns(p_rid)) {
Canvas *canvas = canvas_owner.getornull(p_rid);
ERR_FAIL_COND_V(!canvas, false);
while (canvas->viewports.size()) {
- RenderingServerViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get());
+ RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get());
ERR_FAIL_COND_V(!vp, true);
- Map<RID, RenderingServerViewport::Viewport::CanvasData>::Element *E = vp->canvas_map.find(p_rid);
+ Map<RID, RendererViewport::Viewport::CanvasData>::Element *E = vp->canvas_map.find(p_rid);
ERR_FAIL_COND_V(!E, true);
vp->canvas_map.erase(p_rid);
@@ -1389,11 +1442,11 @@ bool RenderingServerCanvas::free(RID p_rid) {
canvas->child_items[i].item->parent = RID();
}
- for (Set<RasterizerCanvas::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) {
+ for (Set<RendererCanvasRender::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) {
E->get()->canvas = RID();
}
- for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) {
+ for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) {
E->get()->canvas = RID();
}
@@ -1434,7 +1487,7 @@ bool RenderingServerCanvas::free(RID p_rid) {
memdelete(canvas_item);
} else if (canvas_light_owner.owns(p_rid)) {
- RasterizerCanvas::Light *canvas_light = canvas_light_owner.getornull(p_rid);
+ RendererCanvasRender::Light *canvas_light = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND_V(!canvas_light, true);
if (canvas_light->canvas.is_valid()) {
@@ -1450,7 +1503,7 @@ bool RenderingServerCanvas::free(RID p_rid) {
memdelete(canvas_light);
} else if (canvas_light_occluder_owner.owns(p_rid)) {
- RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid);
+ RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid);
ERR_FAIL_COND_V(!occluder, true);
if (occluder->polygon.is_valid()) {
@@ -1487,14 +1540,14 @@ bool RenderingServerCanvas::free(RID p_rid) {
return true;
}
-RenderingServerCanvas::RenderingServerCanvas() {
- z_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *));
- z_last_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *));
+RendererCanvasCull::RendererCanvasCull() {
+ z_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *));
+ z_last_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *));
disable_scale = false;
}
-RenderingServerCanvas::~RenderingServerCanvas() {
+RendererCanvasCull::~RendererCanvasCull() {
memfree(z_list);
memfree(z_last_list);
}
diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/renderer_canvas_cull.h
index 83b76539c4..7496a413ee 100644
--- a/servers/rendering/rendering_server_canvas.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rendering_server_canvas.h */
+/* renderer_canvas_cull.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VISUALSERVERCANVAS_H
-#define VISUALSERVERCANVAS_H
+#ifndef RENDERING_SERVER_CANVAS_CULL_H
+#define RENDERING_SERVER_CANVAS_CULL_H
-#include "rasterizer.h"
-#include "rendering_server_viewport.h"
+#include "renderer_compositor.h"
+#include "renderer_viewport.h"
-class RenderingServerCanvas {
+class RendererCanvasCull {
public:
- struct Item : public RasterizerCanvas::Item {
+ struct Item : public RendererCanvasRender::Item {
RID parent; // canvas it belongs to
List<Item *>::Element *E;
int z_index;
@@ -93,7 +93,7 @@ public:
Rect2 aabb;
RS::CanvasOccluderPolygonCullMode cull_mode;
RID occluder;
- Set<RasterizerCanvas::LightOccluderInstance *> owners;
+ Set<RendererCanvasRender::LightOccluderInstance *> owners;
LightOccluderPolygon() {
active = false;
@@ -103,9 +103,9 @@ public:
RID_PtrOwner<LightOccluderPolygon> canvas_light_occluder_polygon_owner;
- RID_PtrOwner<RasterizerCanvas::LightOccluderInstance> canvas_light_occluder_owner;
+ RID_PtrOwner<RendererCanvasRender::LightOccluderInstance> canvas_light_occluder_owner;
- struct Canvas : public RenderingServerViewport::CanvasBase {
+ struct Canvas : public RendererViewport::CanvasBase {
Set<RID> viewports;
struct ChildItem {
Point2 mirror;
@@ -115,10 +115,10 @@ public:
}
};
- Set<RasterizerCanvas::Light *> lights;
- Set<RasterizerCanvas::Light *> directional_lights;
+ Set<RendererCanvasRender::Light *> lights;
+ Set<RendererCanvasRender::Light *> directional_lights;
- Set<RasterizerCanvas::LightOccluderInstance *> occluders;
+ Set<RendererCanvasRender::LightOccluderInstance *> occluders;
bool children_order_dirty;
Vector<ChildItem> child_items;
@@ -150,21 +150,21 @@ public:
mutable RID_PtrOwner<Canvas> canvas_owner;
RID_PtrOwner<Item> canvas_item_owner;
- RID_PtrOwner<RasterizerCanvas::Light> canvas_light_owner;
+ RID_PtrOwner<RendererCanvasRender::Light> canvas_light_owner;
bool disable_scale;
bool sdf_used = false;
bool snapping_2d_transforms_to_pixel = false;
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, RasterizerCanvas::Light *p_lights, RasterizerCanvas::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, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner);
+ 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 **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner);
- RasterizerCanvas::Item **z_list;
- RasterizerCanvas::Item **z_last_list;
+ RendererCanvasRender::Item **z_list;
+ RendererCanvasRender::Item **z_last_list;
public:
- void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::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);
bool was_sdf_used();
@@ -192,7 +192,7 @@ 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);
- void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0);
+ 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);
@@ -272,8 +272,8 @@ public:
void canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat);
bool free(RID p_rid);
- RenderingServerCanvas();
- ~RenderingServerCanvas();
+ RendererCanvasCull();
+ ~RendererCanvasCull();
};
#endif // VISUALSERVERCANVAS_H
diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp
new file mode 100644
index 0000000000..1945435586
--- /dev/null
+++ b/servers/rendering/renderer_canvas_render.cpp
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* renderer_canvas_render.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_canvas_render.h"
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
new file mode 100644
index 0000000000..f08986b021
--- /dev/null
+++ b/servers/rendering/renderer_canvas_render.h
@@ -0,0 +1,604 @@
+/*************************************************************************/
+/* renderer_canvas_render.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERINGSERVERCANVASRENDER_H
+#define RENDERINGSERVERCANVASRENDER_H
+
+#include "servers/rendering/renderer_storage.h"
+
+class RendererCanvasRender {
+public:
+ static RendererCanvasRender *singleton;
+
+ enum CanvasRectFlags {
+ CANVAS_RECT_REGION = 1,
+ CANVAS_RECT_TILE = 2,
+ CANVAS_RECT_FLIP_H = 4,
+ CANVAS_RECT_FLIP_V = 8,
+ CANVAS_RECT_TRANSPOSE = 16,
+ CANVAS_RECT_CLIP_UV = 32,
+ CANVAS_RECT_IS_GROUP = 64,
+ };
+
+ struct Light {
+ bool enabled;
+ Color color;
+ Transform2D xform;
+ float height;
+ float energy;
+ float scale;
+ int z_min;
+ int z_max;
+ int layer_min;
+ int layer_max;
+ int item_mask;
+ int item_shadow_mask;
+ float directional_distance;
+ RS::CanvasLightMode mode;
+ RS::CanvasLightBlendMode blend_mode;
+ RID texture;
+ Vector2 texture_offset;
+ RID canvas;
+ bool use_shadow;
+ int shadow_buffer_size;
+ RS::CanvasLightShadowFilter shadow_filter;
+ Color shadow_color;
+ float shadow_smooth;
+
+ //void *texture_cache; // implementation dependent
+ Rect2 rect_cache;
+ Transform2D xform_cache;
+ float radius_cache; //used for shadow far plane
+ //CameraMatrix shadow_matrix_cache;
+
+ Transform2D light_shader_xform;
+ //Vector2 light_shader_pos;
+
+ Light *shadows_next_ptr;
+ Light *filter_next_ptr;
+ Light *next_ptr;
+ Light *directional_next_ptr;
+
+ RID light_internal;
+ uint64_t version;
+
+ int32_t render_index_cache;
+
+ Light() {
+ version = 0;
+ enabled = true;
+ color = Color(1, 1, 1);
+ shadow_color = Color(0, 0, 0, 0);
+ height = 0;
+ z_min = -1024;
+ z_max = 1024;
+ layer_min = 0;
+ layer_max = 0;
+ item_mask = 1;
+ scale = 1.0;
+ energy = 1.0;
+ item_shadow_mask = 1;
+ mode = RS::CANVAS_LIGHT_MODE_POINT;
+ blend_mode = RS::CANVAS_LIGHT_BLEND_MODE_ADD;
+ // texture_cache = nullptr;
+ next_ptr = nullptr;
+ directional_next_ptr = nullptr;
+ filter_next_ptr = nullptr;
+ use_shadow = false;
+ shadow_buffer_size = 2048;
+ shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE;
+ shadow_smooth = 0.0;
+ render_index_cache = -1;
+ directional_distance = 10000.0;
+ }
+ };
+
+ //easier wrap to avoid mistakes
+
+ struct Item;
+
+ typedef uint64_t PolygonID;
+ virtual PolygonID request_polygon(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>()) = 0;
+ virtual void free_polygon(PolygonID p_polygon) = 0;
+
+ //also easier to wrap to avoid mistakes
+ struct Polygon {
+ PolygonID polygon_id;
+ Rect2 rect_cache;
+
+ _FORCE_INLINE_ void create(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>()) {
+ ERR_FAIL_COND(polygon_id != 0);
+ {
+ uint32_t pc = p_points.size();
+ const Vector2 *v2 = p_points.ptr();
+ rect_cache.position = *v2;
+ for (uint32_t i = 1; i < pc; i++) {
+ rect_cache.expand_to(v2[i]);
+ }
+ }
+ polygon_id = singleton->request_polygon(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights);
+ }
+
+ _FORCE_INLINE_ Polygon() { polygon_id = 0; }
+ _FORCE_INLINE_ ~Polygon() {
+ if (polygon_id) {
+ singleton->free_polygon(polygon_id);
+ }
+ }
+ };
+
+ //item
+
+ struct Item {
+ //commands are allocated in blocks of 4k to improve performance
+ //and cache coherence.
+ //blocks always grow but never shrink.
+
+ struct CommandBlock {
+ enum {
+ MAX_SIZE = 4096
+ };
+ uint32_t usage;
+ uint8_t *memory;
+ };
+
+ struct Command {
+ enum Type {
+ TYPE_RECT,
+ TYPE_NINEPATCH,
+ TYPE_POLYGON,
+ TYPE_PRIMITIVE,
+ TYPE_MESH,
+ TYPE_MULTIMESH,
+ TYPE_PARTICLES,
+ TYPE_TRANSFORM,
+ TYPE_CLIP_IGNORE,
+ };
+
+ Command *next;
+ Type type;
+ virtual ~Command() {}
+ };
+
+ struct CommandRect : public Command {
+ Rect2 rect;
+ Color modulate;
+ Rect2 source;
+ uint8_t flags;
+
+ RID texture;
+
+ CommandRect() {
+ flags = 0;
+ type = TYPE_RECT;
+ }
+ };
+
+ struct CommandNinePatch : public Command {
+ Rect2 rect;
+ Rect2 source;
+ float margin[4];
+ bool draw_center;
+ Color color;
+ RS::NinePatchAxisMode axis_x;
+ RS::NinePatchAxisMode axis_y;
+
+ RID texture;
+
+ CommandNinePatch() {
+ draw_center = true;
+ type = TYPE_NINEPATCH;
+ }
+ };
+
+ struct CommandPolygon : public Command {
+ RS::PrimitiveType primitive;
+ Polygon polygon;
+
+ RID texture;
+
+ CommandPolygon() {
+ type = TYPE_POLYGON;
+ }
+ };
+
+ struct CommandPrimitive : public Command {
+ uint32_t point_count;
+ Vector2 points[4];
+ Vector2 uvs[4];
+ Color colors[4];
+
+ RID texture;
+
+ CommandPrimitive() {
+ type = TYPE_PRIMITIVE;
+ }
+ };
+
+ struct CommandMesh : public Command {
+ RID mesh;
+ Transform2D transform;
+ Color modulate;
+
+ RID texture;
+
+ CommandMesh() { type = TYPE_MESH; }
+ };
+
+ struct CommandMultiMesh : public Command {
+ RID multimesh;
+
+ RID texture;
+
+ CommandMultiMesh() { type = TYPE_MULTIMESH; }
+ };
+
+ struct CommandParticles : public Command {
+ RID particles;
+
+ RID texture;
+
+ CommandParticles() { type = TYPE_PARTICLES; }
+ };
+
+ struct CommandTransform : public Command {
+ Transform2D xform;
+ CommandTransform() { type = TYPE_TRANSFORM; }
+ };
+
+ struct CommandClipIgnore : public Command {
+ bool ignore;
+ CommandClipIgnore() {
+ type = TYPE_CLIP_IGNORE;
+ ignore = false;
+ }
+ };
+
+ struct ViewportRender {
+ RenderingServer *owner;
+ void *udata;
+ Rect2 rect;
+ };
+
+ Transform2D xform;
+ bool clip;
+ bool visible;
+ bool behind;
+ bool update_when_visible;
+
+ struct CanvasGroup {
+ RS::CanvasGroupMode mode;
+ bool fit_empty;
+ float fit_margin;
+ bool blur_mipmaps;
+ float clear_margin;
+ };
+
+ CanvasGroup *canvas_group = nullptr;
+ int light_mask;
+ int z_final;
+
+ mutable bool custom_rect;
+ mutable bool rect_dirty;
+ mutable Rect2 rect;
+ RID material;
+ RID skeleton;
+
+ Item *next;
+
+ struct CopyBackBuffer {
+ Rect2 rect;
+ Rect2 screen_rect;
+ bool full;
+ };
+ CopyBackBuffer *copy_back_buffer;
+
+ Color final_modulate;
+ Transform2D final_transform;
+ Rect2 final_clip_rect;
+ Item *final_clip_owner;
+ Item *material_owner;
+ Item *canvas_group_owner;
+ ViewportRender *vp_render;
+ bool distance_field;
+ bool light_masked;
+
+ Rect2 global_rect_cache;
+
+ const Rect2 &get_rect() const {
+ if (custom_rect || (!rect_dirty && !update_when_visible)) {
+ return rect;
+ }
+
+ //must update rect
+
+ if (commands == nullptr) {
+ rect = Rect2();
+ rect_dirty = false;
+ return rect;
+ }
+
+ Transform2D xf;
+ bool found_xform = false;
+ bool first = true;
+
+ const Item::Command *c = commands;
+
+ while (c) {
+ Rect2 r;
+
+ switch (c->type) {
+ case Item::Command::TYPE_RECT: {
+ const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c);
+ r = crect->rect;
+
+ } break;
+ case Item::Command::TYPE_NINEPATCH: {
+ const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c);
+ r = style->rect;
+ } break;
+
+ case Item::Command::TYPE_POLYGON: {
+ const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
+ r = polygon->polygon.rect_cache;
+ } break;
+ case Item::Command::TYPE_PRIMITIVE: {
+ const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
+ for (uint32_t j = 0; j < primitive->point_count; j++) {
+ if (j == 0) {
+ r.position = primitive->points[0];
+ } else {
+ r.expand_to(primitive->points[j]);
+ }
+ }
+ } break;
+ case Item::Command::TYPE_MESH: {
+ const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
+ AABB aabb = RendererStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID());
+
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+
+ } break;
+ case Item::Command::TYPE_MULTIMESH: {
+ const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c);
+ AABB aabb = RendererStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh);
+
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+
+ } break;
+ case Item::Command::TYPE_PARTICLES: {
+ const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c);
+ if (particles_cmd->particles.is_valid()) {
+ AABB aabb = RendererStorage::base_singleton->particles_get_aabb(particles_cmd->particles);
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+ }
+
+ } break;
+ case Item::Command::TYPE_TRANSFORM: {
+ const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
+ xf = transform->xform;
+ found_xform = true;
+ [[fallthrough]];
+ }
+ default: {
+ c = c->next;
+ continue;
+ }
+ }
+
+ if (found_xform) {
+ r = xf.xform(r);
+ found_xform = false;
+ }
+
+ if (first) {
+ rect = r;
+ first = false;
+ } else {
+ rect = rect.merge(r);
+ }
+ c = c->next;
+ }
+
+ rect_dirty = false;
+ return rect;
+ }
+
+ Command *commands;
+ Command *last_command;
+ Vector<CommandBlock> blocks;
+ uint32_t current_block;
+
+ template <class T>
+ T *alloc_command() {
+ T *command;
+ if (commands == nullptr) {
+ // As the most common use case of canvas items is to
+ // use only one command, the first is done with it's
+ // own allocation. The rest of them use blocks.
+ command = memnew(T);
+ command->next = nullptr;
+ commands = command;
+ last_command = command;
+ } else {
+ //Subsequent commands go into a block.
+
+ while (true) {
+ if (unlikely(current_block == (uint32_t)blocks.size())) {
+ // If we need more blocks, we allocate them
+ // (they won't be freed until this CanvasItem is
+ // deleted, though).
+ CommandBlock cb;
+ cb.memory = (uint8_t *)memalloc(CommandBlock::MAX_SIZE);
+ cb.usage = 0;
+ blocks.push_back(cb);
+ }
+
+ CommandBlock *c = &blocks.write[current_block];
+ size_t space_left = CommandBlock::MAX_SIZE - c->usage;
+ if (space_left < sizeof(T)) {
+ current_block++;
+ continue;
+ }
+
+ //allocate block and add to the linked list
+ void *memory = c->memory + c->usage;
+ command = memnew_placement(memory, T);
+ command->next = nullptr;
+ last_command->next = command;
+ last_command = command;
+ c->usage += sizeof(T);
+ break;
+ }
+ }
+
+ rect_dirty = true;
+ return command;
+ }
+
+ void clear() {
+ // The first one is always allocated on heap
+ // the rest go in the blocks
+ Command *c = commands;
+ while (c) {
+ Command *n = c->next;
+ if (c == commands) {
+ memdelete(commands);
+ commands = nullptr;
+ } else {
+ c->~Command();
+ }
+ c = n;
+ }
+ {
+ uint32_t cbc = MIN((current_block + 1), (uint32_t)blocks.size());
+ CommandBlock *blockptr = blocks.ptrw();
+ for (uint32_t i = 0; i < cbc; i++) {
+ blockptr[i].usage = 0;
+ }
+ }
+
+ last_command = nullptr;
+ commands = nullptr;
+ current_block = 0;
+ clip = false;
+ rect_dirty = true;
+ final_clip_owner = nullptr;
+ material_owner = nullptr;
+ light_masked = false;
+ }
+
+ RS::CanvasItemTextureFilter texture_filter;
+ RS::CanvasItemTextureRepeat texture_repeat;
+
+ Item() {
+ commands = nullptr;
+ last_command = nullptr;
+ current_block = 0;
+ light_mask = 1;
+ vp_render = nullptr;
+ next = nullptr;
+ final_clip_owner = nullptr;
+ canvas_group_owner = nullptr;
+ clip = false;
+ final_modulate = Color(1, 1, 1, 1);
+ visible = true;
+ rect_dirty = true;
+ custom_rect = false;
+ behind = false;
+ material_owner = nullptr;
+ copy_back_buffer = nullptr;
+ distance_field = false;
+ light_masked = false;
+ update_when_visible = false;
+ z_final = 0;
+ texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
+ texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
+ }
+ virtual ~Item() {
+ clear();
+ for (int i = 0; i < blocks.size(); i++) {
+ memfree(blocks[i].memory);
+ }
+ if (copy_back_buffer) {
+ memdelete(copy_back_buffer);
+ }
+ }
+ };
+
+ 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;
+ RID canvas;
+ RID polygon;
+ RID occluder;
+ Rect2 aabb_cache;
+ Transform2D xform;
+ Transform2D xform_cache;
+ int light_mask;
+ bool sdf_collision;
+ RS::CanvasOccluderPolygonCullMode cull_cache;
+
+ LightOccluderInstance *next;
+
+ LightOccluderInstance() {
+ enabled = true;
+ sdf_collision = false;
+ next = nullptr;
+ light_mask = 1;
+ cull_cache = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
+ }
+ };
+
+ virtual RID light_create() = 0;
+ virtual void light_set_texture(RID p_rid, RID p_texture) = 0;
+ virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0;
+ virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0;
+ virtual void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) = 0;
+
+ virtual void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) = 0;
+
+ virtual RID occluder_polygon_create() = 0;
+ virtual void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) = 0;
+ virtual void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) = 0;
+ virtual void set_shadow_texture_size(int p_size) = 0;
+
+ virtual void draw_window_margins(int *p_margins, RID *p_margin_textures) = 0;
+
+ virtual bool free(RID p_rid) = 0;
+ virtual void update() = 0;
+
+ RendererCanvasRender() { singleton = this; }
+ virtual ~RendererCanvasRender() {}
+};
+
+#endif // RENDERINGSERVERCANVASRENDER_H
diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp
new file mode 100644
index 0000000000..8861522d34
--- /dev/null
+++ b/servers/rendering/renderer_compositor.cpp
@@ -0,0 +1,42 @@
+/*************************************************************************/
+/* renderer_compositor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_compositor.h"
+
+#include "core/os/os.h"
+#include "core/string/print_string.h"
+
+RendererCompositor *(*RendererCompositor::_create_func)() = nullptr;
+
+RendererCompositor *RendererCompositor::create() {
+ return _create_func();
+}
+
+RendererCanvasRender *RendererCanvasRender::singleton = nullptr;
diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h
new file mode 100644
index 0000000000..919ae2c6da
--- /dev/null
+++ b/servers/rendering/renderer_compositor.h
@@ -0,0 +1,78 @@
+/*************************************************************************/
+/* renderer_compositor.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERING_SERVER_COMPOSITOR_H
+#define RENDERING_SERVER_COMPOSITOR_H
+
+#include "core/math/camera_matrix.h"
+#include "core/templates/pair.h"
+#include "core/templates/self_list.h"
+#include "servers/rendering/renderer_canvas_render.h"
+#include "servers/rendering/renderer_scene.h"
+#include "servers/rendering/renderer_scene_render.h"
+#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering_server.h"
+
+class RendererCompositor {
+protected:
+ static RendererCompositor *(*_create_func)();
+
+public:
+ static RendererCompositor *create();
+
+ virtual RendererStorage *get_storage() = 0;
+ virtual RendererCanvasRender *get_canvas() = 0;
+ virtual RendererSceneRender *get_scene() = 0;
+
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) = 0;
+
+ virtual void initialize() = 0;
+ virtual void begin_frame(double frame_step) = 0;
+
+ struct BlitToScreen {
+ RID render_target;
+ Rect2i rect;
+ //lens distorted parameters for VR should go here
+ };
+
+ virtual void prepare_for_blitting_render_targets() = 0;
+ virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0;
+
+ virtual void end_frame(bool p_swap_buffers) = 0;
+ virtual void finalize() = 0;
+ virtual uint64_t get_frame_number() const = 0;
+ virtual float get_frame_delta_time() const = 0;
+
+ virtual bool is_low_end() const = 0;
+
+ virtual ~RendererCompositor() {}
+};
+
+#endif // RASTERIZER_H
diff --git a/servers/rendering/rasterizer_rd/SCsub b/servers/rendering/renderer_rd/SCsub
index 6a2e682c67..6a2e682c67 100644
--- a/servers/rendering/rasterizer_rd/SCsub
+++ b/servers/rendering/renderer_rd/SCsub
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index 97c1e7ba70..6e1d61ff94 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_effects_rd.cpp */
+/* effects_rd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,9 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rasterizer_effects_rd.h"
+#include "effects_rd.h"
#include "core/config/project_settings.h"
+#include "core/math/math_defs.h"
#include "core/os/os.h"
#include "thirdparty/misc/cubemap_coeffs.h"
@@ -58,7 +59,7 @@ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_arra
}
}
-RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) {
+RID EffectsRD::_get_uniform_set_from_image(RID p_image) {
if (image_to_uniform_set_cache.has(p_image)) {
RID uniform_set = image_to_uniform_set_cache[p_image];
if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
@@ -67,7 +68,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) {
}
Vector<RD::Uniform> uniforms;
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 0;
u.ids.push_back(p_image);
uniforms.push_back(u);
@@ -79,7 +80,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) {
return uniform_set;
}
-RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
+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)) {
@@ -89,12 +90,12 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use
Vector<RD::Uniform> uniforms;
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u.binding = 0;
u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
u.ids.push_back(p_texture);
uniforms.push_back(u);
- //any thing with the same configuration (one texture in binding 0 for set 0), is good
+ //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, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 0);
texture_to_uniform_set_cache[p_texture] = uniform_set;
@@ -102,7 +103,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use
return uniform_set;
}
-RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
+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];
if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
@@ -112,7 +113,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo
Vector<RD::Uniform> uniforms;
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u.binding = 0;
u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
u.ids.push_back(p_texture);
@@ -125,7 +126,34 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo
return uniform_set;
}
-RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) {
+RID EffectsRD::_get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RID p_sampler) {
+ TextureSamplerPair tsp;
+ tsp.texture = p_texture;
+ tsp.sampler = p_sampler;
+
+ if (texture_sampler_to_compute_uniform_set_cache.has(tsp)) {
+ RID uniform_set = texture_sampler_to_compute_uniform_set_cache[tsp];
+ 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.ids.push_back(p_sampler);
+ u.ids.push_back(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, ssao.blur_shader.version_get_shader(ssao.blur_shader_version, 0), 0);
+
+ texture_sampler_to_compute_uniform_set_cache[tsp] = uniform_set;
+
+ return uniform_set;
+}
+
+RID EffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) {
TexturePair tp;
tp.texture1 = p_texture1;
tp.texture2 = p_texture2;
@@ -140,7 +168,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u.binding = 0;
u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
u.ids.push_back(p_texture1);
@@ -148,7 +176,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u.binding = 1;
u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
u.ids.push_back(p_texture2);
@@ -162,7 +190,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur
return uniform_set;
}
-RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) {
+RID EffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) {
TexturePair tp;
tp.texture1 = p_texture1;
tp.texture2 = p_texture2;
@@ -177,14 +205,14 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 0;
u.ids.push_back(p_texture1);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(p_texture2);
uniforms.push_back(u);
@@ -197,7 +225,7 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1
return uniform_set;
}
-void RasterizerEffectsRD::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, bool p_panorama) {
+void EffectsRD::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, bool p_panorama) {
zeromem(&copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
copy_to_fb.push_constant.use_section = true;
@@ -218,7 +246,7 @@ void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_f
RD::get_singleton()->draw_list_draw(draw_list, true);
}
-void RasterizerEffectsRD::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) {
+void EffectsRD::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) {
zeromem(&copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
if (p_flip_y) {
@@ -246,7 +274,7 @@ void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_fr
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) {
+void EffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
if (p_flip_y) {
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
@@ -283,7 +311,7 @@ void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_textu
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::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 EffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
copy.push_constant.section[0] = 0;
@@ -306,7 +334,7 @@ void RasterizerEffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::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 EffectsRD::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) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
if (p_flip_y) {
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
@@ -333,7 +361,7 @@ void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_textu
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) {
+void EffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
if (p_flip_y) {
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
@@ -358,7 +386,7 @@ void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) {
+void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
copy.push_constant.section[0] = 0;
@@ -383,7 +411,7 @@ void RasterizerEffectsRD::set_color(RID p_dest_texture, const Color &p_color, co
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) {
+void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
uint32_t base_flags = 0;
@@ -418,7 +446,7 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture,
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::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_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
+void EffectsRD::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_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
@@ -455,7 +483,7 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_text
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
+void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
int32_t x_groups = (p_screen_size.width - 1) / 8 + 1;
@@ -578,7 +606,7 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_ro
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) {
+void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
int32_t x_groups = (p_screen_size.width - 1) / 8 + 1;
@@ -624,7 +652,7 @@ void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2,
}
}
-void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) {
+void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) {
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>());
if (p_reflection.is_valid()) {
@@ -654,7 +682,7 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular,
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {
+void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
copy.push_constant.section[0] = 0;
@@ -674,7 +702,7 @@ void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_textur
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
+void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
CopyToDPPushConstant push_constant;
push_constant.screen_size[0] = p_rect.size.x;
push_constant.screen_size[1] = p_rect.size.y;
@@ -697,7 +725,7 @@ void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
+void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
zeromem(&tonemap.push_constant, sizeof(TonemapPushConstant));
tonemap.push_constant.use_bcs = p_settings.use_bcs;
@@ -718,7 +746,10 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer,
tonemap.push_constant.glow_texture_size[1] = p_settings.glow_texture_size.y;
tonemap.push_constant.glow_mode = p_settings.glow_mode;
- TonemapMode mode = p_settings.glow_use_bicubic_upscale ? TONEMAP_MODE_BICUBIC_GLOW_FILTER : TONEMAP_MODE_NORMAL;
+ int mode = p_settings.glow_use_bicubic_upscale ? TONEMAP_MODE_BICUBIC_GLOW_FILTER : TONEMAP_MODE_NORMAL;
+ if (p_settings.use_1d_color_correction) {
+ mode += 2;
+ }
tonemap.push_constant.tonemapper = p_settings.tonemap_mode;
tonemap.push_constant.use_auto_exposure = p_settings.use_auto_exposure;
@@ -746,7 +777,7 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer,
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::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) {
+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) {
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;
@@ -788,7 +819,7 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) {
+void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) {
bokeh.push_constant.blur_far_active = p_dof_far;
bokeh.push_constant.blur_far_begin = p_dof_far_begin;
bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size;
@@ -948,160 +979,348 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness) {
- //minify first
- ssao.minify_push_constant.orthogonal = p_projection.is_orthogonal();
- ssao.minify_push_constant.z_near = p_projection.get_z_near();
- ssao.minify_push_constant.z_far = p_projection.get_z_far();
- ssao.minify_push_constant.pixel_size[0] = 1.0 / p_depth_buffer_size.x;
- ssao.minify_push_constant.pixel_size[1] = 1.0 / p_depth_buffer_size.y;
- ssao.minify_push_constant.source_size[0] = p_depth_buffer_size.x;
- ssao.minify_push_constant.source_size[1] = p_depth_buffer_size.y;
+void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass) {
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, ssao.gather_uniform_set, 0);
+ if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) {
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, ssao.importance_map_uniform_set, 1);
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ ssao.gather_push_constant.pass_coord_offset[0] = i % 2;
+ ssao.gather_push_constant.pass_coord_offset[1] = i / 2;
+ ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x;
+ ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y;
+ ssao.gather_push_constant.pass = i;
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 2);
+ RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant));
+ int x_groups = ((p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
+ int y_groups = ((p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
+
+ RD::get_singleton()->compute_list_dispatch(p_compute_list, x_groups, y_groups, 1);
+ }
+ RD::get_singleton()->compute_list_add_barrier(p_compute_list);
+}
+
+void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &p_depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
/* FIRST PASS */
- // Minify the depth buffer.
-
- for (int i = 0; i < depth_mipmaps.size(); i++) {
- if (i == 0) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_MINIFY_FIRST]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0);
- } else {
- if (i == 1) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_MINIFY_MIPMAP]);
+ // Downsample and deinterleave the depth buffer.
+ {
+ if (p_invalidate_uniform_sets) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.ids.push_back(p_depth_mipmaps[1]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(p_depth_mipmaps[2]);
+ uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(p_depth_mipmaps[3]);
+ uniforms.push_back(u);
+ }
+ ssao.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.downsample_shader.version_get_shader(ssao.downsample_shader_version, 2), 2);
+ }
+
+ float depth_linearize_mul = -p_projection.matrix[3][2];
+ float depth_linearize_add = p_projection.matrix[2][2];
+ if (depth_linearize_mul * depth_linearize_add < 0) {
+ depth_linearize_add = -depth_linearize_add;
+ }
+
+ ssao.downsample_push_constant.orthogonal = p_projection.is_orthogonal();
+ ssao.downsample_push_constant.z_near = depth_linearize_mul;
+ ssao.downsample_push_constant.z_far = depth_linearize_add;
+ if (ssao.downsample_push_constant.orthogonal) {
+ ssao.downsample_push_constant.z_near = p_projection.get_z_near();
+ ssao.downsample_push_constant.z_far = p_projection.get_z_far();
+ }
+ ssao.downsample_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
+ ssao.downsample_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
+ ssao.downsample_push_constant.radius_sq = p_settings.radius * p_settings.radius;
+
+ int downsample_pipeline = SSAO_DOWNSAMPLE;
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ downsample_pipeline = SSAO_DOWNSAMPLE_HALF;
+ } else if (p_settings.quality > RS::ENV_SSAO_QUALITY_MEDIUM) {
+ downsample_pipeline = SSAO_DOWNSAMPLE_MIPMAP;
+ }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(depth_mipmaps[i - 1]), 0);
+ if (p_settings.half_size) {
+ downsample_pipeline++;
}
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(depth_mipmaps[i]), 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.minify_push_constant, sizeof(SSAOMinifyPushConstant));
- // shrink after set
- ssao.minify_push_constant.source_size[0] = MAX(1, ssao.minify_push_constant.source_size[0] >> 1);
- ssao.minify_push_constant.source_size[1] = MAX(1, ssao.minify_push_constant.source_size[1] >> 1);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[downsample_pipeline]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_depth_mipmaps[0]), 1);
+ if (p_settings.quality > RS::ENV_SSAO_QUALITY_MEDIUM) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.downsample_uniform_set, 2);
+ }
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.downsample_push_constant, sizeof(SSAODownsamplePushConstant));
- int x_groups = (ssao.minify_push_constant.source_size[0] - 1) / 8 + 1;
- int y_groups = (ssao.minify_push_constant.source_size[1] - 1) / 8 + 1;
+ int x_groups = (MAX(1, p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
+ int y_groups = (MAX(1, p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
}
/* SECOND PASS */
- // Gather samples
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[(SSAO_GATHER_LOW + p_quality) + (p_half_size ? 4 : 0)]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_mipmaps_texture), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao1), 1);
- if (!p_half_size) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 2);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_normal_buffer), 3);
-
- ssao.gather_push_constant.screen_size[0] = p_depth_buffer_size.x;
- ssao.gather_push_constant.screen_size[1] = p_depth_buffer_size.y;
- if (p_half_size) {
- ssao.gather_push_constant.screen_size[0] >>= 1;
- ssao.gather_push_constant.screen_size[1] >>= 1;
- }
- ssao.gather_push_constant.z_far = p_projection.get_z_far();
- ssao.gather_push_constant.z_near = p_projection.get_z_near();
- ssao.gather_push_constant.orthogonal = p_projection.is_orthogonal();
-
- ssao.gather_push_constant.proj_info[0] = -2.0f / (ssao.gather_push_constant.screen_size[0] * p_projection.matrix[0][0]);
- ssao.gather_push_constant.proj_info[1] = -2.0f / (ssao.gather_push_constant.screen_size[1] * p_projection.matrix[1][1]);
- ssao.gather_push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
- ssao.gather_push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
- //ssao.gather_push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
- //ssao.gather_push_constant.proj_info[3] = -(1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
-
- ssao.gather_push_constant.radius = p_radius;
-
- ssao.gather_push_constant.proj_scale = float(p_projection.get_pixels_per_meter(ssao.gather_push_constant.screen_size[0]));
- ssao.gather_push_constant.bias = p_bias;
- ssao.gather_push_constant.intensity_div_r6 = p_intensity / pow(p_radius, 6.0f);
-
- ssao.gather_push_constant.pixel_size[0] = 1.0 / p_depth_buffer_size.x;
- ssao.gather_push_constant.pixel_size[1] = 1.0 / p_depth_buffer_size.y;
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant));
+ // Sample SSAO
+ {
+ ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
+ ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
+
+ ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
+ ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
+ float tan_half_fov_x = 1.0 / p_projection.matrix[0][0];
+ float tan_half_fov_y = 1.0 / p_projection.matrix[1][1];
+ ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
+ ssao.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
+ ssao.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
+ ssao.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y;
+ ssao.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
+
+ ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.25;
+ ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.25;
+
+ float radius_near_limit = (p_settings.radius * 1.2f);
+ if (p_settings.quality <= RS::ENV_SSAO_QUALITY_LOW) {
+ radius_near_limit *= 1.50f;
+
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ ssao.gather_push_constant.radius *= 0.8f;
+ }
+ if (p_settings.half_size) {
+ ssao.gather_push_constant.radius *= 0.5f;
+ }
+ }
+ radius_near_limit /= tan_half_fov_y;
+ ssao.gather_push_constant.radius = p_settings.radius;
+ ssao.gather_push_constant.intensity = p_settings.intensity;
+ ssao.gather_push_constant.shadow_power = p_settings.power;
+ ssao.gather_push_constant.shadow_clamp = 0.98;
+ ssao.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from);
+ ssao.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0;
+ ssao.gather_push_constant.horizon_angle_threshold = p_settings.horizon;
+ ssao.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit;
+ ssao.gather_push_constant.neg_inv_radius = -1.0 / ssao.gather_push_constant.radius;
+
+ ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255);
+ ssao.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target;
+
+ ssao.gather_push_constant.detail_intensity = p_settings.detail;
+ ssao.gather_push_constant.quality = MAX(0, p_settings.quality - 1);
+ ssao.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1;
+
+ if (p_invalidate_uniform_sets) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(ssao.mirror_sampler);
+ u.ids.push_back(p_depth_mipmaps_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(p_normal_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(ssao.gather_constants_buffer);
+ uniforms.push_back(u);
+ }
+ ssao.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0), 0);
+ }
- int x_groups = (ssao.gather_push_constant.screen_size[0] - 1) / 8 + 1;
- int y_groups = (ssao.gather_push_constant.screen_size[1] - 1) / 8 + 1;
+ if (p_invalidate_uniform_sets) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.ids.push_back(p_ao_pong);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 1;
+ u.ids.push_back(default_sampler);
+ u.ids.push_back(p_importance_map);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(ssao.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ ssao.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()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) {
+ ssao.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
+ ssao.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
+ ssao.importance_map_push_constant.intensity = p_settings.intensity;
+ ssao.importance_map_push_constant.power = p_settings.power;
+ //base pass
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]);
+ gather_ssao(compute_list, p_ao_pong_slices, p_settings, true);
+ //generate importance map
+ int x_groups = (p_settings.quarter_screen_size.x - 1) / 8 + 1;
+ int y_groups = (p_settings.quarter_screen_size.y - 1) / 8 + 1;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_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(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ //process importance map A
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPA]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_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(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ //process Importance Map B
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPB]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map_pong), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_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(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
- /* THIRD PASS */
- // Blur horizontal
-
- ssao.blur_push_constant.edge_sharpness = p_edge_sharpness;
- ssao.blur_push_constant.filter_scale = p_blur;
- ssao.blur_push_constant.screen_size[0] = ssao.gather_push_constant.screen_size[0];
- ssao.blur_push_constant.screen_size[1] = ssao.gather_push_constant.screen_size[1];
- ssao.blur_push_constant.z_far = p_projection.get_z_far();
- ssao.blur_push_constant.z_near = p_projection.get_z_near();
- ssao.blur_push_constant.orthogonal = p_projection.is_orthogonal();
- ssao.blur_push_constant.axis[0] = 1;
- ssao.blur_push_constant.axis[1] = 0;
-
- if (p_blur != RS::ENV_SSAO_BLUR_DISABLED) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[p_half_size ? SSAO_BLUR_PASS_HALF : SSAO_BLUR_PASS]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao1), 0);
- if (p_half_size) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_mipmaps_texture), 1);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_ADAPTIVE]);
} else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 1);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]);
}
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao2), 3);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant));
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- /* THIRD PASS */
- // Blur vertical
-
- ssao.blur_push_constant.axis[0] = 0;
- ssao.blur_push_constant.axis[1] = 1;
+ gather_ssao(compute_list, p_ao_slices, p_settings, false);
+ }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao2), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao1), 3);
+ // /* THIRD PASS */
+ // // Blur
+ //
+ {
+ ssao.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness;
+ ssao.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
+ ssao.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
+
+ int blur_passes = p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW ? p_settings.blur_passes : 1;
+
+ for (int pass = 0; pass < blur_passes; pass++) {
+ int blur_pipeline = SSAO_BLUR_PASS;
+ if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ if (pass < blur_passes - 2) {
+ blur_pipeline = SSAO_BLUR_PASS_WIDE;
+ }
+ blur_pipeline = SSAO_BLUR_PASS_SMART;
+ }
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant));
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[blur_pipeline]);
+ if (pass % 2 == 0) {
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_slices[i]), 0);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ao_slices[i], ssao.mirror_sampler), 0);
+ }
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_pong_slices[i]), 1);
+ } else {
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong_slices[i]), 0);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ao_pong_slices[i], ssao.mirror_sampler), 0);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 1);
+ }
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant));
+
+ int x_groups = ((p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
+ int y_groups = ((p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
+
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ }
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ }
+ }
}
- if (p_half_size) { //must upscale
- /* FOURTH PASS */
- // upscale if half size
- //back to full size
- ssao.blur_push_constant.screen_size[0] = p_depth_buffer_size.x;
- ssao.blur_push_constant.screen_size[1] = p_depth_buffer_size.y;
+ /* FOURTH PASS */
+ // Interleave buffers
+ // back to full size
+ {
+ ssao.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness;
+ ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
+ ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
+ ssao.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2);
+
+ int interleave_pipeline = SSAO_INTERLEAVE_HALF;
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_LOW) {
+ interleave_pipeline = SSAO_INTERLEAVE;
+ } else if (p_settings.quality >= RS::ENV_SSAO_QUALITY_MEDIUM) {
+ interleave_pipeline = SSAO_INTERLEAVE_SMART;
+ }
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_BLUR_UPSCALE]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[interleave_pipeline]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao1), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_upscale_buffer), 3);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_mipmaps_texture), 2);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_upscale_buffer), 0);
+ if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao), 1);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 1);
+ }
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant)); //not used but set anyway
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant));
- x_groups = (p_depth_buffer_size.x - 1) / 8 + 1;
- y_groups = (p_depth_buffer_size.y - 1) / 8 + 1;
+ int x_groups = (p_settings.full_screen_size.x - 1) / 8 + 1;
+ int y_groups = (p_settings.full_screen_size.y - 1) / 8 + 1;
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
}
RD::get_singleton()->compute_list_end();
+
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, false);
}
-void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
+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;
roughness_limiter.push_constant.curve = p_curve;
@@ -1121,7 +1340,7 @@ void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness,
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
+void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id;
@@ -1146,7 +1365,7 @@ void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) {
+void EffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) {
cubemap_downsampler.push_constant.face_size = p_size.x;
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -1164,11 +1383,11 @@ void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cu
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) {
+void EffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) {
Vector<RD::Uniform> uniforms;
for (int i = 0; i < p_dest_cubemap.size(); i++) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = i;
u.ids.push_back(p_dest_cubemap[i]);
uniforms.push_back(u);
@@ -1193,7 +1412,7 @@ void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_des
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) {
+void EffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) {
SkyPushConstant sky_push_constant;
zeromem(&sky_push_constant, sizeof(SkyPushConstant));
@@ -1229,7 +1448,7 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_
RD::get_singleton()->draw_list_draw(draw_list, true);
}
-void RasterizerEffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples) {
+void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples) {
ResolvePushConstant push_constant;
push_constant.screen_size[0] = p_screen_size.x;
push_constant.screen_size[1] = p_screen_size.y;
@@ -1251,7 +1470,7 @@ void RasterizerEffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_rou
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) {
+void EffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) {
uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, (uint32_t)p_shrink_limit, 0, 0, 0 };
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_REDUCE]);
@@ -1260,7 +1479,7 @@ void RasterizerEffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow,
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1);
}
-void RasterizerEffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) {
+void EffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) {
uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, 0, 0, 0, 0 };
switch (p_filter) {
@@ -1296,7 +1515,7 @@ void RasterizerEffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, cons
}
}
-void RasterizerEffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
+void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
Sort::PushConstant push_constant;
push_constant.total_elements = p_size;
@@ -1365,7 +1584,7 @@ void RasterizerEffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
RD::get_singleton()->compute_list_end();
}
-RasterizerEffectsRD::RasterizerEffectsRD() {
+EffectsRD::EffectsRD() {
{ // Initialize copy
Vector<String> copy_modes;
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
@@ -1423,6 +1642,8 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
Vector<String> tonemap_modes;
tonemap_modes.push_back("\n");
tonemap_modes.push_back("\n#define USE_GLOW_FILTER_BICUBIC\n");
+ tonemap_modes.push_back("\n#define USE_1D_LUT\n");
+ tonemap_modes.push_back("\n#define USE_GLOW_FILTER_BICUBIC\n#define USE_1D_LUT\n");
tonemap.shader.initialize(tonemap_modes);
@@ -1481,57 +1702,142 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
{
// Initialize ssao
+
+ RD::SamplerState sampler;
+ sampler.mag_filter = RD::SAMPLER_FILTER_NEAREST;
+ sampler.min_filter = RD::SAMPLER_FILTER_NEAREST;
+ sampler.mip_filter = RD::SAMPLER_FILTER_NEAREST;
+ sampler.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler.max_lod = 4;
+
+ ssao.mirror_sampler = RD::get_singleton()->sampler_create(sampler);
+
uint32_t pipeline = 0;
{
Vector<String> ssao_modes;
- ssao_modes.push_back("\n#define MINIFY_START\n");
ssao_modes.push_back("\n");
+ ssao_modes.push_back("\n#define USE_HALF_SIZE\n");
+ ssao_modes.push_back("\n#define GENERATE_MIPS\n");
+ ssao_modes.push_back("\n#define GENERATE_MIPS\n#define USE_HALF_SIZE");
+ ssao_modes.push_back("\n#define USE_HALF_BUFFERS\n");
+ ssao_modes.push_back("\n#define USE_HALF_BUFFERS\n#define USE_HALF_SIZE");
- ssao.minify_shader.initialize(ssao_modes);
+ ssao.downsample_shader.initialize(ssao_modes);
- ssao.minify_shader_version = ssao.minify_shader.version_create();
+ ssao.downsample_shader_version = ssao.downsample_shader.version_create();
- for (int i = 0; i <= SSAO_MINIFY_MIPMAP; i++) {
- ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.minify_shader.version_get_shader(ssao.minify_shader_version, i));
+ for (int i = 0; i <= SSAO_DOWNSAMPLE_HALF_RES_HALF; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.downsample_shader.version_get_shader(ssao.downsample_shader_version, i));
pipeline++;
}
}
{
Vector<String> ssao_modes;
- ssao_modes.push_back("\n#define SSAO_QUALITY_LOW\n");
+
ssao_modes.push_back("\n");
- ssao_modes.push_back("\n#define SSAO_QUALITY_HIGH\n");
- ssao_modes.push_back("\n#define SSAO_QUALITY_ULTRA\n");
- ssao_modes.push_back("\n#define SSAO_QUALITY_LOW\n#define USE_HALF_SIZE\n");
- ssao_modes.push_back("\n#define USE_HALF_SIZE\n");
- ssao_modes.push_back("\n#define SSAO_QUALITY_HIGH\n#define USE_HALF_SIZE\n");
- ssao_modes.push_back("\n#define SSAO_QUALITY_ULTRA\n#define USE_HALF_SIZE\n");
+ ssao_modes.push_back("\n#define SSAO_BASE\n");
+ ssao_modes.push_back("\n#define ADAPTIVE\n");
ssao.gather_shader.initialize(ssao_modes);
ssao.gather_shader_version = ssao.gather_shader.version_create();
- for (int i = SSAO_GATHER_LOW; i <= SSAO_GATHER_ULTRA_HALF; i++) {
- ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.gather_shader.version_get_shader(ssao.gather_shader_version, i - SSAO_GATHER_LOW));
+ for (int i = SSAO_GATHER; i <= SSAO_GATHER_ADAPTIVE; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.gather_shader.version_get_shader(ssao.gather_shader_version, i - SSAO_GATHER));
pipeline++;
}
+
+ ssao.gather_constants_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSAOGatherConstants));
+ SSAOGatherConstants gather_constants;
+
+ const int sub_pass_count = 5;
+ for (int pass = 0; pass < 4; pass++) {
+ for (int subPass = 0; subPass < sub_pass_count; subPass++) {
+ int a = pass;
+ int b = subPass;
+
+ int spmap[5]{ 0, 1, 4, 3, 2 };
+ b = spmap[subPass];
+
+ float ca, sa;
+ float angle0 = (float(a) + float(b) / float(sub_pass_count)) * Math_PI * 0.5f;
+
+ ca = Math::cos(angle0);
+ sa = Math::sin(angle0);
+
+ float scale = 1.0f + (a - 1.5f + (b - (sub_pass_count - 1.0f) * 0.5f) / float(sub_pass_count)) * 0.07f;
+
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 0] = scale * ca;
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 1] = scale * -sa;
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 2] = -scale * sa;
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 3] = -scale * ca;
+ }
+ }
+
+ RD::get_singleton()->buffer_update(ssao.gather_constants_buffer, 0, sizeof(SSAOGatherConstants), &gather_constants, false);
}
{
Vector<String> ssao_modes;
- ssao_modes.push_back("\n#define MODE_FULL_SIZE\n");
- ssao_modes.push_back("\n");
- ssao_modes.push_back("\n#define MODE_UPSCALE\n");
+ ssao_modes.push_back("\n#define GENERATE_MAP\n");
+ ssao_modes.push_back("\n#define PROCESS_MAPA\n");
+ ssao_modes.push_back("\n#define PROCESS_MAPB\n");
+
+ ssao.importance_map_shader.initialize(ssao_modes);
+
+ ssao.importance_map_shader_version = ssao.importance_map_shader.version_create();
+
+ for (int i = SSAO_GENERATE_IMPORTANCE_MAP; i <= SSAO_PROCESS_IMPORTANCE_MAPB; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, i - SSAO_GENERATE_IMPORTANCE_MAP));
+
+ pipeline++;
+ }
+ ssao.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t));
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, false);
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(ssao.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2);
+ }
+ {
+ Vector<String> ssao_modes;
+ ssao_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssao_modes.push_back("\n#define MODE_SMART\n");
+ ssao_modes.push_back("\n#define MODE_WIDE\n");
ssao.blur_shader.initialize(ssao_modes);
ssao.blur_shader_version = ssao.blur_shader.version_create();
- for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_UPSCALE; i++) {
+ for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_PASS_WIDE; i++) {
ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.blur_shader.version_get_shader(ssao.blur_shader_version, i - SSAO_BLUR_PASS));
pipeline++;
}
}
+ {
+ Vector<String> ssao_modes;
+ ssao_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssao_modes.push_back("\n#define MODE_SMART\n");
+ ssao_modes.push_back("\n#define MODE_HALF\n");
+
+ ssao.interleave_shader.initialize(ssao_modes);
+
+ ssao.interleave_shader_version = ssao.interleave_shader.version_create();
+ for (int i = SSAO_INTERLEAVE; i <= SSAO_INTERLEAVE_HALF; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, i - SSAO_INTERLEAVE));
+
+ pipeline++;
+ }
+ }
ERR_FAIL_COND(pipeline != SSAO_MAX);
}
@@ -1586,7 +1892,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 0;
u.ids.push_back(filter.coefficient_buffer);
uniforms.push_back(u);
@@ -1758,7 +2064,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
}
}
-RasterizerEffectsRD::~RasterizerEffectsRD() {
+EffectsRD::~EffectsRD() {
if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
RD::get_singleton()->free(filter.image_uniform_set);
}
@@ -1772,6 +2078,10 @@ RasterizerEffectsRD::~RasterizerEffectsRD() {
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
RD::get_singleton()->free(filter.coefficient_buffer);
+ RD::get_singleton()->free(ssao.mirror_sampler);
+ RD::get_singleton()->free(ssao.gather_constants_buffer);
+ RD::get_singleton()->free(ssao.importance_map_load_counter);
+
bokeh.shader.version_free(bokeh.shader_version);
copy.shader.version_free(copy.shader_version);
copy_to_fb.shader.version_free(copy_to_fb.shader_version);
@@ -1786,7 +2096,9 @@ RasterizerEffectsRD::~RasterizerEffectsRD() {
specular_merge.shader.version_free(specular_merge.shader_version);
ssao.blur_shader.version_free(ssao.blur_shader_version);
ssao.gather_shader.version_free(ssao.gather_shader_version);
- ssao.minify_shader.version_free(ssao.minify_shader_version);
+ ssao.downsample_shader.version_free(ssao.downsample_shader_version);
+ ssao.interleave_shader.version_free(ssao.interleave_shader_version);
+ ssao.importance_map_shader.version_free(ssao.importance_map_shader_version);
ssr.shader.version_free(ssr.shader_version);
ssr_filter.shader.version_free(ssr_filter.shader_version);
ssr_scale.shader.version_free(ssr_scale.shader_version);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index a0bdd59fd2..e2cdd0c3d8 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_effects_rd.h */
+/* effects_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,36 +28,38 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_EFFECTS_RD_H
-#define RASTERIZER_EFFECTS_RD_H
+#ifndef EFFECTS_RD_H
+#define EFFECTS_RD_H
#include "core/math/camera_matrix.h"
-#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
-#include "servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/copy.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/resolve.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/sort.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/specular_merge.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/ssao.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/tonemap.glsl.gen.h"
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/shaders/bokeh_dof.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/copy.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/copy_to_fb.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/cube_to_dp.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/cubemap_filter.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/resolve.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/shadow_reduce.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssao_blur.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssao_downsample.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssao_interleave.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/tonemap.glsl.gen.h"
#include "servers/rendering_server.h"
-class RasterizerEffectsRD {
+class EffectsRD {
enum CopyMode {
COPY_MODE_GAUSSIAN_COPY,
COPY_MODE_GAUSSIAN_COPY_8BIT,
@@ -144,7 +146,7 @@ class RasterizerEffectsRD {
CopyToFbPushConstant push_constant;
CopyToFbShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[COPY_TO_FB_MAX];
+ PipelineCacheRD pipelines[COPY_TO_FB_MAX];
} copy_to_fb;
@@ -167,6 +169,8 @@ class RasterizerEffectsRD {
enum TonemapMode {
TONEMAP_MODE_NORMAL,
TONEMAP_MODE_BICUBIC_GLOW_FILTER,
+ TONEMAP_MODE_1D_LUT,
+ TONEMAP_MODE_BICUBIC_GLOW_FILTER_1D_LUT,
TONEMAP_MODE_MAX
};
@@ -198,13 +202,13 @@ class RasterizerEffectsRD {
/* tonemap actually writes to a framebuffer, which is
* better to do using the raster pipeline rather than
- * comptute, as that framebuffer might be in different formats
+ * compute, as that framebuffer might be in different formats
*/
struct Tonemap {
TonemapPushConstant push_constant;
TonemapShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[TONEMAP_MODE_MAX];
+ PipelineCacheRD pipelines[TONEMAP_MODE_MAX];
} tonemap;
enum LuminanceReduceMode {
@@ -286,71 +290,121 @@ class RasterizerEffectsRD {
} bokeh;
enum SSAOMode {
- SSAO_MINIFY_FIRST,
- SSAO_MINIFY_MIPMAP,
- SSAO_GATHER_LOW,
- SSAO_GATHER_MEDIUM,
- SSAO_GATHER_HIGH,
- SSAO_GATHER_ULTRA,
- SSAO_GATHER_LOW_HALF,
- SSAO_GATHER_MEDIUM_HALF,
- SSAO_GATHER_HIGH_HALF,
- SSAO_GATHER_ULTRA_HALF,
+ SSAO_DOWNSAMPLE,
+ SSAO_DOWNSAMPLE_HALF_RES,
+ SSAO_DOWNSAMPLE_MIPMAP,
+ SSAO_DOWNSAMPLE_MIPMAP_HALF_RES,
+ SSAO_DOWNSAMPLE_HALF,
+ SSAO_DOWNSAMPLE_HALF_RES_HALF,
+ SSAO_GATHER,
+ SSAO_GATHER_BASE,
+ SSAO_GATHER_ADAPTIVE,
+ SSAO_GENERATE_IMPORTANCE_MAP,
+ SSAO_PROCESS_IMPORTANCE_MAPA,
+ SSAO_PROCESS_IMPORTANCE_MAPB,
SSAO_BLUR_PASS,
- SSAO_BLUR_PASS_HALF,
- SSAO_BLUR_UPSCALE,
+ SSAO_BLUR_PASS_SMART,
+ SSAO_BLUR_PASS_WIDE,
+ SSAO_INTERLEAVE,
+ SSAO_INTERLEAVE_SMART,
+ SSAO_INTERLEAVE_HALF,
SSAO_MAX
};
- struct SSAOMinifyPushConstant {
+ struct SSAODownsamplePushConstant {
float pixel_size[2];
float z_far;
float z_near;
- int32_t source_size[2];
uint32_t orthogonal;
- uint32_t pad;
+ float radius_sq;
+ uint32_t pad[2];
};
struct SSAOGatherPushConstant {
int32_t screen_size[2];
- float z_far;
- float z_near;
+ int pass;
+ int quality;
+
+ float half_screen_pixel_size[2];
+ int size_multiplier;
+ float detail_intensity;
+
+ float NDC_to_view_mul[2];
+ float NDC_to_view_add[2];
+
+ float pad[2];
+ float half_screen_pixel_size_x025[2];
- uint32_t orthogonal;
- float intensity_div_r6;
float radius;
- float bias;
+ float intensity;
+ float shadow_power;
+ float shadow_clamp;
- float proj_info[4];
- float pixel_size[2];
- float proj_scale;
- uint32_t pad;
+ float fade_out_mul;
+ float fade_out_add;
+ float horizon_angle_threshold;
+ float inv_radius_near_limit;
+
+ bool is_orthogonal;
+ float neg_inv_radius;
+ float load_counter_avg_div;
+ float adaptive_sample_limit;
+
+ int32_t pass_coord_offset[2];
+ float pass_uv_offset[2];
+ };
+
+ struct SSAOGatherConstants {
+ float rotation_matrices[80]; //5 vec4s * 4
+ };
+
+ struct SSAOImportanceMapPushConstant {
+ float half_screen_pixel_size[2];
+ float intensity;
+ float power;
};
struct SSAOBlurPushConstant {
float edge_sharpness;
- int32_t filter_scale;
- float z_far;
- float z_near;
- uint32_t orthogonal;
- uint32_t pad[3];
- int32_t axis[2];
- int32_t screen_size[2];
+ float pad;
+ float half_screen_pixel_size[2];
+ };
+
+ struct SSAOInterleavePushConstant {
+ float inv_sharpness;
+ uint32_t size_modifier;
+ float pixel_size[2];
};
struct SSAO {
- SSAOMinifyPushConstant minify_push_constant;
- SsaoMinifyShaderRD minify_shader;
- RID minify_shader_version;
+ SSAODownsamplePushConstant downsample_push_constant;
+ SsaoDownsampleShaderRD downsample_shader;
+ RID downsample_shader_version;
+ RID downsample_uniform_set;
SSAOGatherPushConstant gather_push_constant;
SsaoShaderRD gather_shader;
RID gather_shader_version;
+ RID gather_uniform_set;
+ RID gather_constants_buffer;
+ bool gather_initialized = false;
+
+ SSAOImportanceMapPushConstant importance_map_push_constant;
+ SsaoImportanceMapShaderRD importance_map_shader;
+ RID importance_map_shader_version;
+ RID importance_map_load_counter;
+ RID importance_map_uniform_set;
+ RID counter_uniform_set;
SSAOBlurPushConstant blur_push_constant;
SsaoBlurShaderRD blur_shader;
RID blur_shader_version;
+ SSAOInterleavePushConstant interleave_push_constant;
+ SsaoInterleaveShaderRD interleave_shader;
+ RID interleave_shader_version;
+
+ RID mirror_sampler;
RID pipelines[SSAO_MAX];
} ssao;
@@ -424,7 +478,7 @@ class RasterizerEffectsRD {
struct SpecularMerge {
SpecularMergeShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[SPECULAR_MERGE_MAX];
+ PipelineCacheRD pipelines[SPECULAR_MERGE_MAX];
} specular_merge;
@@ -596,13 +650,27 @@ class RasterizerEffectsRD {
}
};
+ struct TextureSamplerPair {
+ RID texture;
+ RID sampler;
+ _FORCE_INLINE_ bool operator<(const TextureSamplerPair &p_pair) const {
+ if (texture == p_pair.texture) {
+ return sampler < p_pair.sampler;
+ } else {
+ return texture < p_pair.texture;
+ }
+ }
+ };
+
Map<RID, RID> texture_to_compute_uniform_set_cache;
Map<TexturePair, RID> texture_pair_to_compute_uniform_set_cache;
Map<TexturePair, RID> image_pair_to_compute_uniform_set_cache;
+ Map<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);
+ RID _get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RID p_sampler);
RID _get_compute_uniform_set_from_texture_pair(RID p_texture, RID p_texture2, bool p_use_mipmaps = false);
RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2);
@@ -654,6 +722,7 @@ public:
float saturation = 1.0;
bool use_color_correction = false;
+ bool use_1d_color_correction = false;
RID color_correction_texture;
bool use_fxaa = false;
@@ -661,14 +730,35 @@ public:
Vector2i texture_size;
};
+ struct SSAOSettings {
+ float radius = 1.0;
+ float intensity = 2.0;
+ float power = 1.5;
+ float detail = 0.5;
+ float horizon = 0.06;
+ float sharpness = 0.98;
+
+ RS::EnvironmentSSAOQuality quality = RS::ENV_SSAO_QUALITY_MEDIUM;
+ bool half_size = false;
+ float adaptive_target = 0.5;
+ int blur_passes = 2;
+ float fadeout_from = 50.0;
+ float fadeout_to = 300.0;
+
+ Size2i full_screen_size = Size2i();
+ Size2i half_screen_size = Size2i();
+ Size2i quarter_screen_size = Size2i();
+ };
+
void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings);
- void generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness);
+ void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass);
+ void generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets);
void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve);
void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size);
void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array);
- void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position);
+ void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position);
void screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera);
void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection);
@@ -681,8 +771,8 @@ public:
void sort_buffer(RID p_uniform_set, int p_size);
- RasterizerEffectsRD();
- ~RasterizerEffectsRD();
+ EffectsRD();
+ ~EffectsRD();
};
#endif // !RASTERIZER_EFFECTS_RD_H
diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp b/servers/rendering/renderer_rd/light_cluster_builder.cpp
index efb48e6df7..bb807ca4ca 100644
--- a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp
+++ b/servers/rendering/renderer_rd/light_cluster_builder.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -190,7 +190,7 @@ void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_
{
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
- tf.type = RD::TEXTURE_TYPE_3D;
+ tf.texture_type = RD::TEXTURE_TYPE_3D;
tf.width = width;
tf.height = height;
tf.depth = depth;
diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/renderer_rd/light_cluster_builder.h
index b1da083dad..8f77ece6f5 100644
--- a/servers/rendering/rasterizer_rd/light_cluster_builder.h
+++ b/servers/rendering/renderer_rd/light_cluster_builder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -31,7 +31,7 @@
#ifndef LIGHT_CLUSTER_BUILDER_H
#define LIGHT_CLUSTER_BUILDER_H
-#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
class LightClusterBuilder {
public:
diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
index 5cc3da8d4e..b2b919c40e 100644
--- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* render_pipeline_vertex_format_cache_rd.cpp */
+/* pipeline_cache_rd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "render_pipeline_vertex_format_cache_rd.h"
+#include "pipeline_cache_rd.h"
#include "core/os/memory.h"
-RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) {
+RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) {
RD::PipelineMultisampleState multisample_state_version = multisample_state;
multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id);
@@ -49,7 +49,7 @@ RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_ve
return pipeline;
}
-void RenderPipelineVertexFormatCacheRD::_clear() {
+void PipelineCacheRD::_clear() {
if (versions) {
for (uint32_t i = 0; i < version_count; i++) {
//shader may be gone, so this may not be valid
@@ -63,7 +63,7 @@ void RenderPipelineVertexFormatCacheRD::_clear() {
}
}
-void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
+void PipelineCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
ERR_FAIL_COND(p_shader.is_null());
_clear();
shader = p_shader;
@@ -76,24 +76,24 @@ void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::RenderPrimitive
dynamic_state_flags = p_dynamic_state_flags;
}
-void RenderPipelineVertexFormatCacheRD::update_shader(RID p_shader) {
+void PipelineCacheRD::update_shader(RID p_shader) {
ERR_FAIL_COND(p_shader.is_null());
_clear();
setup(p_shader, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
}
-void RenderPipelineVertexFormatCacheRD::clear() {
+void PipelineCacheRD::clear() {
_clear();
shader = RID(); //clear shader
input_mask = 0;
}
-RenderPipelineVertexFormatCacheRD::RenderPipelineVertexFormatCacheRD() {
+PipelineCacheRD::PipelineCacheRD() {
version_count = 0;
versions = nullptr;
input_mask = 0;
}
-RenderPipelineVertexFormatCacheRD::~RenderPipelineVertexFormatCacheRD() {
+PipelineCacheRD::~PipelineCacheRD() {
_clear();
}
diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h
index 6a72dbc77c..b1c8f21ecc 100644
--- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* render_pipeline_vertex_format_cache_rd.h */
+/* pipeline_cache_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RENDER_PIPELINE_CACHE_RD_H
-#define RENDER_PIPELINE_CACHE_RD_H
+#ifndef PIPELINE_CACHE_RD_H
+#define PIPELINE_CACHE_RD_H
#include "core/os/spin_lock.h"
#include "servers/rendering/rendering_device.h"
-class RenderPipelineVertexFormatCacheRD {
+class PipelineCacheRD {
SpinLock spin_lock;
RID shader;
@@ -89,8 +89,8 @@ public:
return input_mask;
}
void clear();
- RenderPipelineVertexFormatCacheRD();
- ~RenderPipelineVertexFormatCacheRD();
+ PipelineCacheRD();
+ ~PipelineCacheRD();
};
#endif // RENDER_PIPELINE_CACHE_RD_H
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 921a7b966e..792fcb0b59 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_canvas_rd.cpp */
+/* renderer_canvas_render_rd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rasterizer_canvas_rd.h"
+#include "renderer_canvas_render_rd.h"
#include "core/config/project_settings.h"
#include "core/math/geometry_2d.h"
#include "core/math/math_funcs.h"
-#include "rasterizer_rd.h"
+#include "renderer_compositor_rd.h"
-void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
+void RendererCanvasRenderRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
p_mat4[0] = p_transform.elements[0][0];
p_mat4[1] = p_transform.elements[0][1];
p_mat4[2] = 0;
@@ -53,7 +53,7 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_trans
p_mat4[15] = 1;
}
-void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) {
+void RendererCanvasRenderRD::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) {
p_mat2x4[0] = p_transform.elements[0][0];
p_mat2x4[1] = p_transform.elements[1][0];
p_mat2x4[2] = 0;
@@ -65,7 +65,7 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_tra
p_mat2x4[7] = p_transform.elements[2][1];
}
-void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) {
+void RendererCanvasRenderRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) {
p_mat2x3[0] = p_transform.elements[0][0];
p_mat2x3[1] = p_transform.elements[0][1];
p_mat2x3[2] = p_transform.elements[1][0];
@@ -74,7 +74,7 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_tra
p_mat2x3[5] = p_transform.elements[2][1];
}
-void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) {
+void RendererCanvasRenderRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) {
p_mat4[0] = p_transform.basis.elements[0][0];
p_mat4[1] = p_transform.basis.elements[1][0];
p_mat4[2] = p_transform.basis.elements[2][0];
@@ -93,7 +93,7 @@ void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform,
p_mat4[15] = 1;
}
-RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) {
+RendererCanvasRender::PolygonID RendererCanvasRenderRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) {
// Care must be taken to generate array formats
// in ways where they could be reused, so we will
// put single-occuring elements first, and repeated
@@ -119,9 +119,9 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
Vector<uint8_t> polygon_buffer;
polygon_buffer.resize(buffer_size * sizeof(float));
Vector<RD::VertexAttribute> descriptions;
- descriptions.resize(4);
+ descriptions.resize(5);
Vector<RID> buffers;
- buffers.resize(4);
+ buffers.resize(5);
{
const uint8_t *r = polygon_buffer.ptr();
@@ -184,7 +184,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
vd.stride = 0;
descriptions.write[1] = vd;
- buffers.write[1] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_COLOR);
+ buffers.write[1] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_COLOR);
}
//uvs
@@ -212,13 +212,13 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
vd.stride = 0;
descriptions.write[2] = vd;
- buffers.write[2] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_TEX_UV);
+ buffers.write[2] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_TEX_UV);
}
//bones
if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
RD::VertexAttribute vd;
- vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
+ vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_BONES;
vd.stride = stride * sizeof(float);
@@ -226,16 +226,42 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
descriptions.write[3] = vd;
const int *bone_ptr = p_bones.ptr();
- const float *weight_ptr = p_weights.ptr();
for (uint32_t i = 0; i < vertex_count; i++) {
uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
- uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2];
bone16w[0] = bone_ptr[i * 4 + 0];
bone16w[1] = bone_ptr[i * 4 + 1];
bone16w[2] = bone_ptr[i * 4 + 2];
bone16w[3] = bone_ptr[i * 4 + 3];
+ }
+
+ base_offset += 2;
+ } else {
+ RD::VertexAttribute vd;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
+ vd.offset = 0;
+ vd.location = RS::ARRAY_BONES;
+ vd.stride = 0;
+
+ descriptions.write[3] = vd;
+ buffers.write[3] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_BONES);
+ }
+
+ //weights
+ if ((uint32_t)p_weights.size() == vertex_count * 4) {
+ RD::VertexAttribute vd;
+ vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
+ vd.offset = base_offset * sizeof(float);
+ vd.location = RS::ARRAY_WEIGHTS;
+ vd.stride = stride * sizeof(float);
+
+ descriptions.write[4] = vd;
+
+ const float *weight_ptr = p_weights.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride];
weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
@@ -243,16 +269,16 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
}
- base_offset += 4;
+ base_offset += 2;
} else {
RD::VertexAttribute vd;
- vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = 0;
- vd.location = RS::ARRAY_BONES;
+ vd.location = RS::ARRAY_WEIGHTS;
vd.stride = 0;
- descriptions.write[3] = vd;
- buffers.write[3] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES);
+ descriptions.write[4] = vd;
+ buffers.write[4] = storage->mesh_get_default_rd_buffer(RendererStorageRD::DEFAULT_RD_BUFFER_BONES);
}
//check that everything is as it should be
@@ -293,7 +319,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
return id;
}
-void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) {
+void RendererCanvasRenderRD::free_polygon(PolygonID p_polygon) {
PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon);
ERR_FAIL_COND(!pb_ptr);
@@ -314,7 +340,7 @@ void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) {
////////////////////
-void RasterizerCanvasRD::_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) {
+void RendererCanvasRenderRD::_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) {
if (p_texture == RID()) {
p_texture = default_canvas_texture;
}
@@ -364,7 +390,7 @@ void RasterizerCanvasRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_
r_last_texture = p_texture;
}
-void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, 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, 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) {
//create an empty push constant
RS::CanvasItemTextureFilter current_filter = default_filter;
@@ -575,10 +601,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
push_constant.flags |= FLAGS_NINEPACH_DRAW_CENTER;
}
- push_constant.ninepatch_margins[0] = np->margin[MARGIN_LEFT];
- push_constant.ninepatch_margins[1] = np->margin[MARGIN_TOP];
- push_constant.ninepatch_margins[2] = np->margin[MARGIN_RIGHT];
- push_constant.ninepatch_margins[3] = np->margin[MARGIN_BOTTOM];
+ push_constant.ninepatch_margins[0] = np->margin[SIDE_LEFT];
+ push_constant.ninepatch_margins[1] = np->margin[SIDE_TOP];
+ push_constant.ninepatch_margins[2] = np->margin[SIDE_RIGHT];
+ push_constant.ninepatch_margins[3] = np->margin[SIDE_BOTTOM];
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array);
@@ -848,7 +874,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); //not used, so keep white
- RenderingServerRaster::redraw_request();
+ RenderingServerDefault::redraw_request();
storage->particles_request_process(particles_cmd->particles);
//enable instancing
@@ -990,13 +1016,13 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
}
}
-RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_backbuffer) {
+RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, bool p_backbuffer) {
//re create canvas state
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 1;
u.ids.push_back(state.canvas_state_buffer);
uniforms.push_back(u);
@@ -1004,7 +1030,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 2;
u.ids.push_back(state.lights_uniform_buffer);
uniforms.push_back(u);
@@ -1012,7 +1038,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 3;
u.ids.push_back(storage->decal_atlas_get_texture());
uniforms.push_back(u);
@@ -1020,7 +1046,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 4;
u.ids.push_back(state.shadow_texture);
uniforms.push_back(u);
@@ -1028,7 +1054,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 5;
u.ids.push_back(state.shadow_sampler);
uniforms.push_back(u);
@@ -1036,7 +1062,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 6;
RID screen;
if (p_backbuffer) {
@@ -1044,7 +1070,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
} else {
screen = storage->render_target_get_rd_backbuffer(p_to_render_target);
if (screen.is_null()) { //unallocated backbuffer
- screen = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ screen = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
}
}
u.ids.push_back(screen);
@@ -1053,7 +1079,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 7;
RID sdf = storage->render_target_get_sdf_texture(p_to_render_target);
u.ids.push_back(sdf);
@@ -1063,7 +1089,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
//needs samplers for the material (uses custom textures) create them
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 8;
u.ids.resize(12);
RID *ids_ptr = u.ids.ptrw();
@@ -1084,7 +1110,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 9;
u.ids.push_back(storage->global_variables_get_storage_buffer());
uniforms.push_back(u);
@@ -1100,7 +1126,7 @@ RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_
return uniform_set;
}
-void RasterizerCanvasRD::_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 p_to_backbuffer) {
Item *current_clip = nullptr;
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
@@ -1167,7 +1193,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
if (material != prev_material) {
MaterialData *material_data = nullptr;
if (material.is_valid()) {
- material_data = (MaterialData *)storage->material_get_data(material, RasterizerStorageRD::SHADER_TYPE_2D);
+ material_data = (MaterialData *)storage->material_get_data(material, RendererStorageRD::SHADER_TYPE_2D);
}
if (material_data) {
@@ -1192,7 +1218,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
RD::get_singleton()->draw_list_end();
}
-void RasterizerCanvasRD::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, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
+void RendererCanvasRenderRD::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, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
r_sdf_used = false;
int item_count = 0;
@@ -1423,7 +1449,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
}
if (ci->material.is_valid()) {
- MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
+ MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RendererStorageRD::SHADER_TYPE_2D);
if (md && md->shader_data->valid) {
if (md->shader_data->uses_screen_texture && canvas_group_owner == nullptr) {
if (!material_screen_texture_found) {
@@ -1435,12 +1461,12 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
if (md->shader_data->uses_sdf) {
r_sdf_used = true;
}
- if (md->last_frame != RasterizerRD::singleton->get_frame_number()) {
- md->last_frame = RasterizerRD::singleton->get_frame_number();
+ if (md->last_frame != RendererCompositorRD::singleton->get_frame_number()) {
+ md->last_frame = RendererCompositorRD::singleton->get_frame_number();
if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) {
// uniform set may be gone because a dependency was erased. In this case, it will happen
// if a texture is deleted, so just re-create it.
- storage->material_force_update_textures(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
+ storage->material_force_update_textures(ci->material, RendererStorageRD::SHADER_TYPE_2D);
}
}
}
@@ -1501,12 +1527,12 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
}
}
-RID RasterizerCanvasRD::light_create() {
+RID RendererCanvasRenderRD::light_create() {
CanvasLight canvas_light;
return canvas_light_owner.make_rid(canvas_light);
}
-void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) {
+void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND(!cl);
if (cl->texture == p_texture) {
@@ -1522,14 +1548,14 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) {
}
}
-void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable) {
+void RendererCanvasRenderRD::light_set_use_shadow(RID p_rid, bool p_enable) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND(!cl);
cl->shadow.enabled = p_enable;
}
-void RasterizerCanvasRD::_update_shadow_atlas() {
+void RendererCanvasRenderRD::_update_shadow_atlas() {
if (state.shadow_fb == RID()) {
//ah, we lack the shadow texture..
RD::get_singleton()->free(state.shadow_texture); //erase placeholder
@@ -1538,7 +1564,7 @@ void RasterizerCanvasRD::_update_shadow_atlas() {
{ //texture
RD::TextureFormat tf;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.width = state.shadow_texture_size;
tf.height = state.max_lights_per_render * 2;
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
@@ -1549,7 +1575,7 @@ void RasterizerCanvasRD::_update_shadow_atlas() {
}
{
RD::TextureFormat tf;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.width = state.shadow_texture_size;
tf.height = state.max_lights_per_render * 2;
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
@@ -1562,7 +1588,7 @@ void RasterizerCanvasRD::_update_shadow_atlas() {
state.shadow_fb = RD::get_singleton()->framebuffer_create(fb_textures);
}
}
-void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
+void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND(!cl->shadow.enabled);
@@ -1640,7 +1666,7 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, cons
}
}
-void RasterizerCanvasRD::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) {
+void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND(!cl->shadow.enabled);
@@ -1663,7 +1689,7 @@ void RasterizerCanvasRD::light_update_directional_shadow(RID p_rid, int p_shadow
to_light_xform[2] = from_pos;
to_light_xform[1] = light_dir;
- to_light_xform[0] = -light_dir.tangent();
+ to_light_xform[0] = -light_dir.orthogonal();
to_light_xform.invert();
@@ -1720,7 +1746,7 @@ void RasterizerCanvasRD::light_update_directional_shadow(RID p_rid, int p_shadow
cl->shadow.directional_xform = to_shadow * to_light_xform;
}
-void RasterizerCanvasRD::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) {
+void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) {
RID fb = storage->render_target_get_sdf_framebuffer(p_render_target);
Rect2i rect = storage->render_target_get_sdf_rect(p_render_target);
@@ -1782,7 +1808,7 @@ void RasterizerCanvasRD::render_sdf(RID p_render_target, LightOccluderInstance *
storage->render_target_sdf_process(p_render_target); //done rendering, process it
}
-RID RasterizerCanvasRD::occluder_polygon_create() {
+RID RendererCanvasRenderRD::occluder_polygon_create() {
OccluderPolygon occluder;
occluder.line_point_count = 0;
occluder.sdf_point_count = 0;
@@ -1791,27 +1817,30 @@ RID RasterizerCanvasRD::occluder_polygon_create() {
return occluder_polygon_owner.make_rid(occluder);
}
-void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) {
+void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) {
OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder);
ERR_FAIL_COND(!oc);
Vector<Vector2> lines;
- int lc = p_points.size() * 2;
- lines.resize(lc - (p_closed ? 0 : 2));
- {
- Vector2 *w = lines.ptrw();
- const Vector2 *r = p_points.ptr();
+ if (p_points.size()) {
+ int lc = p_points.size() * 2;
- int max = lc / 2;
- if (!p_closed) {
- max--;
- }
- for (int i = 0; i < max; i++) {
- Vector2 a = r[i];
- Vector2 b = r[(i + 1) % (lc / 2)];
- w[i * 2 + 0] = a;
- w[i * 2 + 1] = b;
+ lines.resize(lc - (p_closed ? 0 : 2));
+ {
+ Vector2 *w = lines.ptrw();
+ const Vector2 *r = p_points.ptr();
+
+ int max = lc / 2;
+ if (!p_closed) {
+ max--;
+ }
+ for (int i = 0; i < max; i++) {
+ Vector2 a = r[i];
+ Vector2 b = r[(i + 1) % (lc / 2)];
+ w[i * 2 + 0] = a;
+ w[i * 2 + 1] = b;
+ }
}
}
@@ -1832,7 +1861,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
if (lines.size()) {
Vector<uint8_t> geometry;
Vector<uint8_t> indices;
- lc = lines.size();
+ int lc = lines.size();
geometry.resize(lc * 6 * sizeof(float));
indices.resize(lc * 3 * sizeof(uint16_t));
@@ -1902,19 +1931,21 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
Vector<int> sdf_indices;
- if (p_closed) {
- sdf_indices = Geometry2D::triangulate_polygon(p_points);
- oc->sdf_is_lines = false;
- } else {
- int max = p_points.size();
- sdf_indices.resize(max * 2);
+ if (p_points.size()) {
+ if (p_closed) {
+ sdf_indices = Geometry2D::triangulate_polygon(p_points);
+ oc->sdf_is_lines = false;
+ } else {
+ int max = p_points.size();
+ sdf_indices.resize(max * 2);
- int *iw = sdf_indices.ptrw();
- for (int i = 0; i < max; i++) {
- iw[i * 2 + 0] = i;
- iw[i * 2 + 1] = (i + 1) % max;
+ int *iw = sdf_indices.ptrw();
+ for (int i = 0; i < max; i++) {
+ iw[i * 2 + 0] = i;
+ iw[i * 2 + 1] = (i + 1) % max;
+ }
+ oc->sdf_is_lines = true;
}
- oc->sdf_is_lines = true;
}
if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array.is_valid()) {
@@ -1955,13 +1986,13 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
}
}
-void RasterizerCanvasRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {
+void RendererCanvasRenderRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {
OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder);
ERR_FAIL_COND(!oc);
oc->cull_mode = p_mode;
}
-void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
+void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
//compile
code = p_code;
@@ -1994,7 +2025,7 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
actions.uniforms = &uniforms;
- RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton;
+ RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
Error err = canvas_singleton->shader.compiler.compile(RS::SHADER_CANVAS_ITEM, code, &actions, path, gen_code);
@@ -2139,7 +2170,7 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
valid = true;
}
-void RasterizerCanvasRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererCanvasRenderRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
if (!p_texture.is_valid()) {
default_texture_params.erase(p_name);
} else {
@@ -2147,7 +2178,7 @@ void RasterizerCanvasRD::ShaderData::set_default_texture_param(const StringName
}
}
-void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void RendererCanvasRenderRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
@@ -2168,13 +2199,13 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_
}
}
-void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+void RendererCanvasRenderRD::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
- RasterizerStorage::InstanceShaderParam p;
+ RendererStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E->get());
p.info.name = E->key(); //supply name
p.index = E->get().instance_index;
@@ -2183,7 +2214,7 @@ void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStor
}
}
-bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param) const {
+bool RendererCanvasRenderRD::ShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -2191,15 +2222,15 @@ bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param)
return uniforms[p_param].texture_order >= 0;
}
-bool RasterizerCanvasRD::ShaderData::is_animated() const {
+bool RendererCanvasRenderRD::ShaderData::is_animated() const {
return false;
}
-bool RasterizerCanvasRD::ShaderData::casts_shadows() const {
+bool RendererCanvasRenderRD::ShaderData::casts_shadows() const {
return false;
}
-Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName &p_parameter) const {
+Variant RendererCanvasRenderRD::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;
@@ -2208,14 +2239,19 @@ Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName &
return Variant();
}
-RasterizerCanvasRD::ShaderData::ShaderData() {
+RS::ShaderNativeSourceCode RendererCanvasRenderRD::ShaderData::get_native_source_code() const {
+ RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
+ return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version);
+}
+
+RendererCanvasRenderRD::ShaderData::ShaderData() {
valid = false;
uses_screen_texture = false;
uses_sdf = false;
}
-RasterizerCanvasRD::ShaderData::~ShaderData() {
- RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton;
+RendererCanvasRenderRD::ShaderData::~ShaderData() {
+ RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
ERR_FAIL_COND(!canvas_singleton);
//pipeline variants will clear themselves if shader is gone
if (version.is_valid()) {
@@ -2223,13 +2259,13 @@ RasterizerCanvasRD::ShaderData::~ShaderData() {
}
}
-RasterizerStorageRD::ShaderData *RasterizerCanvasRD::_create_shader_func() {
+RendererStorageRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() {
ShaderData *shader_data = memnew(ShaderData);
return shader_data;
}
-void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
- RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton;
+void RendererCanvasRenderRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
p_uniform_dirty = true;
@@ -2289,7 +2325,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
{
if (shader_data->ubo_size) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 0;
u.ids.push_back(uniform_buffer);
uniforms.push_back(u);
@@ -2298,7 +2334,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
const RID *textures = texture_cache.ptrw();
for (uint32_t i = 0; i < tex_uniform_count; i++) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1 + i;
u.ids.push_back(textures[i]);
uniforms.push_back(u);
@@ -2308,7 +2344,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
}
-RasterizerCanvasRD::MaterialData::~MaterialData() {
+RendererCanvasRenderRD::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
}
@@ -2318,7 +2354,7 @@ RasterizerCanvasRD::MaterialData::~MaterialData() {
}
}
-RasterizerStorageRD::MaterialData *RasterizerCanvasRD::_create_material_func(ShaderData *p_shader) {
+RendererStorageRD::MaterialData *RendererCanvasRenderRD::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
material_data->last_frame = false;
@@ -2326,14 +2362,14 @@ RasterizerStorageRD::MaterialData *RasterizerCanvasRD::_create_material_func(Sha
return material_data;
}
-void RasterizerCanvasRD::set_time(double p_time) {
+void RendererCanvasRenderRD::set_time(double p_time) {
state.time = p_time;
}
-void RasterizerCanvasRD::update() {
+void RendererCanvasRenderRD::update() {
}
-RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
+RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
storage = p_storage;
{ //create default samplers
@@ -2457,8 +2493,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
actions.renames["COLOR"] = "color";
actions.renames["NORMAL"] = "normal";
- actions.renames["NORMALMAP"] = "normal_map";
- actions.renames["NORMALMAP_DEPTH"] = "normal_depth";
+ actions.renames["NORMAL_MAP"] = "normal_map";
+ actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
actions.renames["TEXTURE"] = "color_texture";
actions.renames["TEXTURE_PIXEL_SIZE"] = "draw_data.color_texture_pixel_size";
actions.renames["NORMAL_TEXTURE"] = "normal_texture";
@@ -2470,7 +2506,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["POINT_COORD"] = "gl_PointCoord";
- actions.renames["LIGHT_POSITION"] = "light_pos";
+ actions.renames["LIGHT_POSITION"] = "light_position";
actions.renames["LIGHT_COLOR"] = "light_color";
actions.renames["LIGHT_ENERGY"] = "light_energy";
actions.renames["LIGHT"] = "light";
@@ -2486,7 +2522,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
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";
- actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
+ actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["LIGHT"] = "#define LIGHT_SHADER_CODE_USED\n";
actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
@@ -2636,7 +2672,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
{
//default shadow texture to keep uniform set happy
RD::TextureFormat tf;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.width = 4;
tf.height = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
@@ -2650,7 +2686,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 0;
u.ids.push_back(storage->get_default_rd_storage_buffer());
uniforms.push_back(u);
@@ -2664,8 +2700,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
state.shadow_texture_size = GLOBAL_GET("rendering/quality/2d_shadow_atlas/size");
//create functions for shader and material
- storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_2D, _create_shader_funcs);
- storage->material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_2D, _create_material_funcs);
+ storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_shader_funcs);
+ storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_material_funcs);
state.time = 0;
@@ -2679,7 +2715,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
static_assert(sizeof(PushConstant) == 128);
}
-bool RasterizerCanvasRD::free(RID p_rid) {
+bool RendererCanvasRenderRD::free(RID p_rid) {
if (canvas_light_owner.owns(p_rid)) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND_V(!cl, false);
@@ -2695,7 +2731,7 @@ bool RasterizerCanvasRD::free(RID p_rid) {
return true;
}
-void RasterizerCanvasRD::set_shadow_texture_size(int p_size) {
+void RendererCanvasRenderRD::set_shadow_texture_size(int p_size) {
p_size = nearest_power_of_2_templated(p_size);
if (p_size == state.shadow_texture_size) {
return;
@@ -2709,7 +2745,7 @@ void RasterizerCanvasRD::set_shadow_texture_size(int p_size) {
{
//create a default shadow texture to keep uniform set happy (and that it gets erased when a new one is created)
RD::TextureFormat tf;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.width = 4;
tf.height = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
@@ -2720,7 +2756,7 @@ void RasterizerCanvasRD::set_shadow_texture_size(int p_size) {
}
}
-RasterizerCanvasRD::~RasterizerCanvasRD() {
+RendererCanvasRenderRD::~RendererCanvasRenderRD() {
//canvas state
storage->free(default_canvas_group_material);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index b09d6578f3..cb947d7180 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_canvas_rd.h */
+/* renderer_canvas_render_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,19 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_CANVAS_RD_H
-#define RASTERIZER_CANVAS_RD_H
+#ifndef RENDERING_SERVER_CANVAS_RENDER_RD_H
+#define RENDERING_SERVER_CANVAS_RENDER_RD_H
-#include "servers/rendering/rasterizer.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h"
-#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
-#include "servers/rendering/rasterizer_rd/shader_compiler_rd.h"
-#include "servers/rendering/rasterizer_rd/shaders/canvas.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl.gen.h"
+#include "servers/rendering/renderer_canvas_render.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shader_compiler_rd.h"
+#include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h"
#include "servers/rendering/rendering_device.h"
-class RasterizerCanvasRD : public RasterizerCanvas {
- RasterizerStorageRD *storage;
+class RendererCanvasRenderRD : public RendererCanvasRender {
+ RendererStorageRD *storage;
enum {
BASE_UNIFORM_SET = 0,
@@ -133,7 +134,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
};
struct PipelineVariants {
- RenderPipelineVertexFormatCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX];
+ PipelineCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX];
};
struct {
@@ -151,7 +152,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
ShaderCompilerRD compiler;
} shader;
- struct ShaderData : public RasterizerStorageRD::ShaderData {
+ struct ShaderData : public RendererStorageRD::ShaderData {
enum BlendMode { //used internally
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@@ -181,22 +182,24 @@ class RasterizerCanvasRD : public RasterizerCanvas {
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
+ virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
virtual bool is_param_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;
+
ShaderData();
virtual ~ShaderData();
};
- RasterizerStorageRD::ShaderData *_create_shader_func();
- static RasterizerStorageRD::ShaderData *_create_shader_funcs() {
- return static_cast<RasterizerCanvasRD *>(singleton)->_create_shader_func();
+ RendererStorageRD::ShaderData *_create_shader_func();
+ static RendererStorageRD::ShaderData *_create_shader_funcs() {
+ return static_cast<RendererCanvasRenderRD *>(singleton)->_create_shader_func();
}
- struct MaterialData : public RasterizerStorageRD::MaterialData {
+ struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
RID uniform_buffer;
@@ -210,9 +213,9 @@ class RasterizerCanvasRD : public RasterizerCanvas {
virtual ~MaterialData();
};
- RasterizerStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
- static RasterizerStorageRD::MaterialData *_create_material_funcs(RasterizerStorageRD::ShaderData *p_shader) {
- return static_cast<RasterizerCanvasRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
+ RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
+ static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
+ return static_cast<RendererCanvasRenderRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
}
/**************************/
@@ -462,8 +465,8 @@ public:
void set_time(double p_time);
void update();
bool free(RID p_rid);
- RasterizerCanvasRD(RasterizerStorageRD *p_storage);
- ~RasterizerCanvasRD();
+ RendererCanvasRenderRD(RendererStorageRD *p_storage);
+ ~RendererCanvasRenderRD();
};
#endif // RASTERIZER_CANVAS_RD_H
diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 5f8cf0ee8c..be2552bd32 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_rd.cpp */
+/* renderer_compositor_rd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rasterizer_rd.h"
+#include "renderer_compositor_rd.h"
#include "core/config/project_settings.h"
-void RasterizerRD::prepare_for_blitting_render_targets() {
+void RendererCompositorRD::prepare_for_blitting_render_targets() {
RD::get_singleton()->prepare_screen_for_drawing();
}
-void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) {
+void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) {
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen);
for (int i = 0; i < p_amount; i++) {
@@ -47,7 +47,7 @@ void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_scree
if (!render_target_descriptors.has(rd_texture) || !RD::get_singleton()->uniform_set_is_valid(render_target_descriptors[rd_texture])) {
Vector<RD::Uniform> uniforms;
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u.binding = 0;
u.ids.push_back(copy_viewports_sampler);
u.ids.push_back(rd_texture);
@@ -76,7 +76,7 @@ void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_scree
RD::get_singleton()->draw_list_end();
}
-void RasterizerRD::begin_frame(double frame_step) {
+void RendererCompositorRD::begin_frame(double frame_step) {
frame++;
delta = frame_step;
time += frame_step;
@@ -88,14 +88,14 @@ void RasterizerRD::begin_frame(double frame_step) {
scene->set_time(time, frame_step);
}
-void RasterizerRD::end_frame(bool p_swap_buffers) {
+void RendererCompositorRD::end_frame(bool p_swap_buffers) {
#ifndef _MSC_VER
#warning TODO: likely pass a bool to swap buffers to avoid display?
#endif
RD::get_singleton()->swap_buffers(); //probably should pass some bool to avoid display?
}
-void RasterizerRD::initialize() {
+void RendererCompositorRD::initialize() {
{ //create framebuffer copy shader
RenderingDevice::ShaderStageData vert;
vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX;
@@ -154,12 +154,9 @@ void RasterizerRD::initialize() {
}
}
-ThreadWorkPool RasterizerRD::thread_work_pool;
-uint64_t RasterizerRD::frame = 1;
-
-void RasterizerRD::finalize() {
- thread_work_pool.finish();
+uint64_t RendererCompositorRD::frame = 1;
+void RendererCompositorRD::finalize() {
memdelete(scene);
memdelete(canvas);
memdelete(storage);
@@ -170,14 +167,13 @@ void RasterizerRD::finalize() {
RD::get_singleton()->free(copy_viewports_sampler);
}
-RasterizerRD *RasterizerRD::singleton = nullptr;
+RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
-RasterizerRD::RasterizerRD() {
+RendererCompositorRD::RendererCompositorRD() {
singleton = this;
- thread_work_pool.init();
time = 0;
- storage = memnew(RasterizerStorageRD);
- canvas = memnew(RasterizerCanvasRD(storage));
- scene = memnew(RasterizerSceneHighEndRD(storage));
+ storage = memnew(RendererStorageRD);
+ canvas = memnew(RendererCanvasRenderRD(storage));
+ scene = memnew(RendererSceneRenderForward(storage));
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index 59fb8d2049..cb85fc79e0 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_rd.h */
+/* renderer_compositor_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,21 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_RD_H
-#define RASTERIZER_RD_H
+#ifndef RENDERING_SERVER_COMPOSITOR_RD_H
+#define RENDERING_SERVER_COMPOSITOR_RD_H
#include "core/os/os.h"
#include "core/templates/thread_work_pool.h"
-#include "servers/rendering/rasterizer.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_render_forward.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-class RasterizerRD : public Rasterizer {
+class RendererCompositorRD : public RendererCompositor {
protected:
- RasterizerCanvasRD *canvas;
- RasterizerStorageRD *storage;
- RasterizerSceneHighEndRD *scene;
+ RendererCanvasRenderRD *canvas;
+ RendererStorageRD *storage;
+ RendererSceneRenderForward *scene;
RID copy_viewports_rd_shader;
RID copy_viewports_rd_pipeline;
@@ -58,9 +58,9 @@ protected:
static uint64_t frame;
public:
- RasterizerStorage *get_storage() { return storage; }
- RasterizerCanvas *get_canvas() { return canvas; }
- RasterizerScene *get_scene() { return scene; }
+ RendererStorage *get_storage() { return storage; }
+ RendererCanvasRender *get_canvas() { return canvas; }
+ RendererSceneRender *get_scene() { return scene; }
void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {}
@@ -80,8 +80,8 @@ public:
return OK;
}
- static Rasterizer *_create_current() {
- return memnew(RasterizerRD);
+ static RendererCompositor *_create_current() {
+ return memnew(RendererCompositorRD);
}
static void make_current() {
@@ -90,10 +90,8 @@ public:
virtual bool is_low_end() const { return false; }
- static ThreadWorkPool thread_work_pool;
-
- static RasterizerRD *singleton;
- RasterizerRD();
- ~RasterizerRD() {}
+ static RendererCompositorRD *singleton;
+ RendererCompositorRD();
+ ~RendererCompositorRD() {}
};
#endif // RASTERIZER_RD_H
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp
index 313188ba87..74556f8105 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_scene_high_end_rd.cpp */
+/* renderer_scene_render_forward.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rasterizer_scene_high_end_rd.h"
+#include "renderer_scene_render_forward.h"
#include "core/config/project_settings.h"
#include "servers/rendering/rendering_device.h"
-#include "servers/rendering/rendering_server_raster.h"
+#include "servers/rendering/rendering_server_default.h"
/* SCENE SHADER */
-void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
+void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) {
//compile
code = p_code;
@@ -112,7 +112,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
actions.usage_flag_pointers["TIME"] = &uses_time;
actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
actions.usage_flag_pointers["NORMAL"] = &uses_normal;
- actions.usage_flag_pointers["NORMALMAP"] = &uses_normal;
+ actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal;
actions.usage_flag_pointers["POINT_SIZE"] = &uses_point_size;
actions.usage_flag_pointers["POINT_COORD"] = &uses_point_size;
@@ -123,7 +123,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
actions.uniforms = &uniforms;
- RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton;
+ RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton;
Error err = scene_singleton->shader.compiler.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
@@ -257,6 +257,9 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
for (int k = 0; k < SHADER_VERSION_MAX; k++) {
+ if (!static_cast<RendererSceneRenderForward *>(singleton)->shader.scene_shader.is_variant_enabled(k)) {
+ continue;
+ }
RD::PipelineRasterizationState raster_state;
raster_state.cull_mode = cull_mode_rd;
raster_state.wireframe = wireframe;
@@ -321,7 +324,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
valid = true;
}
-void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererSceneRenderForward::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
if (!p_texture.is_valid()) {
default_texture_params.erase(p_name);
} else {
@@ -329,7 +332,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const Strin
}
}
-void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void RendererSceneRenderForward::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
@@ -351,13 +354,13 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_
}
}
-void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+void RendererSceneRenderForward::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
- RasterizerStorage::InstanceShaderParam p;
+ RendererStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E->get());
p.info.name = E->key(); //supply name
p.index = E->get().instance_index;
@@ -366,7 +369,7 @@ void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<Rasteriz
}
}
-bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_param) const {
+bool RendererSceneRenderForward::ShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -374,15 +377,15 @@ bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_
return uniforms[p_param].texture_order >= 0;
}
-bool RasterizerSceneHighEndRD::ShaderData::is_animated() const {
+bool RendererSceneRenderForward::ShaderData::is_animated() const {
return false;
}
-bool RasterizerSceneHighEndRD::ShaderData::casts_shadows() const {
+bool RendererSceneRenderForward::ShaderData::casts_shadows() const {
return false;
}
-Variant RasterizerSceneHighEndRD::ShaderData::get_default_parameter(const StringName &p_parameter) const {
+Variant RendererSceneRenderForward::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;
@@ -391,13 +394,19 @@ Variant RasterizerSceneHighEndRD::ShaderData::get_default_parameter(const String
return Variant();
}
-RasterizerSceneHighEndRD::ShaderData::ShaderData() {
+RS::ShaderNativeSourceCode RendererSceneRenderForward::ShaderData::get_native_source_code() const {
+ RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton;
+
+ return scene_singleton->shader.scene_shader.version_get_native_source_code(version);
+}
+
+RendererSceneRenderForward::ShaderData::ShaderData() {
valid = false;
uses_screen_texture = false;
}
-RasterizerSceneHighEndRD::ShaderData::~ShaderData() {
- RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton;
+RendererSceneRenderForward::ShaderData::~ShaderData() {
+ RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton;
ERR_FAIL_COND(!scene_singleton);
//pipeline variants will clear themselves if shader is gone
if (version.is_valid()) {
@@ -405,21 +414,21 @@ RasterizerSceneHighEndRD::ShaderData::~ShaderData() {
}
}
-RasterizerStorageRD::ShaderData *RasterizerSceneHighEndRD::_create_shader_func() {
+RendererStorageRD::ShaderData *RendererSceneRenderForward::_create_shader_func() {
ShaderData *shader_data = memnew(ShaderData);
return shader_data;
}
-void RasterizerSceneHighEndRD::MaterialData::set_render_priority(int p_priority) {
+void RendererSceneRenderForward::MaterialData::set_render_priority(int p_priority) {
priority = p_priority - RS::MATERIAL_RENDER_PRIORITY_MIN; //8 bits
}
-void RasterizerSceneHighEndRD::MaterialData::set_next_pass(RID p_pass) {
+void RendererSceneRenderForward::MaterialData::set_next_pass(RID p_pass) {
next_pass = p_pass;
}
-void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
- RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton;
+void RendererSceneRenderForward::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton;
if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
p_uniform_dirty = true;
@@ -479,7 +488,7 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN
{
if (shader_data->ubo_size) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 0;
u.ids.push_back(uniform_buffer);
uniforms.push_back(u);
@@ -488,7 +497,7 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN
const RID *textures = texture_cache.ptrw();
for (uint32_t i = 0; i < tex_uniform_count; i++) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1 + i;
u.ids.push_back(textures[i]);
uniforms.push_back(u);
@@ -498,7 +507,7 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
}
-RasterizerSceneHighEndRD::MaterialData::~MaterialData() {
+RendererSceneRenderForward::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
}
@@ -508,7 +517,7 @@ RasterizerSceneHighEndRD::MaterialData::~MaterialData() {
}
}
-RasterizerStorageRD::MaterialData *RasterizerSceneHighEndRD::_create_material_func(ShaderData *p_shader) {
+RendererStorageRD::MaterialData *RendererSceneRenderForward::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
material_data->last_frame = false;
@@ -516,11 +525,11 @@ RasterizerStorageRD::MaterialData *RasterizerSceneHighEndRD::_create_material_fu
return material_data;
}
-RasterizerSceneHighEndRD::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() {
+RendererSceneRenderForward::RenderBufferDataForward::~RenderBufferDataForward() {
clear();
}
-void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
+void RendererSceneRenderForward::RenderBufferDataForward::ensure_specular() {
if (!specular.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@@ -574,7 +583,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
}
}
-void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_gi() {
+void RendererSceneRenderForward::RenderBufferDataForward::ensure_gi() {
if (!reflection_buffer.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@@ -587,7 +596,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_gi() {
}
}
-void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_giprobe() {
+void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() {
if (!giprobe_buffer.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8_UINT;
@@ -623,7 +632,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_giprobe() {
}
}
-void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() {
+void RendererSceneRenderForward::RenderBufferDataForward::clear() {
if (ambient_buffer != RID() && ambient_buffer != color) {
RD::get_singleton()->free(ambient_buffer);
ambient_buffer = RID();
@@ -687,7 +696,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() {
}
}
-void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
+void RendererSceneRenderForward::RenderBufferDataForward::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
clear();
msaa = p_msaa;
@@ -717,7 +726,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = p_width;
tf.height = p_height;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = {
@@ -754,7 +763,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu
}
}
-void RasterizerSceneHighEndRD::_allocate_normal_roughness_texture(RenderBufferDataHighEnd *rb) {
+void RendererSceneRenderForward::_allocate_normal_roughness_texture(RenderBufferDataForward *rb) {
if (rb->normal_roughness_buffer.is_valid()) {
return;
}
@@ -763,7 +772,7 @@ void RasterizerSceneHighEndRD::_allocate_normal_roughness_texture(RenderBufferDa
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tf.width = rb->width;
tf.height = rb->height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
@@ -779,7 +788,7 @@ void RasterizerSceneHighEndRD::_allocate_normal_roughness_texture(RenderBufferDa
fb.push_back(rb->normal_roughness_buffer);
rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb);
} else {
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
tf.samples = rb->texture_samples;
rb->normal_roughness_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -792,264 +801,100 @@ void RasterizerSceneHighEndRD::_allocate_normal_roughness_texture(RenderBufferDa
_render_buffers_clear_uniform_set(rb);
}
-RasterizerSceneRD::RenderBufferData *RasterizerSceneHighEndRD::_create_render_buffer_data() {
- return memnew(RenderBufferDataHighEnd);
+RendererSceneRenderRD::RenderBufferData *RendererSceneRenderForward::_create_render_buffer_data() {
+ return memnew(RenderBufferDataForward);
}
-bool RasterizerSceneHighEndRD::free(RID p_rid) {
- if (RasterizerSceneRD::free(p_rid)) {
+bool RendererSceneRenderForward::free(RID p_rid) {
+ if (RendererSceneRenderRD::free(p_rid)) {
return true;
}
return false;
}
-void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi, bool p_has_opaque_gi) {
- uint32_t lightmap_captures_used = 0;
-
- for (int i = 0; i < p_element_count; i++) {
- const RenderList::Element *e = p_elements[i];
- InstanceData &id = scene_state.instances[i];
- bool store_transform = true;
- id.flags = 0;
- id.mask = e->instance->layer_mask;
- id.instance_uniforms_ofs = e->instance->instance_allocated_shader_parameters_offset >= 0 ? e->instance->instance_allocated_shader_parameters_offset : 0;
-
- if (e->instance->base_type == RS::INSTANCE_MULTIMESH) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
- uint32_t stride;
- if (storage->multimesh_get_transform_format(e->instance->base) == RS::MULTIMESH_TRANSFORM_2D) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
- stride = 2;
- } else {
- stride = 3;
- }
- if (storage->multimesh_uses_colors(e->instance->base)) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
- stride += 1;
- }
- if (storage->multimesh_uses_custom_data(e->instance->base)) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
- stride += 1;
- }
-
- id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
- } else if (e->instance->base_type == RS::INSTANCE_PARTICLES) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
- uint32_t stride;
- if (false) { // 2D particles
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
- stride = 2;
- } else {
- stride = 3;
- }
-
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
- stride += 1;
-
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
- stride += 1;
-
- id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
-
- if (!storage->particles_is_using_local_coords(e->instance->base)) {
- store_transform = false;
- }
-
- } else if (e->instance->base_type == RS::INSTANCE_MESH) {
- if (e->instance->skeleton.is_valid()) {
- id.flags |= INSTANCE_DATA_FLAG_SKELETON;
- }
- }
-
- if (store_transform) {
- RasterizerStorageRD::store_transform(e->instance->transform, id.transform);
- RasterizerStorageRD::store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform);
- } else {
- RasterizerStorageRD::store_transform(Transform(), id.transform);
- RasterizerStorageRD::store_transform(Transform(), id.normal_transform);
- }
-
- if (p_for_depth) {
- id.gi_offset = 0xFFFFFFFF;
- continue;
- }
-
- if (e->instance->lightmap) {
- int32_t lightmap_index = storage->lightmap_get_array_index(e->instance->lightmap->base);
- if (lightmap_index >= 0) {
- id.gi_offset = lightmap_index;
- id.gi_offset |= e->instance->lightmap_slice_index << 12;
- id.gi_offset |= e->instance->lightmap_cull_index << 20;
- id.lightmap_uv_scale[0] = e->instance->lightmap_uv_scale.position.x;
- id.lightmap_uv_scale[1] = e->instance->lightmap_uv_scale.position.y;
- id.lightmap_uv_scale[2] = e->instance->lightmap_uv_scale.size.width;
- id.lightmap_uv_scale[3] = e->instance->lightmap_uv_scale.size.height;
- id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP;
- if (storage->lightmap_uses_spherical_harmonics(e->instance->lightmap->base)) {
- id.flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP;
- }
- } else {
- id.gi_offset = 0xFFFFFFFF;
- }
- } else if (!e->instance->lightmap_sh.empty()) {
- if (lightmap_captures_used < scene_state.max_lightmap_captures) {
- const Color *src_capture = e->instance->lightmap_sh.ptr();
- LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used];
- for (int j = 0; j < 9; j++) {
- lcd.sh[j * 4 + 0] = src_capture[j].r;
- lcd.sh[j * 4 + 1] = src_capture[j].g;
- lcd.sh[j * 4 + 2] = src_capture[j].b;
- lcd.sh[j * 4 + 3] = src_capture[j].a;
- }
- id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE;
- id.gi_offset = lightmap_captures_used;
- lightmap_captures_used++;
- }
-
- } else {
- if (p_has_opaque_gi) {
- id.flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
- }
-
- if (!e->instance->gi_probe_instances.empty()) {
- uint32_t written = 0;
- for (int j = 0; j < e->instance->gi_probe_instances.size(); j++) {
- RID probe = e->instance->gi_probe_instances[j];
-
- uint32_t index = gi_probe_instance_get_render_index(probe);
-
- if (written == 0) {
- id.gi_offset = index;
- id.flags |= INSTANCE_DATA_FLAG_USE_GIPROBE;
- written = 1;
- } else {
- id.gi_offset = index << 16;
- written = 2;
- break;
- }
- }
- if (written == 0) {
- id.gi_offset = 0xFFFFFFFF;
- } else if (written == 1) {
- id.gi_offset |= 0xFFFF0000;
- }
- } else {
- if (p_has_sdfgi && (e->instance->baked_light || e->instance->dynamic_gi)) {
- id.flags |= INSTANCE_DATA_FLAG_USE_SDFGI;
- }
- id.gi_offset = 0xFFFFFFFF;
- }
- }
- }
-
- RD::get_singleton()->buffer_update(scene_state.instance_buffer, 0, sizeof(InstanceData) * p_element_count, scene_state.instances, true);
- if (lightmap_captures_used) {
- RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, true);
- }
-}
-
/// RENDERING ///
-void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset) {
+template <RendererSceneRenderForward::PassMode p_pass_mode>
+void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
RD::DrawListID draw_list = p_draw_list;
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
//global scope bindings
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, SCENE_UNIFORM_SET);
- if (p_radiance_uniform_set.is_valid()) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_radiance_uniform_set, RADIANCE_UNIFORM_SET);
- } else {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_radiance_uniform_set, RADIANCE_UNIFORM_SET);
- }
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, view_dependant_uniform_set, VIEW_DEPENDANT_UNIFORM_SET);
- if (p_render_buffers_uniform_set.is_valid()) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_render_buffers_uniform_set, RENDER_BUFFERS_UNIFORM_SET);
- } else {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_render_buffers_uniform_set, RENDER_BUFFERS_UNIFORM_SET);
- }
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_params->render_pass_uniform_set, RENDER_PASS_UNIFORM_SET);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_vec4_xform_uniform_set, TRANSFORMS_UNIFORM_SET);
- MaterialData *prev_material = nullptr;
+ RID prev_material_uniform_set;
RID prev_vertex_array_rd;
RID prev_index_array_rd;
RID prev_pipeline_rd;
RID prev_xforms_uniform_set;
- PushConstant push_constant;
- zeromem(&push_constant, sizeof(PushConstant));
- push_constant.bake_uv2_offset[0] = p_uv_offset.x;
- push_constant.bake_uv2_offset[1] = p_uv_offset.y;
+ bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP);
+
+ float old_offset[2] = { 0, 0 };
+
+ for (uint32_t i = p_from_element; i < p_to_element; i++) {
+ const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i];
- for (int i = 0; i < p_element_count; i++) {
- const RenderList::Element *e = p_elements[i];
+ RID material_uniform_set;
+ ShaderData *shader;
+ void *mesh_surface;
- MaterialData *material = e->material;
- ShaderData *shader = material->shader_data;
- RID xforms_uniform_set;
+ if (shadow_pass) {
+ material_uniform_set = surf->material_uniform_set_shadow;
+ shader = surf->shader_shadow;
+ mesh_surface = surf->surface_shadow;
+
+ } else {
+ material_uniform_set = surf->material_uniform_set;
+ shader = surf->shader;
+ mesh_surface = surf->surface;
+ }
+
+ if (!mesh_surface) {
+ continue;
+ }
+
+ if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) {
+ old_offset[0] = surf->owner->push_constant.lightmap_uv_scale[0];
+ old_offset[1] = surf->owner->push_constant.lightmap_uv_scale[1];
+ surf->owner->push_constant.lightmap_uv_scale[0] = p_params->uv_offset.x;
+ surf->owner->push_constant.lightmap_uv_scale[1] = p_params->uv_offset.y;
+ }
//find cull variant
ShaderData::CullVariant cull_variant;
- if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || p_pass_mode == PASS_MODE_SDF || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)) {
+ if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL || p_params->pass_mode == PASS_MODE_SDF || ((p_params->pass_mode == PASS_MODE_SHADOW || p_params->pass_mode == PASS_MODE_SHADOW_DP) && surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS)) {
cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED;
} else {
- bool mirror = e->instance->mirror;
- if (p_reverse_cull) {
+ bool mirror = surf->owner->mirror;
+ if (p_params->reverse_cull) {
mirror = !mirror;
}
cull_variant = mirror ? ShaderData::CULL_VARIANT_REVERSED : ShaderData::CULL_VARIANT_NORMAL;
}
- //find primitive and vertex format
- RS::PrimitiveType primitive;
-
- switch (e->instance->base_type) {
- case RS::INSTANCE_MESH: {
- primitive = storage->mesh_surface_get_primitive(e->instance->base, e->surface_index);
- if (e->instance->skeleton.is_valid()) {
- xforms_uniform_set = storage->skeleton_get_3d_uniform_set(e->instance->skeleton, default_shader_rd, TRANSFORMS_UNIFORM_SET);
- }
- } break;
- case RS::INSTANCE_MULTIMESH: {
- RID mesh = storage->multimesh_get_mesh(e->instance->base);
- ERR_CONTINUE(!mesh.is_valid()); //should be a bug
- primitive = storage->mesh_surface_get_primitive(mesh, e->surface_index);
-
- xforms_uniform_set = storage->multimesh_get_3d_uniform_set(e->instance->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
-
- } break;
- case RS::INSTANCE_IMMEDIATE: {
- ERR_CONTINUE(true); //should be a bug
- } break;
- case RS::INSTANCE_PARTICLES: {
- RID mesh = storage->particles_get_draw_pass_mesh(e->instance->base, e->surface_index >> 16);
- ERR_CONTINUE(!mesh.is_valid()); //should be a bug
- primitive = storage->mesh_surface_get_primitive(mesh, e->surface_index & 0xFFFF);
-
- xforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(e->instance->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
-
- } break;
- default: {
- ERR_CONTINUE(true); //should be a bug
- }
- }
+ RS::PrimitiveType primitive = surf->primitive;
+ RID xforms_uniform_set = surf->owner->transforms_uniform_set;
ShaderVersion shader_version = SHADER_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized.
- switch (p_pass_mode) {
+ switch (p_params->pass_mode) {
case PASS_MODE_COLOR:
case PASS_MODE_COLOR_TRANSPARENT: {
- if (e->uses_lightmap) {
+ if (surf->sort.uses_lightmap) {
shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS;
- } else if (e->uses_forward_gi) {
+ } else if (surf->sort.uses_forward_gi) {
shader_version = SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI;
} else {
shader_version = SHADER_VERSION_COLOR_PASS;
}
} break;
case PASS_MODE_COLOR_SPECULAR: {
- if (e->uses_lightmap) {
+ if (surf->sort.uses_lightmap) {
shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR;
} else {
shader_version = SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR;
@@ -1076,7 +921,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
} break;
}
- RenderPipelineVertexFormatCacheRD *pipeline = nullptr;
+ PipelineCacheRD *pipeline = nullptr;
pipeline = &shader->pipelines[cull_variant][primitive][shader_version];
@@ -1084,26 +929,37 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
RID vertex_array_rd;
RID index_array_rd;
- switch (e->instance->base_type) {
- case RS::INSTANCE_MESH: {
- storage->mesh_surface_get_arrays_and_format(e->instance->base, e->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, index_array_rd, vertex_format);
- } break;
- case RS::INSTANCE_MULTIMESH: {
- RID mesh = storage->multimesh_get_mesh(e->instance->base);
- ERR_CONTINUE(!mesh.is_valid()); //should be a bug
- storage->mesh_surface_get_arrays_and_format(mesh, e->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, index_array_rd, vertex_format);
- } break;
- case RS::INSTANCE_IMMEDIATE: {
- ERR_CONTINUE(true); //should be a bug
- } break;
- case RS::INSTANCE_PARTICLES: {
- RID mesh = storage->particles_get_draw_pass_mesh(e->instance->base, e->surface_index >> 16);
- ERR_CONTINUE(!mesh.is_valid()); //should be a bug
- storage->mesh_surface_get_arrays_and_format(mesh, e->surface_index & 0xFFFF, pipeline->get_vertex_input_mask(), vertex_array_rd, index_array_rd, vertex_format);
- } break;
- default: {
- ERR_CONTINUE(true); //should be a bug
+ //skeleton and blend shape
+ if (surf->owner->mesh_instance.is_valid()) {
+ storage->mesh_instance_surface_get_vertex_arrays_and_format(surf->owner->mesh_instance, surf->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format);
+ } else {
+ storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format);
+ }
+
+ if (p_params->screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(mesh_surface)) {
+ //lod
+ Vector3 support_min = surf->owner->transformed_aabb.get_support(-p_params->lod_plane.normal);
+ Vector3 support_max = surf->owner->transformed_aabb.get_support(p_params->lod_plane.normal);
+
+ float distance_min = p_params->lod_plane.distance_to(support_min);
+ float distance_max = p_params->lod_plane.distance_to(support_max);
+
+ float distance = 0.0;
+
+ if (distance_min * distance_max < 0.0) {
+ //crossing plane
+ distance = 0.0;
+ } else if (distance_min >= 0.0) {
+ distance = distance_min;
+ } else if (distance_max <= 0.0) {
+ distance = -distance_max;
}
+
+ index_array_rd = storage->mesh_surface_get_index_array_with_lod(mesh_surface, surf->owner->lod_model_scale * surf->owner->lod_bias, distance * p_params->lod_distance_multiplier, p_params->screen_lod_threshold);
+
+ } else {
+ //no lod
+ index_array_rd = storage->mesh_surface_get_index_array(mesh_surface);
}
if (prev_vertex_array_rd != vertex_array_rd) {
@@ -1118,7 +974,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
prev_index_array_rd = index_array_rd;
}
- RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_force_wireframe);
+ RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe);
if (pipeline_rd != prev_pipeline_rd) {
// checking with prev shader does not make so much sense, as
@@ -1132,40 +988,90 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
prev_xforms_uniform_set = xforms_uniform_set;
}
- if (material != prev_material) {
+ if (material_uniform_set != prev_material_uniform_set) {
//update uniform set
- if (material->uniform_set.is_valid()) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material->uniform_set, MATERIAL_UNIFORM_SET);
+ if (material_uniform_set.is_valid()) {
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_uniform_set, MATERIAL_UNIFORM_SET);
}
- prev_material = material;
+ prev_material_uniform_set = material_uniform_set;
}
- push_constant.index = i;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(PushConstant));
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &surf->owner->push_constant, sizeof(GeometryInstanceForward::PushConstant));
- switch (e->instance->base_type) {
- case RS::INSTANCE_MESH: {
- RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid());
- } break;
- case RS::INSTANCE_MULTIMESH: {
- uint32_t instances = storage->multimesh_get_instances_to_draw(e->instance->base);
- RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances);
- } break;
- case RS::INSTANCE_IMMEDIATE: {
- } break;
- case RS::INSTANCE_PARTICLES: {
- uint32_t instances = storage->particles_get_amount(e->instance->base);
- RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances);
- } break;
- default: {
- ERR_CONTINUE(true); //should be a bug
- }
+ RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), surf->owner->instance_count);
+
+ if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) {
+ surf->owner->push_constant.lightmap_uv_scale[0] = old_offset[0];
+ surf->owner->push_constant.lightmap_uv_scale[1] = old_offset[1];
}
}
}
-void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) {
+void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
+ //use template for faster performance (pass mode comparisons are inlined)
+
+ switch (p_params->pass_mode) {
+ case PASS_MODE_COLOR: {
+ _render_list_template<PASS_MODE_COLOR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_COLOR_SPECULAR: {
+ _render_list_template<PASS_MODE_COLOR_SPECULAR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_COLOR_TRANSPARENT: {
+ _render_list_template<PASS_MODE_COLOR_TRANSPARENT>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_SHADOW: {
+ _render_list_template<PASS_MODE_SHADOW>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_SHADOW_DP: {
+ _render_list_template<PASS_MODE_SHADOW_DP>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH: {
+ _render_list_template<PASS_MODE_DEPTH>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
+ _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: {
+ _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH_MATERIAL: {
+ _render_list_template<PASS_MODE_DEPTH_MATERIAL>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_SDF: {
+ _render_list_template<PASS_MODE_SDF>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ }
+}
+
+void RendererSceneRenderForward::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) {
+ uint32_t render_total = p_params->element_count;
+ uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
+ uint32_t render_from = p_thread * render_total / total_threads;
+ uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads);
+ _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to);
+}
+
+void RendererSceneRenderForward::_render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
+ RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer);
+ p_params->framebuffer_format = fb_format;
+
+ if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time
+ //multi threaded
+ thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count());
+ RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures);
+ RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RendererSceneRenderForward::_render_list_thread_function, p_params);
+ RD::get_singleton()->draw_list_end();
+ } else {
+ //single threaded
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures);
+ _render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
+ RD::get_singleton()->draw_list_end();
+ }
+}
+
+void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) {
//CameraMatrix projection = p_cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
CameraMatrix correction;
@@ -1173,20 +1079,20 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende
CameraMatrix projection = correction * p_cam_projection;
//store camera into ubo
- RasterizerStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
- RasterizerStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RasterizerStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix);
- RasterizerStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix);
+ RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
+ RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
+ RendererStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix);
+ RendererStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix);
scene_state.ubo.z_far = p_zfar;
scene_state.ubo.z_near = p_znear;
scene_state.ubo.pancake_shadows = p_pancake_shadows;
- RasterizerStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
- RasterizerStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
- RasterizerStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
- RasterizerStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
+ RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
+ RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
+ RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
+ RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
scene_state.ubo.directional_penumbra_shadow_samples = directional_penumbra_shadow_samples_get();
scene_state.ubo.directional_soft_shadow_samples = directional_soft_shadow_samples_get();
@@ -1214,7 +1120,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende
scene_state.ubo.fog_enabled = false;
if (p_render_buffers.is_valid()) {
- RenderBufferDataHighEnd *render_buffers = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
+ RenderBufferDataForward *render_buffers = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
if (render_buffers->msaa != RS::VIEWPORT_MSAA_DISABLED) {
scene_state.ubo.gi_upscale_for_msaa = true;
}
@@ -1330,7 +1236,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende
Basis sky_transform = environment_get_sky_orientation(p_environment);
sky_transform = sky_transform.inverse() * p_cam_transform.basis;
- RasterizerStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
+ RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
@@ -1397,251 +1303,196 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende
RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true);
}
-void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
- RID m_src;
-
- m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material;
-
- if (unlikely(get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_DISABLED)) {
- if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
- m_src = overdraw_material;
- } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING) {
- m_src = default_material;
- }
- }
-
- MaterialData *material = nullptr;
-
- if (m_src.is_valid()) {
- material = (MaterialData *)storage->material_get_data(m_src, RasterizerStorageRD::SHADER_TYPE_3D);
- if (!material || !material->shader_data->valid) {
- material = nullptr;
- }
- }
-
- if (!material) {
- material = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D);
- m_src = default_material;
- }
-
- ERR_FAIL_COND(!material);
-
- _add_geometry_with_material(p_instance, p_surface, material, m_src, p_pass_mode, p_geometry_index, p_using_sdfgi);
-
- while (material->next_pass.is_valid()) {
- material = (MaterialData *)storage->material_get_data(material->next_pass, RasterizerStorageRD::SHADER_TYPE_3D);
- if (!material || !material->shader_data->valid) {
- break;
- }
- _add_geometry_with_material(p_instance, p_surface, material, material->next_pass, p_pass_mode, p_geometry_index, p_using_sdfgi);
- }
-}
-
-void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
- 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 || has_read_screen_alpha);
- bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
- bool has_alpha = has_base_alpha || has_blend_alpha;
-
- if (p_material->shader_data->uses_sss) {
- scene_state.used_sss = true;
- }
-
- if (p_material->shader_data->uses_screen_texture) {
- scene_state.used_screen_texture = true;
- }
-
- if (p_material->shader_data->uses_depth_texture) {
- scene_state.used_depth_texture = true;
- }
-
- if (p_material->shader_data->uses_normal_texture) {
- scene_state.used_normal_texture = true;
- }
-
- if (p_pass_mode != PASS_MODE_COLOR && p_pass_mode != PASS_MODE_COLOR_SPECULAR) {
- if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED || p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
- //conditions in which no depth pass should be processed
- return;
- }
-
- if ((p_pass_mode != PASS_MODE_DEPTH_MATERIAL && p_pass_mode != PASS_MODE_SDF) && !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) {
- //shader does not use discard and does not write a vertex position, use generic material
- if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_DEPTH) {
- p_material = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D);
- } else if ((p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) && !p_material->shader_data->uses_normal && !p_material->shader_data->uses_roughness) {
- p_material = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D);
- }
- }
-
- has_alpha = false;
- }
-
- has_alpha = has_alpha || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED;
-
- RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element();
-
- if (!e) {
- return;
- }
-
- e->instance = p_instance;
- e->material = p_material;
- e->surface_index = p_surface;
- e->sort_key = 0;
-
- if (e->material->last_pass != render_pass) {
- if (!RD::get_singleton()->uniform_set_is_valid(e->material->uniform_set)) {
- //uniform set no longer valid, probably a texture changed
- storage->material_force_update_textures(p_material_rid, RasterizerStorageRD::SHADER_TYPE_3D);
- }
- e->material->last_pass = render_pass;
- e->material->index = scene_state.current_material_index++;
- if (e->material->shader_data->last_pass != render_pass) {
- e->material->shader_data->last_pass = scene_state.current_material_index++;
- e->material->shader_data->index = scene_state.current_shader_index++;
- }
- }
- e->geometry_index = p_geometry_index;
- e->material_index = e->material->index;
- e->uses_instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH;
- e->uses_lightmap = e->instance->lightmap != nullptr || !e->instance->lightmap_sh.empty();
- e->uses_forward_gi = has_alpha && (e->instance->gi_probe_instances.size() || p_using_sdfgi);
- e->shader_index = e->shader_index;
- e->depth_layer = e->instance->depth_layer;
- e->priority = p_material->priority;
-
- if (p_material->shader_data->uses_time) {
- RenderingServerRaster::redraw_request();
- }
-}
-
-void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_using_sdfgi) {
- scene_state.current_shader_index = 0;
- scene_state.current_material_index = 0;
+void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi) {
scene_state.used_sss = false;
scene_state.used_screen_texture = false;
scene_state.used_normal_texture = false;
scene_state.used_depth_texture = false;
- uint32_t geometry_index = 0;
+ Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
+ near_plane.d += p_cam_projection.get_z_near();
+ float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near();
+ uint32_t lightmap_captures_used = 0;
+
+ _update_dirty_geometry_instances();
+ render_list.clear();
//fill list
- for (int i = 0; i < p_cull_count; i++) {
- InstanceBase *inst = p_cull_result[i];
+ for (int i = 0; i < (int)p_instances.size(); i++) {
+ GeometryInstanceForward *inst = static_cast<GeometryInstanceForward *>(p_instances[i]);
- //add geometry for drawing
- switch (inst->base_type) {
- case RS::INSTANCE_MESH: {
- const RID *materials = nullptr;
- uint32_t surface_count;
+ Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
+ inst->depth = near_plane.distance_to(support_min);
+ uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
- materials = storage->mesh_get_surface_count_and_materials(inst->base, surface_count);
- if (!materials) {
- continue; //nothing to do
- }
+ uint32_t flags = inst->base_flags; //fill flags if appropriate
- const RID *inst_materials = inst->materials.ptr();
+ bool uses_lightmap = false;
+ bool uses_gi = false;
- for (uint32_t j = 0; j < surface_count; j++) {
- RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j];
+ if (p_pass_mode == PASS_MODE_COLOR) {
+ //setup GI
- uint32_t surface_index = storage->mesh_surface_get_render_pass_index(inst->base, j, render_pass, &geometry_index);
- _add_geometry(inst, j, material, p_pass_mode, surface_index, p_using_sdfgi);
+ if (inst->lightmap_instance.is_valid()) {
+ int32_t lightmap_cull_index = -1;
+ for (uint32_t j = 0; j < scene_state.lightmaps_used; j++) {
+ if (scene_state.lightmap_ids[j] == inst->lightmap_instance) {
+ lightmap_cull_index = j;
+ break;
+ }
}
-
- //mesh->last_pass=frame;
-
- } break;
-
- case RS::INSTANCE_MULTIMESH: {
- if (storage->multimesh_get_instances_to_draw(inst->base) == 0) {
- //not visible, 0 instances
- continue;
+ if (lightmap_cull_index >= 0) {
+ inst->push_constant.gi_offset &= 0xFFFF;
+ inst->push_constant.gi_offset |= lightmap_cull_index;
+ flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP;
+ if (scene_state.lightmap_has_sh[lightmap_cull_index]) {
+ flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP;
+ }
+ uses_lightmap = true;
+ } else {
+ inst->push_constant.gi_offset = 0xFFFFFFFF;
}
- RID mesh = storage->multimesh_get_mesh(inst->base);
- if (!mesh.is_valid()) {
- continue;
+ } else if (inst->lightmap_sh) {
+ if (lightmap_captures_used < scene_state.max_lightmap_captures) {
+ const Color *src_capture = inst->lightmap_sh->sh;
+ LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used];
+ for (int j = 0; j < 9; j++) {
+ lcd.sh[j * 4 + 0] = src_capture[j].r;
+ lcd.sh[j * 4 + 1] = src_capture[j].g;
+ lcd.sh[j * 4 + 2] = src_capture[j].b;
+ lcd.sh[j * 4 + 3] = src_capture[j].a;
+ }
+ flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE;
+ inst->push_constant.gi_offset = lightmap_captures_used;
+ lightmap_captures_used++;
+ uses_lightmap = true;
}
- const RID *materials = nullptr;
- uint32_t surface_count;
-
- materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
- if (!materials) {
- continue; //nothing to do
+ } else if (!low_end) {
+ if (p_using_opaque_gi) {
+ flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
}
- for (uint32_t j = 0; j < surface_count; j++) {
- uint32_t surface_index = storage->mesh_surface_get_multimesh_render_pass_index(mesh, j, render_pass, &geometry_index);
- _add_geometry(inst, j, materials[j], p_pass_mode, surface_index, p_using_sdfgi);
- }
+ if (inst->gi_probes[0].is_valid()) {
+ uint32_t probe0_index = 0xFFFF;
+ uint32_t probe1_index = 0xFFFF;
- } break;
-#if 0
- case RS::INSTANCE_IMMEDIATE: {
- RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base);
- ERR_CONTINUE(!immediate);
+ for (uint32_t j = 0; j < scene_state.giprobes_used; j++) {
+ if (scene_state.giprobe_ids[j] == inst->gi_probes[0]) {
+ probe0_index = j;
+ } else if (scene_state.giprobe_ids[j] == inst->gi_probes[1]) {
+ probe1_index = j;
+ }
+ }
- _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass);
+ if (probe0_index == 0xFFFF && probe1_index != 0xFFFF) {
+ //0 must always exist if a probe exists
+ SWAP(probe0_index, probe1_index);
+ }
- } break;
-#endif
- case RS::INSTANCE_PARTICLES: {
- int draw_passes = storage->particles_get_draw_passes(inst->base);
+ inst->push_constant.gi_offset = probe0_index | (probe1_index << 16);
+ uses_gi = true;
+ } else {
+ if (p_using_sdfgi && inst->can_sdfgi) {
+ flags |= INSTANCE_DATA_FLAG_USE_SDFGI;
+ uses_gi = true;
+ }
+ inst->push_constant.gi_offset = 0xFFFFFFFF;
+ }
+ }
+ }
+ inst->push_constant.flags = flags;
- for (int j = 0; j < draw_passes; j++) {
- RID mesh = storage->particles_get_draw_pass_mesh(inst->base, j);
- if (!mesh.is_valid())
- continue;
+ GeometryInstanceSurfaceDataCache *surf = inst->surface_caches;
- const RID *materials = nullptr;
- uint32_t surface_count;
+ while (surf) {
+ surf->sort.uses_forward_gi = 0;
+ surf->sort.uses_lightmap = 0;
- materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
- if (!materials) {
- continue; //nothing to do
+ if (p_pass_mode == PASS_MODE_COLOR) {
+ if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
+ render_list.add_element(surf);
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA) {
+ render_list.add_alpha_element(surf);
+ if (uses_gi) {
+ surf->sort.uses_forward_gi = 1;
}
+ }
- for (uint32_t k = 0; k < surface_count; k++) {
- uint32_t surface_index = storage->mesh_surface_get_particles_render_pass_index(mesh, j, render_pass, &geometry_index);
- _add_geometry(inst, (j << 16) | k, materials[j], p_pass_mode, surface_index, p_using_sdfgi);
- }
+ if (uses_lightmap) {
+ surf->sort.uses_lightmap = 1;
}
- } break;
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_SUBSURFACE_SCATTERING) {
+ scene_state.used_sss = true;
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_SCREEN_TEXTURE) {
+ scene_state.used_screen_texture = true;
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_NORMAL_TEXTURE) {
+ scene_state.used_normal_texture = true;
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE) {
+ scene_state.used_depth_texture = true;
+ }
- default: {
+ } else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) {
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) {
+ render_list.add_element(surf);
+ }
+ } else {
+ if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
+ render_list.add_element(surf);
+ }
}
+
+ surf->sort.depth_layer = depth_layer;
+
+ surf = surf->next;
}
}
+
+ if (lightmap_captures_used) {
+ RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, true);
+ }
+}
+
+void RendererSceneRenderForward::_setup_giprobes(const PagedArray<RID> &p_giprobes) {
+ scene_state.giprobes_used = MIN(p_giprobes.size(), uint32_t(MAX_GI_PROBES));
+ for (uint32_t i = 0; i < scene_state.giprobes_used; i++) {
+ scene_state.giprobe_ids[i] = p_giprobes[i];
+ }
}
-void RasterizerSceneHighEndRD::_setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform) {
- uint32_t lightmaps_used = 0;
- for (int i = 0; i < p_lightmap_cull_count; i++) {
+void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) {
+ scene_state.lightmaps_used = 0;
+ for (int i = 0; i < (int)p_lightmaps.size(); i++) {
if (i >= (int)scene_state.max_lightmaps) {
break;
}
- InstanceBase *lm = p_lightmap_cull_result[i];
- Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis;
+ RID lightmap = lightmap_instance_get_lightmap(p_lightmaps[i]);
+
+ Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
to_lm = to_lm.inverse().transposed(); //will transform normals
- RasterizerStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
- lm->lightmap_cull_index = i;
- lightmaps_used++;
+ RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
+ scene_state.lightmap_ids[i] = p_lightmaps[i];
+ scene_state.lightmap_has_sh[i] = storage->lightmap_uses_spherical_harmonics(lightmap);
+
+ scene_state.lightmaps_used++;
}
- if (lightmaps_used > 0) {
- RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * lightmaps_used, scene_state.lightmaps, true);
+ if (scene_state.lightmaps_used > 0) {
+ RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, true);
}
}
-void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) {
- RenderBufferDataHighEnd *render_buffer = nullptr;
+void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
+ RenderBufferDataForward *render_buffer = nullptr;
if (p_render_buffer.is_valid()) {
- render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffer);
+ render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer);
}
//first of all, make a new render pass
@@ -1657,6 +1508,13 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
scene_state.ubo.reflection_multiplier = 1.0;
}
+ float lod_distance_multiplier = p_cam_projection.get_lod_multiplier();
+ Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
+
+ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
+ p_screen_lod_threshold = 0.0;
+ }
+
//scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size;
Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
@@ -1686,7 +1544,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
opaque_framebuffer = render_buffer->color_fb;
- if (p_gi_probe_cull_count > 0) {
+ if (!low_end && p_gi_probes.size() > 0) {
using_giprobe = true;
render_buffer->ensure_gi();
}
@@ -1753,15 +1611,15 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
ERR_FAIL(); //bug?
}
- _setup_lightmaps(p_lightmap_cull_result, p_lightmap_cull_count, p_cam_transform);
+ _setup_lightmaps(p_lightmaps, p_cam_transform);
+ _setup_giprobes(p_gi_probes);
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
- render_list.clear();
- _fill_render_list(p_cull_result, p_cull_count, PASS_MODE_COLOR, using_sdfgi);
+ _fill_render_list(p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe);
- bool using_sss = render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
+ bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
if (using_sss) {
using_separate_specular = true;
@@ -1769,7 +1627,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
using_separate_specular = true;
opaque_specular_framebuffer = render_buffer->color_specular_fb;
}
- RID radiance_uniform_set;
+ RID radiance_texture;
bool draw_sky = false;
bool draw_sky_fog_only = false;
@@ -1831,7 +1689,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
RID sky = environment_get_sky(p_environment);
if (sky.is_valid()) {
_update_sky(p_environment, projection, p_cam_transform);
- radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET);
+ radiance_texture = sky_get_radiance_texture_rd(sky);
} else {
// do not try to draw sky if invalid
draw_sky = false;
@@ -1841,27 +1699,23 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
clear_color = p_default_bg_color;
}
- _setup_view_dependant_uniform_set(p_shadow_atlas, p_reflection_atlas, p_gi_probe_cull_result, p_gi_probe_cull_count);
-
render_list.sort_by_key(false);
- _fill_instances(render_list.elements, render_list.element_count, false, false, using_sdfgi || using_giprobe);
-
bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION;
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
- bool depth_pre_pass = depth_framebuffer.is_valid();
- RID render_buffers_uniform_set;
+ bool depth_pre_pass = !low_end && depth_framebuffer.is_valid();
bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment);
bool continue_depth = false;
if (depth_pre_pass) { //depth pre pass
RENDER_TIMESTAMP("Render Depth Pre-Pass");
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
+
bool finish_depth = using_ssao || using_sdfgi || using_giprobe;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID(), get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ _render_list_with_threads(&render_list_params, depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
RENDER_TIMESTAMP("Resolve Depth Pre-Pass");
@@ -1881,19 +1735,15 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
}
if (using_sdfgi || using_giprobe) {
- _process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probe_cull_result, p_gi_probe_cull_count);
- }
-
- if (p_render_buffer.is_valid()) {
- //update the render buffers uniform set in case it changed
- _update_render_buffers_uniform_set(p_render_buffer);
- render_buffers_uniform_set = render_buffer->uniform_set;
+ _process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probes);
}
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
RENDER_TIMESTAMP("Render Opaque Pass");
+ RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probes, p_lightmaps);
+
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;
@@ -1913,13 +1763,13 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
}
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+
+ _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
if (will_continue_color && using_separate_specular) {
// close the specular framebuffer, as it's no longer used
- draw_list = RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
+ RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
RD::get_singleton()->draw_list_end();
}
}
@@ -1933,8 +1783,8 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
dc.set_depth_correction(true);
CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
- for (int i = 0; i < p_gi_probe_cull_count; i++) {
- _debug_giprobe(p_gi_probe_cull_result[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
+ for (int i = 0; i < (int)p_gi_probes.size(); i++) {
+ _debug_giprobe(p_gi_probes[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
}
RD::get_singleton()->draw_list_end();
}
@@ -1998,12 +1848,9 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
render_list.sort_by_reverse_depth_and_priority(true);
- _fill_instances(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, using_sdfgi);
-
{
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_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, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ _render_list_with_threads(&render_list_params, alpha_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);
}
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
@@ -2011,7 +1858,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
}
}
-void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &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) {
+void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &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, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
RENDER_TIMESTAMP("Setup Rendering Shadow");
_update_render_base_uniform_set();
@@ -2022,29 +1869,28 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **
_setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar, false, p_use_pancake);
- render_list.clear();
+ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
+ p_screen_lod_threshold = 0.0;
+ }
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
- _fill_render_list(p_cull_result, p_cull_count, pass_mode);
+ _fill_render_list(p_instances, pass_mode, p_projection, p_transform);
- _setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Shadow");
render_list.sort_by_key(false);
- _fill_instances(render_list.elements, render_list.element_count, true);
-
{
//regular forward for now
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, RID(), RID());
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
+ _render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
}
}
-void RasterizerSceneHighEndRD::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count) {
+void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
RENDER_TIMESTAMP("Setup Render Collider Heightfield");
_update_render_base_uniform_set();
@@ -2055,29 +1901,24 @@ void RasterizerSceneHighEndRD::_render_particle_collider_heightfield(RID p_fb, c
_setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false);
- render_list.clear();
-
PassMode pass_mode = PASS_MODE_SHADOW;
- _fill_render_list(p_cull_result, p_cull_count, pass_mode);
+ _fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform);
- _setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Collider Heightield");
render_list.sort_by_key(false);
- _fill_instances(render_list.elements, render_list.element_count, true);
-
{
//regular forward for now
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_fb), render_list.elements, render_list.element_count, false, pass_mode, true, RID(), RID());
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, pass_mode, true, rp_uniform_set);
+ _render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
}
}
-void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
+void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering Material");
_update_render_base_uniform_set();
@@ -2089,20 +1930,17 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform
_setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
- render_list.clear();
-
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(p_cull_result, p_cull_count, pass_mode);
+ _fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform);
- _setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Material");
render_list.sort_by_key(false);
- _fill_instances(render_list.elements, render_list.element_count, true);
-
{
+ RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set);
//regular forward for now
Vector<Color> clear;
clear.push_back(Color(0, 0, 0, 0));
@@ -2111,12 +1949,12 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform
clear.push_back(Color(0, 0, 0, 0));
clear.push_back(Color(0, 0, 0, 0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID());
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count);
RD::get_singleton()->draw_list_end();
}
}
-void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
+void RendererSceneRenderForward::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering UV2");
_update_render_base_uniform_set();
@@ -2128,20 +1966,17 @@ void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_c
_setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
- render_list.clear();
-
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(p_cull_result, p_cull_count, pass_mode);
+ _fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform());
- _setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Material");
render_list.sort_by_key(false);
- _fill_instances(render_list.elements, render_list.element_count, true);
-
{
+ RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, true);
//regular forward for now
Vector<Color> clear;
clear.push_back(Color(0, 0, 0, 0));
@@ -2169,69 +2004,35 @@ void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_c
Vector2 ofs = uv_offsets[i];
ofs.x /= p_region.size.width;
ofs.y /= p_region.size.height;
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), true, ofs); //first wireframe, for pseudo conservative
+ render_list_params.uv_offset = ofs;
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); //first wireframe, for pseudo conservative
}
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), false); //second regular triangles
+ render_list_params.uv_offset = Vector2();
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); //second regular triangles
RD::get_singleton()->draw_list_end();
}
}
-void RasterizerSceneHighEndRD::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
+void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
RENDER_TIMESTAMP("Render SDFGI");
_update_render_base_uniform_set();
- RenderBufferDataHighEnd *render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
+ RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
ERR_FAIL_COND(!render_buffer);
render_pass++;
- render_list.clear();
PassMode pass_mode = PASS_MODE_SDF;
- _fill_render_list(p_cull_result, p_cull_count, pass_mode);
+ _fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform());
render_list.sort_by_key(false);
- _fill_instances(render_list.elements, render_list.element_count, true);
- _setup_view_dependant_uniform_set(RID(), RID(), nullptr, 0);
+ RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture);
Vector3 half_extents = p_bounds.size * 0.5;
Vector3 center = p_bounds.position + half_extents;
- if (render_buffer->render_sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_buffer->render_sdfgi_uniform_set)) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.ids.push_back(p_albedo_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(p_emission_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(p_emission_aniso_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- u.ids.push_back(p_geom_facing_texture);
- uniforms.push_back(u);
- }
-
- render_buffer->render_sdfgi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_sdfgi_rd, RENDER_BUFFERS_UNIFORM_SET);
- }
-
Vector<RID> sbs;
sbs.push_back(p_albedo_texture);
sbs.push_back(p_emission_texture);
@@ -2276,7 +2077,7 @@ void RasterizerSceneHighEndRD::_render_sdfgi(RID p_render_buffers, const Vector3
to_bounds.origin = p_bounds.position;
to_bounds.basis.scale(p_bounds.size);
- RasterizerStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds);
+ RendererStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds);
_setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
@@ -2286,20 +2087,19 @@ void RasterizerSceneHighEndRD::_render_sdfgi(RID p_render_buffers, const Vector3
E = sdfgi_framebuffer_size_cache.insert(fb_size, fb);
}
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(E->get()), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), render_buffer->render_sdfgi_uniform_set, false); //second regular triangles
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false);
+ _render_list_with_threads(&render_list_params, E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs);
}
}
-void RasterizerSceneHighEndRD::_base_uniforms_changed() {
+void RendererSceneRenderForward::_base_uniforms_changed() {
if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
}
render_base_uniform_set = RID();
}
-void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
+void RendererSceneRenderForward::_update_render_base_uniform_set() {
if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) {
if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
@@ -2311,7 +2111,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 1;
u.ids.resize(12);
RID *ids_ptr = u.ids.ptrw();
@@ -2333,7 +2133,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 2;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.ids.push_back(shadow_sampler);
uniforms.push_back(u);
}
@@ -2341,22 +2141,15 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 3;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(scene_state.uniform_buffer);
uniforms.push_back(u);
}
- {
- RD::Uniform u;
- u.binding = 4;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(scene_state.instance_buffer);
- uniforms.push_back(u);
- }
{
RD::Uniform u;
u.binding = 5;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_positional_light_buffer());
uniforms.push_back(u);
}
@@ -2364,101 +2157,94 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 6;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_reflection_probe_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 7;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(get_directional_light_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 10;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(scene_state.lightmap_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 11;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids = storage->lightmap_array_get_textures();
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 12;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(scene_state.lightmap_capture_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 13;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 12;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture();
u.ids.push_back(decal_atlas);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 14;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 13;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
u.ids.push_back(decal_atlas);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 15;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 14;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_decal_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 16;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 15;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(get_cluster_builder_texture());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 17;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 16;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_cluster_builder_indices_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 18;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 17;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (directional_shadow_get_texture().is_valid()) {
u.ids.push_back(directional_shadow_get_texture());
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 19;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 18;
u.ids.push_back(storage->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
- {
+ if (!low_end) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 20;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 19;
u.ids.push_back(sdfgi_get_ubo());
uniforms.push_back(u);
}
@@ -2467,9 +2253,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
}
}
-void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) {
- if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) {
- RD::get_singleton()->free(view_dependant_uniform_set);
+RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps) {
+ if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
+ RD::get_singleton()->free(render_pass_uniform_set);
+ }
+
+ RenderBufferDataForward *rb = nullptr;
+ if (p_render_buffers.is_valid()) {
+ rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
}
//default render buffer and scene state uniform set
@@ -2477,211 +2268,868 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at
Vector<RD::Uniform> uniforms;
{
- RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
+ RID radiance_texture;
+ if (p_radiance_texture.is_valid()) {
+ radiance_texture = p_radiance_texture;
+ } else {
+ radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
+ }
RD::Uniform u;
u.binding = 0;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(radiance_texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (ref_texture.is_valid()) {
u.ids.push_back(ref_texture);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK));
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 1;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture;
if (p_shadow_atlas.is_valid()) {
texture = shadow_atlas_get_texture(p_shadow_atlas);
}
if (!texture.is_valid()) {
- texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
}
u.ids.push_back(texture);
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.resize(scene_state.max_lightmaps);
+ RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
+ for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
+ if (i < p_lightmaps.size()) {
+ RID base = lightmap_instance_get_lightmap(p_lightmaps[i]);
+ RID texture = storage->lightmap_get_texture(base);
+ RID rd_texture = storage->texture_get_rd_texture(texture);
+ u.ids.write[i] = rd_texture;
+ } else {
+ u.ids.write[i] = default_tex;
+ }
+ }
+ uniforms.push_back(u);
+ }
{
RD::Uniform u;
- u.binding = 2;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID default_tex = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.resize(MAX_GI_PROBES);
+ RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
for (int i = 0; i < MAX_GI_PROBES; i++) {
- if (i < p_gi_probe_cull_count) {
- RID tex = gi_probe_instance_get_texture(p_gi_probe_cull_result[i]);
+ if (i < (int)p_gi_probes.size()) {
+ RID tex = gi_probe_instance_get_texture(p_gi_probes[i]);
if (!tex.is_valid()) {
tex = default_tex;
}
- u.ids.push_back(tex);
+ u.ids.write[i] = tex;
} else {
- u.ids.push_back(default_tex);
+ u.ids.write[i] = default_tex;
}
}
uniforms.push_back(u);
}
- view_dependant_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, VIEW_DEPENDANT_UNIFORM_SET);
-}
-void RasterizerSceneHighEndRD::_render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb) {
- if (!rb->uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) {
- RD::get_singleton()->free(rb->uniform_set);
+ {
+ RD::Uniform u;
+ u.binding = 5;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
}
- rb->uniform_set = RID();
-}
-
-void RasterizerSceneHighEndRD::_render_buffers_uniform_set_changed(RID p_render_buffers) {
- RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
-
- _render_buffers_clear_uniform_set(rb);
-}
-
-RID RasterizerSceneHighEndRD::_render_buffers_get_normal_texture(RID p_render_buffers) {
- RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
-
- return rb->normal_roughness_buffer;
-}
-
-RID RasterizerSceneHighEndRD::_render_buffers_get_ambient_texture(RID p_render_buffers) {
- RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
-
- return rb->ambient_buffer;
-}
-
-RID RasterizerSceneHighEndRD::_render_buffers_get_reflection_texture(RID p_render_buffers) {
- RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
-
- return rb->reflection_buffer;
-}
-
-void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_buffers) {
- RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
-
- if (rb->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 0;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = false && rb->depth.is_valid() ? rb->depth : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
- u.ids.push_back(texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 1;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID bbt = render_buffers_get_back_buffer_texture(p_render_buffers);
- RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
- u.ids.push_back(texture);
- uniforms.push_back(u);
- }
+ {
+ RD::Uniform u;
+ u.binding = 6;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
+ RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+ if (!low_end) {
{
RD::Uniform u;
- u.binding = 2;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
+ u.binding = 7;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 4;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID aot = render_buffers_get_ao_texture(p_render_buffers);
- RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.binding = 8;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID();
+ RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 5;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.binding = 9;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = rb && rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 6;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.binding = 10;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = rb && rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 7;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 11;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID t;
- if (render_buffers_is_sdfgi_enabled(p_render_buffers)) {
+ if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
t = render_buffers_get_sdfgi_irradiance_probes(p_render_buffers);
} else {
- t = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
+ t = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
}
u.ids.push_back(t);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 8;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- if (render_buffers_is_sdfgi_enabled(p_render_buffers)) {
+ u.binding = 12;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers));
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 9;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(render_buffers_get_gi_probe_buffer(p_render_buffers));
+ u.binding = 13;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 10;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 14;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID vfog = RID();
- if (p_render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_buffers)) {
+ if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) {
vfog = render_buffers_get_volumetric_fog_texture(p_render_buffers);
if (vfog.is_null()) {
- vfog = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
}
} else {
- vfog = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
}
u.ids.push_back(vfog);
uniforms.push_back(u);
}
- rb->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_BUFFERS_UNIFORM_SET);
}
+
+ render_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET);
+ return render_pass_uniform_set;
}
-RasterizerSceneHighEndRD *RasterizerSceneHighEndRD::singleton = nullptr;
+RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) {
+ if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) {
+ RD::get_singleton()->free(sdfgi_pass_uniform_set);
+ }
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ // No radiance texture.
+ RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
+ RD::Uniform u;
+ u.binding = 0;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(radiance_texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ // No reflection atlas.
+ RID ref_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK);
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(ref_texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ // No shadow atlas.
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ // No Lightmaps
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.resize(scene_state.max_lightmaps);
+ RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
+ for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
+ u.ids.write[i] = default_tex;
+ }
+
+ uniforms.push_back(u);
+ }
-void RasterizerSceneHighEndRD::set_time(double p_time, double p_step) {
+ {
+ // No GIProbes
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.resize(MAX_GI_PROBES);
+ RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ for (int i = 0; i < MAX_GI_PROBES; i++) {
+ u.ids.write[i] = default_tex;
+ }
+
+ uniforms.push_back(u);
+ }
+ // actual sdfgi stuff
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 5;
+ u.ids.push_back(p_albedo_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 6;
+ u.ids.push_back(p_emission_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 7;
+ u.ids.push_back(p_emission_aniso_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 8;
+ u.ids.push_back(p_geom_facing_texture);
+ uniforms.push_back(u);
+ }
+
+ sdfgi_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_sdfgi_rd, RENDER_PASS_UNIFORM_SET);
+ return sdfgi_pass_uniform_set;
+}
+
+void RendererSceneRenderForward::_render_buffers_clear_uniform_set(RenderBufferDataForward *rb) {
+}
+
+void RendererSceneRenderForward::_render_buffers_uniform_set_changed(RID p_render_buffers) {
+ RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+
+ _render_buffers_clear_uniform_set(rb);
+}
+
+RID RendererSceneRenderForward::_render_buffers_get_normal_texture(RID p_render_buffers) {
+ RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+
+ return rb->normal_roughness_buffer;
+}
+
+RID RendererSceneRenderForward::_render_buffers_get_ambient_texture(RID p_render_buffers) {
+ RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+
+ return rb->ambient_buffer;
+}
+
+RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) {
+ RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+
+ return rb->reflection_buffer;
+}
+
+RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr;
+
+void RendererSceneRenderForward::set_time(double p_time, double p_step) {
time = p_time;
- RasterizerSceneRD::set_time(p_time, p_step);
+ RendererSceneRenderRD::set_time(p_time, p_step);
+}
+
+void RendererSceneRenderForward::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ if (ginstance->dirty_list_element.in_list()) {
+ return;
+ }
+
+ //clear surface caches
+ GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches;
+
+ while (surf) {
+ GeometryInstanceSurfaceDataCache *next = surf->next;
+ geometry_instance_surface_alloc.free(surf);
+ surf = next;
+ }
+
+ ginstance->surface_caches = nullptr;
+
+ geometry_instance_dirty_list.add(&ginstance->dirty_list_element);
+}
+
+void RendererSceneRenderForward::_geometry_instance_add_surface_with_material(GeometryInstanceForward *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {
+ 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 || has_read_screen_alpha);
+ bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
+ bool has_alpha = has_base_alpha || has_blend_alpha;
+
+ uint32_t flags = 0;
+
+ if (p_material->shader_data->uses_sss) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SUBSURFACE_SCATTERING;
+ }
+
+ if (p_material->shader_data->uses_screen_texture) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SCREEN_TEXTURE;
+ }
+
+ if (p_material->shader_data->uses_depth_texture) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE;
+ }
+
+ if (p_material->shader_data->uses_normal_texture) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_NORMAL_TEXTURE;
+ }
+
+ if (ginstance->data->cast_double_sided_shaodows) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS;
+ }
+
+ if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == 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 == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED)) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
+ }
+ } else {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE;
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
+ }
+
+ MaterialData *material_shadow = nullptr;
+ //void *surface_shadow = nullptr;
+ if (!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) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
+ material_shadow = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
+ } else {
+ material_shadow = p_material;
+ }
+
+ GeometryInstanceSurfaceDataCache *sdcache = geometry_instance_surface_alloc.alloc();
+
+ sdcache->flags = flags;
+
+ sdcache->shader = p_material->shader_data;
+ sdcache->material_uniform_set = p_material->uniform_set;
+ sdcache->surface = storage->mesh_get_surface(p_mesh, p_surface);
+ sdcache->primitive = storage->mesh_surface_get_primitive(sdcache->surface);
+ sdcache->surface_index = p_surface;
+
+ if (ginstance->data->dirty_dependencies) {
+ storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
+ }
+
+ //shadow
+ sdcache->shader_shadow = material_shadow->shader_data;
+ sdcache->material_uniform_set_shadow = material_shadow->uniform_set;
+ sdcache->surface_shadow = sdcache->surface; //when adding special shadow meshes, will use this
+
+ sdcache->owner = ginstance;
+
+ sdcache->next = ginstance->surface_caches;
+ ginstance->surface_caches = sdcache;
+
+ //sortkey
+
+ sdcache->sort.sort_key1 = 0;
+ sdcache->sort.sort_key2 = 0;
+
+ sdcache->sort.surface_type = ginstance->data->base_type;
+ sdcache->sort.material_id = p_material_id;
+ sdcache->sort.shader_id = p_shader_id;
+ sdcache->sort.geometry_id = p_mesh.get_local_index();
+ sdcache->sort.uses_forward_gi = ginstance->can_sdfgi;
+ sdcache->sort.priority = p_material->priority;
+}
+
+void RendererSceneRenderForward::_geometry_instance_add_surface(GeometryInstanceForward *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
+ RID m_src;
+
+ m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material;
+
+ MaterialData *material = nullptr;
+
+ if (m_src.is_valid()) {
+ material = (MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
+ if (!material || !material->shader_data->valid) {
+ material = nullptr;
+ }
+ }
+
+ if (material) {
+ if (ginstance->data->dirty_dependencies) {
+ storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
+ }
+ } else {
+ material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
+ m_src = default_material;
+ }
+
+ ERR_FAIL_COND(!material);
+
+ _geometry_instance_add_surface_with_material(ginstance, p_surface, material, m_src.get_local_index(), storage->material_get_shader_id(m_src), p_mesh);
+
+ while (material->next_pass.is_valid()) {
+ RID next_pass = material->next_pass;
+ material = (MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
+ if (!material || !material->shader_data->valid) {
+ break;
+ }
+ if (ginstance->data->dirty_dependencies) {
+ storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
+ }
+ _geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
+ }
+}
+
+void RendererSceneRenderForward::_geometry_instance_update(GeometryInstance *p_geometry_instance) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+
+ if (ginstance->data->dirty_dependencies) {
+ ginstance->data->dependency_tracker.update_begin();
+ }
+
+ //add geometry for drawing
+ switch (ginstance->data->base_type) {
+ case RS::INSTANCE_MESH: {
+ const RID *materials = nullptr;
+ uint32_t surface_count;
+ RID mesh = ginstance->data->base;
+
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (materials) {
+ //if no materials, no surfaces.
+ const RID *inst_materials = ginstance->data->surface_materials.ptr();
+ uint32_t surf_mat_count = ginstance->data->surface_materials.size();
+
+ for (uint32_t j = 0; j < surface_count; j++) {
+ RID material = (j < surf_mat_count && inst_materials[j].is_valid()) ? inst_materials[j] : materials[j];
+ _geometry_instance_add_surface(ginstance, j, material, mesh);
+ }
+ }
+
+ ginstance->instance_count = 1;
+
+ } break;
+
+ case RS::INSTANCE_MULTIMESH: {
+ RID mesh = storage->multimesh_get_mesh(ginstance->data->base);
+ if (mesh.is_valid()) {
+ const RID *materials = nullptr;
+ uint32_t surface_count;
+
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (materials) {
+ for (uint32_t j = 0; j < surface_count; j++) {
+ _geometry_instance_add_surface(ginstance, j, materials[j], mesh);
+ }
+ }
+
+ ginstance->instance_count = storage->multimesh_get_instances_to_draw(ginstance->data->base);
+ }
+
+ } break;
+#if 0
+ case RS::INSTANCE_IMMEDIATE: {
+ RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base);
+ ERR_CONTINUE(!immediate);
+
+ _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass);
+
+ } break;
+#endif
+ case RS::INSTANCE_PARTICLES: {
+ int draw_passes = storage->particles_get_draw_passes(ginstance->data->base);
+
+ for (int j = 0; j < draw_passes; j++) {
+ RID mesh = storage->particles_get_draw_pass_mesh(ginstance->data->base, j);
+ if (!mesh.is_valid())
+ continue;
+
+ const RID *materials = nullptr;
+ uint32_t surface_count;
+
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (materials) {
+ for (uint32_t k = 0; k < surface_count; k++) {
+ _geometry_instance_add_surface(ginstance, k, materials[k], mesh);
+ }
+ }
+ }
+
+ ginstance->instance_count = storage->particles_get_amount(ginstance->data->base);
+
+ } break;
+
+ default: {
+ }
+ }
+
+ //Fill push constant
+
+ ginstance->push_constant.instance_uniforms_ofs = ginstance->data->shader_parameters_offset >= 0 ? ginstance->data->shader_parameters_offset : 0;
+ ginstance->push_constant.layer_mask = ginstance->data->layer_mask;
+ ginstance->push_constant.flags = 0;
+ ginstance->push_constant.gi_offset = 0xFFFFFFFF; //disabled
+
+ bool store_transform = true;
+
+ if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;
+ uint32_t stride;
+ if (storage->multimesh_get_transform_format(ginstance->data->base) == RS::MULTIMESH_TRANSFORM_2D) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
+ stride = 2;
+ } else {
+ stride = 3;
+ }
+ if (storage->multimesh_uses_colors(ginstance->data->base)) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
+ stride += 1;
+ }
+ if (storage->multimesh_uses_custom_data(ginstance->data->base)) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
+ stride += 1;
+ }
+
+ ginstance->base_flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
+ ginstance->transforms_uniform_set = storage->multimesh_get_3d_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+
+ } else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;
+ uint32_t stride;
+ if (false) { // 2D particles
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
+ stride = 2;
+ } else {
+ stride = 3;
+ }
+
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
+ stride += 1;
+
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
+ stride += 1;
+
+ ginstance->base_flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
+
+ if (!storage->particles_is_using_local_coords(ginstance->data->base)) {
+ store_transform = false;
+ }
+ ginstance->transforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+
+ } else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
+ if (storage->skeleton_is_valid(ginstance->data->skeleton)) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_SKELETON;
+ ginstance->transforms_uniform_set = storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ if (ginstance->data->dirty_dependencies) {
+ storage->skeleton_update_dependency(ginstance->data->skeleton, &ginstance->data->dependency_tracker);
+ }
+ }
+ }
+
+ if (store_transform) {
+ RendererStorageRD::store_transform(ginstance->data->transform, ginstance->push_constant.transform);
+ } else {
+ RendererStorageRD::store_transform(Transform(), ginstance->push_constant.transform);
+ }
+
+ ginstance->can_sdfgi = false;
+
+ if (lightmap_instance_is_valid(ginstance->lightmap_instance)) {
+ ginstance->push_constant.gi_offset = ginstance->data->lightmap_slice_index << 16;
+ ginstance->push_constant.lightmap_uv_scale[0] = ginstance->data->lightmap_uv_scale.position.x;
+ ginstance->push_constant.lightmap_uv_scale[1] = ginstance->data->lightmap_uv_scale.position.y;
+ ginstance->push_constant.lightmap_uv_scale[2] = ginstance->data->lightmap_uv_scale.size.width;
+ ginstance->push_constant.lightmap_uv_scale[3] = ginstance->data->lightmap_uv_scale.size.height;
+ } else if (!low_end) {
+ if (ginstance->gi_probes[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) {
+ ginstance->can_sdfgi = true;
+ }
+ }
+
+ if (ginstance->data->dirty_dependencies) {
+ ginstance->data->dependency_tracker.update_end();
+ ginstance->data->dirty_dependencies = false;
+ }
+
+ ginstance->dirty_list_element.remove_from_list();
+}
+
+void RendererSceneRenderForward::_update_dirty_geometry_instances() {
+ while (geometry_instance_dirty_list.first()) {
+ _geometry_instance_update(geometry_instance_dirty_list.first()->self());
+ }
+}
+
+void RendererSceneRenderForward::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+ switch (p_notification) {
+ case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
+ case RendererStorage::DEPENDENCY_CHANGED_MESH:
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
+ case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
+ static_cast<RendererSceneRenderForward *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_tracker->userdata);
+ if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
+ ginstance->instance_count = static_cast<RendererSceneRenderForward *>(singleton)->storage->multimesh_get_instances_to_draw(ginstance->data->base);
+ }
+ } break;
+ default: {
+ //rest of notifications of no interest
+ } break;
+ }
+}
+void RendererSceneRenderForward::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+ static_cast<RendererSceneRenderForward *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
}
-RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storage) :
- RasterizerSceneRD(p_storage) {
+RendererSceneRender::GeometryInstance *RendererSceneRenderForward::geometry_instance_create(RID p_base) {
+ RS::InstanceType type = storage->get_base_type(p_base);
+ ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
+
+ GeometryInstanceForward *ginstance = geometry_instance_alloc.alloc();
+ ginstance->data = memnew(GeometryInstanceForward::Data);
+
+ 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;
+
+ _geometry_instance_mark_dirty(ginstance);
+
+ return ginstance;
+}
+void RendererSceneRenderForward::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->skeleton = p_skeleton;
+ _geometry_instance_mark_dirty(ginstance);
+ ginstance->data->dirty_dependencies = true;
+}
+void RendererSceneRenderForward::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->material_override = p_override;
+ _geometry_instance_mark_dirty(ginstance);
+ ginstance->data->dirty_dependencies = true;
+}
+void RendererSceneRenderForward::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->surface_materials = p_materials;
+ _geometry_instance_mark_dirty(ginstance);
+ ginstance->data->dirty_dependencies = true;
+}
+void RendererSceneRenderForward::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->mesh_instance = p_mesh_instance;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForward::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ RendererStorageRD::store_transform(p_transform, ginstance->push_constant.transform);
+ ginstance->data->transform = p_transform;
+ ginstance->mirror = p_transform.basis.determinant() < 0;
+ ginstance->data->aabb = p_aabb;
+ ginstance->transformed_aabb = p_transformed_aabb;
+
+ Vector3 model_scale_vec = p_transform.basis.get_scale_abs();
+ // handle non uniform scale here
+
+ float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z));
+ float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z));
+ ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9;
+
+ ginstance->lod_model_scale = max_scale;
+}
+void RendererSceneRenderForward::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->lod_bias = p_lod_bias;
+}
+void RendererSceneRenderForward::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->use_baked_light = p_enable;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForward::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->use_dynamic_gi = p_enable;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForward::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->lightmap_instance = p_lightmap_instance;
+ ginstance->data->lightmap_uv_scale = p_lightmap_uv_scale;
+ ginstance->data->lightmap_slice_index = p_lightmap_slice_index;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForward::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ if (p_sh9) {
+ if (ginstance->lightmap_sh == nullptr) {
+ ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc();
+ }
+
+ copymem(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9);
+ } else {
+ if (ginstance->lightmap_sh != nullptr) {
+ geometry_instance_lightmap_sh.free(ginstance->lightmap_sh);
+ ginstance->lightmap_sh = nullptr;
+ }
+ }
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForward::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->shader_parameters_offset = p_offset;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForward::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+
+ ginstance->data->cast_double_sided_shaodows = p_enable;
+ _geometry_instance_mark_dirty(ginstance);
+}
+
+void RendererSceneRenderForward::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->layer_mask = p_layer_mask;
+ ginstance->push_constant.layer_mask = p_layer_mask;
+}
+
+void RendererSceneRenderForward::geometry_instance_free(GeometryInstance *p_geometry_instance) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ if (ginstance->lightmap_sh != nullptr) {
+ geometry_instance_lightmap_sh.free(ginstance->lightmap_sh);
+ }
+ GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches;
+ while (surf) {
+ GeometryInstanceSurfaceDataCache *next = surf->next;
+ geometry_instance_surface_alloc.free(surf);
+ surf = next;
+ }
+ memdelete(ginstance->data);
+ geometry_instance_alloc.free(ginstance);
+}
+
+uint32_t RendererSceneRenderForward::geometry_instance_get_pair_mask() {
+ return (1 << RS::INSTANCE_GI_PROBE);
+}
+void RendererSceneRenderForward::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) {
+}
+void RendererSceneRenderForward::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
+}
+void RendererSceneRenderForward::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) {
+}
+
+Transform RendererSceneRenderForward::geometry_instance_get_transform(GeometryInstance *p_instance) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance);
+ ERR_FAIL_COND_V(!ginstance, Transform());
+ return ginstance->data->transform;
+}
+AABB RendererSceneRenderForward::geometry_instance_get_aabb(GeometryInstance *p_instance) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance);
+ ERR_FAIL_COND_V(!ginstance, AABB());
+ return ginstance->data->aabb;
+}
+
+void RendererSceneRenderForward::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) {
+ GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ if (p_gi_probe_instance_count > 0) {
+ ginstance->gi_probes[0] = p_gi_probe_instances[0];
+ } else {
+ ginstance->gi_probes[0] = RID();
+ }
+
+ if (p_gi_probe_instance_count > 1) {
+ ginstance->gi_probes[1] = p_gi_probe_instances[1];
+ } else {
+ ginstance->gi_probes[1] = RID();
+ }
+}
+
+RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_storage) :
+ RendererSceneRenderRD(p_storage) {
singleton = this;
+ low_end = is_low_end();
storage = p_storage;
/* SCENE SHADER */
{
String defines;
+ if (low_end) {
+ defines += "\n#define LOW_END_MODE \n";
+ }
+
defines += "\n#define MAX_ROUGHNESS_LOD " + itos(get_roughness_layers() - 1) + ".0\n";
if (is_using_radiance_cubemap_array()) {
defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
@@ -2691,11 +3139,10 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
{
//lightmaps
- scene_state.max_lightmaps = storage->lightmap_array_get_size();
+ scene_state.max_lightmaps = low_end ? 2 : MAX_LIGHTMAPS;
defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n";
defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n";
- scene_state.lightmaps = memnew_arr(LightmapData, scene_state.max_lightmaps);
scene_state.lightmap_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapData) * scene_state.max_lightmaps);
}
{
@@ -2721,10 +3168,20 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
shader_versions.push_back("\n#define USE_LIGHTMAP\n");
shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n");
shader.scene_shader.initialize(shader_versions, defines);
+
+ if (is_low_end()) {
+ //disable the high end versions
+ shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS, false);
+ shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE, false);
+ shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_SDF, false);
+ shader.scene_shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI, false);
+ shader.scene_shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
+ shader.scene_shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
+ }
}
- storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
- storage->material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_3D, _create_material_funcs);
+ storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
+ storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_material_funcs);
{
//shader compiler
@@ -2762,8 +3219,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["FRONT_FACING"] = "gl_FrontFacing";
- actions.renames["NORMALMAP"] = "normalmap";
- actions.renames["NORMALMAP_DEPTH"] = "normaldepth";
+ actions.renames["NORMAL_MAP"] = "normal_map";
+ actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
actions.renames["ALBEDO"] = "albedo";
actions.renames["ALPHA"] = "alpha";
actions.renames["METALLIC"] = "metallic";
@@ -2795,6 +3252,12 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.renames["FOG"] = "custom_fog";
actions.renames["RADIANCE"] = "custom_radiance";
actions.renames["IRRADIANCE"] = "custom_irradiance";
+ actions.renames["BONE_INDICES"] = "bone_attrib";
+ actions.renames["BONE_WEIGHTS"] = "weight_attrib";
+ actions.renames["CUSTOM0"] = "custom0_attrib";
+ actions.renames["CUSTOM1"] = "custom1_attrib";
+ actions.renames["CUSTOM2"] = "custom2_attrib";
+ actions.renames["CUSTOM3"] = "custom3_attrib";
//for light
actions.renames["VIEW"] = "view";
@@ -2805,6 +3268,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.renames["DIFFUSE_LIGHT"] = "diffuse_light";
actions.renames["SPECULAR_LIGHT"] = "specular_light";
+ actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions.usage_defines["TANGENT"] = "#define TANGENT_USED\n";
actions.usage_defines["BINORMAL"] = "@TANGENT";
actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n";
@@ -2817,8 +3281,14 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n";
actions.usage_defines["UV"] = "#define UV_USED\n";
actions.usage_defines["UV2"] = "#define UV2_USED\n";
- actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
- actions.usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
+ actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n";
+ actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n";
+ actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n";
+ actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
+ actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
+ actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
+ actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
+ actions.usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
@@ -2885,7 +3355,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
actions.global_buffer_array_variable = "global_variables.data";
- actions.instance_uniform_index_variable = "instances.data[instance_index].instance_uniforms_ofs";
+ actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
shader.compiler.initialize(actions);
}
@@ -2895,12 +3365,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
render_list.init();
render_pass = 0;
- {
- scene_state.max_instances = render_list.max_elements;
- scene_state.instances = memnew_arr(InstanceData, scene_state.max_instances);
- scene_state.instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(InstanceData) * scene_state.max_instances);
- }
-
scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
{
@@ -2910,9 +3374,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
default_material = storage->material_create();
storage->material_set_shader(default_material, default_shader);
- MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D);
+ MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
default_shader_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
- default_shader_sdfgi_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
+ if (!low_end) {
+ default_shader_sdfgi_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
+ }
}
{
@@ -2931,7 +3397,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
Vector<RD::Uniform> uniforms;
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(default_vec4_xform_buffer);
u.binding = 0;
uniforms.push_back(u);
@@ -2947,73 +3413,21 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
shadow_sampler = RD::get_singleton()->sampler_create(sampler);
}
- {
- Vector<RD::Uniform> uniforms;
-
- RD::Uniform u;
- u.binding = 0;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
- u.ids.push_back(texture);
- uniforms.push_back(u);
-
- default_radiance_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RADIANCE_UNIFORM_SET);
- }
-
- { //render buffers
- Vector<RD::Uniform> uniforms;
- for (int i = 0; i < 7; i++) {
- RD::Uniform u;
- u.binding = i;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = storage->texture_rd_get_default(i == 0 ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE : (i == 2 ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_NORMAL : RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK));
- u.ids.push_back(texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 7;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
- u.ids.push_back(texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 8;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 9;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(render_buffers_get_default_gi_probe_buffer());
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 10;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- uniforms.push_back(u);
- }
-
- default_render_buffers_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_BUFFERS_UNIFORM_SET);
- }
+ render_list_thread_threshold = GLOBAL_GET("rendering/forward_renderer/threaded_render_minimum_instances");
}
-RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() {
+RendererSceneRenderForward::~RendererSceneRenderForward() {
directional_shadow_atlas_set_size(0);
//clear base uniform set if still valid
- if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) {
- RD::get_singleton()->free(view_dependant_uniform_set);
+ if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
+ RD::get_singleton()->free(render_pass_uniform_set);
+ }
+
+ if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) {
+ RD::get_singleton()->free(sdfgi_pass_uniform_set);
}
- RD::get_singleton()->free(default_render_buffers_uniform_set);
- RD::get_singleton()->free(default_radiance_uniform_set);
RD::get_singleton()->free(default_vec4_xform_buffer);
RD::get_singleton()->free(shadow_sampler);
@@ -3027,11 +3441,8 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() {
{
RD::get_singleton()->free(scene_state.uniform_buffer);
- RD::get_singleton()->free(scene_state.instance_buffer);
RD::get_singleton()->free(scene_state.lightmap_buffer);
RD::get_singleton()->free(scene_state.lightmap_capture_buffer);
- memdelete_arr(scene_state.instances);
- memdelete_arr(scene_state.lightmaps);
memdelete_arr(scene_state.lightmap_captures);
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.h b/servers/rendering/renderer_rd/renderer_scene_render_forward.h
new file mode 100644
index 0000000000..3b5a5ad96f
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.h
@@ -0,0 +1,745 @@
+/*************************************************************************/
+/* renderer_scene_render_forward.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_H
+#define RENDERING_SERVER_SCENE_RENDER_FORWARD_H
+
+#include "core/templates/paged_allocator.h"
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/scene_forward.glsl.gen.h"
+
+class RendererSceneRenderForward : public RendererSceneRenderRD {
+ enum {
+ SCENE_UNIFORM_SET = 0,
+ RENDER_PASS_UNIFORM_SET = 1,
+ TRANSFORMS_UNIFORM_SET = 2,
+ MATERIAL_UNIFORM_SET = 3
+ };
+
+ enum {
+ SDFGI_MAX_CASCADES = 8,
+ MAX_GI_PROBES = 8,
+ MAX_LIGHTMAPS = 8,
+ MAX_GI_PROBES_PER_INSTANCE = 2,
+ };
+
+ /* Scene Shader */
+
+ enum ShaderVersion {
+ SHADER_VERSION_DEPTH_PASS,
+ SHADER_VERSION_DEPTH_PASS_DP,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE,
+ SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
+ SHADER_VERSION_DEPTH_PASS_WITH_SDF,
+ SHADER_VERSION_COLOR_PASS,
+ SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI,
+ SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_MAX
+ };
+
+ struct {
+ SceneForwardShaderRD scene_shader;
+ ShaderCompilerRD compiler;
+ } shader;
+
+ RendererStorageRD *storage;
+
+ /* Material */
+
+ struct ShaderData : public RendererStorageRD::ShaderData {
+ enum BlendMode { //used internally
+ BLEND_MODE_MIX,
+ BLEND_MODE_ADD,
+ BLEND_MODE_SUB,
+ BLEND_MODE_MUL,
+ BLEND_MODE_ALPHA_TO_COVERAGE
+ };
+
+ enum DepthDraw {
+ DEPTH_DRAW_DISABLED,
+ DEPTH_DRAW_OPAQUE,
+ DEPTH_DRAW_ALWAYS
+ };
+
+ enum DepthTest {
+ DEPTH_TEST_DISABLED,
+ DEPTH_TEST_ENABLED
+ };
+
+ enum Cull {
+ CULL_DISABLED,
+ CULL_FRONT,
+ CULL_BACK
+ };
+
+ enum CullVariant {
+ CULL_VARIANT_NORMAL,
+ CULL_VARIANT_REVERSED,
+ CULL_VARIANT_DOUBLE_SIDED,
+ CULL_VARIANT_MAX
+
+ };
+
+ enum AlphaAntiAliasing {
+ ALPHA_ANTIALIASING_OFF,
+ ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
+ ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
+ };
+
+ bool valid;
+ RID version;
+ uint32_t vertex_input_mask;
+ PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
+
+ String path;
+
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ DepthDraw depth_draw;
+ DepthTest depth_test;
+
+ bool uses_point_size;
+ bool uses_alpha;
+ bool uses_blend_alpha;
+ bool uses_alpha_clip;
+ bool uses_depth_pre_pass;
+ bool uses_discard;
+ bool uses_roughness;
+ bool uses_normal;
+
+ bool unshaded;
+ bool uses_vertex;
+ bool uses_sss;
+ bool uses_transmittance;
+ bool uses_screen_texture;
+ bool uses_depth_texture;
+ bool uses_normal_texture;
+ bool uses_time;
+ bool writes_modelview_or_projection;
+ bool uses_world_coordinates;
+
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
+
+ virtual bool is_param_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;
+
+ ShaderData();
+ virtual ~ShaderData();
+ };
+
+ RendererStorageRD::ShaderData *_create_shader_func();
+ static RendererStorageRD::ShaderData *_create_shader_funcs() {
+ return static_cast<RendererSceneRenderForward *>(singleton)->_create_shader_func();
+ }
+
+ struct MaterialData : public RendererStorageRD::MaterialData {
+ uint64_t last_frame;
+ ShaderData *shader_data;
+ RID uniform_buffer;
+ RID uniform_set;
+ Vector<RID> texture_cache;
+ Vector<uint8_t> ubo_data;
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+ RID next_pass;
+ uint8_t priority;
+ virtual void set_render_priority(int p_priority);
+ virtual void set_next_pass(RID p_pass);
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual ~MaterialData();
+ };
+
+ RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
+ static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
+ return static_cast<RendererSceneRenderForward *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
+ }
+
+ /* Framebuffer */
+
+ struct RenderBufferDataForward : public RenderBufferData {
+ //for rendering, may be MSAAd
+
+ RID color;
+ RID depth;
+ RID specular;
+ RID normal_roughness_buffer;
+ RID giprobe_buffer;
+
+ RID ambient_buffer;
+ RID reflection_buffer;
+
+ RS::ViewportMSAA msaa;
+ RD::TextureSamples texture_samples;
+
+ RID color_msaa;
+ RID depth_msaa;
+ RID specular_msaa;
+ RID normal_roughness_buffer_msaa;
+ RID roughness_buffer_msaa;
+ RID giprobe_buffer_msaa;
+
+ RID depth_fb;
+ RID depth_normal_roughness_fb;
+ RID depth_normal_roughness_giprobe_fb;
+ RID color_fb;
+ RID color_specular_fb;
+ RID specular_only_fb;
+ int width, height;
+
+ RID render_sdfgi_uniform_set;
+ void ensure_specular();
+ void ensure_gi();
+ void ensure_giprobe();
+ void clear();
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
+
+ ~RenderBufferDataForward();
+ };
+
+ virtual RenderBufferData *_create_render_buffer_data();
+ void _allocate_normal_roughness_texture(RenderBufferDataForward *rb);
+
+ RID shadow_sampler;
+ RID render_base_uniform_set;
+ RID render_pass_uniform_set;
+ RID sdfgi_pass_uniform_set;
+
+ uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
+
+ virtual void _base_uniforms_changed();
+ void _render_buffers_clear_uniform_set(RenderBufferDataForward *rb);
+ virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
+ virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
+ virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers);
+ virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers);
+
+ void _update_render_base_uniform_set();
+ RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
+ RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps);
+
+ struct LightmapData {
+ float normal_xform[12];
+ };
+
+ struct LightmapCaptureData {
+ float sh[9 * 4];
+ };
+
+ enum {
+ INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
+ INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
+ INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
+ INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
+ INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
+ INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11,
+ INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
+ INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT = 16,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_MASK = 0x7,
+ INSTANCE_DATA_FLAG_SKELETON = 1 << 19,
+ };
+
+ struct SceneState {
+ struct UBO {
+ float projection_matrix[16];
+ float inv_projection_matrix[16];
+
+ float camera_matrix[16];
+ float inv_camera_matrix[16];
+
+ float viewport_size[2];
+ float screen_pixel_size[2];
+
+ float directional_penumbra_shadow_kernel[128]; //32 vec4s
+ float directional_soft_shadow_kernel[128];
+ float penumbra_shadow_kernel[128];
+ float soft_shadow_kernel[128];
+
+ uint32_t directional_penumbra_shadow_samples;
+ uint32_t directional_soft_shadow_samples;
+ uint32_t penumbra_shadow_samples;
+ uint32_t soft_shadow_samples;
+
+ float ambient_light_color_energy[4];
+
+ float ambient_color_sky_mix;
+ uint32_t use_ambient_light;
+ uint32_t use_ambient_cubemap;
+ uint32_t use_reflection_cubemap;
+
+ float radiance_inverse_xform[12];
+
+ float shadow_atlas_pixel_size[2];
+ float directional_shadow_pixel_size[2];
+
+ uint32_t directional_light_count;
+ float dual_paraboloid_side;
+ float z_far;
+ float z_near;
+
+ uint32_t ssao_enabled;
+ float ssao_light_affect;
+ float ssao_ao_affect;
+ uint32_t roughness_limiter_enabled;
+
+ float roughness_limiter_amount;
+ float roughness_limiter_limit;
+ uint32_t roughness_limiter_pad[2];
+
+ float ao_color[4];
+
+ float sdf_to_bounds[16];
+
+ int32_t sdf_offset[3];
+ uint32_t material_uv2_mode;
+
+ int32_t sdf_size[3];
+ uint32_t gi_upscale_for_msaa;
+
+ uint32_t volumetric_fog_enabled;
+ float volumetric_fog_inv_length;
+ float volumetric_fog_detail_spread;
+ uint32_t volumetric_fog_pad;
+
+ // Fog
+ uint32_t fog_enabled;
+ float fog_density;
+ float fog_height;
+ float fog_height_density;
+
+ float fog_light_color[3];
+ float fog_sun_scatter;
+
+ float fog_aerial_perspective;
+
+ float time;
+ float reflection_multiplier;
+
+ uint32_t pancake_shadows;
+ };
+
+ UBO ubo;
+
+ RID uniform_buffer;
+
+ LightmapData lightmaps[MAX_LIGHTMAPS];
+ RID lightmap_ids[MAX_LIGHTMAPS];
+ bool lightmap_has_sh[MAX_LIGHTMAPS];
+ uint32_t lightmaps_used = 0;
+ uint32_t max_lightmaps;
+ RID lightmap_buffer;
+
+ LightmapCaptureData *lightmap_captures;
+ uint32_t max_lightmap_captures;
+ RID lightmap_capture_buffer;
+
+ RID giprobe_ids[MAX_GI_PROBES];
+ uint32_t giprobes_used = 0;
+
+ bool used_screen_texture = false;
+ bool used_normal_texture = false;
+ bool used_depth_texture = false;
+ bool used_sss = false;
+
+ } scene_state;
+
+ static RendererSceneRenderForward *singleton;
+ uint64_t render_pass;
+ double time;
+ RID default_shader;
+ RID default_material;
+ RID overdraw_material_shader;
+ RID overdraw_material;
+ RID wireframe_material_shader;
+ RID wireframe_material;
+ RID default_shader_rd;
+ RID default_shader_sdfgi_rd;
+
+ RID default_vec4_xform_buffer;
+ RID default_vec4_xform_uniform_set;
+
+ enum PassMode {
+ PASS_MODE_COLOR,
+ PASS_MODE_COLOR_SPECULAR,
+ PASS_MODE_COLOR_TRANSPARENT,
+ PASS_MODE_SHADOW,
+ PASS_MODE_SHADOW_DP,
+ PASS_MODE_DEPTH,
+ PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
+ PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE,
+ PASS_MODE_DEPTH_MATERIAL,
+ PASS_MODE_SDF,
+ };
+
+ void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
+ void _setup_giprobes(const PagedArray<RID> &p_giprobes);
+ void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform);
+
+ struct GeometryInstanceSurfaceDataCache;
+
+ struct RenderListParameters {
+ GeometryInstanceSurfaceDataCache **elements = nullptr;
+ int element_count = 0;
+ bool reverse_cull = false;
+ PassMode pass_mode = PASS_MODE_COLOR;
+ bool no_gi = false;
+ RID render_pass_uniform_set;
+ bool force_wireframe = false;
+ Vector2 uv_offset;
+ Plane lod_plane;
+ float lod_distance_multiplier = 0.0;
+ float screen_lod_threshold = 0.0;
+ RD::FramebufferFormatID framebuffer_format = 0;
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) {
+ elements = p_elements;
+ element_count = p_element_count;
+ reverse_cull = p_reverse_cull;
+ pass_mode = p_pass_mode;
+ no_gi = p_no_gi;
+ render_pass_uniform_set = p_render_pass_uniform_set;
+ force_wireframe = p_force_wireframe;
+ uv_offset = p_uv_offset;
+ lod_plane = p_lod_plane;
+ lod_distance_multiplier = p_lod_distance_multiplier;
+ screen_lod_threshold = p_screen_lod_threshold;
+ }
+ };
+
+ template <PassMode p_pass_mode>
+ _FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
+
+ void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
+
+ LocalVector<RD::DrawListID> thread_draw_lists;
+ void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params);
+ void _render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::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 Vector<RID> &p_storage_textures = Vector<RID>());
+
+ uint32_t render_list_thread_threshold = 500;
+
+ void _fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false);
+
+ Map<Size2i, RID> sdfgi_framebuffer_size_cache;
+
+ struct GeometryInstanceData;
+ struct GeometryInstanceForward;
+
+ struct GeometryInstanceLightmapSH {
+ Color sh[9];
+ };
+
+ // Cached data for drawing surfaces
+ struct GeometryInstanceSurfaceDataCache {
+ enum {
+ FLAG_PASS_DEPTH = 1,
+ FLAG_PASS_OPAQUE = 2,
+ FLAG_PASS_ALPHA = 4,
+ FLAG_PASS_SHADOW = 8,
+ FLAG_USES_SHARED_SHADOW_MATERIAL = 128,
+ FLAG_USES_SUBSURFACE_SCATTERING = 2048,
+ FLAG_USES_SCREEN_TEXTURE = 4096,
+ FLAG_USES_DEPTH_TEXTURE = 8192,
+ FLAG_USES_NORMAL_TEXTURE = 16384,
+ FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768,
+ };
+
+ union {
+ struct {
+ uint32_t geometry_id;
+ uint32_t material_id;
+ uint32_t shader_id;
+ uint32_t surface_type : 4;
+ uint32_t uses_forward_gi : 1; //set during addition
+ uint32_t uses_lightmap : 1; //set during addition
+ uint32_t depth_layer : 4; //set during addition
+ uint32_t priority : 8;
+ };
+ struct {
+ uint64_t sort_key1;
+ uint64_t sort_key2;
+ };
+ } sort;
+
+ RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
+ uint32_t flags = 0;
+ uint32_t surface_index = 0;
+
+ void *surface = nullptr;
+ RID material_uniform_set;
+ ShaderData *shader = nullptr;
+
+ void *surface_shadow = nullptr;
+ RID material_uniform_set_shadow;
+ ShaderData *shader_shadow = nullptr;
+
+ GeometryInstanceSurfaceDataCache *next = nullptr;
+ GeometryInstanceForward *owner = nullptr;
+ };
+
+ struct GeometryInstanceForward : public GeometryInstance {
+ //used during rendering
+ bool mirror = false;
+ bool non_uniform_scale = false;
+ float lod_bias = 0.0;
+ float lod_model_scale = 1.0;
+ AABB transformed_aabb; //needed for LOD
+ float depth = 0;
+ struct PushConstant {
+ float transform[16];
+ uint32_t flags;
+ uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables
+ uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index)
+ uint32_t layer_mask;
+ float lightmap_uv_scale[4];
+ } push_constant;
+ RID transforms_uniform_set;
+ uint32_t instance_count = 0;
+ RID mesh_instance;
+ bool can_sdfgi = false;
+ //used during setup
+ uint32_t base_flags = 0;
+ RID gi_probes[MAX_GI_PROBES_PER_INSTANCE];
+ RID lightmap_instance;
+ GeometryInstanceLightmapSH *lightmap_sh = nullptr;
+ GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
+ SelfList<GeometryInstanceForward> dirty_list_element;
+
+ struct Data {
+ //data used less often goes into regular heap
+ RID base;
+ RS::InstanceType base_type;
+
+ RID skeleton;
+
+ uint32_t layer_mask = 1;
+
+ Vector<RID> surface_materials;
+ RID material_override;
+ Transform transform;
+ AABB aabb;
+ int32_t shader_parameters_offset = -1;
+
+ bool use_dynamic_gi = false;
+ bool use_baked_light = false;
+ bool cast_double_sided_shaodows = false;
+ bool mirror = false;
+ Rect2 lightmap_uv_scale;
+ uint32_t lightmap_slice_index = 0;
+ bool dirty_dependencies = false;
+
+ RendererStorage::DependencyTracker dependency_tracker;
+ };
+
+ Data *data = nullptr;
+
+ GeometryInstanceForward() :
+ dirty_list_element(this) {}
+ };
+
+ static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
+
+ SelfList<GeometryInstanceForward>::List geometry_instance_dirty_list;
+
+ PagedAllocator<GeometryInstanceForward> geometry_instance_alloc;
+ PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc;
+ PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
+
+ void _geometry_instance_add_surface_with_material(GeometryInstanceForward *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
+ void _geometry_instance_add_surface(GeometryInstanceForward *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
+ void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
+ void _geometry_instance_update(GeometryInstance *p_geometry_instance);
+ void _update_dirty_geometry_instances();
+
+ bool low_end = false;
+
+ /* Render List */
+
+ struct RenderList {
+ int max_elements;
+
+ GeometryInstanceSurfaceDataCache **elements = nullptr;
+
+ int element_count;
+ int alpha_element_count;
+
+ void clear() {
+ element_count = 0;
+ alpha_element_count = 0;
+ }
+
+ //should eventually be replaced by radix
+
+ struct SortByKey {
+ _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
+ return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
+ }
+ };
+
+ void sort_by_key(bool p_alpha) {
+ SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
+ if (p_alpha) {
+ sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
+ } else {
+ sorter.sort(elements, element_count);
+ }
+ }
+
+ struct SortByDepth {
+ _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
+ return (A->owner->depth < B->owner->depth);
+ }
+ };
+
+ void sort_by_depth(bool p_alpha) { //used for shadows
+
+ SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter;
+ if (p_alpha) {
+ sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
+ } else {
+ sorter.sort(elements, element_count);
+ }
+ }
+
+ struct SortByReverseDepthAndPriority {
+ _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
+ return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority);
+ }
+ };
+
+ void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
+
+ SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter;
+ if (p_alpha) {
+ sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
+ } else {
+ sorter.sort(elements, element_count);
+ }
+ }
+
+ _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) {
+ if (element_count + alpha_element_count >= max_elements) {
+ return;
+ }
+ elements[element_count] = p_element;
+ element_count++;
+ }
+
+ _FORCE_INLINE_ void add_alpha_element(GeometryInstanceSurfaceDataCache *p_element) {
+ if (element_count + alpha_element_count >= max_elements) {
+ return;
+ }
+ int idx = max_elements - alpha_element_count - 1;
+ elements[idx] = p_element;
+ alpha_element_count++;
+ }
+
+ void init() {
+ element_count = 0;
+ alpha_element_count = 0;
+ elements = memnew_arr(GeometryInstanceSurfaceDataCache *, max_elements);
+ }
+
+ RenderList() {
+ max_elements = 0;
+ }
+
+ ~RenderList() {
+ memdelete_arr(elements);
+ }
+ };
+
+ RenderList render_list;
+
+protected:
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
+ virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold = 0.0);
+ virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
+ virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
+ virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
+ virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances);
+
+public:
+ virtual GeometryInstance *geometry_instance_create(RID p_base);
+ virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton);
+ virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override);
+ virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials);
+ virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance);
+ virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb);
+ virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask);
+ virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias);
+ virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable);
+ virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable);
+ virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index);
+ virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9);
+ virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset);
+ virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable);
+
+ virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance);
+ virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance);
+
+ virtual void geometry_instance_free(GeometryInstance *p_geometry_instance);
+
+ virtual uint32_t geometry_instance_get_pair_mask();
+ virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count);
+ virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count);
+ virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count);
+ virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count);
+
+ virtual void set_time(double p_time, double p_step);
+
+ virtual bool free(RID p_rid);
+
+ RendererSceneRenderForward(RendererStorageRD *p_storage);
+ ~RendererSceneRenderForward();
+};
+#endif // RASTERIZER_SCENE_HIGHEND_RD_H
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 12fcc6fbb9..a655edcfa7 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_scene_rd.cpp */
+/* renderer_scene_render_rd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rasterizer_scene_rd.h"
+#include "renderer_scene_render_rd.h"
#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "rasterizer_rd.h"
-#include "servers/rendering/rendering_server_raster.h"
+#include "renderer_compositor_rd.h"
+#include "servers/rendering/rendering_server_default.h"
-uint64_t RasterizerSceneRD::auto_exposure_counter = 2;
+uint64_t RendererSceneRenderRD::auto_exposure_counter = 2;
void get_vogel_disk(float *r_kernel, int p_sample_count) {
const float golden_angle = 2.4;
@@ -49,7 +49,7 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) {
}
}
-void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) {
+void RendererSceneRenderRD::_clear_reflection_data(ReflectionData &rd) {
rd.layers.clear();
rd.radiance_base_cubemap = RID();
if (rd.downsampled_radiance_cubemap.is_valid()) {
@@ -60,7 +60,7 @@ void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) {
rd.coefficient_buffer = RID();
}
-void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality) {
+void RendererSceneRenderRD::_update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality) {
//recreate radiance and all data
int mipmaps = p_mipmaps;
@@ -129,7 +129,7 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size,
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = 64; // Always 64x64
tf.height = 64;
- tf.type = RD::TEXTURE_TYPE_CUBE;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE;
tf.array_layers = 6;
tf.mipmaps = 7;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
@@ -151,7 +151,7 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size,
}
}
-void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) {
+void RendererSceneRenderRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) {
storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size);
for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) {
@@ -172,7 +172,7 @@ void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool
storage->get_effects()->cubemap_filter(rd.downsampled_radiance_cubemap, views, p_use_arrays);
}
-void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) {
+void RendererSceneRenderRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) {
if (p_use_arrays) {
//render directly to the layers
storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, rd.layers[p_base_layer].views[0], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers.size() - 1.0), rd.layers[p_base_layer].mipmaps[0].size.x);
@@ -181,7 +181,7 @@ void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd,
}
}
-void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end) {
+void RendererSceneRenderRD::_update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end) {
for (int i = p_start; i < p_end; i++) {
for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) {
for (int k = 0; k < 6; k++) {
@@ -194,7 +194,7 @@ void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd, int p_sta
}
}
-void RasterizerSceneRD::_sdfgi_erase(RenderBuffers *rb) {
+void RendererSceneRenderRD::_sdfgi_erase(RenderBuffers *rb) {
for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
const SDFGI::Cascade &c = rb->sdfgi->cascades[i];
RD::get_singleton()->free(c.light_data);
@@ -236,9 +236,9 @@ void RasterizerSceneRD::_sdfgi_erase(RenderBuffers *rb) {
rb->sdfgi = nullptr;
}
-const Vector3i RasterizerSceneRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
+const Vector3i RendererSceneRenderRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
-void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) {
+void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) {
Environment *env = environment_owner.getornull(p_environment);
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
bool needs_sdfgi = env && env->sdfgi_enabled;
@@ -284,7 +284,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
tf_sdf.width = sdfgi->cascade_size; // Always 64x64
tf_sdf.height = sdfgi->cascade_size;
tf_sdf.depth = sdfgi->cascade_size;
- tf_sdf.type = RD::TEXTURE_TYPE_3D;
+ tf_sdf.texture_type = RD::TEXTURE_TYPE_3D;
tf_sdf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
{
@@ -341,7 +341,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
tf_probes.width = sdfgi->probe_axis_count * sdfgi->probe_axis_count;
tf_probes.height = sdfgi->probe_axis_count * SDFGI::SH_SIZE;
tf_probes.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
- tf_probes.type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf_probes.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
sdfgi->history_size = requested_history_size;
@@ -351,7 +351,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
RD::TextureFormat tf_probe_average = tf_probes;
tf_probe_average.format = RD::DATA_FORMAT_R32G32B32A32_SINT; //signed integer because SH are signed
- tf_probe_average.type = RD::TEXTURE_TYPE_2D;
+ tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D;
sdfgi->lightprobe_history_scroll = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());
sdfgi->lightprobe_average_scroll = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());
@@ -378,7 +378,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
tf_ambient.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; //pack well with RGBE
tf_ambient.width = sdfgi->probe_axis_count * sdfgi->probe_axis_count;
tf_ambient.height = sdfgi->probe_axis_count;
- tf_ambient.type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
//lightprobe texture is an octahedral texture
sdfgi->ambient_texture = RD::get_singleton()->texture_create(tf_ambient, RD::TextureView());
}
@@ -443,21 +443,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->render_albedo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 3;
for (int j = 0; j < 8; j++) {
u.ids.push_back(sdfgi->render_occlusion[j]);
@@ -466,21 +466,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 4;
u.ids.push_back(sdfgi->render_emission);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 5;
u.ids.push_back(sdfgi->render_emission_aniso);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 6;
u.ids.push_back(sdfgi->render_geom_facing);
uniforms.push_back(u);
@@ -488,28 +488,28 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 7;
u.ids.push_back(cascade.sdf_tex);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 8;
u.ids.push_back(sdfgi->occlusion_data);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 10;
u.ids.push_back(cascade.solid_cell_dispatch_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 11;
u.ids.push_back(cascade.solid_cell_buffer);
uniforms.push_back(u);
@@ -522,42 +522,42 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_albedo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->render_geom_facing);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 3;
u.ids.push_back(sdfgi->render_emission);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 4;
u.ids.push_back(sdfgi->render_emission_aniso);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 5;
u.ids.push_back(cascade.solid_cell_dispatch_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 6;
u.ids.push_back(cascade.solid_cell_buffer);
uniforms.push_back(u);
@@ -569,7 +569,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
for (int j = 0; j < 8; j++) {
u.ids.push_back(sdfgi->render_occlusion[j]);
@@ -578,7 +578,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->occlusion_data);
uniforms.push_back(u);
@@ -596,12 +596,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
u.binding = 1;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (j < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -609,63 +609,63 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
u.binding = 2;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 3;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(cascade.solid_cell_dispatch_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 4;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(cascade.solid_cell_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 5;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.ids.push_back(cascade.light_data);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 6;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.ids.push_back(cascade.light_aniso_0_tex);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 7;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.ids.push_back(cascade.light_aniso_1_tex);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 8;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(rb->sdfgi->cascades_ubo);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 9;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(cascade.lights_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 10;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(rb->sdfgi->lightprobe_texture);
uniforms.push_back(u);
}
@@ -678,14 +678,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_albedo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->render_sdf[0]);
uniforms.push_back(u);
@@ -698,14 +698,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_albedo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->render_sdf_half[0]);
uniforms.push_back(u);
@@ -719,14 +719,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_sdf[0]);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->render_sdf[1]);
uniforms.push_back(u);
@@ -741,14 +741,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_sdf_half[0]);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->render_sdf_half[1]);
uniforms.push_back(u);
@@ -764,21 +764,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_albedo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(sdfgi->render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 3;
u.ids.push_back(sdfgi->render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass
uniforms.push_back(u);
@@ -793,14 +793,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(sdfgi->render_albedo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
for (int i = 0; i < 8; i++) {
u.ids.push_back(sdfgi->render_occlusion[i]);
@@ -809,7 +809,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 3;
u.ids.push_back(sdfgi->render_geom_facing);
uniforms.push_back(u);
@@ -826,12 +826,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
u.binding = 1;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (j < sdfgi->cascades.size()) {
u.ids.push_back(sdfgi->cascades[j].sdf_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -839,12 +839,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
u.binding = 2;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (j < sdfgi->cascades.size()) {
u.ids.push_back(sdfgi->cascades[j].light_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -852,12 +852,12 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
u.binding = 3;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (j < sdfgi->cascades.size()) {
u.ids.push_back(sdfgi->cascades[j].light_aniso_0_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -865,19 +865,19 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
u.binding = 4;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (j < sdfgi->cascades.size()) {
u.ids.push_back(sdfgi->cascades[j].light_aniso_1_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 6;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -885,14 +885,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 7;
u.ids.push_back(sdfgi->cascades_ubo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 8;
u.ids.push_back(sdfgi->lightprobe_data);
uniforms.push_back(u);
@@ -900,14 +900,14 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 9;
u.ids.push_back(sdfgi->cascades[i].lightprobe_history_tex);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 10;
u.ids.push_back(sdfgi->cascades[i].lightprobe_average_tex);
uniforms.push_back(u);
@@ -915,21 +915,21 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 11;
u.ids.push_back(sdfgi->lightprobe_history_scroll);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 12;
u.ids.push_back(sdfgi->lightprobe_average_scroll);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 13;
RID parent_average;
if (i < sdfgi->cascades.size() - 1) {
@@ -942,7 +942,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 14;
u.ids.push_back(sdfgi->ambient_texture);
uniforms.push_back(u);
@@ -1021,7 +1021,7 @@ void RasterizerSceneRD::sdfgi_update(RID p_render_buffers, RID p_environment, co
}
}
-int RasterizerSceneRD::sdfgi_get_pending_region_count(RID p_render_buffers) const {
+int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers) const {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(rb == nullptr, 0);
@@ -1048,7 +1048,7 @@ int RasterizerSceneRD::sdfgi_get_pending_region_count(RID p_render_buffers) cons
return dirty_count;
}
-int RasterizerSceneRD::_sdfgi_get_pending_region_data(RID p_render_buffers, int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {
+int RendererSceneRenderRD::_sdfgi_get_pending_region_data(RID p_render_buffers, int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(rb == nullptr, -1);
ERR_FAIL_COND_V(rb->sdfgi == nullptr, -1);
@@ -1108,7 +1108,7 @@ int RasterizerSceneRD::_sdfgi_get_pending_region_data(RID p_render_buffers, int
return -1;
}
-AABB RasterizerSceneRD::sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const {
+AABB RendererSceneRenderRD::sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const {
AABB bounds;
Vector3i from;
Vector3i size;
@@ -1118,7 +1118,7 @@ AABB RasterizerSceneRD::sdfgi_get_pending_region_bounds(RID p_render_buffers, in
return bounds;
}
-uint32_t RasterizerSceneRD::sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const {
+uint32_t RendererSceneRenderRD::sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const {
AABB bounds;
Vector3i from;
Vector3i size;
@@ -1126,7 +1126,7 @@ uint32_t RasterizerSceneRD::sdfgi_get_pending_region_cascade(RID p_render_buffer
return _sdfgi_get_pending_region_data(p_render_buffers, p_region, from, size, bounds);
}
-void RasterizerSceneRD::_sdfgi_update_cascades(RID p_render_buffers) {
+void RendererSceneRenderRD::_sdfgi_update_cascades(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(rb == nullptr);
if (rb->sdfgi == nullptr) {
@@ -1153,7 +1153,7 @@ void RasterizerSceneRD::_sdfgi_update_cascades(RID p_render_buffers) {
RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, true);
}
-void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {
+void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(rb == nullptr);
if (rb->sdfgi == nullptr) {
@@ -1179,13 +1179,18 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm
SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];
uint32_t idx = 0;
- for (uint32_t j = 0; j < p_directional_light_count; j++) {
+ for (uint32_t j = 0; j < (uint32_t)p_directional_lights.size(); j++) {
if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
break;
}
- LightInstance *li = light_instance_owner.getornull(p_directional_light_instances[j]);
+ LightInstance *li = light_instance_owner.getornull(p_directional_lights[j]);
ERR_CONTINUE(!li);
+
+ if (storage->light_directional_is_sky_only(li->light)) {
+ continue;
+ }
+
Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
dir.y *= rb->sdfgi->y_mult;
dir.normalize();
@@ -1333,7 +1338,7 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
u.ids.push_back(sky->radiance);
uniforms.push_back(u);
@@ -1341,7 +1346,7 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 1;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -1397,7 +1402,7 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm
RENDER_TIMESTAMP("<SDFGI Update Probes");
}
-void RasterizerSceneRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, uint32_t &r_gi_probes_used) {
+void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used) {
r_gi_probes_used = 0;
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(rb == nullptr);
@@ -1412,8 +1417,8 @@ void RasterizerSceneRD::_setup_giprobes(RID p_render_buffers, const Transform &p
for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
RID texture;
- if (i < p_gi_probe_cull_count) {
- GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_gi_probe_cull_result[i]);
+ if (i < (int)p_gi_probes.size()) {
+ GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_gi_probes[i]);
if (gipi) {
texture = gipi->texture;
@@ -1460,7 +1465,7 @@ void RasterizerSceneRD::_setup_giprobes(RID p_render_buffers, const Transform &p
}
if (texture == RID()) {
- texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
}
if (texture != rb->giprobe_textures[i]) {
@@ -1484,12 +1489,12 @@ void RasterizerSceneRD::_setup_giprobes(RID p_render_buffers, const Transform &p
}
}
- if (p_gi_probe_cull_count > 0) {
- RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN(RenderBuffers::MAX_GIPROBES, p_gi_probe_cull_count), gi_probe_data, true);
+ if (p_gi_probes.size() > 0) {
+ RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, true);
}
}
-void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) {
+void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) {
RENDER_TIMESTAMP("Render GI");
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
@@ -1507,7 +1512,7 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]);
push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
- push_constant.max_giprobes = MIN(RenderBuffers::MAX_GIPROBES, p_gi_probe_cull_count);
+ push_constant.max_giprobes = MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size());
push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH;
push_constant.use_sdfgi = rb->sdfgi != nullptr;
@@ -1609,12 +1614,12 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
{
RD::Uniform u;
u.binding = 1;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -1622,12 +1627,12 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
{
RD::Uniform u;
u.binding = 2;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[j].light_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -1635,12 +1640,12 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
{
RD::Uniform u;
u.binding = 3;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_0_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -1648,37 +1653,37 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
{
RD::Uniform u;
u.binding = 4;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_1_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 5;
if (rb->sdfgi) {
u.ids.push_back(rb->sdfgi->occlusion_texture);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 6;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 7;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -1686,7 +1691,7 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 9;
u.ids.push_back(p_ambient_buffer);
uniforms.push_back(u);
@@ -1694,7 +1699,7 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 10;
u.ids.push_back(p_reflection_buffer);
uniforms.push_back(u);
@@ -1702,54 +1707,54 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 11;
if (rb->sdfgi) {
u.ids.push_back(rb->sdfgi->lightprobe_texture);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 12;
u.ids.push_back(rb->depth_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 13;
u.ids.push_back(p_normal_roughness_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 14;
- RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 15;
u.ids.push_back(gi.sdfgi_ubo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 16;
u.ids.push_back(rb->giprobe_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 17;
for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
u.ids.push_back(rb->giprobe_textures[i]);
@@ -1768,11 +1773,11 @@ void RasterizerSceneRD::_process_gi(RID p_render_buffers, RID p_normal_roughness
RD::get_singleton()->compute_list_end();
}
-RID RasterizerSceneRD::sky_create() {
+RID RendererSceneRenderRD::sky_create() {
return sky_owner.make_rid(Sky());
}
-void RasterizerSceneRD::_sky_invalidate(Sky *p_sky) {
+void RendererSceneRenderRD::_sky_invalidate(Sky *p_sky) {
if (!p_sky->dirty) {
p_sky->dirty = true;
p_sky->dirty_list = dirty_sky_list;
@@ -1780,7 +1785,7 @@ void RasterizerSceneRD::_sky_invalidate(Sky *p_sky) {
}
}
-void RasterizerSceneRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
+void RendererSceneRenderRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND(!sky);
ERR_FAIL_COND(p_radiance_size < 32 || p_radiance_size > 2048);
@@ -1802,7 +1807,7 @@ void RasterizerSceneRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
_clear_reflection_data(sky->reflection);
}
-void RasterizerSceneRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
+void RendererSceneRenderRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND(!sky);
@@ -1825,14 +1830,14 @@ void RasterizerSceneRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
_clear_reflection_data(sky->reflection);
}
-void RasterizerSceneRD::sky_set_material(RID p_sky, RID p_material) {
+void RendererSceneRenderRD::sky_set_material(RID p_sky, RID p_material) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND(!sky);
sky->material = p_material;
_sky_invalidate(sky);
}
-Ref<Image> RasterizerSceneRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
+Ref<Image> RendererSceneRenderRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND_V(!sky, Ref<Image>());
@@ -1868,7 +1873,7 @@ Ref<Image> RasterizerSceneRD::sky_bake_panorama(RID p_sky, float p_energy, bool
return Ref<Image>();
}
-void RasterizerSceneRD::_update_dirty_skys() {
+void RendererSceneRenderRD::_update_dirty_skys() {
Sky *sky = dirty_sky_list;
while (sky) {
@@ -1892,7 +1897,7 @@ void RasterizerSceneRD::_update_dirty_skys() {
RD::TextureFormat tf;
tf.array_layers = layers * 6;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
tf.mipmaps = mipmaps;
tf.width = w;
tf.height = h;
@@ -1907,7 +1912,7 @@ void RasterizerSceneRD::_update_dirty_skys() {
RD::TextureFormat tf;
tf.array_layers = 6;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.type = RD::TEXTURE_TYPE_CUBE;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE;
tf.mipmaps = MIN(mipmaps, layers);
tf.width = w;
tf.height = h;
@@ -1927,7 +1932,7 @@ void RasterizerSceneRD::_update_dirty_skys() {
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.type = RD::TEXTURE_TYPE_2D;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
sky->half_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
Vector<RID> texs;
@@ -1942,7 +1947,7 @@ void RasterizerSceneRD::_update_dirty_skys() {
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.type = RD::TEXTURE_TYPE_2D;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
sky->quarter_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
Vector<RID> texs;
@@ -1972,14 +1977,14 @@ void RasterizerSceneRD::_update_dirty_skys() {
dirty_sky_list = nullptr;
}
-RID RasterizerSceneRD::sky_get_radiance_texture_rd(RID p_sky) const {
+RID RendererSceneRenderRD::sky_get_radiance_texture_rd(RID p_sky) const {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND_V(!sky, RID());
return sky->radiance;
}
-RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const {
+RID RendererSceneRenderRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND_V(!sky, RID());
@@ -1989,7 +1994,7 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader,
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
u.ids.push_back(sky->radiance);
uniforms.push_back(u);
@@ -2002,25 +2007,25 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader,
return sky->uniform_set;
}
-RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) {
+RID RendererSceneRenderRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) {
if (p_sky->texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(p_sky->texture_uniform_sets[p_version])) {
return p_sky->texture_uniform_sets[p_version];
}
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
if (p_sky->radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) {
u.ids.push_back(p_sky->radiance);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1; // half res
if (p_sky->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) {
@@ -2030,16 +2035,16 @@ RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_vers
}
} else {
if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
}
}
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2; // quarter res
if (p_sky->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) {
@@ -2049,9 +2054,9 @@ RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_vers
}
} else {
if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
}
}
uniforms.push_back(u);
@@ -2061,14 +2066,14 @@ RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_vers
return p_sky->texture_uniform_sets[p_version];
}
-RID RasterizerSceneRD::sky_get_material(RID p_sky) const {
+RID RendererSceneRenderRD::sky_get_material(RID p_sky) const {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND_V(!sky, RID());
return sky->material;
}
-void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
+void RendererSceneRenderRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
ERR_FAIL_COND(!is_environment(p_environment));
SkyMaterialData *material = nullptr;
@@ -2084,7 +2089,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
sky_material = sky_get_material(environment_get_sky(p_environment));
if (sky_material.is_valid()) {
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@@ -2092,13 +2097,13 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
if (!material) {
sky_material = sky_shader.default_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
}
}
if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
sky_material = sky_scene_state.fog_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);
@@ -2129,7 +2134,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
sky_transform = p_transform.basis * sky_transform;
if (shader_data->uses_quarter_res) {
- RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_QUARTER_RES];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_QUARTER_RES];
RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_QUARTER_RES);
@@ -2142,7 +2147,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
}
if (shader_data->uses_half_res) {
- RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_HALF_RES];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_HALF_RES];
RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_HALF_RES);
@@ -2154,7 +2159,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
RD::get_singleton()->draw_list_end();
}
- RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND];
RID texture_uniform_set;
if (sky) {
@@ -2168,7 +2173,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
RD::get_singleton()->draw_list_end();
}
-void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size) {
+void RendererSceneRenderRD::_setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size) {
ERR_FAIL_COND(!is_environment(p_environment));
SkyMaterialData *material = nullptr;
@@ -2186,7 +2191,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons
sky_material = sky_get_material(environment_get_sky(p_environment));
if (sky_material.is_valid()) {
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@@ -2194,7 +2199,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons
if (!material) {
sky_material = sky_shader.default_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);
@@ -2237,7 +2242,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons
if (shader_data->uses_time && time - sky->prev_time > 0.00001) {
sky->prev_time = time;
sky->reflection.dirty = true;
- RenderingServerRaster::redraw_request();
+ RenderingServerDefault::redraw_request();
}
if (material != sky->prev_material) {
@@ -2285,7 +2290,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons
if (light_data_dirty) {
RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights, true);
- RasterizerSceneRD::SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights;
+ RendererSceneRenderRD::SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights;
sky_scene_state.last_frame_directional_lights = sky_scene_state.directional_lights;
sky_scene_state.directional_lights = temp;
sky_scene_state.last_frame_directional_light_count = sky_scene_state.ubo.directional_light_count;
@@ -2338,7 +2343,7 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, RID p_render_buffers, cons
RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo, true);
}
-void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
+void RendererSceneRenderRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
ERR_FAIL_COND(!is_environment(p_environment));
Sky *sky = sky_owner.getornull(environment_get_sky(p_environment));
@@ -2349,7 +2354,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
SkyMaterialData *material = nullptr;
if (sky_material.is_valid()) {
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@@ -2357,7 +2362,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
if (!material) {
sky_material = sky_shader.default_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);
@@ -2418,7 +2423,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
cm = correction * cm;
if (shader_data->uses_quarter_res) {
- RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES];
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -2436,7 +2441,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
}
if (shader_data->uses_half_res) {
- RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES];
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -2454,7 +2459,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
}
RD::DrawListID cubemap_draw_list;
- RenderPipelineVertexFormatCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP];
for (int i = 0; i < 6; i++) {
Transform local_view;
@@ -2505,7 +2510,7 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
/* SKY SHADER */
-void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) {
+void RendererSceneRenderRD::SkyShaderData::set_code(const String &p_code) {
//compile
code = p_code;
@@ -2554,7 +2559,7 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) {
actions.uniforms = &uniforms;
- RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton;
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
Error err = scene_singleton->sky_shader.compiler.compile(RS::SHADER_SKY, code, &actions, path, gen_code);
@@ -2599,7 +2604,7 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) {
valid = true;
}
-void RasterizerSceneRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererSceneRenderRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
if (!p_texture.is_valid()) {
default_texture_params.erase(p_name);
} else {
@@ -2607,7 +2612,7 @@ void RasterizerSceneRD::SkyShaderData::set_default_texture_param(const StringNam
}
}
-void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void RendererSceneRenderRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
@@ -2629,13 +2634,13 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para
}
}
-void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+void RendererSceneRenderRD::SkyShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
- RasterizerStorage::InstanceShaderParam p;
+ RendererStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E->get());
p.info.name = E->key(); //supply name
p.index = E->get().instance_index;
@@ -2644,7 +2649,7 @@ void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerSt
}
}
-bool RasterizerSceneRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
+bool RendererSceneRenderRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -2652,15 +2657,15 @@ bool RasterizerSceneRD::SkyShaderData::is_param_texture(const StringName &p_para
return uniforms[p_param].texture_order >= 0;
}
-bool RasterizerSceneRD::SkyShaderData::is_animated() const {
+bool RendererSceneRenderRD::SkyShaderData::is_animated() const {
return false;
}
-bool RasterizerSceneRD::SkyShaderData::casts_shadows() const {
+bool RendererSceneRenderRD::SkyShaderData::casts_shadows() const {
return false;
}
-Variant RasterizerSceneRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
+Variant RendererSceneRenderRD::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;
@@ -2669,12 +2674,18 @@ Variant RasterizerSceneRD::SkyShaderData::get_default_parameter(const StringName
return Variant();
}
-RasterizerSceneRD::SkyShaderData::SkyShaderData() {
+RS::ShaderNativeSourceCode RendererSceneRenderRD::SkyShaderData::get_native_source_code() const {
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
+
+ return scene_singleton->sky_shader.shader.version_get_native_source_code(version);
+}
+
+RendererSceneRenderRD::SkyShaderData::SkyShaderData() {
valid = false;
}
-RasterizerSceneRD::SkyShaderData::~SkyShaderData() {
- RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton;
+RendererSceneRenderRD::SkyShaderData::~SkyShaderData() {
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
ERR_FAIL_COND(!scene_singleton);
//pipeline variants will clear themselves if shader is gone
if (version.is_valid()) {
@@ -2682,13 +2693,13 @@ RasterizerSceneRD::SkyShaderData::~SkyShaderData() {
}
}
-RasterizerStorageRD::ShaderData *RasterizerSceneRD::_create_sky_shader_func() {
+RendererStorageRD::ShaderData *RendererSceneRenderRD::_create_sky_shader_func() {
SkyShaderData *shader_data = memnew(SkyShaderData);
return shader_data;
}
-void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
- RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton;
+void RendererSceneRenderRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
uniform_set_updated = true;
@@ -2750,7 +2761,7 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName,
{
if (shader_data->ubo_size) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 0;
u.ids.push_back(uniform_buffer);
uniforms.push_back(u);
@@ -2759,7 +2770,7 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName,
const RID *textures = texture_cache.ptrw();
for (uint32_t i = 0; i < tex_uniform_count; i++) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1 + i;
u.ids.push_back(textures[i]);
uniforms.push_back(u);
@@ -2769,7 +2780,7 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName,
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
}
-RasterizerSceneRD::SkyMaterialData::~SkyMaterialData() {
+RendererSceneRenderRD::SkyMaterialData::~SkyMaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
}
@@ -2779,7 +2790,7 @@ RasterizerSceneRD::SkyMaterialData::~SkyMaterialData() {
}
}
-RasterizerStorageRD::MaterialData *RasterizerSceneRD::_create_sky_material_func(SkyShaderData *p_shader) {
+RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_sky_material_func(SkyShaderData *p_shader) {
SkyMaterialData *material_data = memnew(SkyMaterialData);
material_data->shader_data = p_shader;
material_data->last_frame = false;
@@ -2787,53 +2798,53 @@ RasterizerStorageRD::MaterialData *RasterizerSceneRD::_create_sky_material_func(
return material_data;
}
-RID RasterizerSceneRD::environment_create() {
+RID RendererSceneRenderRD::environment_create() {
return environment_owner.make_rid(Environment());
}
-void RasterizerSceneRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) {
+void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->background = p_bg;
}
-void RasterizerSceneRD::environment_set_sky(RID p_env, RID p_sky) {
+void RendererSceneRenderRD::environment_set_sky(RID p_env, RID p_sky) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky = p_sky;
}
-void RasterizerSceneRD::environment_set_sky_custom_fov(RID p_env, float p_scale) {
+void RendererSceneRenderRD::environment_set_sky_custom_fov(RID p_env, float p_scale) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_custom_fov = p_scale;
}
-void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
+void RendererSceneRenderRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_orientation = p_orientation;
}
-void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) {
+void RendererSceneRenderRD::environment_set_bg_color(RID p_env, const Color &p_color) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_color = p_color;
}
-void RasterizerSceneRD::environment_set_bg_energy(RID p_env, float p_energy) {
+void RendererSceneRenderRD::environment_set_bg_energy(RID p_env, float p_energy) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_energy = p_energy;
}
-void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
+void RendererSceneRenderRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->canvas_max_layer = p_max_layer;
}
-void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) {
+void RendererSceneRenderRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->ambient_light = p_color;
@@ -2844,85 +2855,85 @@ void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_
env->ao_color = p_ao_color;
}
-RS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const {
+RS::EnvironmentBG RendererSceneRenderRD::environment_get_background(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX);
return env->background;
}
-RID RasterizerSceneRD::environment_get_sky(RID p_env) const {
+RID RendererSceneRenderRD::environment_get_sky(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RID());
return env->sky;
}
-float RasterizerSceneRD::environment_get_sky_custom_fov(RID p_env) const {
+float RendererSceneRenderRD::environment_get_sky_custom_fov(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->sky_custom_fov;
}
-Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const {
+Basis RendererSceneRenderRD::environment_get_sky_orientation(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Basis());
return env->sky_orientation;
}
-Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const {
+Color RendererSceneRenderRD::environment_get_bg_color(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->bg_color;
}
-float RasterizerSceneRD::environment_get_bg_energy(RID p_env) const {
+float RendererSceneRenderRD::environment_get_bg_energy(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->bg_energy;
}
-int RasterizerSceneRD::environment_get_canvas_max_layer(RID p_env) const {
+int RendererSceneRenderRD::environment_get_canvas_max_layer(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->canvas_max_layer;
}
-Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const {
+Color RendererSceneRenderRD::environment_get_ambient_light_color(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->ambient_light;
}
-RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_source(RID p_env) const {
+RS::EnvironmentAmbientSource RendererSceneRenderRD::environment_get_ambient_source(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG);
return env->ambient_source;
}
-float RasterizerSceneRD::environment_get_ambient_light_energy(RID p_env) const {
+float RendererSceneRenderRD::environment_get_ambient_light_energy(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_light_energy;
}
-float RasterizerSceneRD::environment_get_ambient_sky_contribution(RID p_env) const {
+float RendererSceneRenderRD::environment_get_ambient_sky_contribution(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_sky_contribution;
}
-RS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_source(RID p_env) const {
+RS::EnvironmentReflectionSource RendererSceneRenderRD::environment_get_reflection_source(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED);
return env->reflection_source;
}
-Color RasterizerSceneRD::environment_get_ao_color(RID p_env) const {
+Color RendererSceneRenderRD::environment_get_ao_color(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->ao_color;
}
-void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
+void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->exposure = p_exposure;
@@ -2938,7 +2949,7 @@ void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMa
env->auto_exp_scale = p_auto_exp_scale;
}
-void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
+void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
@@ -2954,18 +2965,22 @@ void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, Vector<fl
env->glow_hdr_luminance_cap = p_hdr_luminance_cap;
}
-void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable) {
+void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enable) {
glow_bicubic_upscale = p_enable;
}
-void RasterizerSceneRD::environment_glow_set_use_high_quality(bool p_enable) {
+void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) {
glow_high_quality = p_enable;
}
-void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
+void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+ if (low_end) {
+ return;
+ }
+
env->sdfgi_enabled = p_enable;
env->sdfgi_cascades = p_cascades;
env->sdfgi_min_cell_size = p_min_cell_size;
@@ -2978,7 +2993,7 @@ void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::Envi
env->sdfgi_y_scale = p_y_scale;
}
-void RasterizerSceneRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) {
+void RendererSceneRenderRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -2992,54 +3007,58 @@ void RasterizerSceneRD::environment_set_fog(RID p_env, bool p_enable, const Colo
env->fog_aerial_perspective = p_fog_aerial_perspective;
}
-bool RasterizerSceneRD::environment_is_fog_enabled(RID p_env) const {
+bool RendererSceneRenderRD::environment_is_fog_enabled(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->fog_enabled;
}
-Color RasterizerSceneRD::environment_get_fog_light_color(RID p_env) const {
+Color RendererSceneRenderRD::environment_get_fog_light_color(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->fog_light_color;
}
-float RasterizerSceneRD::environment_get_fog_light_energy(RID p_env) const {
+float RendererSceneRenderRD::environment_get_fog_light_energy(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_light_energy;
}
-float RasterizerSceneRD::environment_get_fog_sun_scatter(RID p_env) const {
+float RendererSceneRenderRD::environment_get_fog_sun_scatter(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_sun_scatter;
}
-float RasterizerSceneRD::environment_get_fog_density(RID p_env) const {
+float RendererSceneRenderRD::environment_get_fog_density(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_density;
}
-float RasterizerSceneRD::environment_get_fog_height(RID p_env) const {
+float RendererSceneRenderRD::environment_get_fog_height(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_height;
}
-float RasterizerSceneRD::environment_get_fog_height_density(RID p_env) const {
+float RendererSceneRenderRD::environment_get_fog_height_density(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_height_density;
}
-float RasterizerSceneRD::environment_get_fog_aerial_perspective(RID p_env) const {
+float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) const {
const Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_aerial_perspective;
}
-void RasterizerSceneRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) {
+void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+ if (low_end) {
+ return;
+ }
+
env->volumetric_fog_enabled = p_enable;
env->volumetric_fog_density = p_density;
env->volumetric_fog_light = p_light;
@@ -3050,15 +3069,15 @@ void RasterizerSceneRD::environment_set_volumetric_fog(RID p_env, bool p_enable,
env->volumetric_fog_gi_inject = p_gi_inject;
}
-void RasterizerSceneRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {
+void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {
volumetric_fog_size = p_size;
volumetric_fog_depth = p_depth;
}
-void RasterizerSceneRD::environment_set_volumetric_fog_filter_active(bool p_enable) {
+void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) {
volumetric_fog_filter_active = p_enable;
}
-void RasterizerSceneRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) {
+void RendererSceneRenderRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) {
p_shrink_size = nearest_power_of_2_templated(p_shrink_size);
if (volumetric_fog_directional_shadow_shrink == (uint32_t)p_shrink_size) {
return;
@@ -3066,7 +3085,7 @@ void RasterizerSceneRD::environment_set_volumetric_fog_directional_shadow_shrink
_clear_shadow_shrink_stages(directional_shadow.shrink_stages);
}
-void RasterizerSceneRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) {
+void RendererSceneRenderRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) {
p_shrink_size = nearest_power_of_2_templated(p_shrink_size);
if (volumetric_fog_positional_shadow_shrink == (uint32_t)p_shrink_size) {
return;
@@ -3078,18 +3097,22 @@ void RasterizerSceneRD::environment_set_volumetric_fog_positional_shadow_shrink_
}
}
-void RasterizerSceneRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {
+void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {
sdfgi_ray_count = p_ray_count;
}
-void RasterizerSceneRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {
+void RendererSceneRenderRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {
sdfgi_frames_to_converge = p_frames;
}
-void RasterizerSceneRD::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) {
+void RendererSceneRenderRD::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) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+ if (low_end) {
+ return;
+ }
+
env->ssr_enabled = p_enable;
env->ssr_max_steps = p_max_steps;
env->ssr_fade_in = p_fade_int;
@@ -3097,66 +3120,76 @@ void RasterizerSceneRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_
env->ssr_depth_tolerance = p_depth_tolerance;
}
-void RasterizerSceneRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {
+void RendererSceneRenderRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {
ssr_roughness_quality = p_quality;
}
-RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughness_quality() const {
+RS::EnvironmentSSRRoughnessQuality RendererSceneRenderRD::environment_get_ssr_roughness_quality() const {
return ssr_roughness_quality;
}
-void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {
+void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+ if (low_end) {
+ return;
+ }
+
env->ssao_enabled = p_enable;
env->ssao_radius = p_radius;
env->ssao_intensity = p_intensity;
- env->ssao_bias = p_bias;
+ env->ssao_power = p_power;
+ env->ssao_detail = p_detail;
+ env->ssao_horizon = p_horizon;
+ env->ssao_sharpness = p_sharpness;
env->ssao_direct_light_affect = p_light_affect;
env->ssao_ao_channel_affect = p_ao_channel_affect;
- env->ssao_blur = p_blur;
}
-void RasterizerSceneRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) {
+void RendererSceneRenderRD::environment_set_ssao_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) {
ssao_quality = p_quality;
ssao_half_size = p_half_size;
+ ssao_adaptive_target = p_adaptive_target;
+ ssao_blur_passes = p_blur_passes;
+ ssao_fadeout_from = p_fadeout_from;
+ ssao_fadeout_to = p_fadeout_to;
}
-bool RasterizerSceneRD::environment_is_ssao_enabled(RID p_env) const {
+bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->ssao_enabled;
}
-float RasterizerSceneRD::environment_get_ssao_ao_affect(RID p_env) const {
+float RendererSceneRenderRD::environment_get_ssao_ao_affect(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
- ERR_FAIL_COND_V(!env, false);
+ ERR_FAIL_COND_V(!env, 0.0);
return env->ssao_ao_channel_affect;
}
-float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const {
+float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
- ERR_FAIL_COND_V(!env, false);
+ ERR_FAIL_COND_V(!env, 0.0);
return env->ssao_direct_light_affect;
}
-bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const {
+bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->ssr_enabled;
}
-bool RasterizerSceneRD::environment_is_sdfgi_enabled(RID p_env) const {
+bool RendererSceneRenderRD::environment_is_sdfgi_enabled(RID p_env) const {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->sdfgi_enabled;
}
-bool RasterizerSceneRD::is_environment(RID p_env) const {
+bool RendererSceneRenderRD::is_environment(RID p_env) const {
return environment_owner.owns(p_env);
}
-Ref<Image> RasterizerSceneRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) {
+Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Ref<Image>());
@@ -3195,7 +3228,7 @@ Ref<Image> RasterizerSceneRD::environment_bake_panorama(RID p_env, bool p_bake_i
////////////////////////////////////////////////////////////
-RID RasterizerSceneRD::reflection_atlas_create() {
+RID RendererSceneRenderRD::reflection_atlas_create() {
ReflectionAtlas ra;
ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count");
ra.size = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_size");
@@ -3203,7 +3236,7 @@ RID RasterizerSceneRD::reflection_atlas_create() {
return reflection_atlas_owner.make_rid(ra);
}
-void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {
+void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {
ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas);
ERR_FAIL_COND(!ra);
@@ -3234,14 +3267,21 @@ void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflect
}
}
+int RendererSceneRenderRD::reflection_atlas_get_size(RID p_ref_atlas) const {
+ ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas);
+ ERR_FAIL_COND_V(!ra, 0);
+
+ return ra->size;
+}
+
////////////////////////
-RID RasterizerSceneRD::reflection_probe_instance_create(RID p_probe) {
+RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) {
ReflectionProbeInstance rpi;
rpi.probe = p_probe;
return reflection_probe_instance_owner.make_rid(rpi);
}
-void RasterizerSceneRD::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) {
+void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND(!rpi);
@@ -3249,7 +3289,7 @@ void RasterizerSceneRD::reflection_probe_instance_set_transform(RID p_instance,
rpi->dirty = true;
}
-void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) {
+void RendererSceneRenderRD::reflection_probe_release_atlas_index(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND(!rpi);
@@ -3264,7 +3304,7 @@ void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) {
rpi->atlas = RID();
}
-bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) {
+bool RendererSceneRenderRD::reflection_probe_instance_needs_redraw(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
@@ -3283,14 +3323,14 @@ bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) {
return rpi->atlas_index == -1;
}
-bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance) {
+bool RendererSceneRenderRD::reflection_probe_instance_has_reflection(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
return rpi->atlas.is_valid();
}
-bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
+bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_reflection_atlas);
ERR_FAIL_COND_V(!atlas, false);
@@ -3326,7 +3366,7 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R
RD::TextureFormat tf;
tf.array_layers = 6 * atlas->count;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
tf.mipmaps = mipmaps;
tf.width = atlas->size;
tf.height = atlas->size;
@@ -3389,7 +3429,7 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R
return true;
}
-bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instance) {
+bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
ERR_FAIL_COND_V(!rpi->rendering, false);
@@ -3435,7 +3475,7 @@ bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instanc
return false;
}
-uint32_t RasterizerSceneRD::reflection_probe_instance_get_resolution(RID p_instance) {
+uint32_t RendererSceneRenderRD::reflection_probe_instance_get_resolution(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, 0);
@@ -3444,7 +3484,7 @@ uint32_t RasterizerSceneRD::reflection_probe_instance_get_resolution(RID p_insta
return atlas->size;
}
-RID RasterizerSceneRD::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) {
+RID RendererSceneRenderRD::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, RID());
ERR_FAIL_INDEX_V(p_index, 6, RID());
@@ -3454,7 +3494,7 @@ RID RasterizerSceneRD::reflection_probe_instance_get_framebuffer(RID p_instance,
return atlas->reflections[rpi->atlas_index].fbs[p_index];
}
-RID RasterizerSceneRD::reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index) {
+RID RendererSceneRenderRD::reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, RID());
ERR_FAIL_INDEX_V(p_index, 6, RID());
@@ -3466,11 +3506,11 @@ RID RasterizerSceneRD::reflection_probe_instance_get_depth_framebuffer(RID p_ins
///////////////////////////////////////////////////////////
-RID RasterizerSceneRD::shadow_atlas_create() {
+RID RendererSceneRenderRD::shadow_atlas_create() {
return shadow_atlas_owner.make_rid(ShadowAtlas());
}
-void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
+void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND(!shadow_atlas);
ERR_FAIL_COND(p_size < 0);
@@ -3515,7 +3555,7 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
}
}
-void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
+void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND(!shadow_atlas);
ERR_FAIL_INDEX(p_quadrant, 4);
@@ -3577,7 +3617,7 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p
} while (swaps > 0);
}
-bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) {
+bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) {
for (int i = p_quadrant_count - 1; i >= 0; i--) {
int qidx = p_in_quadrants[i];
@@ -3632,7 +3672,7 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int
return false;
}
-bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
+bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND_V(!shadow_atlas, false);
@@ -3767,7 +3807,7 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan
return false;
}
-void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
+void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
p_size = nearest_power_of_2_templated(p_size);
if (directional_shadow.size == p_size) {
@@ -3795,7 +3835,7 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
_base_uniforms_changed();
}
-void RasterizerSceneRD::set_directional_shadow_count(int p_count) {
+void RendererSceneRenderRD::set_directional_shadow_count(int p_count) {
directional_shadow.light_count = p_count;
directional_shadow.current_light = 0;
}
@@ -3822,7 +3862,7 @@ static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p
return rect;
}
-int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) {
+int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance) {
ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0);
Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0);
@@ -3846,20 +3886,20 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) {
//////////////////////////////////////////////////
-RID RasterizerSceneRD::camera_effects_create() {
+RID RendererSceneRenderRD::camera_effects_create() {
return camera_effects_owner.make_rid(CameraEffects());
}
-void RasterizerSceneRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) {
+void RendererSceneRenderRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) {
dof_blur_quality = p_quality;
dof_blur_use_jitter = p_use_jitter;
}
-void RasterizerSceneRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) {
+void RendererSceneRenderRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) {
dof_blur_bokeh_shape = p_shape;
}
-void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) {
+void RendererSceneRenderRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) {
CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects);
ERR_FAIL_COND(!camfx);
@@ -3874,7 +3914,7 @@ void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p
camfx->dof_blur_amount = p_amount;
}
-void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) {
+void RendererSceneRenderRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) {
CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects);
ERR_FAIL_COND(!camfx);
@@ -3882,7 +3922,7 @@ void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects,
camfx->override_exposure = p_exposure;
}
-RID RasterizerSceneRD::light_instance_create(RID p_light) {
+RID RendererSceneRenderRD::light_instance_create(RID p_light) {
RID li = light_instance_owner.make_rid(LightInstance());
LightInstance *light_instance = light_instance_owner.getornull(li);
@@ -3894,21 +3934,21 @@ RID RasterizerSceneRD::light_instance_create(RID p_light) {
return li;
}
-void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
+void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
light_instance->transform = p_transform;
}
-void RasterizerSceneRD::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {
+void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
light_instance->aabb = p_aabb;
}
-void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
+void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -3928,14 +3968,14 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance
light_instance->shadow_transform[p_pass].uv_scale = p_uv_scale;
}
-void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) {
+void RendererSceneRenderRD::light_instance_mark_visible(RID p_light_instance) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
light_instance->last_scene_pass = scene_pass;
}
-RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_size) {
+RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap(int p_size) {
if (!shadow_cubemaps.has(p_size)) {
ShadowCubemap sc;
{
@@ -3943,7 +3983,7 @@ RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_s
tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
tf.width = p_size;
tf.height = p_size;
- tf.type = RD::TEXTURE_TYPE_CUBE;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE;
tf.array_layers = 6;
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
sc.cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -3962,7 +4002,7 @@ RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_s
return &shadow_cubemaps[p_size];
}
-RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p_size) {
+RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) {
if (!shadow_maps.has(p_size)) {
ShadowMap sm;
{
@@ -3987,13 +4027,13 @@ RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p
//////////////////////////
-RID RasterizerSceneRD::decal_instance_create(RID p_decal) {
+RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {
DecalInstance di;
di.decal = p_decal;
return decal_instance_owner.make_rid(di);
}
-void RasterizerSceneRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) {
+void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) {
DecalInstance *di = decal_instance_owner.getornull(p_decal);
ERR_FAIL_COND(!di);
di->transform = p_transform;
@@ -4001,32 +4041,53 @@ void RasterizerSceneRD::decal_instance_set_transform(RID p_decal, const Transfor
/////////////////////////////////
-RID RasterizerSceneRD::gi_probe_instance_create(RID p_base) {
+RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) {
+ LightmapInstance li;
+ li.lightmap = p_lightmap;
+ return lightmap_instance_owner.make_rid(li);
+}
+void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) {
+ LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap);
+ ERR_FAIL_COND(!li);
+ li->transform = p_transform;
+}
+
+/////////////////////////////////
+
+RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) {
GIProbeInstance gi_probe;
gi_probe.probe = p_base;
RID rid = gi_probe_instance_owner.make_rid(gi_probe);
return rid;
}
-void RasterizerSceneRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
+void RendererSceneRenderRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->transform = p_xform;
}
-bool RasterizerSceneRD::gi_probe_needs_update(RID p_probe) const {
+bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gi_probe, false);
+ if (low_end) {
+ return false;
+ }
+
//return true;
return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
}
-void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {
+void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gi_probe);
+ if (low_end) {
+ return;
+ }
+
uint32_t data_version = storage->gi_probe_get_data_version(gi_probe->probe);
// (RE)CREATE IF NEEDED
@@ -4057,7 +4118,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
tf.width = octree_size.x;
tf.height = octree_size.y;
tf.depth = octree_size.z;
- tf.type = RD::TEXTURE_TYPE_3D;
+ tf.texture_type = RD::TEXTURE_TYPE_3D;
tf.mipmaps = levels.size();
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
@@ -4088,14 +4149,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
u.ids.push_back(storage->gi_probe_get_octree_buffer(gi_probe->probe));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
u.ids.push_back(storage->gi_probe_get_data_buffer(gi_probe->probe));
uniforms.push_back(u);
@@ -4103,21 +4164,21 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 4;
u.ids.push_back(gi_probe->write_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 10;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -4128,7 +4189,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
if (i == 0) {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 3;
u.ids.push_back(gi_probe_lights_uniform);
copy_uniforms.push_back(u);
@@ -4140,7 +4201,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 5;
u.ids.push_back(gi_probe->texture);
copy_uniforms.push_back(u);
@@ -4153,7 +4214,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 5;
u.ids.push_back(mipmap.texture);
uniforms.push_back(u);
@@ -4227,7 +4288,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 3;
u.ids.push_back(gi_probe_lights_uniform);
uniforms.push_back(u);
@@ -4235,56 +4296,56 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 5;
u.ids.push_back(dmap.albedo);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 6;
u.ids.push_back(dmap.normal);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 7;
u.ids.push_back(dmap.orm);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 8;
u.ids.push_back(dmap.fb_depth);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 10;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 11;
u.ids.push_back(dmap.texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 12;
u.ids.push_back(dmap.depth);
uniforms.push_back(u);
@@ -4300,14 +4361,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 5;
u.ids.push_back(gi_probe->dynamic_maps[gi_probe->dynamic_maps.size() - 1].texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 6;
u.ids.push_back(gi_probe->dynamic_maps[gi_probe->dynamic_maps.size() - 1].depth);
uniforms.push_back(u);
@@ -4316,14 +4377,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
if (write) {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 7;
u.ids.push_back(dmap.texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 8;
u.ids.push_back(dmap.depth);
uniforms.push_back(u);
@@ -4332,14 +4393,14 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 10;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -4348,14 +4409,17 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
if (plot) {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 11;
u.ids.push_back(gi_probe->mipmaps[dmap.mipmap].texture);
uniforms.push_back(u);
}
}
- dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT], 0);
+ dmap.uniform_set = RD::get_singleton()->uniform_set_create(
+ uniforms,
+ giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)],
+ 0);
}
gi_probe->dynamic_maps.push_back(dmap);
@@ -4378,7 +4442,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
uint32_t light_count = 0;
- if (p_update_light_instances || p_dynamic_object_count > 0) {
+ if (p_update_light_instances || p_dynamic_objects.size() > 0) {
light_count = MIN(gi_probe_max_lights, (uint32_t)p_light_instances.size());
{
@@ -4392,6 +4456,11 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
RID light = light_instance_get_base_light(light_instance);
l.type = storage->light_get_type(light);
+ if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_is_sky_only(light)) {
+ light_count--;
+ continue;
+ }
+
l.attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
l.energy = storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
l.radius = to_cell.basis.xform(Vector3(storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();
@@ -4423,7 +4492,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
}
}
- if (gi_probe->has_dynamic_object_data || p_update_light_instances || p_dynamic_object_count) {
+ if (gi_probe->has_dynamic_object_data || p_update_light_instances || p_dynamic_objects.size()) {
// PROCESS MIPMAPS
if (gi_probe->mipmaps.size()) {
//can update mipmaps
@@ -4516,7 +4585,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
gi_probe->has_dynamic_object_data = false; //clear until dynamic object data is used again
- if (p_dynamic_object_count && gi_probe->dynamic_maps.size()) {
+ if (p_dynamic_objects.size() && gi_probe->dynamic_maps.size()) {
Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe);
int multiplier = gi_probe->dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
@@ -4530,14 +4599,11 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
AABB probe_aabb(Vector3(), octree_size);
//this could probably be better parallelized in compute..
- for (int i = 0; i < p_dynamic_object_count; i++) {
- InstanceBase *instance = p_dynamic_objects[i];
- //not used, so clear
- instance->depth_layer = 0;
- instance->depth = 0;
+ for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {
+ GeometryInstance *instance = p_dynamic_objects[i];
//transform aabb to giprobe
- AABB aabb = (to_probe_xform * instance->transform).xform(instance->aabb);
+ AABB aabb = (to_probe_xform * geometry_instance_get_transform(instance)).xform(geometry_instance_get_aabb(instance));
//this needs to wrap to grid resolution to avoid jitter
//also extend margin a bit just in case
@@ -4601,7 +4667,12 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
CameraMatrix cm;
cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);
- _render_material(to_world_xform * xform, cm, true, &instance, 1, gi_probe->dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size));
+ if (cull_argument.size() == 0) {
+ cull_argument.push_back(nullptr);
+ }
+ cull_argument[0] = instance;
+
+ _render_material(to_world_xform * xform, cm, true, cull_argument, gi_probe->dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size));
GIProbeDynamicPushConstant push_constant;
zeromem(&push_constant, sizeof(GIProbeDynamicPushConstant));
@@ -4718,7 +4789,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
gi_probe->last_probe_version = storage->gi_probe_get_version(gi_probe->probe);
}
-void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
+void RendererSceneRenderRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -4754,21 +4825,21 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
u.ids.push_back(storage->gi_probe_get_data_buffer(gi_probe->probe));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2;
u.ids.push_back(gi_probe->texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 3;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -4782,13 +4853,22 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis
}
giprobe_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_debug_shader_version_shaders[0], 0);
- RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, giprobe_debug_shader_version_pipelines[p_emission ? GI_PROBE_DEBUG_EMISSION : p_lighting ? (gi_probe->has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT) : GI_PROBE_DEBUG_COLOR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
+
+ int giprobe_debug_pipeline = GI_PROBE_DEBUG_COLOR;
+ if (p_emission) {
+ giprobe_debug_pipeline = GI_PROBE_DEBUG_EMISSION;
+ } else if (p_lighting) {
+ giprobe_debug_pipeline = gi_probe->has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT;
+ }
+ RD::get_singleton()->draw_list_bind_render_pipeline(
+ p_draw_list,
+ giprobe_debug_shader_version_pipelines[giprobe_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, giprobe_debug_uniform_set, 0);
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(GIProbeDebugPushConstant));
RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36);
}
-void RasterizerSceneRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
+void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -4827,28 +4907,28 @@ void RasterizerSceneRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID
{
RD::Uniform u;
u.binding = 1;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(rb->sdfgi->cascades_ubo);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 2;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(rb->sdfgi->lightprobe_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 3;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 4;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(rb->sdfgi->occlusion_texture);
uniforms.push_back(u);
}
@@ -4925,13 +5005,13 @@ void RasterizerSceneRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID
}
////////////////////////////////
-RID RasterizerSceneRD::render_buffers_create() {
+RID RendererSceneRenderRD::render_buffers_create() {
RenderBuffers rb;
rb.data = _create_render_buffer_data();
return render_buffers_owner.make_rid(rb);
}
-void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
+void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) {
ERR_FAIL_COND(!rb->blur[0].texture.is_null());
uint32_t mipmaps_required = Image::get_image_required_mipmaps(rb->width, rb->height, Image::FORMAT_RGBAH);
@@ -4940,7 +5020,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = rb->width;
tf.height = rb->height;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tf.mipmaps = mipmaps_required;
@@ -4974,7 +5054,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
}
}
-void RasterizerSceneRD::_allocate_luminance_textures(RenderBuffers *rb) {
+void RendererSceneRenderRD::_allocate_luminance_textures(RenderBuffers *rb) {
ERR_FAIL_COND(!rb->luminance.current.is_null());
int w = rb->width;
@@ -5007,7 +5087,7 @@ void RasterizerSceneRD::_allocate_luminance_textures(RenderBuffers *rb) {
}
}
-void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) {
+void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
if (rb->texture.is_valid()) {
RD::get_singleton()->free(rb->texture);
rb->texture = RID();
@@ -5040,21 +5120,24 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->luminance.current = RID();
}
- if (rb->ssao.ao[0].is_valid()) {
+ if (rb->ssao.depth.is_valid()) {
RD::get_singleton()->free(rb->ssao.depth);
- RD::get_singleton()->free(rb->ssao.ao[0]);
- if (rb->ssao.ao[1].is_valid()) {
- RD::get_singleton()->free(rb->ssao.ao[1]);
- }
- if (rb->ssao.ao_full.is_valid()) {
- RD::get_singleton()->free(rb->ssao.ao_full);
- }
+ RD::get_singleton()->free(rb->ssao.ao_deinterleaved);
+ RD::get_singleton()->free(rb->ssao.ao_pong);
+ RD::get_singleton()->free(rb->ssao.ao_final);
+
+ RD::get_singleton()->free(rb->ssao.importance_map[0]);
+ RD::get_singleton()->free(rb->ssao.importance_map[1]);
rb->ssao.depth = RID();
- rb->ssao.ao[0] = RID();
- rb->ssao.ao[1] = RID();
- rb->ssao.ao_full = RID();
+ rb->ssao.ao_deinterleaved = RID();
+ rb->ssao.ao_pong = RID();
+ rb->ssao.ao_final = RID();
+ rb->ssao.importance_map[0] = RID();
+ rb->ssao.importance_map[1] = RID();
rb->ssao.depth_slices.clear();
+ rb->ssao.ao_deinterleaved_slices.clear();
+ rb->ssao.ao_pong_slices.clear();
}
if (rb->ssr.blur_radius[0].is_valid()) {
@@ -5072,7 +5155,7 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) {
}
}
-void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
+void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -5091,7 +5174,7 @@ void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p
storage->get_effects()->sub_surface_scattering(rb->texture, rb->blur[0].mipmaps[0].texture, rb->depth_texture, p_camera, Size2i(rb->width, rb->height), sss_scale, sss_depth_scale, sss_quality);
}
-void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) {
+void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -5113,7 +5196,7 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
tf.width = rb->width / 2;
tf.height = rb->height / 2;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
rb->ssr.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -5128,7 +5211,7 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe
tf.format = RD::DATA_FORMAT_R8_UNORM;
tf.width = rb->width / 2;
tf.height = rb->height / 2;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
rb->ssr.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -5144,7 +5227,7 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe
storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->texture, rb->blur[0].mipmaps[1].texture);
}
-void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) {
+void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -5153,67 +5236,135 @@ void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, R
RENDER_TIMESTAMP("Process SSAO");
- if (rb->ssao.ao[0].is_valid() && rb->ssao.ao_full.is_valid() != ssao_half_size) {
+ if (rb->ssao.ao_final.is_valid() && ssao_using_half_size != ssao_half_size) {
RD::get_singleton()->free(rb->ssao.depth);
- RD::get_singleton()->free(rb->ssao.ao[0]);
- if (rb->ssao.ao[1].is_valid()) {
- RD::get_singleton()->free(rb->ssao.ao[1]);
- }
- if (rb->ssao.ao_full.is_valid()) {
- RD::get_singleton()->free(rb->ssao.ao_full);
- }
+ RD::get_singleton()->free(rb->ssao.ao_deinterleaved);
+ RD::get_singleton()->free(rb->ssao.ao_pong);
+ RD::get_singleton()->free(rb->ssao.ao_final);
+
+ RD::get_singleton()->free(rb->ssao.importance_map[0]);
+ RD::get_singleton()->free(rb->ssao.importance_map[1]);
rb->ssao.depth = RID();
- rb->ssao.ao[0] = RID();
- rb->ssao.ao[1] = RID();
- rb->ssao.ao_full = RID();
+ rb->ssao.ao_deinterleaved = RID();
+ rb->ssao.ao_pong = RID();
+ rb->ssao.ao_final = RID();
+ rb->ssao.importance_map[0] = RID();
+ rb->ssao.importance_map[1] = RID();
rb->ssao.depth_slices.clear();
+ rb->ssao.ao_deinterleaved_slices.clear();
+ rb->ssao.ao_pong_slices.clear();
+ }
+
+ int buffer_width;
+ int buffer_height;
+ int half_width;
+ int half_height;
+ if (ssao_half_size) {
+ buffer_width = (rb->width + 3) / 4;
+ buffer_height = (rb->height + 3) / 4;
+ half_width = (rb->width + 7) / 8;
+ half_height = (rb->height + 7) / 8;
+ } else {
+ buffer_width = (rb->width + 1) / 2;
+ buffer_height = (rb->height + 1) / 2;
+ half_width = (rb->width + 3) / 4;
+ half_height = (rb->height + 3) / 4;
}
-
- if (!rb->ssao.ao[0].is_valid()) {
+ bool uniform_sets_are_invalid = false;
+ if (rb->ssao.depth.is_null()) {
//allocate depth slices
{
RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- tf.width = rb->width / 2;
- tf.height = rb->height / 2;
- tf.mipmaps = Image::get_image_required_mipmaps(tf.width, tf.height, Image::FORMAT_RF) + 1;
+ tf.format = RD::DATA_FORMAT_R16_SFLOAT;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = buffer_width;
+ tf.height = buffer_height;
+ tf.mipmaps = 4;
+ tf.array_layers = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->ssao.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
for (uint32_t i = 0; i < tf.mipmaps; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.depth, 0, i);
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.depth, 0, i, RD::TEXTURE_SLICE_2D_ARRAY);
rb->ssao.depth_slices.push_back(slice);
}
}
{
RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = ssao_half_size ? rb->width / 2 : rb->width;
- tf.height = ssao_half_size ? rb->height / 2 : rb->height;
+ tf.format = RD::DATA_FORMAT_R8G8_UNORM;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = buffer_width;
+ tf.height = buffer_height;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->ssao.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_deinterleaved, i, 0);
+ rb->ssao.ao_deinterleaved_slices.push_back(slice);
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8G8_UNORM;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = buffer_width;
+ tf.height = buffer_height;
+ tf.array_layers = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ssao.ao[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- rb->ssao.ao[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->ssao.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_pong, i, 0);
+ rb->ssao.ao_pong_slices.push_back(slice);
+ }
}
- if (ssao_half_size) {
- //upsample texture
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = half_width;
+ tf.height = half_height;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->ssao.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->ssao.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ }
+ {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8_UNORM;
tf.width = rb->width;
tf.height = rb->height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ssao.ao_full = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->ssao.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ _render_buffers_uniform_set_changed(p_render_buffers);
}
-
- _render_buffers_uniform_set_changed(p_render_buffers);
+ ssao_using_half_size = ssao_half_size;
+ uniform_sets_are_invalid = true;
}
- storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, Size2i(rb->width, rb->height), rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao[0], rb->ssao.ao_full.is_valid(), rb->ssao.ao[1], rb->ssao.ao_full, env->ssao_intensity, env->ssao_radius, env->ssao_bias, p_projection, ssao_quality, env->ssao_blur, env->ssao_blur_edge_sharpness);
+ EffectsRD::SSAOSettings settings;
+ settings.radius = env->ssao_radius;
+ settings.intensity = env->ssao_intensity;
+ settings.power = env->ssao_power;
+ settings.detail = env->ssao_detail;
+ settings.horizon = env->ssao_horizon;
+ settings.sharpness = env->ssao_sharpness;
+
+ settings.quality = ssao_quality;
+ settings.half_size = ssao_half_size;
+ settings.adaptive_target = ssao_adaptive_target;
+ settings.blur_passes = ssao_blur_passes;
+ settings.fadeout_from = ssao_fadeout_from;
+ settings.fadeout_to = ssao_fadeout_to;
+ settings.full_screen_size = Size2i(rb->width, rb->height);
+ settings.half_screen_size = Size2i(buffer_width, buffer_height);
+ settings.quarter_screen_size = Size2i(half_width, half_height);
+
+ storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid);
}
-void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) {
+void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -5247,7 +5398,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
//swap final reduce with prev luminance
SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]);
- RenderingServerRaster::redraw_request(); //redraw all the time if auto exposure rendering is on
+ RenderingServerDefault::redraw_request(); //redraw all the time if auto exposure rendering is on
}
int max_glow_level = -1;
@@ -5288,21 +5439,19 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
{
//tonemap
- RasterizerEffectsRD::TonemapSettings tonemap;
-
- tonemap.color_correction_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ EffectsRD::TonemapSettings tonemap;
if (can_use_effects && env && env->auto_exposure && rb->luminance.current.is_valid()) {
tonemap.use_auto_exposure = true;
tonemap.exposure_texture = rb->luminance.current;
tonemap.auto_exposure_grey = env->auto_exp_scale;
} else {
- tonemap.exposure_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ tonemap.exposure_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
}
if (can_use_effects && env && env->glow_enabled) {
tonemap.use_glow = true;
- tonemap.glow_mode = RasterizerEffectsRD::TonemapSettings::GlowMode(env->glow_blend_mode);
+ tonemap.glow_mode = EffectsRD::TonemapSettings::GlowMode(env->glow_blend_mode);
tonemap.glow_intensity = env->glow_blend_mode == RS::ENV_GLOW_BLEND_MODE_MIX ? env->glow_mix : env->glow_intensity;
for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) {
tonemap.glow_levels[i] = env->glow_levels[i];
@@ -5312,7 +5461,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale;
tonemap.glow_texture = rb->blur[1].texture;
} else {
- tonemap.glow_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ tonemap.glow_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
}
if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) {
@@ -5328,14 +5477,30 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
tonemap.exposure = env->exposure;
}
+ tonemap.use_color_correction = false;
+ tonemap.use_1d_color_correction = false;
+ tonemap.color_correction_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+
+ if (can_use_effects && env) {
+ tonemap.use_bcs = env->adjustments_enabled;
+ tonemap.brightness = env->adjustments_brightness;
+ tonemap.contrast = env->adjustments_contrast;
+ tonemap.saturation = env->adjustments_saturation;
+ if (env->adjustments_enabled && env->color_correction.is_valid()) {
+ tonemap.use_color_correction = true;
+ tonemap.use_1d_color_correction = env->use_1d_color_correction;
+ tonemap.color_correction_texture = storage->texture_get_rd_texture(env->color_correction);
+ }
+ }
+
storage->get_effects()->tonemapper(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), tonemap);
}
storage->render_target_disable_clear_request(rb->render_target);
}
-void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas) {
- RasterizerEffectsRD *effects = storage->get_effects();
+void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas) {
+ EffectsRD *effects = storage->get_effects();
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -5376,9 +5541,9 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
}
}
- if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao[0].is_valid()) {
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao_final.is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- RID ao_buf = rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0];
+ RID ao_buf = rb->ssao.ao_final;
effects->copy_to_fb_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
}
@@ -5395,7 +5560,19 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
}
}
-void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform) {
+void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) {
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->adjustments_enabled = p_enable;
+ env->adjustments_brightness = p_brightness;
+ env->adjustments_contrast = p_contrast;
+ env->adjustments_saturation = p_saturation;
+ env->use_1d_color_correction = p_use_1d_color_correction;
+ env->color_correction = p_color_correction;
+}
+
+void RendererSceneRenderRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -5408,12 +5585,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr
{
RD::Uniform u;
u.binding = 1;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
if (i < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[i].sdf_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -5421,12 +5598,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr
{
RD::Uniform u;
u.binding = 2;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
if (i < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[i].light_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -5434,12 +5611,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr
{
RD::Uniform u;
u.binding = 3;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
if (i < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[i].light_aniso_0_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -5447,12 +5624,12 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr
{
RD::Uniform u;
u.binding = 4;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
if (i < rb->sdfgi->cascades.size()) {
u.ids.push_back(rb->sdfgi->cascades[i].light_aniso_1_tex);
} else {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
}
uniforms.push_back(u);
@@ -5460,35 +5637,35 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr
{
RD::Uniform u;
u.binding = 5;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(rb->sdfgi->occlusion_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 8;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 9;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(rb->sdfgi->cascades_ubo);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 10;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.ids.push_back(rb->texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 11;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(rb->sdfgi->lightprobe_texture);
uniforms.push_back(u);
}
@@ -5541,7 +5718,7 @@ void RasterizerSceneRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatr
storage->get_effects()->copy_to_fb_rect(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), true);
}
-RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) {
+RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
if (!rb->blur[0].texture.is_valid()) {
@@ -5550,14 +5727,14 @@ RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffe
return rb->blur[0].texture;
}
-RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) {
+RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- return rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0];
+ return rb->ssao.ao_final;
}
-RID RasterizerSceneRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) {
+RID RendererSceneRenderRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
if (rb->giprobe_buffer.is_null()) {
@@ -5566,24 +5743,24 @@ RID RasterizerSceneRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers)
return rb->giprobe_buffer;
}
-RID RasterizerSceneRD::render_buffers_get_default_gi_probe_buffer() {
+RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() {
return default_giprobe_buffer;
}
-uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const {
+uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, 0);
ERR_FAIL_COND_V(!rb->sdfgi, 0);
return rb->sdfgi->cascades.size();
}
-bool RasterizerSceneRD::render_buffers_is_sdfgi_enabled(RID p_render_buffers) const {
+bool RendererSceneRenderRD::render_buffers_is_sdfgi_enabled(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, false);
return rb->sdfgi != nullptr;
}
-RID RasterizerSceneRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_buffers) const {
+RID RendererSceneRenderRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
ERR_FAIL_COND_V(!rb->sdfgi, RID());
@@ -5591,7 +5768,7 @@ RID RasterizerSceneRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_b
return rb->sdfgi->lightprobe_texture;
}
-Vector3 RasterizerSceneRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_buffers, uint32_t p_cascade) const {
+Vector3 RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_buffers, uint32_t p_cascade) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, Vector3());
ERR_FAIL_COND_V(!rb->sdfgi, Vector3());
@@ -5600,7 +5777,7 @@ Vector3 RasterizerSceneRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_
return Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + rb->sdfgi->cascades[p_cascade].position)) * rb->sdfgi->cascades[p_cascade].cell_size;
}
-Vector3i RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_render_buffers, uint32_t p_cascade) const {
+Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_render_buffers, uint32_t p_cascade) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, Vector3i());
ERR_FAIL_COND_V(!rb->sdfgi, Vector3i());
@@ -5610,14 +5787,14 @@ Vector3i RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_
return rb->sdfgi->cascades[p_cascade].position / probe_divisor;
}
-float RasterizerSceneRD::render_buffers_get_sdfgi_normal_bias(RID p_render_buffers) const {
+float RendererSceneRenderRD::render_buffers_get_sdfgi_normal_bias(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, 0);
ERR_FAIL_COND_V(!rb->sdfgi, 0);
return rb->sdfgi->normal_bias;
}
-float RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_render_buffers, uint32_t p_cascade) const {
+float RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_render_buffers, uint32_t p_cascade) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, 0);
ERR_FAIL_COND_V(!rb->sdfgi, 0);
@@ -5625,7 +5802,7 @@ float RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_rende
return float(rb->sdfgi->cascade_size) * rb->sdfgi->cascades[p_cascade].cell_size / float(rb->sdfgi->probe_axis_count - 1);
}
-uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_render_buffers) const {
+uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, 0);
ERR_FAIL_COND_V(!rb->sdfgi, 0);
@@ -5633,7 +5810,7 @@ uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_r
return rb->sdfgi->probe_axis_count;
}
-uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_size(RID p_render_buffers) const {
+uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_size(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, 0);
ERR_FAIL_COND_V(!rb->sdfgi, 0);
@@ -5641,7 +5818,7 @@ uint32_t RasterizerSceneRD::render_buffers_get_sdfgi_cascade_size(RID p_render_b
return rb->sdfgi->cascade_size;
}
-bool RasterizerSceneRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buffers) const {
+bool RendererSceneRenderRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, false);
ERR_FAIL_COND_V(!rb->sdfgi, false);
@@ -5649,14 +5826,14 @@ bool RasterizerSceneRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buf
return rb->sdfgi->uses_occlusion;
}
-float RasterizerSceneRD::render_buffers_get_sdfgi_energy(RID p_render_buffers) const {
+float RendererSceneRenderRD::render_buffers_get_sdfgi_energy(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND_V(!rb, 0);
- ERR_FAIL_COND_V(!rb->sdfgi, false);
+ ERR_FAIL_COND_V(!rb, 0.0);
+ ERR_FAIL_COND_V(!rb->sdfgi, 0.0);
return rb->sdfgi->energy;
}
-RID RasterizerSceneRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_buffers) const {
+RID RendererSceneRenderRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
ERR_FAIL_COND_V(!rb->sdfgi, RID());
@@ -5664,20 +5841,20 @@ RID RasterizerSceneRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_b
return rb->sdfgi->occlusion_texture;
}
-bool RasterizerSceneRD::render_buffers_has_volumetric_fog(RID p_render_buffers) const {
+bool RendererSceneRenderRD::render_buffers_has_volumetric_fog(RID p_render_buffers) const {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, false);
return rb->volumetric_fog != nullptr;
}
-RID RasterizerSceneRD::render_buffers_get_volumetric_fog_texture(RID p_render_buffers) {
+RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_texture(RID p_render_buffers) {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, RID());
return rb->volumetric_fog->fog_map;
}
-RID RasterizerSceneRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_render_buffers) {
+RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_render_buffers) {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
@@ -5688,18 +5865,18 @@ RID RasterizerSceneRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_r
return rb->volumetric_fog->sky_uniform_set;
}
-float RasterizerSceneRD::render_buffers_get_volumetric_fog_end(RID p_render_buffers) {
+float RendererSceneRenderRD::render_buffers_get_volumetric_fog_end(RID p_render_buffers) {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0);
return rb->volumetric_fog->length;
}
-float RasterizerSceneRD::render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers) {
+float RendererSceneRenderRD::render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers) {
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0);
return rb->volumetric_fog->spread;
}
-void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) {
+void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
rb->width = p_width;
rb->height = p_height;
@@ -5749,20 +5926,20 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren
_render_buffers_uniform_set_changed(p_render_buffers);
}
-void RasterizerSceneRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {
+void RendererSceneRenderRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {
sss_quality = p_quality;
}
-RS::SubSurfaceScatteringQuality RasterizerSceneRD::sub_surface_scattering_get_quality() const {
+RS::SubSurfaceScatteringQuality RendererSceneRenderRD::sub_surface_scattering_get_quality() const {
return sss_quality;
}
-void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) {
+void RendererSceneRenderRD::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) {
sss_scale = p_scale;
sss_depth_scale = p_depth_scale;
}
-void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) {
+void RendererSceneRenderRD::shadows_quality_set(RS::ShadowQuality p_quality) {
ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
if (shadows_quality != p_quality) {
@@ -5802,7 +5979,7 @@ void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) {
}
}
-void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) {
+void RendererSceneRenderRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) {
ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
if (directional_shadow_quality != p_quality) {
@@ -5842,25 +6019,25 @@ void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quali
}
}
-int RasterizerSceneRD::get_roughness_layers() const {
+int RendererSceneRenderRD::get_roughness_layers() const {
return roughness_layers;
}
-bool RasterizerSceneRD::is_using_radiance_cubemap_array() const {
+bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const {
return sky_use_cubemap_array;
}
-RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data(RID p_render_buffers) {
+RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_get_data(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, nullptr);
return rb->data;
}
-void RasterizerSceneRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) {
- for (int i = 0; i < p_reflection_probe_cull_count; i++) {
- RID rpi = p_reflection_probe_cull_result[i];
+void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment) {
+ for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) {
+ RID rpi = p_reflections[i];
- if (i >= (int)cluster.max_reflections) {
+ if (i >= cluster.max_reflections) {
reflection_probe_instance_set_render_index(rpi, 0); //invalid, but something needs to be set
continue;
}
@@ -5904,26 +6081,26 @@ void RasterizerSceneRD::_setup_reflections(RID *p_reflection_probe_cull_result,
Transform transform = reflection_probe_instance_get_transform(rpi);
Transform proj = (p_camera_inverse_transform * transform).inverse();
- RasterizerStorageRD::store_transform(proj, reflection_ubo.local_matrix);
+ RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix);
cluster.builder.add_reflection_probe(transform, extents);
reflection_probe_instance_set_render_pass(rpi, RSG::rasterizer->get_frame_number());
}
- if (p_reflection_probe_cull_count) {
- RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, MIN(cluster.max_reflections, (unsigned int)p_reflection_probe_cull_count) * sizeof(ReflectionData), cluster.reflections, true);
+ if (p_reflections.size()) {
+ RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, MIN(cluster.max_reflections, (unsigned int)p_reflections.size()) * sizeof(ReflectionData), cluster.reflections, true);
}
}
-void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
+void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
uint32_t light_count = 0;
r_directional_light_count = 0;
r_positional_light_count = 0;
sky_scene_state.ubo.directional_light_count = 0;
- for (int i = 0; i < p_light_cull_count; i++) {
- RID li = p_light_cull_result[i];
+ for (int i = 0; i < (int)p_lights.size(); i++) {
+ RID li = p_lights[i];
RID base = light_instance_get_base_light(li);
ERR_CONTINUE(base.is_null());
@@ -5931,7 +6108,40 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
RS::LightType type = storage->light_get_type(base);
switch (type) {
case RS::LIGHT_DIRECTIONAL: {
- if (r_directional_light_count >= cluster.max_directional_lights) {
+ // Copy to SkyDirectionalLightData
+ if (r_directional_light_count < sky_scene_state.max_directional_lights) {
+ SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count];
+ Transform light_transform = light_instance_get_base_transform(li);
+ Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
+
+ sky_light_data.direction[0] = world_direction.x;
+ sky_light_data.direction[1] = world_direction.y;
+ sky_light_data.direction[2] = -world_direction.z;
+
+ float sign = storage->light_is_negative(base) ? -1 : 1;
+ sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
+
+ Color linear_col = storage->light_get_color(base).to_linear();
+ sky_light_data.color[0] = linear_col.r;
+ sky_light_data.color[1] = linear_col.g;
+ sky_light_data.color[2] = linear_col.b;
+
+ sky_light_data.enabled = true;
+
+ float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+ if (angular_diameter > 0.0) {
+ // I know tan(0) is 0, but let's not risk it with numerical precision.
+ // technically this will keep expanding until reaching the sun, but all we care
+ // is expand until we reach the radius of the near plane (there can't be more occluders than that)
+ angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
+ } else {
+ angular_diameter = 0.0;
+ }
+ sky_light_data.size = angular_diameter;
+ sky_scene_state.ubo.directional_light_count++;
+ }
+
+ if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) {
continue;
}
@@ -6037,7 +6247,7 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale;
light_data.shadow_z_range[j] = light_instance_get_shadow_range(li, j);
light_data.shadow_range_begin[j] = light_instance_get_shadow_range_begin(li, j);
- RasterizerStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
+ RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
Vector2 uv_scale = light_instance_get_shadow_uv_scale(li, j);
uv_scale *= atlas_rect.size; //adapt to atlas size
@@ -6074,27 +6284,6 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
}
}
- // Copy to SkyDirectionalLightData
- if (r_directional_light_count < sky_scene_state.max_directional_lights) {
- SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count];
-
- Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
-
- sky_light_data.direction[0] = world_direction.x;
- sky_light_data.direction[1] = world_direction.y;
- sky_light_data.direction[2] = -world_direction.z;
-
- sky_light_data.energy = light_data.energy / Math_PI;
-
- sky_light_data.color[0] = light_data.color[0];
- sky_light_data.color[1] = light_data.color[1];
- sky_light_data.color[2] = light_data.color[2];
-
- sky_light_data.enabled = true;
- sky_light_data.size = angular_diameter;
- sky_scene_state.ubo.directional_light_count++;
- }
-
r_directional_light_count++;
} break;
case RS::LIGHT_SPOT:
@@ -6211,7 +6400,7 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another
Transform proj = (p_camera_inverse_transform * light_transform).inverse();
- RasterizerStorageRD::store_transform(proj, light_data.shadow_matrix);
+ RendererStorageRD::store_transform(proj, light_data.shadow_matrix);
if (size > 0.0) {
light_data.soft_shadow_size = size;
@@ -6226,7 +6415,7 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
bias.set_light_bias();
CameraMatrix shadow_mtx = bias * light_instance_get_shadow_camera(li, 0) * modelview;
- RasterizerStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix);
+ RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix);
if (size > 0.0) {
CameraMatrix cm = light_instance_get_shadow_camera(li, 0);
@@ -6264,15 +6453,15 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
}
}
-void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) {
+void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform) {
Transform uv_xform;
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
- p_decal_count = MIN((uint32_t)p_decal_count, cluster.max_decals);
+ uint32_t decal_count = MIN((uint32_t)p_decals.size(), cluster.max_decals);
int idx = 0;
- for (int i = 0; i < p_decal_count; i++) {
- RID di = p_decal_instances[i];
+ for (uint32_t i = 0; i < decal_count; i++) {
+ RID di = p_decals[i];
RID decal = decal_instance_get_base(di);
Transform xform = decal_instance_get_transform(di);
@@ -6300,7 +6489,7 @@ void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_
Transform scale_xform;
scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z));
Transform to_decal_xform = (p_camera_inverse_xform * decal_instance_get_transform(di) * scale_xform * uv_xform).affine_inverse();
- RasterizerStorageRD::store_transform(to_decal_xform, dd.xform);
+ RendererStorageRD::store_transform(to_decal_xform, dd.xform);
Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized();
normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
@@ -6338,7 +6527,7 @@ void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_
dd.normal_rect[3] = rect.size.y;
Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized();
- RasterizerStorageRD::store_basis_3x4(normal_xform, dd.normal_xform);
+ RendererStorageRD::store_basis_3x4(normal_xform, dd.normal_xform);
} else {
dd.normal_rect[0] = 0;
dd.normal_rect[1] = 0;
@@ -6394,7 +6583,7 @@ void RasterizerSceneRD::_setup_decals(const RID *p_decal_instances, int p_decal_
}
}
-void RasterizerSceneRD::_volumetric_fog_erase(RenderBuffers *rb) {
+void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
ERR_FAIL_COND(!rb->volumetric_fog);
RD::get_singleton()->free(rb->volumetric_fog->light_density_map);
@@ -6418,7 +6607,7 @@ void RasterizerSceneRD::_volumetric_fog_erase(RenderBuffers *rb) {
rb->volumetric_fog = nullptr;
}
-void RasterizerSceneRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) {
+void RendererSceneRenderRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) {
//create fog mipmaps
uint32_t fog_texture_size = p_target_size;
uint32_t base_texture_size = p_base_size;
@@ -6451,7 +6640,7 @@ void RasterizerSceneRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_si
}
}
-void RasterizerSceneRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) {
+void RendererSceneRenderRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) {
for (int i = 1; i < shrink_stages.size(); i++) {
RD::get_singleton()->free(shrink_stages[i].texture);
if (shrink_stages[i].filter_texture.is_valid()) {
@@ -6461,7 +6650,7 @@ void RasterizerSceneRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &s
shrink_stages.clear();
}
-void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) {
+void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
Environment *env = environment_owner.getornull(p_environment);
@@ -6495,7 +6684,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
tf.width = target_width;
tf.height = target_height;
tf.depth = volumetric_fog_depth;
- tf.type = RD::TEXTURE_TYPE_3D;
+ tf.texture_type = RD::TEXTURE_TYPE_3D;
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
rb->volumetric_fog->light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -6509,7 +6698,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
u.binding = 0;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(rb->volumetric_fog->fog_map);
uniforms.push_back(u);
}
@@ -6520,7 +6709,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
//update directional shadow
if (p_use_directional_shadows) {
- if (directional_shadow.shrink_stages.empty()) {
+ if (directional_shadow.shrink_stages.is_empty()) {
if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
//invalidate uniform set, we will need a new one
RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
@@ -6555,7 +6744,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
bool force_shrink_shadows = false;
- if (shadow_atlas->shrink_stages.empty()) {
+ if (shadow_atlas->shrink_stages.is_empty()) {
if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
//invalidate uniform set, we will need a new one
RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
@@ -6682,10 +6871,10 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1;
if (shadow_atlas == nullptr || shadow_atlas->shrink_stages.size() == 0) {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
} else {
u.ids.push_back(shadow_atlas->shrink_stages[shadow_atlas->shrink_stages.size() - 1].texture);
}
@@ -6695,10 +6884,10 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2;
if (directional_shadow.shrink_stages.size() == 0) {
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
} else {
u.ids.push_back(directional_shadow.shrink_stages[directional_shadow.shrink_stages.size() - 1].texture);
}
@@ -6707,7 +6896,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 3;
u.ids.push_back(get_positional_light_buffer());
uniforms.push_back(u);
@@ -6715,7 +6904,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 4;
u.ids.push_back(get_directional_light_buffer());
uniforms.push_back(u);
@@ -6723,7 +6912,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 5;
u.ids.push_back(get_cluster_builder_texture());
uniforms.push_back(u);
@@ -6731,7 +6920,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 6;
u.ids.push_back(get_cluster_builder_indices_buffer());
uniforms.push_back(u);
@@ -6739,7 +6928,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 7;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -6747,7 +6936,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 8;
u.ids.push_back(rb->volumetric_fog->light_density_map);
uniforms.push_back(u);
@@ -6755,7 +6944,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 9;
u.ids.push_back(rb->volumetric_fog->fog_map);
uniforms.push_back(u);
@@ -6763,7 +6952,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 10;
u.ids.push_back(shadow_sampler);
uniforms.push_back(u);
@@ -6771,7 +6960,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 11;
u.ids.push_back(render_buffers_get_gi_probe_buffer(p_render_buffers));
uniforms.push_back(u);
@@ -6779,7 +6968,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 12;
for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
u.ids.push_back(rb->giprobe_textures[i]);
@@ -6788,7 +6977,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 13;
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
@@ -6809,7 +6998,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 0;
u.ids.push_back(gi.sdfgi_ubo);
uniforms.push_back(u);
@@ -6817,7 +7006,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1;
u.ids.push_back(rb->sdfgi->ambient_texture);
uniforms.push_back(u);
@@ -6825,7 +7014,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2;
u.ids.push_back(rb->sdfgi->occlusion_texture);
uniforms.push_back(u);
@@ -6940,7 +7129,7 @@ void RasterizerSceneRD::_update_volumetric_fog(RID p_render_buffers, RID p_envir
RD::get_singleton()->compute_list_end();
}
-void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
+void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
Color clear_color;
if (p_render_buffers.is_valid()) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
@@ -6951,17 +7140,23 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca
}
//assign render indices to giprobes
- for (int i = 0; i < p_gi_probe_cull_count; i++) {
- GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probe_cull_result[i]);
+ for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) {
+ GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probes[i]);
if (giprobe_inst) {
giprobe_inst->render_index = i;
}
}
+ const PagedArray<RID> *lights = &p_lights;
+ const PagedArray<RID> *reflections = &p_reflection_probes;
+ const PagedArray<RID> *gi_probes = &p_gi_probes;
+
+ PagedArray<RID> empty;
+
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
- p_light_cull_count = 0;
- p_reflection_probe_cull_count = 0;
- p_gi_probe_cull_count = 0;
+ lights = &empty;
+ reflections = &empty;
+ gi_probes = &empty;
}
cluster.builder.begin(p_cam_transform.affine_inverse(), p_cam_projection); //prepare cluster
@@ -6974,17 +7169,17 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca
}
} else {
//do not render reflections when rendering a reflection probe
- _setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment);
+ _setup_reflections(*reflections, p_cam_transform.affine_inverse(), p_environment);
}
uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0;
- _setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows, directional_light_count, positional_light_count);
- _setup_decals(p_decal_cull_result, p_decal_cull_count, p_cam_transform.affine_inverse());
+ _setup_lights(*lights, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows, directional_light_count, positional_light_count);
+ _setup_decals(p_decals, p_cam_transform.affine_inverse());
cluster.builder.bake_cluster(); //bake to cluster
uint32_t gi_probe_count = 0;
- _setup_giprobes(p_render_buffers, p_cam_transform, p_gi_probe_cull_result, p_gi_probe_cull_count, gi_probe_count);
+ _setup_giprobes(p_render_buffers, p_cam_transform, *gi_probes, gi_probe_count);
if (p_render_buffers.is_valid()) {
bool directional_shadows = false;
@@ -6997,7 +7192,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca
_update_volumetric_fog(p_render_buffers, p_environment, p_cam_projection, p_cam_transform, p_shadow_atlas, directional_light_count, directional_shadows, positional_light_count, gi_probe_count);
}
- _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, directional_light_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_lightmap_cull_result, p_lightmap_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color);
+ _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, directional_light_count, *gi_probes, p_lightmaps, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold);
if (p_render_buffers.is_valid()) {
RENDER_TIMESTAMP("Tonemap");
@@ -7010,7 +7205,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca
}
}
-void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {
+void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
LightInstance *light_instance = light_instance_owner.getornull(p_light);
ERR_FAIL_COND(!light_instance);
@@ -7161,7 +7356,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
if (render_cubemap) {
//rendering to cubemap
- _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake);
+ _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
if (finalize_cubemap) {
//reblit
atlas_rect.size.height /= 2;
@@ -7172,7 +7367,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
} else {
//render shadow
- _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake);
+ _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
//copy to atlas
if (use_linear_depth) {
@@ -7186,11 +7381,11 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
}
}
-void RasterizerSceneRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
- _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_framebuffer, p_region);
+void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+ _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region);
}
-void RasterizerSceneRD::render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) {
+void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) {
//print_line("rendering region " + itos(p_region));
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -7213,7 +7408,7 @@ void RasterizerSceneRD::render_sdfgi(RID p_render_buffers, int p_region, Instanc
}
//print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(rb->sdfgi->cascades[cascade].cell_size));
- _render_sdfgi(p_render_buffers, from, size, bounds, p_cull_result, p_cull_count, rb->sdfgi->render_albedo, rb->sdfgi->render_emission, rb->sdfgi->render_emission_aniso, rb->sdfgi->render_geom_facing);
+ _render_sdfgi(p_render_buffers, from, size, bounds, p_instances, rb->sdfgi->render_albedo, rb->sdfgi->render_emission, rb->sdfgi->render_emission_aniso, rb->sdfgi->render_geom_facing);
if (cascade_next != cascade) {
RENDER_TIMESTAMP(">SDFGI Update SDF");
@@ -7289,7 +7484,6 @@ void RasterizerSceneRD::render_sdfgi(RID p_render_buffers, int p_region, Instanc
ipush_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count;
ipush_constant.image_size[1] = rb->sdfgi->probe_axis_count;
- ipush_constant.image_size[1] = rb->sdfgi->probe_axis_count;
int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
ipush_constant.cascade = cascade;
@@ -7528,7 +7722,7 @@ void RasterizerSceneRD::render_sdfgi(RID p_render_buffers, int p_region, Instanc
}
}
-void RasterizerSceneRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) {
+void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) {
ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider));
Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();
CameraMatrix cm;
@@ -7542,16 +7736,14 @@ void RasterizerSceneRD::render_particle_collider_heightfield(RID p_collider, con
RID fb = storage->particles_collision_get_heightfield_framebuffer(p_collider);
- _render_particle_collider_heightfield(fb, cam_xform, cm, p_cull_result, p_cull_count);
+ _render_particle_collider_heightfield(fb, cam_xform, cm, p_instances);
}
-void RasterizerSceneRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) {
+void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
ERR_FAIL_COND(!rb->sdfgi);
- ERR_FAIL_COND(p_positional_light_cull_count == 0);
-
_sdfgi_update_cascades(p_render_buffers); //need cascades updated for this
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -7587,7 +7779,7 @@ void RasterizerSceneRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_
int idx = 0;
- for (uint32_t j = 0; j < p_positional_light_cull_count[i]; j++) {
+ for (uint32_t j = 0; j < (uint32_t)p_positional_light_cull_result[i].size(); j++) {
if (idx == SDFGI::MAX_STATIC_LIGHTS) {
break;
}
@@ -7652,7 +7844,7 @@ void RasterizerSceneRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_
RD::get_singleton()->compute_list_end();
}
-bool RasterizerSceneRD::free(RID p_rid) {
+bool RendererSceneRenderRD::free(RID p_rid) {
if (render_buffers_owner.owns(p_rid)) {
RenderBuffers *rb = render_buffers_owner.getornull(p_rid);
_free_render_buffer_data(rb);
@@ -7680,6 +7872,8 @@ bool RasterizerSceneRD::free(RID p_rid) {
reflection_probe_instance_owner.free(p_rid);
} else if (decal_instance_owner.owns(p_rid)) {
decal_instance_owner.free(p_rid);
+ } else if (lightmap_instance_owner.owns(p_rid)) {
+ lightmap_instance_owner.free(p_rid);
} else if (gi_probe_instance_owner.owns(p_rid)) {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_rid);
if (gi_probe->texture.is_valid()) {
@@ -7751,38 +7945,38 @@ bool RasterizerSceneRD::free(RID p_rid) {
return true;
}
-void RasterizerSceneRD::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {
+void RendererSceneRenderRD::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {
debug_draw = p_debug_draw;
}
-void RasterizerSceneRD::update() {
+void RendererSceneRenderRD::update() {
_update_dirty_skys();
}
-void RasterizerSceneRD::set_time(double p_time, double p_step) {
+void RendererSceneRenderRD::set_time(double p_time, double p_step) {
time = p_time;
time_step = p_step;
}
-void RasterizerSceneRD::screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) {
+void RendererSceneRenderRD::screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) {
screen_space_roughness_limiter = p_enable;
screen_space_roughness_limiter_amount = p_amount;
screen_space_roughness_limiter_limit = p_limit;
}
-bool RasterizerSceneRD::screen_space_roughness_limiter_is_active() const {
+bool RendererSceneRenderRD::screen_space_roughness_limiter_is_active() const {
return screen_space_roughness_limiter;
}
-float RasterizerSceneRD::screen_space_roughness_limiter_get_amount() const {
+float RendererSceneRenderRD::screen_space_roughness_limiter_get_amount() const {
return screen_space_roughness_limiter_amount;
}
-float RasterizerSceneRD::screen_space_roughness_limiter_get_limit() const {
+float RendererSceneRenderRD::screen_space_roughness_limiter_get_limit() const {
return screen_space_roughness_limiter_limit;
}
-TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) {
+TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tf.width = p_image_size.width; // Always 64x64
@@ -7815,19 +8009,27 @@ TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RI
//RID sampled_light;
- InstanceBase ins;
+ GeometryInstance *gi = geometry_instance_create(p_base);
+
+ uint32_t sc = RSG::storage->mesh_get_surface_count(p_base);
+ Vector<RID> materials;
+ materials.resize(sc);
- ins.base_type = RSG::storage->get_base_type(p_base);
- ins.base = p_base;
- ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base));
- for (int i = 0; i < ins.materials.size(); i++) {
- if (i < p_material_overrides.size()) {
- ins.materials.write[i] = p_material_overrides[i];
+ for (uint32_t i = 0; i < sc; i++) {
+ if (i < (uint32_t)p_material_overrides.size()) {
+ materials.write[i] = p_material_overrides[i];
}
}
- InstanceBase *cull = &ins;
- _render_uv2(&cull, 1, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
+ geometry_instance_set_surface_materials(gi, materials);
+
+ if (cull_argument.size() == 0) {
+ cull_argument.push_back(nullptr);
+ }
+ cull_argument[0] = gi;
+ _render_uv2(cull_argument, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
+
+ geometry_instance_free(gi);
TypedArray<Image> ret;
@@ -7873,38 +8075,42 @@ TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RI
return ret;
}
-void RasterizerSceneRD::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {
+void RendererSceneRenderRD::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {
sdfgi_debug_probe_pos = p_position;
sdfgi_debug_probe_dir = p_dir;
}
-RasterizerSceneRD *RasterizerSceneRD::singleton = nullptr;
+RendererSceneRenderRD *RendererSceneRenderRD::singleton = nullptr;
-RID RasterizerSceneRD::get_cluster_builder_texture() {
+RID RendererSceneRenderRD::get_cluster_builder_texture() {
return cluster.builder.get_cluster_texture();
}
-RID RasterizerSceneRD::get_cluster_builder_indices_buffer() {
+RID RendererSceneRenderRD::get_cluster_builder_indices_buffer() {
return cluster.builder.get_cluster_indices_buffer();
}
-RID RasterizerSceneRD::get_reflection_probe_buffer() {
+RID RendererSceneRenderRD::get_reflection_probe_buffer() {
return cluster.reflection_buffer;
}
-RID RasterizerSceneRD::get_positional_light_buffer() {
+RID RendererSceneRenderRD::get_positional_light_buffer() {
return cluster.light_buffer;
}
-RID RasterizerSceneRD::get_directional_light_buffer() {
+RID RendererSceneRenderRD::get_directional_light_buffer() {
return cluster.directional_light_buffer;
}
-RID RasterizerSceneRD::get_decal_buffer() {
+RID RendererSceneRenderRD::get_decal_buffer() {
return cluster.decal_buffer;
}
-int RasterizerSceneRD::get_max_directional_lights() const {
+int RendererSceneRenderRD::get_max_directional_lights() const {
return cluster.max_directional_lights;
}
-RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
+bool RendererSceneRenderRD::is_low_end() const {
+ return low_end;
+}
+
+RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
storage = p_storage;
singleton = this;
@@ -7913,9 +8119,15 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
// sky_use_cubemap_array = false;
- //uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
+ uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
- {
+ low_end = GLOBAL_GET("rendering/quality/rd_renderer/use_low_end_renderer");
+
+ if (textures_per_stage < 48) {
+ low_end = true;
+ }
+
+ if (!low_end) {
//kinda complicated to compute the amount of slots, we try to use as many as we can
gi_probe_max_lights = 32;
@@ -7944,7 +8156,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
}
}
- {
+ if (!low_end) {
String defines;
Vector<String> versions;
versions.push_back("\n#define MODE_DEBUG_COLOR\n");
@@ -7993,8 +8205,8 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
}
// register our shader funds
- storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
- storage->material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
+ storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
+ storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
{
ShaderCompilerRD::DefaultIdentifierActions actions;
@@ -8058,7 +8270,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
sky_shader.default_material = storage->material_create();
storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
- SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND);
sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO));
@@ -8067,7 +8279,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 0;
u.ids.resize(12);
RID *ids_ptr = u.ids.ptrw();
@@ -8088,7 +8300,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
u.ids.push_back(storage->global_variables_get_storage_buffer());
uniforms.push_back(u);
@@ -8097,7 +8309,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
{
RD::Uniform u;
u.binding = 2;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(sky_scene_state.uniform_buffer);
uniforms.push_back(u);
}
@@ -8105,7 +8317,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
{
RD::Uniform u;
u.binding = 3;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(sky_scene_state.directional_light_buffer);
uniforms.push_back(u);
}
@@ -8118,8 +8330,8 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
{
RD::Uniform u;
u.binding = 0;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- RID vfog = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
u.ids.push_back(vfog);
uniforms.push_back(u);
}
@@ -8137,144 +8349,148 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
uniforms.push_back(u);
}
sky_scene_state.fog_only_texture_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES);
}
- {
- Vector<String> preprocess_modes;
- preprocess_modes.push_back("\n#define MODE_SCROLL\n");
- preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");
- preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");
- preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");
- preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");
- preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");
- preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");
- preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");
- preprocess_modes.push_back("\n#define MODE_STORE\n");
- String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";
- sdfgi_shader.preprocess.initialize(preprocess_modes, defines);
- sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();
- for (int i = 0; i < SDGIShader::PRE_PROCESS_MAX; i++) {
- sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));
+ if (!low_end) {
+ //SDFGI
+ {
+ Vector<String> preprocess_modes;
+ preprocess_modes.push_back("\n#define MODE_SCROLL\n");
+ preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");
+ preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");
+ preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");
+ preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");
+ preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");
+ preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");
+ preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");
+ preprocess_modes.push_back("\n#define MODE_STORE\n");
+ String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";
+ sdfgi_shader.preprocess.initialize(preprocess_modes, defines);
+ sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();
+ for (int i = 0; i < SDGIShader::PRE_PROCESS_MAX; i++) {
+ sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));
+ }
}
- }
- {
- //calculate tables
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+ {
+ //calculate tables
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- Vector<String> direct_light_modes;
- direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");
- direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");
- sdfgi_shader.direct_light.initialize(direct_light_modes, defines);
- sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();
- for (int i = 0; i < SDGIShader::DIRECT_LIGHT_MODE_MAX; i++) {
- sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));
+ Vector<String> direct_light_modes;
+ direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");
+ direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");
+ sdfgi_shader.direct_light.initialize(direct_light_modes, defines);
+ sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();
+ for (int i = 0; i < SDGIShader::DIRECT_LIGHT_MODE_MAX; i++) {
+ sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));
+ }
}
- }
- {
- //calculate tables
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";
-
- Vector<String> integrate_modes;
- integrate_modes.push_back("\n#define MODE_PROCESS\n");
- integrate_modes.push_back("\n#define MODE_STORE\n");
- integrate_modes.push_back("\n#define MODE_SCROLL\n");
- integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");
- sdfgi_shader.integrate.initialize(integrate_modes, defines);
- sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();
+ {
+ //calculate tables
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+ defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";
- for (int i = 0; i < SDGIShader::INTEGRATE_MODE_MAX; i++) {
- sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));
- }
+ Vector<String> integrate_modes;
+ integrate_modes.push_back("\n#define MODE_PROCESS\n");
+ integrate_modes.push_back("\n#define MODE_STORE\n");
+ integrate_modes.push_back("\n#define MODE_SCROLL\n");
+ integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");
+ sdfgi_shader.integrate.initialize(integrate_modes, defines);
+ sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();
- {
- Vector<RD::Uniform> uniforms;
+ for (int i = 0; i < SDGIShader::INTEGRATE_MODE_MAX; i++) {
+ sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));
+ }
{
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
- uniforms.push_back(u);
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 1;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);
}
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 1;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
+ }
+ {
+ //calculate tables
+ String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+ Vector<String> gi_modes;
+ gi_modes.push_back("");
+ gi.shader.initialize(gi_modes, defines);
+ gi.shader_version = gi.shader.version_create();
+ for (int i = 0; i < GI::MODE_MAX; i++) {
+ gi.pipelines[i] = RD::get_singleton()->compute_pipeline_create(gi.shader.version_get_shader(gi.shader_version, i));
}
- sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);
+ gi.sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(GI::SDFGIData));
}
- }
- {
- //calculate tables
- String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- Vector<String> gi_modes;
- gi_modes.push_back("");
- gi.shader.initialize(gi_modes, defines);
- gi.shader_version = gi.shader.version_create();
- for (int i = 0; i < GI::MODE_MAX; i++) {
- gi.pipelines[i] = RD::get_singleton()->compute_pipeline_create(gi.shader.version_get_shader(gi.shader_version, i));
+ {
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+ Vector<String> debug_modes;
+ debug_modes.push_back("");
+ sdfgi_shader.debug.initialize(debug_modes, defines);
+ sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();
+ sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);
+ sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version);
}
+ {
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- gi.sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(GI::SDFGIData));
- }
- {
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- Vector<String> debug_modes;
- debug_modes.push_back("");
- sdfgi_shader.debug.initialize(debug_modes, defines);
- sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();
- sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);
- sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version);
- }
- {
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
-
- Vector<String> versions;
- versions.push_back("\n#define MODE_PROBES\n");
- versions.push_back("\n#define MODE_VISIBILITY\n");
+ Vector<String> versions;
+ versions.push_back("\n#define MODE_PROBES\n");
+ versions.push_back("\n#define MODE_VISIBILITY\n");
- sdfgi_shader.debug_probes.initialize(versions, defines);
- sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();
+ sdfgi_shader.debug_probes.initialize(versions, defines);
+ sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();
- {
- RD::PipelineRasterizationState rs;
- rs.cull_mode = RD::POLYGON_CULL_DISABLED;
- RD::PipelineDepthStencilState ds;
- ds.enable_depth_test = true;
- ds.enable_depth_write = true;
- ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
- for (int i = 0; i < SDGIShader::PROBE_DEBUG_MAX; i++) {
- RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);
- sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
+ {
+ RD::PipelineRasterizationState rs;
+ rs.cull_mode = RD::POLYGON_CULL_DISABLED;
+ RD::PipelineDepthStencilState ds;
+ ds.enable_depth_test = true;
+ ds.enable_depth_write = true;
+ ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
+ for (int i = 0; i < SDGIShader::PROBE_DEBUG_MAX; i++) {
+ RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);
+ sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
+ }
}
}
+ default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES);
}
//cluster setup
@@ -8303,7 +8519,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
cluster.lights_instances = memnew_arr(RID, cluster.max_lights);
cluster.lights_shadow_rect_cache = memnew_arr(Rect2i, cluster.max_lights);
- cluster.max_directional_lights = 8;
+ cluster.max_directional_lights = MAX_DIRECTIONAL_LIGHTS;
uint32_t directional_light_buffer_size = cluster.max_directional_lights * sizeof(Cluster::DirectionalLightData);
cluster.directional_lights = memnew_arr(Cluster::DirectionalLightData, cluster.max_directional_lights);
cluster.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
@@ -8318,7 +8534,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
cluster.builder.setup(16, 8, 24);
- {
+ if (!low_end) {
String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n";
Vector<String> volumetric_fog_modes;
volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n");
@@ -8331,7 +8547,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
volumetric_fog.pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, i));
}
}
- default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES);
{
RD::SamplerState sampler;
@@ -8344,7 +8559,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape"))));
camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter"));
- environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"));
+ environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"), GLOBAL_GET("rendering/quality/ssao/adaptive_target"), GLOBAL_GET("rendering/quality/ssao/blur_passes"), GLOBAL_GET("rendering/quality/ssao/fadeout_from"), GLOBAL_GET("rendering/quality/ssao/fadeout_to"));
screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled");
screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount");
screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit");
@@ -8365,9 +8580,11 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter"));
environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink"));
environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
+
+ cull_argument.set_page_pool(&cull_argument_pool);
}
-RasterizerSceneRD::~RasterizerSceneRD() {
+RendererSceneRenderRD::~RendererSceneRenderRD() {
for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) {
RD::get_singleton()->free(E->get().depth);
}
@@ -8379,23 +8596,26 @@ RasterizerSceneRD::~RasterizerSceneRD() {
RD::get_singleton()->free(sky_scene_state.uniform_set);
}
- RD::get_singleton()->free(default_giprobe_buffer);
- RD::get_singleton()->free(gi_probe_lights_uniform);
- RD::get_singleton()->free(gi.sdfgi_ubo);
+ if (!low_end) {
+ RD::get_singleton()->free(default_giprobe_buffer);
+ RD::get_singleton()->free(gi_probe_lights_uniform);
+ RD::get_singleton()->free(gi.sdfgi_ubo);
+
+ giprobe_debug_shader.version_free(giprobe_debug_shader_version);
+ giprobe_shader.version_free(giprobe_lighting_shader_version);
+ gi.shader.version_free(gi.shader_version);
+ sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);
+ sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);
+ sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);
+ sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);
+ sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);
- giprobe_debug_shader.version_free(giprobe_debug_shader_version);
- giprobe_shader.version_free(giprobe_lighting_shader_version);
- gi.shader.version_free(gi.shader_version);
- sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);
- sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);
- sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);
- sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);
- sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);
+ volumetric_fog.shader.version_free(volumetric_fog.shader_version);
- volumetric_fog.shader.version_free(volumetric_fog.shader_version);
+ memdelete_arr(gi_probe_lights);
+ }
- memdelete_arr(gi_probe_lights);
- SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RasterizerStorageRD::SHADER_TYPE_SKY);
+ SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
sky_shader.shader.version_free(md->shader_data->version);
RD::get_singleton()->free(sky_scene_state.directional_light_buffer);
RD::get_singleton()->free(sky_scene_state.uniform_buffer);
@@ -8426,4 +8646,5 @@ RasterizerSceneRD::~RasterizerSceneRD() {
RD::get_singleton()->free(shadow_sampler);
directional_shadow_atlas_set_size(0);
+ cull_argument.reset(); //avoid exit error
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 3d5310bb7e..3f9c117602 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_scene_rd.h */
+/* renderer_scene_render_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,27 +28,28 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_SCENE_RD_H
-#define RASTERIZER_SCENE_RD_H
+#ifndef RENDERING_SERVER_SCENE_RENDER_RD_H
+#define RENDERING_SERVER_SCENE_RENDER_RD_H
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
-#include "servers/rendering/rasterizer.h"
-#include "servers/rendering/rasterizer_rd/light_cluster_builder.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h"
-#include "servers/rendering/rasterizer_rd/shaders/gi.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/giprobe.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/sdfgi_debug.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/sdfgi_debug_probes.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/sky.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl.gen.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/light_cluster_builder.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/giprobe.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/giprobe_debug.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
-class RasterizerSceneRD : public RasterizerScene {
+class RendererSceneRenderRD : public RendererSceneRender {
protected:
double time;
@@ -103,17 +104,17 @@ protected:
};
virtual RenderBufferData *_create_render_buffer_data() = 0;
- void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
- void _setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform);
- void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment);
- void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, uint32_t &r_gi_probes_used);
+ void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
+ void _setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform);
+ void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment);
+ void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used);
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0;
- virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake) = 0;
- virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
- virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
- virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
- virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count) = 0;
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
+ virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
+ virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
+ virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0;
virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
@@ -133,16 +134,19 @@ protected:
void _setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size);
void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
- void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count);
+ void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes);
+ // needed for a single argument calls (material and uv2)
+ PagedArrayPool<GeometryInstance *> cull_argument_pool;
+ PagedArray<GeometryInstance *> cull_argument; //need this to exist
private:
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
double time_step = 0;
- static RasterizerSceneRD *singleton;
+ static RendererSceneRenderRD *singleton;
int roughness_layers;
- RasterizerStorageRD *storage;
+ RendererStorageRD *storage;
struct ReflectionData {
struct Layer {
@@ -200,11 +204,11 @@ private:
RID default_shader_rd;
} sky_shader;
- struct SkyShaderData : public RasterizerStorageRD::ShaderData {
+ struct SkyShaderData : public RendererStorageRD::ShaderData {
bool valid;
RID version;
- RenderPipelineVertexFormatCacheRD pipelines[SKY_VERSION_MAX];
+ PipelineCacheRD pipelines[SKY_VERSION_MAX];
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
@@ -224,21 +228,22 @@ private:
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
+ virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
virtual bool is_param_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();
};
- RasterizerStorageRD::ShaderData *_create_sky_shader_func();
- static RasterizerStorageRD::ShaderData *_create_sky_shader_funcs() {
- return static_cast<RasterizerSceneRD *>(singleton)->_create_sky_shader_func();
+ RendererStorageRD::ShaderData *_create_sky_shader_func();
+ static RendererStorageRD::ShaderData *_create_sky_shader_funcs() {
+ return static_cast<RendererSceneRenderRD *>(singleton)->_create_sky_shader_func();
};
- struct SkyMaterialData : public RasterizerStorageRD::MaterialData {
+ struct SkyMaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
SkyShaderData *shader_data;
RID uniform_buffer;
@@ -253,9 +258,9 @@ private:
virtual ~SkyMaterialData();
};
- RasterizerStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
- static RasterizerStorageRD::MaterialData *_create_sky_material_funcs(RasterizerStorageRD::ShaderData *p_shader) {
- return static_cast<RasterizerSceneRD *>(singleton)->_create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
+ RendererStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
+ static RendererStorageRD::MaterialData *_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader) {
+ return static_cast<RendererSceneRenderRD *>(singleton)->_create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
};
enum SkyTextureSetVersion {
@@ -338,7 +343,7 @@ private:
Vector<Reflection> reflections;
};
- RID_Owner<ReflectionAtlas> reflection_atlas_owner;
+ mutable RID_Owner<ReflectionAtlas> reflection_atlas_owner;
/* REFLECTION PROBE INSTANCE */
@@ -370,6 +375,15 @@ private:
mutable RID_Owner<DecalInstance> decal_instance_owner;
+ /* LIGHTMAP INSTANCE */
+
+ struct LightmapInstance {
+ RID lightmap;
+ Transform transform;
+ };
+
+ mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
+
/* GIPROBE INSTANCE */
struct GIProbeLight {
@@ -512,7 +526,7 @@ private:
GiprobeDebugShaderRD giprobe_debug_shader;
RID giprobe_debug_shader_version;
RID giprobe_debug_shader_version_shaders[GI_PROBE_DEBUG_MAX];
- RenderPipelineVertexFormatCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX];
+ PipelineCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX];
RID giprobe_debug_uniform_set;
/* SHADOW ATLAS */
@@ -736,13 +750,14 @@ private:
/// SSAO
bool ssao_enabled = false;
- float ssao_radius = 1;
- float ssao_intensity = 1;
- float ssao_bias = 0.01;
+ float ssao_radius = 1.0;
+ float ssao_intensity = 2.0;
+ float ssao_power = 1.5;
+ float ssao_detail = 0.5;
+ float ssao_horizon = 0.06;
+ float ssao_sharpness = 0.98;
float ssao_direct_light_affect = 0.0;
float ssao_ao_channel_affect = 0.0;
- float ssao_blur_edge_sharpness = 4.0;
- RS::EnvironmentSSAOBlur ssao_blur = RS::ENV_SSAO_BLUR_3x3;
/// SSR
///
@@ -763,10 +778,25 @@ private:
float sdfgi_normal_bias = 1.1;
float sdfgi_probe_bias = 1.1;
RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_DISABLED;
+
+ /// Adjustments
+
+ bool adjustments_enabled = false;
+ float adjustments_brightness = 1.0f;
+ float adjustments_contrast = 1.0f;
+ float adjustments_saturation = 1.0f;
+ bool use_1d_color_correction = false;
+ RID color_correction = RID();
};
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
bool ssao_half_size = false;
+ bool ssao_using_half_size = false;
+ float ssao_adaptive_target = 0.5;
+ int ssao_blur_passes = 2;
+ float ssao_fadeout_from = 50.0;
+ float ssao_fadeout_to = 300.0;
+
bool glow_bicubic_upscale = false;
bool glow_high_quality = false;
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGNESS_QUALITY_LOW;
@@ -851,8 +881,12 @@ private:
struct SSAO {
RID depth;
Vector<RID> depth_slices;
- RID ao[2];
- RID ao_full; //when using half-size
+ RID ao_deinterleaved;
+ Vector<RID> ao_deinterleaved_slices;
+ RID ao_pong;
+ Vector<RID> ao_pong_slices;
+ RID ao_final;
+ RID importance_map[2];
} ssao;
struct SSR {
@@ -1068,7 +1102,7 @@ private:
RID debug_probes_shader;
RID debug_probes_shader_version;
- RenderPipelineVertexFormatCacheRD debug_probes_pipeline[PROBE_DEBUG_MAX];
+ PipelineCacheRD debug_probes_pipeline[PROBE_DEBUG_MAX];
struct Light {
float color[3];
@@ -1446,7 +1480,12 @@ private:
float weight;
};
+ bool low_end = false;
+
public:
+ virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
+ virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0;
+
/* SHADOW ATLAS API */
RID shadow_atlas_create();
@@ -1490,7 +1529,7 @@ public:
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const;
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const;
virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const;
- virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count);
+ virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count);
RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
/* SKY API */
@@ -1555,8 +1594,8 @@ public:
virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size);
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);
- void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness);
- void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size);
+ void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect);
+ void environment_set_ssao_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);
bool environment_is_ssao_enabled(RID p_env) const;
float environment_get_ssao_ao_affect(RID p_env) const;
float environment_get_ssao_light_affect(RID p_env) const;
@@ -1571,7 +1610,7 @@ public:
RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const;
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
- void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {}
+ void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction);
virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size);
@@ -1716,6 +1755,8 @@ public:
virtual RID reflection_atlas_create();
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count);
+ virtual int reflection_atlas_get_size(RID p_ref_atlas) const;
+
_FORCE_INLINE_ RID reflection_atlas_get_texture(RID p_ref_atlas) {
ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_ref_atlas);
ERR_FAIL_COND_V(!atlas, RID());
@@ -1794,10 +1835,25 @@ public:
return decal->transform;
}
+ virtual RID lightmap_instance_create(RID p_lightmap);
+ virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform);
+ _FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) {
+ return lightmap_instance_owner.getornull(p_lightmap_instance) != nullptr;
+ }
+
+ _FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) {
+ LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
+ return li->lightmap;
+ }
+ _FORCE_INLINE_ Transform lightmap_instance_get_transform(RID p_lightmap_instance) {
+ LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
+ return li->transform;
+ }
+
RID gi_probe_instance_create(RID p_base);
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
bool gi_probe_needs_update(RID p_probe) const;
- void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects);
+ void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects);
void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi_probe_quality = p_quality; }
@@ -1872,16 +1928,16 @@ public:
float render_buffers_get_volumetric_fog_end(RID p_render_buffers);
float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers);
- void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
+ void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
- void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
+ void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
- void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
+ void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count);
- void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count);
+ void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances);
+ void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result);
- void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count);
+ void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances);
virtual void set_scene_pass(uint64_t p_pass) {
scene_pass = p_pass;
@@ -1942,8 +1998,10 @@ public:
void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir);
- RasterizerSceneRD(RasterizerStorageRD *p_storage);
- ~RasterizerSceneRD();
+ bool is_low_end() const;
+
+ RendererSceneRenderRD(RendererStorageRD *p_storage);
+ ~RendererSceneRenderRD();
};
#endif // RASTERIZER_SCENE_RD_H
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 444ef9c49a..b74a1083e7 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_storage_rd.cpp */
+/* renderer_storage_rd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rasterizer_storage_rd.h"
+#include "renderer_storage_rd.h"
#include "core/config/engine.h"
#include "core/config/project_settings.h"
#include "core/io/resource_loader.h"
-#include "rasterizer_rd.h"
+#include "renderer_compositor_rd.h"
#include "servers/rendering/shader_language.h"
-Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
+Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
Ref<Image> image = p_image->duplicate();
switch (p_image->get_format()) {
@@ -318,7 +318,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break; //unsigned float bc6hu
- case Image::FORMAT_PVRTC2: {
+ case Image::FORMAT_PVRTC1_2: {
//this is not properly supported by MoltekVK it seems, so best to use ETC2
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG;
@@ -336,7 +336,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break; //pvrtc
- case Image::FORMAT_PVRTC2A: {
+ case Image::FORMAT_PVRTC1_2A: {
//this is not properly supported by MoltekVK it seems, so best to use ETC2
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG;
@@ -353,7 +353,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break;
- case Image::FORMAT_PVRTC4: {
+ case Image::FORMAT_PVRTC1_4: {
//this is not properly supported by MoltekVK it seems, so best to use ETC2
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG;
@@ -370,7 +370,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
- case Image::FORMAT_PVRTC4A: {
+ case Image::FORMAT_PVRTC1_4A: {
//this is not properly supported by MoltekVK it seems, so best to use ETC2
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG;
@@ -535,9 +535,9 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
return image;
}
-RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
+RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) {
ERR_FAIL_COND_V(p_image.is_null(), RID());
- ERR_FAIL_COND_V(p_image->empty(), RID());
+ ERR_FAIL_COND_V(p_image->is_empty(), RID());
TextureToRDFormat ret_format;
Ref<Image> image = _validate_texture_format(p_image, ret_format);
@@ -567,7 +567,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
rd_format.depth = 1;
rd_format.array_layers = 1;
rd_format.mipmaps = texture.mipmaps;
- rd_format.type = texture.rd_type;
+ rd_format.texture_type = texture.rd_type;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
@@ -605,7 +605,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
return texture_owner.make_rid(texture);
}
-RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
+RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
ERR_FAIL_COND_V(p_layers.size() == 0, RID());
ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID());
@@ -620,7 +620,7 @@ RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_l
Image::Format valid_format = Image::FORMAT_MAX;
for (int i = 0; i < p_layers.size(); i++) {
- ERR_FAIL_COND_V(p_layers[i]->empty(), RID());
+ ERR_FAIL_COND_V(p_layers[i]->is_empty(), RID());
if (i == 0) {
valid_width = p_layers[i]->get_width();
@@ -675,7 +675,7 @@ RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_l
rd_format.depth = 1;
rd_format.array_layers = texture.layers;
rd_format.mipmaps = texture.mipmaps;
- rd_format.type = texture.rd_type;
+ rd_format.texture_type = texture.rd_type;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
@@ -715,7 +715,7 @@ RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_l
return texture_owner.make_rid(texture);
}
-RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
+RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
ERR_FAIL_COND_V(p_data.size() == 0, RID());
Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
if (verr != Image::VALIDATE_3D_OK) {
@@ -793,7 +793,7 @@ RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width,
rd_format.depth = texture.depth;
rd_format.array_layers = 1;
rd_format.mipmaps = texture.mipmaps;
- rd_format.type = texture.rd_type;
+ rd_format.texture_type = texture.rd_type;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
@@ -831,7 +831,7 @@ RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width,
return texture_owner.make_rid(texture);
}
-RID RasterizerStorageRD::texture_proxy_create(RID p_base) {
+RID RendererStorageRD::texture_proxy_create(RID p_base) {
Texture *tex = texture_owner.getornull(p_base);
ERR_FAIL_COND_V(!tex, RID());
Texture proxy_tex = *tex;
@@ -854,8 +854,8 @@ RID RasterizerStorageRD::texture_proxy_create(RID p_base) {
return rid;
}
-void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) {
- ERR_FAIL_COND(p_image.is_null() || p_image->empty());
+void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) {
+ ERR_FAIL_COND(p_image.is_null() || p_image->is_empty());
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
@@ -876,15 +876,15 @@ void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_
RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data(), !p_immediate);
}
-void RasterizerStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) {
+void RendererStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) {
_texture_2d_update(p_texture, p_image, p_layer, true);
}
-void RasterizerStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
+void RendererStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
_texture_2d_update(p_texture, p_image, p_layer, false);
}
-void RasterizerStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) {
+void RendererStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
ERR_FAIL_COND(tex->type != Texture::TYPE_3D);
@@ -921,7 +921,7 @@ void RasterizerStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Imag
RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data, true);
}
-void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
+void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
ERR_FAIL_COND(!tex->is_proxy);
@@ -961,7 +961,7 @@ void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
}
//these two APIs can be used together or in combination with the others.
-RID RasterizerStorageRD::texture_2d_placeholder_create() {
+RID RendererStorageRD::texture_2d_placeholder_create() {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
@@ -977,7 +977,7 @@ RID RasterizerStorageRD::texture_2d_placeholder_create() {
return texture_2d_create(image);
}
-RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) {
+RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
@@ -1003,7 +1003,7 @@ RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayere
return texture_2d_layered_create(images, p_layered_type);
}
-RID RasterizerStorageRD::texture_3d_placeholder_create() {
+RID RendererStorageRD::texture_3d_placeholder_create() {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
@@ -1025,7 +1025,7 @@ RID RasterizerStorageRD::texture_3d_placeholder_create() {
return texture_3d_create(Image::FORMAT_RGBA8, 4, 4, 4, false, images);
}
-Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const {
+Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!tex, Ref<Image>());
@@ -1039,7 +1039,7 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const {
Ref<Image> image;
image.instance();
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
- ERR_FAIL_COND_V(image->empty(), Ref<Image>());
+ ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (tex->format != tex->validated_format) {
image->convert(tex->format);
}
@@ -1053,7 +1053,7 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const {
return image;
}
-Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const {
+Ref<Image> RendererStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!tex, Ref<Image>());
@@ -1062,7 +1062,7 @@ Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer)
Ref<Image> image;
image.instance();
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
- ERR_FAIL_COND_V(image->empty(), Ref<Image>());
+ ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (tex->format != tex->validated_format) {
image->convert(tex->format);
}
@@ -1070,7 +1070,7 @@ Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer)
return image;
}
-Vector<Ref<Image>> RasterizerStorageRD::texture_3d_get(RID p_texture) const {
+Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>());
ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>());
@@ -1090,7 +1090,7 @@ Vector<Ref<Image>> RasterizerStorageRD::texture_3d_get(RID p_texture) const {
Ref<Image> img;
img.instance();
img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region);
- ERR_FAIL_COND_V(img->empty(), Vector<Ref<Image>>());
+ ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>());
if (tex->format != tex->validated_format) {
img->convert(tex->format);
}
@@ -1101,7 +1101,7 @@ Vector<Ref<Image>> RasterizerStorageRD::texture_3d_get(RID p_texture) const {
return ret;
}
-void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
+void RendererStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
ERR_FAIL_COND(tex->proxy_to.is_valid()); //can't replace proxy
@@ -1150,7 +1150,7 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
}
}
-void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) {
+void RendererStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
ERR_FAIL_COND(tex->type != Texture::TYPE_2D);
@@ -1158,53 +1158,53 @@ void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width,
tex->height_2d = p_height;
}
-void RasterizerStorageRD::texture_set_path(RID p_texture, const String &p_path) {
+void RendererStorageRD::texture_set_path(RID p_texture, const String &p_path) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
tex->path = p_path;
}
-String RasterizerStorageRD::texture_get_path(RID p_texture) const {
+String RendererStorageRD::texture_get_path(RID p_texture) const {
return String();
}
-void RasterizerStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
+void RendererStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
tex->detect_3d_callback_ud = p_userdata;
tex->detect_3d_callback = p_callback;
}
-void RasterizerStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
+void RendererStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
tex->detect_normal_callback_ud = p_userdata;
tex->detect_normal_callback = p_callback;
}
-void RasterizerStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {
+void RendererStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
tex->detect_roughness_callback_ud = p_userdata;
tex->detect_roughness_callback = p_callback;
}
-void RasterizerStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) {
+void RendererStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) {
}
-void RasterizerStorageRD::texture_set_proxy(RID p_proxy, RID p_base) {
+void RendererStorageRD::texture_set_proxy(RID p_proxy, RID p_base) {
}
-void RasterizerStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
+void RendererStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
}
-Size2 RasterizerStorageRD::texture_size_with_proxy(RID p_proxy) {
+Size2 RendererStorageRD::texture_size_with_proxy(RID p_proxy) {
return texture_2d_get_size(p_proxy);
}
/* CANVAS TEXTURE */
-void RasterizerStorageRD::CanvasTexture::clear_sets() {
+void RendererStorageRD::CanvasTexture::clear_sets() {
if (cleared_cache) {
return;
}
@@ -1219,22 +1219,22 @@ void RasterizerStorageRD::CanvasTexture::clear_sets() {
cleared_cache = true;
}
-RasterizerStorageRD::CanvasTexture::~CanvasTexture() {
+RendererStorageRD::CanvasTexture::~CanvasTexture() {
clear_sets();
}
-RID RasterizerStorageRD::canvas_texture_create() {
+RID RendererStorageRD::canvas_texture_create() {
return canvas_texture_owner.make_rid(memnew(CanvasTexture));
}
-void RasterizerStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
+void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
switch (p_channel) {
case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
ct->diffuse = p_texture;
} break;
case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
- ct->normalmap = p_texture;
+ ct->normal_map = p_texture;
} break;
case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
ct->specular = p_texture;
@@ -1244,7 +1244,7 @@ void RasterizerStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::C
ct->clear_sets();
}
-void RasterizerStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
+void RendererStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
ct->specular_color.r = p_specular_color.r;
ct->specular_color.g = p_specular_color.g;
@@ -1253,19 +1253,19 @@ void RasterizerStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_tex
ct->clear_sets();
}
-void RasterizerStorageRD::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
+void RendererStorageRD::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
ct->texture_filter = p_filter;
ct->clear_sets();
}
-void RasterizerStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
+void RendererStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
ct->texture_repeat = p_repeat;
ct->clear_sets();
}
-bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) {
+bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) {
CanvasTexture *ct = nullptr;
Texture *t = texture_owner.getornull(p_texture);
@@ -1298,7 +1298,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv
Vector<RD::Uniform> uniforms;
{ //diffuse
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
t = texture_owner.getornull(ct->diffuse);
@@ -1313,10 +1313,10 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv
}
{ //normal
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1;
- t = texture_owner.getornull(ct->normalmap);
+ t = texture_owner.getornull(ct->normal_map);
if (!t) {
u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
ct->use_normal_cache = false;
@@ -1328,7 +1328,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv
}
{ //specular
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2;
t = texture_owner.getornull(ct->specular);
@@ -1343,7 +1343,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv
}
{ //sampler
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 3;
u.ids.push_back(sampler_rd_get_default(filter, repeat));
uniforms.push_back(u);
@@ -1365,7 +1365,7 @@ bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canv
/* SHADER API */
-RID RasterizerStorageRD::shader_create() {
+RID RendererStorageRD::shader_create() {
Shader shader;
shader.data = nullptr;
shader.type = SHADER_TYPE_MAX;
@@ -1373,7 +1373,7 @@ RID RasterizerStorageRD::shader_create() {
return shader_owner.make_rid(shader);
}
-void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
+void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
@@ -1438,18 +1438,18 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
Material *material = E->get();
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
}
-String RasterizerStorageRD::shader_get_code(RID p_shader) const {
+String RendererStorageRD::shader_get_code(RID p_shader) const {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND_V(!shader, String());
return shader->code;
}
-void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
+void RendererStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
if (shader->data) {
@@ -1457,7 +1457,7 @@ void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo>
}
}
-void RasterizerStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {
+void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
@@ -1475,7 +1475,7 @@ void RasterizerStorageRD::shader_set_default_texture_param(RID p_shader, const S
}
}
-RID RasterizerStorageRD::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const {
+RID RendererStorageRD::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND_V(!shader, RID());
if (shader->default_texture_parameter.has(p_name)) {
@@ -1485,7 +1485,7 @@ RID RasterizerStorageRD::shader_get_default_texture_param(RID p_shader, const St
return RID();
}
-Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const {
+Variant RendererStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND_V(!shader, Variant());
if (shader->data) {
@@ -1494,14 +1494,23 @@ Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const String
return Variant();
}
-void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function) {
+void RendererStorageRD::shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function) {
ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX);
shader_data_request_func[p_shader_type] = p_function;
}
+RS::ShaderNativeSourceCode RendererStorageRD::shader_get_native_source_code(RID p_shader) const {
+ Shader *shader = shader_owner.getornull(p_shader);
+ ERR_FAIL_COND_V(!shader, RS::ShaderNativeSourceCode());
+ if (shader->data) {
+ return shader->data->get_native_source_code();
+ }
+ return RS::ShaderNativeSourceCode();
+}
+
/* COMMON MATERIAL API */
-RID RasterizerStorageRD::material_create() {
+RID RendererStorageRD::material_create() {
Material material;
material.data = nullptr;
material.shader = nullptr;
@@ -1519,7 +1528,7 @@ RID RasterizerStorageRD::material_create() {
return id;
}
-void RasterizerStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) {
+void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) {
if (material->update_requested) {
return;
}
@@ -1531,7 +1540,7 @@ void RasterizerStorageRD::_material_queue_update(Material *material, bool p_unif
material->texture_dirty = material->texture_dirty || p_texture;
}
-void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
+void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1547,7 +1556,8 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
}
if (p_shader.is_null()) {
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
+ material->shader_id = 0;
return;
}
@@ -1555,6 +1565,7 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
ERR_FAIL_COND(!shader);
material->shader = shader;
material->shader_type = shader->type;
+ material->shader_id = p_shader.get_local_index();
shader->owners.insert(material);
if (shader->type == SHADER_TYPE_MAX) {
@@ -1568,11 +1579,11 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
material->data->set_next_pass(material->next_pass);
material->data->set_render_priority(material->priority);
//updating happens later
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
-void RasterizerStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
+void RendererStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1590,7 +1601,7 @@ void RasterizerStorageRD::material_set_param(RID p_material, const StringName &p
}
}
-Variant RasterizerStorageRD::material_get_param(RID p_material, const StringName &p_param) const {
+Variant RendererStorageRD::material_get_param(RID p_material, const StringName &p_param) const {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND_V(!material, Variant());
if (material->params.has(p_param)) {
@@ -1600,7 +1611,7 @@ Variant RasterizerStorageRD::material_get_param(RID p_material, const StringName
}
}
-void RasterizerStorageRD::material_set_next_pass(RID p_material, RID p_next_material) {
+void RendererStorageRD::material_set_next_pass(RID p_material, RID p_next_material) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1613,10 +1624,10 @@ void RasterizerStorageRD::material_set_next_pass(RID p_material, RID p_next_mate
material->data->set_next_pass(p_next_material);
}
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
}
-void RasterizerStorageRD::material_set_render_priority(RID p_material, int priority) {
+void RendererStorageRD::material_set_render_priority(RID p_material, int priority) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
material->priority = priority;
@@ -1625,7 +1636,7 @@ void RasterizerStorageRD::material_set_render_priority(RID p_material, int prior
}
}
-bool RasterizerStorageRD::material_is_animated(RID p_material) {
+bool RendererStorageRD::material_is_animated(RID p_material) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND_V(!material, false);
if (material->shader && material->shader->data) {
@@ -1638,7 +1649,7 @@ bool RasterizerStorageRD::material_is_animated(RID p_material) {
return false; //by default nothing is animated
}
-bool RasterizerStorageRD::material_casts_shadows(RID p_material) {
+bool RendererStorageRD::material_casts_shadows(RID p_material) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND_V(!material, true);
if (material->shader && material->shader->data) {
@@ -1651,7 +1662,7 @@ bool RasterizerStorageRD::material_casts_shadows(RID p_material) {
return true; //by default everything casts shadows
}
-void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
+void RendererStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
if (material->shader && material->shader->data) {
@@ -1663,16 +1674,16 @@ void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material
}
}
-void RasterizerStorageRD::material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) {
+void RendererStorageRD::material_update_dependency(RID p_material, DependencyTracker *p_instance) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
- p_instance->update_dependency(&material->instance_dependency);
+ p_instance->update_dependency(&material->dependency);
if (material->next_pass.is_valid()) {
material_update_dependency(material->next_pass, p_instance);
}
}
-void RasterizerStorageRD::material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function) {
+void RendererStorageRD::material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function) {
ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX);
material_data_request_func[p_shader_type] = p_function;
}
@@ -2119,7 +2130,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
}
}
-void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) {
+void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) {
bool uses_global_buffer = false;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) {
@@ -2133,7 +2144,7 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa
if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
//this is a global variable, get the index to it
- RasterizerStorageRD *rs = base_singleton;
+ RendererStorageRD *rs = base_singleton;
GlobalVariables::Variable *gv = rs->global_variables.variables.getptr(E->key());
uint32_t index = 0;
@@ -2180,7 +2191,7 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa
}
if (uses_global_buffer != (global_buffer_E != nullptr)) {
- RasterizerStorageRD *rs = base_singleton;
+ RendererStorageRD *rs = base_singleton;
if (uses_global_buffer) {
global_buffer_E = rs->global_variables.materials_using_buffer.push_back(self);
} else {
@@ -2190,16 +2201,16 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa
}
}
-RasterizerStorageRD::MaterialData::~MaterialData() {
+RendererStorageRD::MaterialData::~MaterialData() {
if (global_buffer_E) {
//unregister global buffers
- RasterizerStorageRD *rs = base_singleton;
+ RendererStorageRD *rs = base_singleton;
rs->global_variables.materials_using_buffer.erase(global_buffer_E);
}
if (global_texture_E) {
//unregister global textures
- RasterizerStorageRD *rs = base_singleton;
+ RendererStorageRD *rs = base_singleton;
for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) {
GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E->key());
@@ -2212,11 +2223,11 @@ RasterizerStorageRD::MaterialData::~MaterialData() {
}
}
-void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
- RasterizerStorageRD *singleton = (RasterizerStorageRD *)RasterizerStorage::base_singleton;
+void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
+ RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton;
#ifdef TOOLS_ENABLED
Texture *roughness_detect_texture = nullptr;
- RS::TextureDetectRoughnessChannel roughness_channel = RS::TEXTURE_DETECT_ROUGNHESS_R;
+ RS::TextureDetectRoughnessChannel roughness_channel = RS::TEXTURE_DETECT_ROUGHNESS_R;
Texture *normal_detect_texture = nullptr;
#endif
@@ -2229,7 +2240,7 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
RID texture;
if (p_texture_uniforms[i].global) {
- RasterizerStorageRD *rs = base_singleton;
+ RendererStorageRD *rs = base_singleton;
uses_global_textures = true;
@@ -2330,7 +2341,7 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
{
//for textures no longer used, unregister them
List<Map<StringName, uint64_t>::Element *> to_delete;
- RasterizerStorageRD *rs = base_singleton;
+ RendererStorageRD *rs = base_singleton;
for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) {
if (E->get() != global_textures_pass) {
@@ -2359,7 +2370,7 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
}
}
-void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
+void RendererStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.getornull(p_material);
if (material->shader_type != p_shader_type) {
return;
@@ -2369,7 +2380,7 @@ void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderT
}
}
-void RasterizerStorageRD::_update_queued_materials() {
+void RendererStorageRD::_update_queued_materials() {
Material *material = material_update_list;
while (material) {
Material *next = material->update_next;
@@ -2388,23 +2399,32 @@ void RasterizerStorageRD::_update_queued_materials() {
/* MESH API */
-RID RasterizerStorageRD::mesh_create() {
+RID RendererStorageRD::mesh_create() {
return mesh_owner.make_rid(Mesh());
}
-/// Returns stride
-void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {
+void RendererStorageRD::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) {
+ ERR_FAIL_COND(p_blend_shape_count < 0);
+
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
- //ensure blend shape consistency
- ERR_FAIL_COND(mesh->blend_shape_count && p_surface.blend_shapes.size() != (int)mesh->blend_shape_count);
- ERR_FAIL_COND(mesh->blend_shape_count && p_surface.bone_aabbs.size() != mesh->bone_aabbs.size());
+ ERR_FAIL_COND(mesh->surface_count > 0); //surfaces already exist
+
+ mesh->blend_shape_count = p_blend_shape_count;
+}
+
+/// Returns stride
+void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ ERR_FAIL_COND(!mesh);
#ifdef DEBUG_ENABLED
//do a validation, to catch errors first
{
uint32_t stride = 0;
+ uint32_t attrib_stride = 0;
+ uint32_t skin_stride = 0;
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
if ((p_surface.format & (1 << i))) {
@@ -2418,59 +2438,59 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
} break;
case RS::ARRAY_NORMAL: {
- if (p_surface.format & RS::ARRAY_COMPRESS_NORMAL) {
- stride += sizeof(int8_t) * 4;
- } else {
- stride += sizeof(float) * 4;
- }
+ stride += sizeof(int32_t);
} break;
case RS::ARRAY_TANGENT: {
- if (p_surface.format & RS::ARRAY_COMPRESS_TANGENT) {
- stride += sizeof(int8_t) * 4;
- } else {
- stride += sizeof(float) * 4;
- }
+ stride += sizeof(int32_t);
} break;
case RS::ARRAY_COLOR: {
- if (p_surface.format & RS::ARRAY_COMPRESS_COLOR) {
- stride += sizeof(int8_t) * 4;
- } else {
- stride += sizeof(float) * 4;
- }
-
+ attrib_stride += sizeof(int16_t) * 4;
} break;
case RS::ARRAY_TEX_UV: {
- if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV) {
- stride += sizeof(int16_t) * 2;
- } else {
- stride += sizeof(float) * 2;
- }
+ attrib_stride += sizeof(float) * 2;
} break;
case RS::ARRAY_TEX_UV2: {
- if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV2) {
- stride += sizeof(int16_t) * 2;
- } else {
- stride += sizeof(float) * 2;
- }
+ attrib_stride += sizeof(float) * 2;
} break;
- case RS::ARRAY_BONES: {
- //assumed weights too
-
- //unique format, internally 16 bits, exposed as single array for 32
-
- stride += sizeof(int32_t) * 4;
+ case RS::ARRAY_CUSTOM0:
+ case RS::ARRAY_CUSTOM1:
+ case RS::ARRAY_CUSTOM2:
+ case RS::ARRAY_CUSTOM3: {
+ int idx = i - RS::ARRAY_CUSTOM0;
+ uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
+ uint32_t fmt = (p_surface.format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
+ uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
+ attrib_stride += fmtsize[fmt];
} break;
+ case RS::ARRAY_WEIGHTS:
+ case RS::ARRAY_BONES: {
+ //uses a separate array
+ bool use_8 = p_surface.format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
+ skin_stride += sizeof(int16_t) * (use_8 ? 16 : 8);
+ } break;
}
}
}
int expected_size = stride * p_surface.vertex_count;
- ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
+ ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of vertex data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
+
+ int bs_expected_size = expected_size * mesh->blend_shape_count;
+
+ ERR_FAIL_COND_MSG(bs_expected_size != p_surface.blend_shape_data.size(), "Size of blend shape data provided (" + itos(p_surface.blend_shape_data.size()) + ") does not match expected (" + itos(bs_expected_size) + ")");
+
+ int expected_attrib_size = attrib_stride * p_surface.vertex_count;
+ ERR_FAIL_COND_MSG(expected_attrib_size != p_surface.attribute_data.size(), "Size of attribute data provided (" + itos(p_surface.attribute_data.size()) + ") does not match expected (" + itos(expected_attrib_size) + ")");
+
+ if ((p_surface.format & RS::ARRAY_FORMAT_WEIGHTS) && (p_surface.format & RS::ARRAY_FORMAT_BONES)) {
+ expected_size = skin_stride * p_surface.vertex_count;
+ ERR_FAIL_COND_MSG(expected_size != p_surface.skin_data.size(), "Size of skin data provided (" + itos(p_surface.skin_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
+ }
}
#endif
@@ -2480,9 +2500,25 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
s->format = p_surface.format;
s->primitive = p_surface.primitive;
- s->vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.vertex_data.size(), p_surface.vertex_data);
+ bool use_as_storage = (p_surface.skin_data.size() || mesh->blend_shape_count > 0);
+
+ s->vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.vertex_data.size(), p_surface.vertex_data, use_as_storage);
+ s->vertex_buffer_size = p_surface.vertex_data.size();
+
+ if (p_surface.attribute_data.size()) {
+ s->attribute_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.attribute_data.size(), p_surface.attribute_data);
+ }
+ if (p_surface.skin_data.size()) {
+ s->skin_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.skin_data.size(), p_surface.skin_data, use_as_storage);
+ s->skin_buffer_size = p_surface.skin_data.size();
+ }
+
s->vertex_count = p_surface.vertex_count;
+ if (p_surface.format & RS::ARRAY_FORMAT_BONES) {
+ mesh->has_bone_weights = true;
+ }
+
if (p_surface.index_count) {
bool is_index_16 = p_surface.vertex_count <= 65536;
@@ -2505,21 +2541,54 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
s->aabb = p_surface.aabb;
s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them.
- for (int i = 0; i < p_surface.blend_shapes.size(); i++) {
- if (p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()) {
- memdelete(s);
- ERR_FAIL_COND(p_surface.blend_shapes[i].size() != p_surface.vertex_data.size());
- }
- RID vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.blend_shapes[i].size(), p_surface.blend_shapes[i]);
- s->blend_shapes.push_back(vertex_buffer);
+ if (mesh->blend_shape_count > 0) {
+ s->blend_shape_buffer = RD::get_singleton()->storage_buffer_create(p_surface.blend_shape_data.size(), p_surface.blend_shape_data);
}
- mesh->blend_shape_count = p_surface.blend_shapes.size();
+ if (use_as_storage) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 0;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(s->vertex_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ if (s->skin_buffer.is_valid()) {
+ u.ids.push_back(s->skin_buffer);
+ } else {
+ u.ids.push_back(default_rd_storage_buffer);
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ if (s->blend_shape_buffer.is_valid()) {
+ u.ids.push_back(s->blend_shape_buffer);
+ } else {
+ u.ids.push_back(default_rd_storage_buffer);
+ }
+ uniforms.push_back(u);
+ }
+
+ s->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_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++) {
mesh->bone_aabbs.write[i].merge_with(p_surface.bone_aabbs[i]);
}
@@ -2532,18 +2601,24 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
mesh->surfaces[mesh->surface_count] = s;
mesh->surface_count++;
- mesh->instance_dependency.instance_notify_changed(true, true);
+ for (List<MeshInstance *>::Element *E = mesh->instances.front(); E; E = E->next()) {
+ //update instances
+ MeshInstance *mi = E->get();
+ _mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);
+ }
+
+ mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
mesh->material_cache.clear();
}
-int RasterizerStorageRD::mesh_get_blend_shape_count(RID p_mesh) const {
+int RendererStorageRD::mesh_get_blend_shape_count(RID p_mesh) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, -1);
return mesh->blend_shape_count;
}
-void RasterizerStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) {
+void RendererStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
ERR_FAIL_INDEX((int)p_mode, 2);
@@ -2551,13 +2626,13 @@ void RasterizerStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMo
mesh->blend_shape_mode = p_mode;
}
-RS::BlendShapeMode RasterizerStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const {
+RS::BlendShapeMode RendererStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, RS::BLEND_SHAPE_MODE_NORMALIZED);
return mesh->blend_shape_mode;
}
-void RasterizerStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
+void RendererStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
@@ -2568,17 +2643,17 @@ void RasterizerStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface,
RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->vertex_buffer, p_offset, data_size, r);
}
-void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
+void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
mesh->surfaces[p_surface]->material = p_material;
- mesh->instance_dependency.instance_notify_changed(false, true);
+ mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
mesh->material_cache.clear();
}
-RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const {
+RID RendererStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, RID());
ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RID());
@@ -2586,7 +2661,7 @@ RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) co
return mesh->surfaces[p_surface]->material;
}
-RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const {
+RS::SurfaceData RendererStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, RS::SurfaceData());
ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData());
@@ -2596,6 +2671,12 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface)
RS::SurfaceData sd;
sd.format = s.format;
sd.vertex_data = RD::get_singleton()->buffer_get_data(s.vertex_buffer);
+ if (s.attribute_buffer.is_valid()) {
+ sd.attribute_data = RD::get_singleton()->buffer_get_data(s.attribute_buffer);
+ }
+ if (s.skin_buffer.is_valid()) {
+ sd.skin_data = RD::get_singleton()->buffer_get_data(s.skin_buffer);
+ }
sd.vertex_count = s.vertex_count;
sd.index_count = s.index_count;
sd.primitive = s.primitive;
@@ -2613,33 +2694,32 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface)
sd.bone_aabbs = s.bone_aabbs;
- for (int i = 0; i < s.blend_shapes.size(); i++) {
- Vector<uint8_t> bs = RD::get_singleton()->buffer_get_data(s.blend_shapes[i]);
- sd.blend_shapes.push_back(bs);
+ if (s.blend_shape_buffer.is_valid()) {
+ sd.blend_shape_data = RD::get_singleton()->buffer_get_data(s.blend_shape_buffer);
}
return sd;
}
-int RasterizerStorageRD::mesh_get_surface_count(RID p_mesh) const {
+int RendererStorageRD::mesh_get_surface_count(RID p_mesh) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, 0);
return mesh->surface_count;
}
-void RasterizerStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
+void RendererStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
mesh->custom_aabb = p_aabb;
}
-AABB RasterizerStorageRD::mesh_get_custom_aabb(RID p_mesh) const {
+AABB RendererStorageRD::mesh_get_custom_aabb(RID p_mesh) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, AABB());
return mesh->custom_aabb;
}
-AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
+AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, AABB());
@@ -2744,12 +2824,18 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
return aabb;
}
-void RasterizerStorageRD::mesh_clear(RID p_mesh) {
+void RendererStorageRD::mesh_clear(RID p_mesh) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
for (uint32_t i = 0; i < mesh->surface_count; i++) {
Mesh::Surface &s = *mesh->surfaces[i];
RD::get_singleton()->free(s.vertex_buffer); //clears arrays as dependency automatically, including all versions
+ if (s.attribute_buffer.is_valid()) {
+ RD::get_singleton()->free(s.attribute_buffer);
+ }
+ if (s.skin_buffer.is_valid()) {
+ RD::get_singleton()->free(s.skin_buffer);
+ }
if (s.versions) {
memfree(s.versions); //reallocs, so free with memfree.
}
@@ -2765,12 +2851,8 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) {
memdelete_arr(s.lods);
}
- for (int32_t j = 0; j < s.blend_shapes.size(); j++) {
- RD::get_singleton()->free(s.blend_shapes[j]);
- }
-
- if (s.blend_shape_base_buffer.is_valid()) {
- RD::get_singleton()->free(s.blend_shape_base_buffer);
+ if (s.blend_shape_buffer.is_valid()) {
+ RD::get_singleton()->free(s.blend_shape_buffer);
}
memdelete(mesh->surfaces[i]);
@@ -2782,22 +2864,231 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) {
mesh->surfaces = nullptr;
mesh->surface_count = 0;
mesh->material_cache.clear();
- mesh->instance_dependency.instance_notify_changed(true, true);
+ //clear instance data
+ for (List<MeshInstance *>::Element *E = mesh->instances.front(); E; E = E->next()) {
+ MeshInstance *mi = E->get();
+ _mesh_instance_clear(mi);
+ }
+ mesh->has_bone_weights = false;
+ mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
+}
+
+bool RendererStorageRD::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) {
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ ERR_FAIL_COND_V(!mesh, false);
+
+ return mesh->blend_shape_count > 0 || (mesh->has_bone_weights && p_has_skeleton);
+}
+
+/* MESH INSTANCE */
+
+RID RendererStorageRD::mesh_instance_create(RID p_base) {
+ Mesh *mesh = mesh_owner.getornull(p_base);
+ ERR_FAIL_COND_V(!mesh, RID());
+
+ MeshInstance *mi = memnew(MeshInstance);
+
+ mi->mesh = mesh;
+
+ for (uint32_t i = 0; i < mesh->surface_count; i++) {
+ _mesh_instance_add_surface(mi, mesh, i);
+ }
+
+ mi->I = mesh->instances.push_back(mi);
+
+ mi->dirty = true;
+
+ return mesh_instance_owner.make_rid(mi);
+}
+void RendererStorageRD::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {
+ MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance);
+ if (mi->skeleton == p_skeleton) {
+ return;
+ }
+ mi->skeleton = p_skeleton;
+ mi->skeleton_version = 0;
+ mi->dirty = true;
+}
+
+void RendererStorageRD::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) {
+ MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance);
+ ERR_FAIL_COND(!mi);
+ ERR_FAIL_INDEX(p_shape, (int)mi->blend_weights.size());
+ mi->blend_weights[p_shape] = p_weight;
+ mi->weights_dirty = true;
+ //will be eventually updated
+}
+
+void RendererStorageRD::_mesh_instance_clear(MeshInstance *mi) {
+ for (uint32_t i = 0; i < mi->surfaces.size(); i++) {
+ if (mi->surfaces[i].vertex_buffer.is_valid()) {
+ RD::get_singleton()->free(mi->surfaces[i].vertex_buffer);
+ }
+ 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);
+ }
+ memfree(mi->surfaces[i].versions);
+ }
+ }
+ mi->surfaces.clear();
+
+ if (mi->blend_weights_buffer.is_valid()) {
+ RD::get_singleton()->free(mi->blend_weights_buffer);
+ }
+ mi->blend_weights.clear();
+ mi->weights_dirty = false;
+ mi->skeleton_version = 0;
+}
+
+void RendererStorageRD::_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;
+ }
+ 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;
+ }
+
+ MeshInstance::Surface s;
+ if (mesh->blend_shape_count > 0 || (mesh->surfaces[p_surface]->format & RS::ARRAY_FORMAT_BONES)) {
+ //surface warrants transform
+ s.vertex_buffer = RD::get_singleton()->vertex_buffer_create(mesh->surfaces[p_surface]->vertex_buffer_size, Vector<uint8_t>(), true);
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(s.vertex_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ if (mi->blend_weights_buffer.is_valid()) {
+ u.ids.push_back(mi->blend_weights_buffer);
+ } else {
+ u.ids.push_back(default_rd_storage_buffer);
+ }
+ uniforms.push_back(u);
+ }
+ s.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_INSTANCE);
+ }
+
+ mi->surfaces.push_back(s);
+ mi->dirty = true;
+}
+
+void RendererStorageRD::mesh_instance_check_for_update(RID p_mesh_instance) {
+ MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance);
+
+ bool needs_update = mi->dirty;
+
+ if (mi->weights_dirty && !mi->weight_update_list.in_list()) {
+ dirty_mesh_instance_weights.add(&mi->weight_update_list);
+ needs_update = true;
+ }
+
+ if (mi->array_update_list.in_list()) {
+ return;
+ }
+
+ if (!needs_update && mi->skeleton.is_valid()) {
+ Skeleton *sk = skeleton_owner.getornull(mi->skeleton);
+ if (sk && sk->version != mi->skeleton_version) {
+ needs_update = true;
+ }
+ }
+
+ if (needs_update) {
+ dirty_mesh_instance_arrays.add(&mi->array_update_list);
+ }
}
-void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surface *s, uint32_t p_input_mask) {
- uint32_t version = s->version_count;
- s->version_count++;
- s->versions = (Mesh::Surface::Version *)memrealloc(s->versions, sizeof(Mesh::Surface::Version) * s->version_count);
+void RendererStorageRD::update_mesh_instances() {
+ while (dirty_mesh_instance_weights.first()) {
+ MeshInstance *mi = dirty_mesh_instance_weights.first()->self();
- Mesh::Surface::Version &v = s->versions[version];
+ if (mi->blend_weights_buffer.is_valid()) {
+ RD::get_singleton()->buffer_update(mi->blend_weights_buffer, 0, mi->blend_weights.size() * sizeof(float), mi->blend_weights.ptr(), true);
+ }
+ dirty_mesh_instance_weights.remove(&mi->weight_update_list);
+ mi->weights_dirty = false;
+ }
+ if (dirty_mesh_instance_arrays.first() == nullptr) {
+ return; //nothing to do
+ }
+
+ //process skeletons and blend shapes
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ while (dirty_mesh_instance_arrays.first()) {
+ MeshInstance *mi = dirty_mesh_instance_arrays.first()->self();
+
+ Skeleton *sk = skeleton_owner.getornull(mi->skeleton);
+
+ for (uint32_t i = 0; i < mi->surfaces.size(); i++) {
+ if (mi->surfaces[i].uniform_set == RID() || mi->mesh->surfaces[i]->uniform_set == RID()) {
+ continue;
+ }
+
+ bool array_is_2d = mi->mesh->surfaces[i]->format & RS::ARRAY_FLAG_USE_2D_VERTICES;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, skeleton_shader.pipeline[array_is_2d ? SkeletonShader::SHADER_MODE_2D : SkeletonShader::SHADER_MODE_3D]);
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mi->surfaces[i].uniform_set, SkeletonShader::UNIFORM_SET_INSTANCE);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mi->mesh->surfaces[i]->uniform_set, SkeletonShader::UNIFORM_SET_SURFACE);
+ if (sk && sk->uniform_set_mi.is_valid()) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sk->uniform_set_mi, SkeletonShader::UNIFORM_SET_SKELETON);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, skeleton_shader.default_skeleton_uniform_set, SkeletonShader::UNIFORM_SET_SKELETON);
+ }
+
+ SkeletonShader::PushConstant push_constant;
+
+ push_constant.has_normal = mi->mesh->surfaces[i]->format & RS::ARRAY_FORMAT_NORMAL;
+ push_constant.has_tangent = mi->mesh->surfaces[i]->format & RS::ARRAY_FORMAT_TANGENT;
+ push_constant.has_skeleton = sk != nullptr && sk->use_2d == array_is_2d && (mi->mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES);
+ push_constant.has_blend_shape = mi->mesh->blend_shape_count > 0;
+ push_constant.vertex_count = mi->mesh->surfaces[i]->vertex_count;
+ push_constant.vertex_stride = (mi->mesh->surfaces[i]->vertex_buffer_size / mi->mesh->surfaces[i]->vertex_count) / 4;
+ 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;
+
+ 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;
+ push_constant.pad1 = 0;
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SkeletonShader::PushConstant));
+
+ //dispatch without barrier, so all is done at the same time
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1, 64, 1, 1);
+ }
+
+ mi->dirty = false;
+ if (sk) {
+ mi->skeleton_version = sk->version;
+ }
+ dirty_mesh_instance_arrays.remove(&mi->array_update_list);
+ }
+
+ RD::get_singleton()->compute_list_end();
+}
+
+void RendererStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::Version &v, Mesh::Surface *s, uint32_t p_input_mask, MeshInstance::Surface *mis) {
Vector<RD::VertexAttribute> attributes;
Vector<RID> buffers;
uint32_t stride = 0;
+ uint32_t attribute_stride = 0;
+ uint32_t skin_stride = 0;
- for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
+ for (int i = 0; i < RS::ARRAY_INDEX; i++) {
RD::VertexAttribute vd;
RID buffer;
vd.location = i;
@@ -2805,6 +3096,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
if (!(s->format & (1 << i))) {
// Not supplied by surface, use default value
buffer = mesh_default_rd_buffers[i];
+ vd.stride = 0;
switch (i) {
case RS::ARRAY_VERTEX: {
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
@@ -2827,20 +3119,31 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
case RS::ARRAY_TEX_UV2: {
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
} break;
+ case RS::ARRAY_CUSTOM0:
+ case RS::ARRAY_CUSTOM1:
+ case RS::ARRAY_CUSTOM2:
+ case RS::ARRAY_CUSTOM3: {
+ //assumed weights too
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ } break;
case RS::ARRAY_BONES: {
//assumed weights too
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
} break;
+ case RS::ARRAY_WEIGHTS: {
+ //assumed weights too
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
+ } break;
}
} else {
//Supplied, use it
- vd.offset = stride;
- vd.stride = 1; //mark that it needs a stride set
- buffer = s->vertex_buffer;
+ vd.stride = 1; //mark that it needs a stride set (default uses 0)
switch (i) {
case RS::ARRAY_VERTEX: {
+ vd.offset = stride;
+
if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
stride += sizeof(float) * 2;
@@ -2849,71 +3152,92 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
stride += sizeof(float) * 3;
}
+ if (mis) {
+ buffer = mis->vertex_buffer;
+ } else {
+ buffer = s->vertex_buffer;
+ }
+
} break;
case RS::ARRAY_NORMAL: {
- if (s->format & RS::ARRAY_COMPRESS_NORMAL) {
- vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
- stride += sizeof(int8_t) * 4;
+ vd.offset = stride;
+
+ vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
+
+ stride += sizeof(uint32_t);
+ if (mis) {
+ buffer = mis->vertex_buffer;
} else {
- vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- stride += sizeof(float) * 4;
+ buffer = s->vertex_buffer;
}
-
} break;
case RS::ARRAY_TANGENT: {
- if (s->format & RS::ARRAY_COMPRESS_TANGENT) {
- vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
- stride += sizeof(int8_t) * 4;
+ vd.offset = stride;
+
+ vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
+ stride += sizeof(uint32_t);
+ if (mis) {
+ buffer = mis->vertex_buffer;
} else {
- vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- stride += sizeof(float) * 4;
+ buffer = s->vertex_buffer;
}
-
} break;
case RS::ARRAY_COLOR: {
- if (s->format & RS::ARRAY_COMPRESS_COLOR) {
- vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
- stride += sizeof(int8_t) * 4;
- } else {
- vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- stride += sizeof(float) * 4;
- }
+ vd.offset = attribute_stride;
+ vd.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ attribute_stride += sizeof(int16_t) * 4;
+ buffer = s->attribute_buffer;
} break;
case RS::ARRAY_TEX_UV: {
- if (s->format & RS::ARRAY_COMPRESS_TEX_UV) {
- vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
- stride += sizeof(int16_t) * 2;
- } else {
- vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
- stride += sizeof(float) * 2;
- }
+ vd.offset = attribute_stride;
+
+ vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
+ attribute_stride += sizeof(float) * 2;
+ buffer = s->attribute_buffer;
} break;
case RS::ARRAY_TEX_UV2: {
- if (s->format & RS::ARRAY_COMPRESS_TEX_UV2) {
- vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
- stride += sizeof(int16_t) * 2;
- } else {
- vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
- stride += sizeof(float) * 2;
- }
+ vd.offset = attribute_stride;
+ vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
+ attribute_stride += sizeof(float) * 2;
+ buffer = s->attribute_buffer;
+ } break;
+ case RS::ARRAY_CUSTOM0:
+ case RS::ARRAY_CUSTOM1:
+ case RS::ARRAY_CUSTOM2:
+ case RS::ARRAY_CUSTOM3: {
+ vd.offset = attribute_stride;
+
+ int idx = i - RS::ARRAY_CUSTOM0;
+ uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
+ uint32_t fmt = (s->format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
+ uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
+ RD::DataFormat fmtrd[RS::ARRAY_CUSTOM_MAX] = { RD::DATA_FORMAT_R8G8B8A8_UNORM, RD::DATA_FORMAT_R8G8B8A8_SNORM, RD::DATA_FORMAT_R16G16_SFLOAT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::DATA_FORMAT_R32_SFLOAT, RD::DATA_FORMAT_R32G32_SFLOAT, RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::DATA_FORMAT_R32G32B32A32_SFLOAT };
+ vd.format = fmtrd[fmt];
+ attribute_stride += fmtsize[fmt];
+ buffer = s->attribute_buffer;
} break;
case RS::ARRAY_BONES: {
- //assumed weights too
+ vd.offset = skin_stride;
- //unique format, internally 16 bits, exposed as single array for 32
-
- vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
- stride += sizeof(int32_t) * 4;
+ vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
+ skin_stride += sizeof(int16_t) * 4;
+ buffer = s->skin_buffer;
+ } break;
+ case RS::ARRAY_WEIGHTS: {
+ vd.offset = skin_stride;
+ vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
+ skin_stride += sizeof(int16_t) * 4;
+ buffer = s->skin_buffer;
} break;
}
}
if (!(p_input_mask & (1 << i))) {
- continue; // Shader does not need this, skip it
+ continue; // Shader does not need this, skip it (but computing stride was important anyway)
}
attributes.push_back(vd);
@@ -2922,8 +3246,17 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
//update final stride
for (int i = 0; i < attributes.size(); i++) {
- if (attributes[i].stride == 1) {
+ if (attributes[i].stride == 0) {
+ continue; //default location
+ }
+ int loc = attributes[i].location;
+
+ if (loc < RS::ARRAY_COLOR) {
attributes.write[i].stride = stride;
+ } else if (loc < RS::ARRAY_BONES) {
+ attributes.write[i].stride = attribute_stride;
+ } else {
+ attributes.write[i].stride = skin_stride;
}
}
@@ -2934,11 +3267,11 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
////////////////// MULTIMESH
-RID RasterizerStorageRD::multimesh_create() {
+RID RendererStorageRD::multimesh_create() {
return multimesh_owner.make_rid(MultiMesh());
}
-void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
+void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
@@ -2976,15 +3309,17 @@ void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, R
if (multimesh->instances) {
multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4);
}
+
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH);
}
-int RasterizerStorageRD::multimesh_get_instance_count(RID p_multimesh) const {
+int RendererStorageRD::multimesh_get_instance_count(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, 0);
return multimesh->instances;
}
-void RasterizerStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
+void RendererStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
if (multimesh->mesh == p_mesh) {
@@ -3009,12 +3344,12 @@ void RasterizerStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
}
}
- multimesh->instance_dependency.instance_notify_changed(true, true);
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
}
#define MULTIMESH_DIRTY_REGION_SIZE 512
-void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const {
+void RendererStorageRD::_multimesh_make_local(MultiMesh *multimesh) const {
if (multimesh->data_cache.size() > 0) {
return; //already local
}
@@ -3043,7 +3378,7 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const {
multimesh->data_cache_used_dirty_regions = 0;
}
-void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) {
+void RendererStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) {
uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE;
#ifdef DEBUG_ENABLED
uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
@@ -3065,7 +3400,7 @@ void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_inde
}
}
-void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) {
+void RendererStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) {
if (p_data) {
uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
@@ -3088,7 +3423,7 @@ void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p
}
}
-void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) {
+void RendererStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) {
ERR_FAIL_COND(multimesh->mesh.is_null());
AABB aabb;
AABB mesh_aabb = mesh_get_aabb(multimesh->mesh);
@@ -3130,7 +3465,7 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const
multimesh->aabb = aabb;
}
-void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
+void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -3160,7 +3495,7 @@ void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int
_multimesh_mark_dirty(multimesh, p_index, true);
}
-void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {
+void RendererStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -3186,7 +3521,7 @@ void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, i
_multimesh_mark_dirty(multimesh, p_index, true);
}
-void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
+void RendererStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -3208,7 +3543,7 @@ void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_in
_multimesh_mark_dirty(multimesh, p_index, false);
}
-void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {
+void RendererStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -3230,14 +3565,14 @@ void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, in
_multimesh_mark_dirty(multimesh, p_index, false);
}
-RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const {
+RID RendererStorageRD::multimesh_get_mesh(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, RID());
return multimesh->mesh;
}
-Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
+Transform RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Transform());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform());
@@ -3268,7 +3603,7 @@ Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh,
return t;
}
-Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
+Transform2D RendererStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Transform2D());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D());
@@ -3293,7 +3628,7 @@ Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multi
return t;
}
-Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
+Color RendererStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Color());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
@@ -3316,7 +3651,7 @@ Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_i
return c;
}
-Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
+Color RendererStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Color());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
@@ -3339,7 +3674,7 @@ Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, i
return c;
}
-void RasterizerStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {
+void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));
@@ -3368,11 +3703,11 @@ void RasterizerStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<flo
const float *data = p_buffer.ptr();
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
- multimesh->instance_dependency.instance_notify_changed(true, false);
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
}
-Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const {
+Vector<float> RendererStorageRD::multimesh_get_buffer(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Vector<float>());
if (multimesh->buffer.is_null()) {
@@ -3395,7 +3730,7 @@ Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const {
}
}
-void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
+void RendererStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances);
@@ -3409,24 +3744,26 @@ void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p
}
multimesh->visible_instances = p_visible;
+
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
}
-int RasterizerStorageRD::multimesh_get_visible_instances(RID p_multimesh) const {
+int RendererStorageRD::multimesh_get_visible_instances(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, 0);
return multimesh->visible_instances;
}
-AABB RasterizerStorageRD::multimesh_get_aabb(RID p_multimesh) const {
+AABB RendererStorageRD::multimesh_get_aabb(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, AABB());
if (multimesh->aabb_dirty) {
- const_cast<RasterizerStorageRD *>(this)->_update_dirty_multimeshes();
+ const_cast<RendererStorageRD *>(this)->_update_dirty_multimeshes();
}
return multimesh->aabb;
}
-void RasterizerStorageRD::_update_dirty_multimeshes() {
+void RendererStorageRD::_update_dirty_multimeshes() {
while (multimesh_dirty_list) {
MultiMesh *multimesh = multimesh_dirty_list;
@@ -3466,7 +3803,7 @@ void RasterizerStorageRD::_update_dirty_multimeshes() {
//aabb is dirty..
_multimesh_re_create_aabb(multimesh, data, visible_instances);
multimesh->aabb_dirty = false;
- multimesh->instance_dependency.instance_notify_changed(true, false);
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
}
@@ -3481,25 +3818,25 @@ void RasterizerStorageRD::_update_dirty_multimeshes() {
/* PARTICLES */
-RID RasterizerStorageRD::particles_create() {
+RID RendererStorageRD::particles_create() {
return particles_owner.make_rid(Particles());
}
-void RasterizerStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) {
+void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->emitting = p_emitting;
}
-bool RasterizerStorageRD::particles_get_emitting(RID p_particles) {
+bool RendererStorageRD::particles_get_emitting(RID p_particles) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, false);
return particles->emitting;
}
-void RasterizerStorageRD::_particles_free_data(Particles *particles) {
+void RendererStorageRD::_particles_free_data(Particles *particles) {
if (!particles->particle_buffer.is_valid()) {
return;
}
@@ -3526,7 +3863,7 @@ void RasterizerStorageRD::_particles_free_data(Particles *particles) {
}
}
-void RasterizerStorageRD::particles_set_amount(RID p_particles, int p_amount) {
+void RendererStorageRD::particles_set_amount(RID p_particles, int p_amount) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
@@ -3549,14 +3886,14 @@ void RasterizerStorageRD::particles_set_amount(RID p_particles, int p_amount) {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
u.ids.push_back(particles->particle_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
u.ids.push_back(particles->particle_instance_buffer);
uniforms.push_back(u);
@@ -3572,111 +3909,111 @@ void RasterizerStorageRD::particles_set_amount(RID p_particles, int p_amount) {
particles->clear = true;
}
-void RasterizerStorageRD::particles_set_lifetime(RID p_particles, float p_lifetime) {
+void RendererStorageRD::particles_set_lifetime(RID p_particles, float p_lifetime) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->lifetime = p_lifetime;
}
-void RasterizerStorageRD::particles_set_one_shot(RID p_particles, bool p_one_shot) {
+void RendererStorageRD::particles_set_one_shot(RID p_particles, bool p_one_shot) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->one_shot = p_one_shot;
}
-void RasterizerStorageRD::particles_set_pre_process_time(RID p_particles, float p_time) {
+void RendererStorageRD::particles_set_pre_process_time(RID p_particles, float p_time) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->pre_process_time = p_time;
}
-void RasterizerStorageRD::particles_set_explosiveness_ratio(RID p_particles, float p_ratio) {
+void RendererStorageRD::particles_set_explosiveness_ratio(RID p_particles, float p_ratio) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->explosiveness = p_ratio;
}
-void RasterizerStorageRD::particles_set_randomness_ratio(RID p_particles, float p_ratio) {
+void RendererStorageRD::particles_set_randomness_ratio(RID p_particles, float p_ratio) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->randomness = p_ratio;
}
-void RasterizerStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {
+void RendererStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->custom_aabb = p_aabb;
- particles->instance_dependency.instance_notify_changed(true, false);
+ particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-void RasterizerStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) {
+void RendererStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->speed_scale = p_scale;
}
-void RasterizerStorageRD::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
+void RendererStorageRD::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->use_local_coords = p_enable;
}
-void RasterizerStorageRD::particles_set_fixed_fps(RID p_particles, int p_fps) {
+void RendererStorageRD::particles_set_fixed_fps(RID p_particles, int p_fps) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->fixed_fps = p_fps;
}
-void RasterizerStorageRD::particles_set_fractional_delta(RID p_particles, bool p_enable) {
+void RendererStorageRD::particles_set_fractional_delta(RID p_particles, bool p_enable) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->fractional_delta = p_enable;
}
-void RasterizerStorageRD::particles_set_collision_base_size(RID p_particles, float p_size) {
+void RendererStorageRD::particles_set_collision_base_size(RID p_particles, float p_size) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->collision_base_size = p_size;
}
-void RasterizerStorageRD::particles_set_process_material(RID p_particles, RID p_material) {
+void RendererStorageRD::particles_set_process_material(RID p_particles, RID p_material) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->process_material = p_material;
}
-void RasterizerStorageRD::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) {
+void RendererStorageRD::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->draw_order = p_order;
}
-void RasterizerStorageRD::particles_set_draw_passes(RID p_particles, int p_passes) {
+void RendererStorageRD::particles_set_draw_passes(RID p_particles, int p_passes) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->draw_passes.resize(p_passes);
}
-void RasterizerStorageRD::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {
+void RendererStorageRD::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
particles->draw_passes.write[p_pass] = p_mesh;
}
-void RasterizerStorageRD::particles_restart(RID p_particles) {
+void RendererStorageRD::particles_restart(RID p_particles) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->restart_request = true;
}
-void RasterizerStorageRD::_particles_allocate_emission_buffer(Particles *particles) {
+void RendererStorageRD::_particles_allocate_emission_buffer(Particles *particles) {
ERR_FAIL_COND(particles->emission_buffer != nullptr);
particles->emission_buffer_data.resize(sizeof(ParticleEmissionBuffer::Data) * particles->amount + sizeof(uint32_t) * 4);
@@ -3693,7 +4030,7 @@ void RasterizerStorageRD::_particles_allocate_emission_buffer(Particles *particl
}
}
-void RasterizerStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) {
+void RendererStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_COND(p_particles == p_subemitter_particles);
@@ -3706,7 +4043,7 @@ void RasterizerStorageRD::particles_set_subemitter(RID p_particles, RID p_subemi
}
}
-void RasterizerStorageRD::particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
+void RendererStorageRD::particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_COND(particles->amount == 0);
@@ -3749,7 +4086,7 @@ void RasterizerStorageRD::particles_emit(RID p_particles, const Transform &p_tra
}
}
-void RasterizerStorageRD::particles_request_process(RID p_particles) {
+void RendererStorageRD::particles_request_process(RID p_particles) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
@@ -3760,7 +4097,7 @@ void RasterizerStorageRD::particles_request_process(RID p_particles) {
}
}
-AABB RasterizerStorageRD::particles_get_current_aabb(RID p_particles) {
+AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, AABB());
@@ -3804,28 +4141,28 @@ AABB RasterizerStorageRD::particles_get_current_aabb(RID p_particles) {
return aabb;
}
-AABB RasterizerStorageRD::particles_get_aabb(RID p_particles) const {
+AABB RendererStorageRD::particles_get_aabb(RID p_particles) const {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, AABB());
return particles->custom_aabb;
}
-void RasterizerStorageRD::particles_set_emission_transform(RID p_particles, const Transform &p_transform) {
+void RendererStorageRD::particles_set_emission_transform(RID p_particles, const Transform &p_transform) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->emission_transform = p_transform;
}
-int RasterizerStorageRD::particles_get_draw_passes(RID p_particles) const {
+int RendererStorageRD::particles_get_draw_passes(RID p_particles) const {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, 0);
return particles->draw_passes.size();
}
-RID RasterizerStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
+RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, RID());
ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID());
@@ -3833,36 +4170,34 @@ RID RasterizerStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pas
return particles->draw_passes[p_pass];
}
-void RasterizerStorageRD::particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) {
+void RendererStorageRD::particles_add_collision(RID p_particles, RID p_particles_collision_instance) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_PARTICLES_COLLISION);
-
- particles->collisions.insert(p_instance);
+ particles->collisions.insert(p_particles_collision_instance);
}
-void RasterizerStorageRD::particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) {
+void RendererStorageRD::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- particles->collisions.erase(p_instance);
+ particles->collisions.erase(p_particles_collision_instance);
}
-void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_delta) {
+void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta) {
if (p_particles->particles_material_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_particles->particles_material_uniform_set)) {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 0;
u.ids.push_back(p_particles->frame_params_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
u.ids.push_back(p_particles->particle_buffer);
uniforms.push_back(u);
@@ -3870,7 +4205,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
if (p_particles->emission_storage_buffer.is_valid()) {
u.ids.push_back(p_particles->emission_storage_buffer);
@@ -3881,7 +4216,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 3;
Particles *sub_emitter = particles_owner.getornull(p_particles->sub_emitter);
if (sub_emitter) {
@@ -3918,7 +4253,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del
p_particles->phase = new_phase;
- frame_params.time = RasterizerRD::singleton->get_total_time();
+ frame_params.time = RendererCompositorRD::singleton->get_total_time();
frame_params.delta = p_delta * p_particles->speed_scale;
frame_params.random_seed = p_particles->random_seed;
frame_params.explosiveness = p_particles->explosiveness;
@@ -3946,9 +4281,15 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del
to_particles = p_particles->emission_transform.affine_inverse();
}
uint32_t collision_3d_textures_used = 0;
- for (const Set<RasterizerScene::InstanceBase *>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
- ParticlesCollision *pc = particles_collision_owner.getornull(E->get()->base);
- Transform to_collider = E->get()->transform;
+ for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
+ ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(E->get());
+ if (!pci || !pci->active) {
+ continue;
+ }
+ ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision);
+ ERR_CONTINUE(!pc);
+
+ Transform to_collider = pci->transform;
if (p_particles->use_local_coords) {
to_collider = to_particles * to_collider;
}
@@ -4088,7 +4429,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
for (uint32_t i = 0; i < ParticlesFrameParams::MAX_3D_TEXTURES; i++) {
RID rd_tex;
@@ -4108,7 +4449,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1;
if (collision_heightmap_texture.is_valid()) {
u.ids.push_back(collision_heightmap_texture);
@@ -4188,7 +4529,7 @@ void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_del
RD::get_singleton()->compute_list_end();
}
-void RasterizerStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &p_axis) {
+void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &p_axis) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
@@ -4209,7 +4550,7 @@ void RasterizerStorageRD::particles_set_view_axis(RID p_particles, const Vector3
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 0;
u.ids.push_back(particles->particles_sort_buffer);
uniforms.push_back(u);
@@ -4254,7 +4595,7 @@ void RasterizerStorageRD::particles_set_view_axis(RID p_particles, const Vector3
RD::get_singleton()->compute_list_end();
}
-void RasterizerStorageRD::update_particles() {
+void RendererStorageRD::update_particles() {
while (particle_update_list) {
//use transform feedback to process particles
@@ -4289,7 +4630,7 @@ void RasterizerStorageRD::update_particles() {
particles->inactive = false;
particles->inactive_time = 0;
} else {
- particles->inactive_time += particles->speed_scale * RasterizerRD::singleton->get_frame_delta_time();
+ particles->inactive_time += particles->speed_scale * RendererCompositorRD::singleton->get_frame_delta_time();
if (particles->inactive_time > particles->lifetime * 1.2) {
particles->inactive = true;
continue;
@@ -4323,7 +4664,7 @@ void RasterizerStorageRD::update_particles() {
frame_time = 1.0 / particles->fixed_fps;
decr = frame_time;
}
- float delta = RasterizerRD::singleton->get_frame_delta_time();
+ float delta = RendererCompositorRD::singleton->get_frame_delta_time();
if (delta > 0.1) { //avoid recursive stalls if fps goes below 10
delta = 0.1;
} else if (delta <= 0.0) { //unlikely but..
@@ -4342,7 +4683,7 @@ void RasterizerStorageRD::update_particles() {
if (zero_time_scale)
_particles_process(particles, 0.0);
else
- _particles_process(particles, RasterizerRD::singleton->get_frame_delta_time());
+ _particles_process(particles, RendererCompositorRD::singleton->get_frame_delta_time());
}
//copy particles to instance buffer
@@ -4361,11 +4702,11 @@ void RasterizerStorageRD::update_particles() {
RD::get_singleton()->compute_list_end();
}
- particles->instance_dependency.instance_notify_changed(true, false); //make sure shadows are updated
+ particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
}
-bool RasterizerStorageRD::particles_is_inactive(RID p_particles) const {
+bool RendererStorageRD::particles_is_inactive(RID p_particles) const {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, false);
return !particles->emitting && particles->inactive;
@@ -4373,7 +4714,7 @@ bool RasterizerStorageRD::particles_is_inactive(RID p_particles) const {
/* SKY SHADER */
-void RasterizerStorageRD::ParticlesShaderData::set_code(const String &p_code) {
+void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
//compile
code = p_code;
@@ -4421,7 +4762,7 @@ void RasterizerStorageRD::ParticlesShaderData::set_code(const String &p_code) {
valid = true;
}
-void RasterizerStorageRD::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererStorageRD::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
if (!p_texture.is_valid()) {
default_texture_params.erase(p_name);
} else {
@@ -4429,7 +4770,7 @@ void RasterizerStorageRD::ParticlesShaderData::set_default_texture_param(const S
}
}
-void RasterizerStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void RendererStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
@@ -4451,13 +4792,13 @@ void RasterizerStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo>
}
}
-void RasterizerStorageRD::ParticlesShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+void RendererStorageRD::ParticlesShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
- RasterizerStorage::InstanceShaderParam p;
+ RendererStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E->get());
p.info.name = E->key(); //supply name
p.index = E->get().instance_index;
@@ -4466,7 +4807,7 @@ void RasterizerStorageRD::ParticlesShaderData::get_instance_param_list(List<Rast
}
}
-bool RasterizerStorageRD::ParticlesShaderData::is_param_texture(const StringName &p_param) const {
+bool RendererStorageRD::ParticlesShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -4474,15 +4815,15 @@ bool RasterizerStorageRD::ParticlesShaderData::is_param_texture(const StringName
return uniforms[p_param].texture_order >= 0;
}
-bool RasterizerStorageRD::ParticlesShaderData::is_animated() const {
+bool RendererStorageRD::ParticlesShaderData::is_animated() const {
return false;
}
-bool RasterizerStorageRD::ParticlesShaderData::casts_shadows() const {
+bool RendererStorageRD::ParticlesShaderData::casts_shadows() const {
return false;
}
-Variant RasterizerStorageRD::ParticlesShaderData::get_default_parameter(const StringName &p_parameter) const {
+Variant RendererStorageRD::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;
@@ -4491,23 +4832,27 @@ Variant RasterizerStorageRD::ParticlesShaderData::get_default_parameter(const St
return Variant();
}
-RasterizerStorageRD::ParticlesShaderData::ParticlesShaderData() {
+RS::ShaderNativeSourceCode RendererStorageRD::ParticlesShaderData::get_native_source_code() const {
+ return base_singleton->particles_shader.shader.version_get_native_source_code(version);
+}
+
+RendererStorageRD::ParticlesShaderData::ParticlesShaderData() {
valid = false;
}
-RasterizerStorageRD::ParticlesShaderData::~ParticlesShaderData() {
+RendererStorageRD::ParticlesShaderData::~ParticlesShaderData() {
//pipeline variants will clear themselves if shader is gone
if (version.is_valid()) {
base_singleton->particles_shader.shader.version_free(version);
}
}
-RasterizerStorageRD::ShaderData *RasterizerStorageRD::_create_particles_shader_func() {
+RendererStorageRD::ShaderData *RendererStorageRD::_create_particles_shader_func() {
ParticlesShaderData *shader_data = memnew(ParticlesShaderData);
return shader_data;
}
-void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+void RendererStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
uniform_set_updated = true;
if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
@@ -4568,7 +4913,7 @@ void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<Str
{
if (shader_data->ubo_size) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 0;
u.ids.push_back(uniform_buffer);
uniforms.push_back(u);
@@ -4577,7 +4922,7 @@ void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<Str
const RID *textures = texture_cache.ptrw();
for (uint32_t i = 0; i < tex_uniform_count; i++) {
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1 + i;
u.ids.push_back(textures[i]);
uniforms.push_back(u);
@@ -4587,7 +4932,7 @@ void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<Str
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 3);
}
-RasterizerStorageRD::ParticlesMaterialData::~ParticlesMaterialData() {
+RendererStorageRD::ParticlesMaterialData::~ParticlesMaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
}
@@ -4597,7 +4942,7 @@ RasterizerStorageRD::ParticlesMaterialData::~ParticlesMaterialData() {
}
}
-RasterizerStorageRD::MaterialData *RasterizerStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) {
+RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) {
ParticlesMaterialData *material_data = memnew(ParticlesMaterialData);
material_data->shader_data = p_shader;
material_data->last_frame = false;
@@ -4608,11 +4953,11 @@ RasterizerStorageRD::MaterialData *RasterizerStorageRD::_create_particles_materi
/* PARTICLES COLLISION API */
-RID RasterizerStorageRD::particles_collision_create() {
+RID RendererStorageRD::particles_collision_create() {
return particles_collision_owner.make_rid(ParticlesCollision());
}
-RID RasterizerStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const {
+RID RendererStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND_V(!particles_collision, RID());
ERR_FAIL_COND_V(particles_collision->type != RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE, RID());
@@ -4633,7 +4978,7 @@ RID RasterizerStorageRD::particles_collision_get_heightfield_framebuffer(RID p_p
tf.format = RD::DATA_FORMAT_D32_SFLOAT;
tf.width = size.x;
tf.height = size.y;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
particles_collision->heightfield_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -4647,7 +4992,7 @@ RID RasterizerStorageRD::particles_collision_get_heightfield_framebuffer(RID p_p
return particles_collision->heightfield_fb;
}
-void RasterizerStorageRD::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) {
+void RendererStorageRD::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
@@ -4660,66 +5005,66 @@ void RasterizerStorageRD::particles_collision_set_collision_type(RID p_particles
particles_collision->heightfield_texture = RID();
}
particles_collision->type = p_type;
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-void RasterizerStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
+void RendererStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
particles_collision->cull_mask = p_cull_mask;
}
-void RasterizerStorageRD::particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) {
+void RendererStorageRD::particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
particles_collision->radius = p_radius;
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-void RasterizerStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
+void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
particles_collision->extents = p_extents;
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-void RasterizerStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) {
+void RendererStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
particles_collision->attractor_strength = p_strength;
}
-void RasterizerStorageRD::particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) {
+void RendererStorageRD::particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
particles_collision->attractor_directionality = p_directionality;
}
-void RasterizerStorageRD::particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) {
+void RendererStorageRD::particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
particles_collision->attractor_attenuation = p_curve;
}
-void RasterizerStorageRD::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) {
+void RendererStorageRD::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
particles_collision->field_texture = p_texture;
}
-void RasterizerStorageRD::particles_collision_height_field_update(RID p_particles_collision) {
+void RendererStorageRD::particles_collision_height_field_update(RID p_particles_collision) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-void RasterizerStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
+void RendererStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
@@ -4735,7 +5080,7 @@ void RasterizerStorageRD::particles_collision_set_height_field_resolution(RID p_
}
}
-AABB RasterizerStorageRD::particles_collision_get_aabb(RID p_particles_collision) const {
+AABB RendererStorageRD::particles_collision_get_aabb(RID p_particles_collision) const {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND_V(!particles_collision, AABB());
@@ -4758,25 +5103,41 @@ AABB RasterizerStorageRD::particles_collision_get_aabb(RID p_particles_collision
return AABB();
}
-Vector3 RasterizerStorageRD::particles_collision_get_extents(RID p_particles_collision) const {
+Vector3 RendererStorageRD::particles_collision_get_extents(RID p_particles_collision) const {
const ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND_V(!particles_collision, Vector3());
return particles_collision->extents;
}
-bool RasterizerStorageRD::particles_collision_is_heightfield(RID p_particles_collision) const {
+bool RendererStorageRD::particles_collision_is_heightfield(RID p_particles_collision) const {
const ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND_V(!particles_collision, false);
return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE;
}
+RID RendererStorageRD::particles_collision_instance_create(RID p_collision) {
+ ParticlesCollisionInstance pci;
+ pci.collision = p_collision;
+ return particles_collision_instance_owner.make_rid(pci);
+}
+void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) {
+ ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
+ ERR_FAIL_COND(!pci);
+ pci->transform = p_transform;
+}
+void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) {
+ ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
+ ERR_FAIL_COND(!pci);
+ pci->active = p_active;
+}
+
/* SKELETON API */
-RID RasterizerStorageRD::skeleton_create() {
+RID RendererStorageRD::skeleton_create() {
return skeleton_owner.make_rid(Skeleton());
}
-void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) {
+void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) {
if (!skeleton->dirty) {
skeleton->dirty = true;
skeleton->dirty_list = skeleton_dirty_list;
@@ -4784,7 +5145,7 @@ void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) {
}
}
-void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
+void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
ERR_FAIL_COND(p_bones < 0);
@@ -4801,6 +5162,7 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_
RD::get_singleton()->free(skeleton->buffer);
skeleton->buffer = RID();
skeleton->data.resize(0);
+ skeleton->uniform_set_mi = RID();
}
if (skeleton->size) {
@@ -4809,17 +5171,31 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_
zeromem(skeleton->data.ptrw(), skeleton->data.size() * sizeof(float));
_skeleton_make_dirty(skeleton);
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 0;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(skeleton->buffer);
+ uniforms.push_back(u);
+ }
+ skeleton->uniform_set_mi = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON);
+ }
}
+
+ skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_DATA);
}
-int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
+int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, 0);
return skeleton->size;
}
-void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
+void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -4844,7 +5220,7 @@ void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone
_skeleton_make_dirty(skeleton);
}
-Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
+Transform RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, Transform());
@@ -4871,7 +5247,7 @@ Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p
return t;
}
-void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
+void RendererStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -4892,7 +5268,7 @@ void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_b
_skeleton_make_dirty(skeleton);
}
-Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
+Transform2D RendererStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, Transform2D());
@@ -4912,7 +5288,7 @@ Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton,
return t;
}
-void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
+void RendererStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton->use_2d);
@@ -4920,7 +5296,7 @@ void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const T
skeleton->base_transform_2d = p_base_transform;
}
-void RasterizerStorageRD::_update_dirty_skeletons() {
+void RendererStorageRD::_update_dirty_skeletons() {
while (skeleton_dirty_list) {
Skeleton *skeleton = skeleton_dirty_list;
@@ -4930,7 +5306,9 @@ void RasterizerStorageRD::_update_dirty_skeletons() {
skeleton_dirty_list = skeleton->dirty_list;
- skeleton->instance_dependency.instance_notify_changed(true, false);
+ skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_BONES);
+
+ skeleton->version++;
skeleton->dirty = false;
skeleton->dirty_list = nullptr;
@@ -4941,7 +5319,7 @@ void RasterizerStorageRD::_update_dirty_skeletons() {
/* LIGHT */
-RID RasterizerStorageRD::light_create(RS::LightType p_type) {
+RID RendererStorageRD::light_create(RS::LightType p_type) {
Light light;
light.type = p_type;
@@ -4950,29 +5328,32 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) {
light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
+ light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;
light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
+ light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;
light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
- light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
+ light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
+ light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
- light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0;
+ light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
return light_owner.make_rid(light);
}
-void RasterizerStorageRD::light_set_color(RID p_light, const Color &p_color) {
+void RendererStorageRD::light_set_color(RID p_light, const Color &p_color) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->color = p_color;
}
-void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
+void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX);
@@ -4988,7 +5369,7 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f
case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
case RS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
} break;
default: {
}
@@ -4997,22 +5378,22 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f
light->param[p_param] = p_value;
}
-void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
+void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->shadow = p_enabled;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-void RasterizerStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) {
+void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->shadow_color = p_color;
}
-void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) {
+void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -5031,138 +5412,152 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) {
}
}
-void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) {
+void RendererStorageRD::light_set_negative(RID p_light, bool p_enable) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->negative = p_enable;
}
-void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
+void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->cull_mask = p_mask;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-void RasterizerStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
+void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->reverse_cull = p_enabled;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-void RasterizerStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
+void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->bake_mode = p_bake_mode;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-void RasterizerStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
+void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->max_sdfgi_cascade = p_cascade;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
+void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->omni_shadow_mode = p_mode;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_light) {
+RS::LightOmniShadowMode RendererStorageRD::light_omni_get_shadow_mode(RID p_light) {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE);
return light->omni_shadow_mode;
}
-void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
+void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->directional_shadow_mode = p_mode;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) {
+void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->directional_blend_splits = p_enable;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
-bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const {
+bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, false);
return light->directional_blend_splits;
}
-RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) {
+void RendererStorageRD::light_directional_set_sky_only(RID p_light, bool p_sky_only) {
+ Light *light = light_owner.getornull(p_light);
+ ERR_FAIL_COND(!light);
+
+ light->directional_sky_only = p_sky_only;
+}
+
+bool RendererStorageRD::light_directional_is_sky_only(RID p_light) const {
+ const Light *light = light_owner.getornull(p_light);
+ ERR_FAIL_COND_V(!light, false);
+
+ return light->directional_sky_only;
+}
+
+RS::LightDirectionalShadowMode RendererStorageRD::light_directional_get_shadow_mode(RID p_light) {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
return light->directional_shadow_mode;
}
-void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) {
+void RendererStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->directional_range_mode = p_range_mode;
}
-RS::LightDirectionalShadowDepthRangeMode RasterizerStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const {
+RS::LightDirectionalShadowDepthRangeMode RendererStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE);
return light->directional_range_mode;
}
-uint32_t RasterizerStorageRD::light_get_max_sdfgi_cascade(RID p_light) {
+uint32_t RendererStorageRD::light_get_max_sdfgi_cascade(RID p_light) {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, 0);
return light->max_sdfgi_cascade;
}
-RS::LightBakeMode RasterizerStorageRD::light_get_bake_mode(RID p_light) {
+RS::LightBakeMode RendererStorageRD::light_get_bake_mode(RID p_light) {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_BAKE_DISABLED);
return light->bake_mode;
}
-uint64_t RasterizerStorageRD::light_get_version(RID p_light) const {
+uint64_t RendererStorageRD::light_get_version(RID p_light) const {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, 0);
return light->version;
}
-AABB RasterizerStorageRD::light_get_aabb(RID p_light) const {
+AABB RendererStorageRD::light_get_aabb(RID p_light) const {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, AABB());
@@ -5186,56 +5581,56 @@ AABB RasterizerStorageRD::light_get_aabb(RID p_light) const {
/* REFLECTION PROBE */
-RID RasterizerStorageRD::reflection_probe_create() {
+RID RendererStorageRD::reflection_probe_create() {
return reflection_probe_owner.make_rid(ReflectionProbe());
}
-void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
+void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->update_mode = p_mode;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
+void RendererStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->intensity = p_intensity;
}
-void RasterizerStorageRD::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {
+void RendererStorageRD::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->ambient_mode = p_mode;
}
-void RasterizerStorageRD::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {
+void RendererStorageRD::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->ambient_color = p_color;
}
-void RasterizerStorageRD::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {
+void RendererStorageRD::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->ambient_color_energy = p_energy;
}
-void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
+void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->max_distance = p_distance;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
+void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -5243,49 +5638,49 @@ void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector
return;
}
reflection_probe->extents = p_extents;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
+void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->origin_offset = p_offset;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void RasterizerStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
+void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
+void RendererStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->box_projection = p_enable;
}
-void RasterizerStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
+void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->enable_shadows = p_enable;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
+void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->cull_mask = p_layers;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
-void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
+void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
ERR_FAIL_COND(p_resolution < 32);
@@ -5293,7 +5688,16 @@ void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_res
reflection_probe->resolution = p_resolution;
}
-AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const {
+void RendererStorageRD::reflection_probe_set_lod_threshold(RID p_probe, float p_ratio) {
+ ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND(!reflection_probe);
+
+ reflection_probe->lod_threshold = p_ratio;
+
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
+AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, AABB());
@@ -5304,107 +5708,114 @@ AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const {
return aabb;
}
-RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const {
+RS::ReflectionProbeUpdateMode RendererStorageRD::reflection_probe_get_update_mode(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS);
return reflection_probe->update_mode;
}
-uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const {
+uint32_t RendererStorageRD::reflection_probe_get_cull_mask(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
return reflection_probe->cull_mask;
}
-Vector3 RasterizerStorageRD::reflection_probe_get_extents(RID p_probe) const {
+Vector3 RendererStorageRD::reflection_probe_get_extents(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Vector3());
return reflection_probe->extents;
}
-Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const {
+Vector3 RendererStorageRD::reflection_probe_get_origin_offset(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Vector3());
return reflection_probe->origin_offset;
}
-bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const {
+bool RendererStorageRD::reflection_probe_renders_shadows(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, false);
return reflection_probe->enable_shadows;
}
-float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const {
+float RendererStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
return reflection_probe->max_distance;
}
-int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const {
+float RendererStorageRD::reflection_probe_get_lod_threshold(RID p_probe) const {
+ const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND_V(!reflection_probe, 0);
+
+ return reflection_probe->lod_threshold;
+}
+
+int RendererStorageRD::reflection_probe_get_resolution(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
return reflection_probe->resolution;
}
-float RasterizerStorageRD::reflection_probe_get_intensity(RID p_probe) const {
+float RendererStorageRD::reflection_probe_get_intensity(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
return reflection_probe->intensity;
}
-bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const {
+bool RendererStorageRD::reflection_probe_is_interior(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, false);
return reflection_probe->interior;
}
-bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const {
+bool RendererStorageRD::reflection_probe_is_box_projection(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, false);
return reflection_probe->box_projection;
}
-RS::ReflectionProbeAmbientMode RasterizerStorageRD::reflection_probe_get_ambient_mode(RID p_probe) const {
+RS::ReflectionProbeAmbientMode RendererStorageRD::reflection_probe_get_ambient_mode(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_AMBIENT_DISABLED);
return reflection_probe->ambient_mode;
}
-Color RasterizerStorageRD::reflection_probe_get_ambient_color(RID p_probe) const {
+Color RendererStorageRD::reflection_probe_get_ambient_color(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Color());
return reflection_probe->ambient_color;
}
-float RasterizerStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) const {
+float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
return reflection_probe->ambient_color_energy;
}
-RID RasterizerStorageRD::decal_create() {
+RID RendererStorageRD::decal_create() {
return decal_owner.make_rid(Decal());
}
-void RasterizerStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
+void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->extents = p_extents;
- decal->instance_dependency.instance_notify_changed(true, false);
+ decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
+void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
@@ -5425,35 +5836,35 @@ void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type
texture_add_to_decal_atlas(decal->textures[p_type]);
}
- decal->instance_dependency.instance_notify_changed(false, true);
+ decal->dependency.changed_notify(DEPENDENCY_CHANGED_DECAL);
}
-void RasterizerStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
+void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->emission_energy = p_energy;
}
-void RasterizerStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) {
+void RendererStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->albedo_mix = p_mix;
}
-void RasterizerStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) {
+void RendererStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->modulate = p_modulate;
}
-void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
+void RendererStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->cull_mask = p_layers;
- decal->instance_dependency.instance_notify_changed(true, false);
+ decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
+void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->distance_fade = p_enabled;
@@ -5461,31 +5872,31 @@ void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, f
decal->distance_fade_length = p_length;
}
-void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) {
+void RendererStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->upper_fade = p_above;
decal->lower_fade = p_below;
}
-void RasterizerStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) {
+void RendererStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->normal_fade = p_fade;
}
-AABB RasterizerStorageRD::decal_get_aabb(RID p_decal) const {
+AABB RendererStorageRD::decal_get_aabb(RID p_decal) const {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND_V(!decal, AABB());
return AABB(-decal->extents, decal->extents * 2.0);
}
-RID RasterizerStorageRD::gi_probe_create() {
+RID RendererStorageRD::gi_probe_create() {
return gi_probe_owner.make_rid(GIProbe());
}
-void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
+void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -5528,7 +5939,7 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t
tf.width = gi_probe->octree_size.x;
tf.height = gi_probe->octree_size.y;
tf.depth = gi_probe->octree_size.z;
- tf.type = RD::TEXTURE_TYPE_3D;
+ tf.texture_type = RD::TEXTURE_TYPE_3D;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
Vector<Vector<uint8_t>> s;
s.push_back(p_distance_field);
@@ -5557,21 +5968,21 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
u.ids.push_back(gi_probe->octree_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
u.ids.push_back(gi_probe->data_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 3;
u.ids.push_back(shared_tex);
uniforms.push_back(u);
@@ -5607,23 +6018,23 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t
gi_probe->version++;
gi_probe->data_version++;
- gi_probe->instance_dependency.instance_notify_changed(true, false);
+ gi_probe->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-AABB RasterizerStorageRD::gi_probe_get_bounds(RID p_gi_probe) const {
+AABB RendererStorageRD::gi_probe_get_bounds(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, AABB());
return gi_probe->bounds;
}
-Vector3i RasterizerStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const {
+Vector3i RendererStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector3i());
return gi_probe->octree_size;
}
-Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const {
+Vector<uint8_t> RendererStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
@@ -5633,7 +6044,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) c
return Vector<uint8_t>();
}
-Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const {
+Vector<uint8_t> RendererStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
@@ -5643,7 +6054,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) con
return Vector<uint8_t>();
}
-Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const {
+Vector<uint8_t> RendererStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
@@ -5653,21 +6064,21 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe)
return Vector<uint8_t>();
}
-Vector<int> RasterizerStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const {
+Vector<int> RendererStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<int>());
return gi_probe->level_counts;
}
-Transform RasterizerStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const {
+Transform RendererStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Transform());
return gi_probe->to_cell_xform;
}
-void RasterizerStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) {
+void RendererStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -5675,14 +6086,14 @@ void RasterizerStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_ran
gi_probe->version++;
}
-float RasterizerStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->dynamic_range;
}
-void RasterizerStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range) {
+void RendererStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -5690,98 +6101,98 @@ void RasterizerStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range
gi_probe->version++;
}
-float RasterizerStorageRD::gi_probe_get_propagation(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_propagation(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->propagation;
}
-void RasterizerStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) {
+void RendererStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->energy = p_energy;
}
-float RasterizerStorageRD::gi_probe_get_energy(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_energy(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->energy;
}
-void RasterizerStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) {
+void RendererStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->ao = p_ao;
}
-float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_ao(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->ao;
}
-void RasterizerStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) {
+void RendererStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->ao_size = p_strength;
}
-float RasterizerStorageRD::gi_probe_get_ao_size(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_ao_size(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->ao_size;
}
-void RasterizerStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) {
+void RendererStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->bias = p_bias;
}
-float RasterizerStorageRD::gi_probe_get_bias(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_bias(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->bias;
}
-void RasterizerStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_normal_bias) {
+void RendererStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_normal_bias) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->normal_bias = p_normal_bias;
}
-float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->normal_bias;
}
-void RasterizerStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) {
+void RendererStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->anisotropy_strength = p_strength;
}
-float RasterizerStorageRD::gi_probe_get_anisotropy_strength(RID p_gi_probe) const {
+float RendererStorageRD::gi_probe_get_anisotropy_strength(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->anisotropy_strength;
}
-void RasterizerStorageRD::gi_probe_set_interior(RID p_gi_probe, bool p_enable) {
+void RendererStorageRD::gi_probe_set_interior(RID p_gi_probe, bool p_enable) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
gi_probe->interior = p_enable;
}
-void RasterizerStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) {
+void RendererStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -5789,43 +6200,43 @@ void RasterizerStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_en
gi_probe->version++;
}
-bool RasterizerStorageRD::gi_probe_is_using_two_bounces(RID p_gi_probe) const {
+bool RendererStorageRD::gi_probe_is_using_two_bounces(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, false);
return gi_probe->use_two_bounces;
}
-bool RasterizerStorageRD::gi_probe_is_interior(RID p_gi_probe) const {
+bool RendererStorageRD::gi_probe_is_interior(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->interior;
}
-uint32_t RasterizerStorageRD::gi_probe_get_version(RID p_gi_probe) {
+uint32_t RendererStorageRD::gi_probe_get_version(RID p_gi_probe) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->version;
}
-uint32_t RasterizerStorageRD::gi_probe_get_data_version(RID p_gi_probe) {
+uint32_t RendererStorageRD::gi_probe_get_data_version(RID p_gi_probe) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
return gi_probe->data_version;
}
-RID RasterizerStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const {
+RID RendererStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, RID());
return gi_probe->octree_buffer;
}
-RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const {
+RID RendererStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, RID());
return gi_probe->data_buffer;
}
-RID RasterizerStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) {
+RID RendererStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, RID());
@@ -5834,11 +6245,11 @@ RID RasterizerStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) {
/* LIGHTMAP API */
-RID RasterizerStorageRD::lightmap_create() {
+RID RendererStorageRD::lightmap_create() {
return lightmap_owner.make_rid(Lightmap());
}
-void RasterizerStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
+void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND(!lm);
@@ -5886,19 +6297,19 @@ void RasterizerStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, boo
}
}
-void RasterizerStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
+void RendererStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND(!lm);
lm->bounds = p_bounds;
}
-void RasterizerStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
+void RendererStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND(!lm);
lm->interior = p_interior;
}
-void RasterizerStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
+void RendererStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND(!lm);
@@ -5914,36 +6325,36 @@ void RasterizerStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const
lm->tetrahedra = p_tetrahedra;
}
-PackedVector3Array RasterizerStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const {
+PackedVector3Array RendererStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND_V(!lm, PackedVector3Array());
return lm->points;
}
-PackedColorArray RasterizerStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const {
+PackedColorArray RendererStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND_V(!lm, PackedColorArray());
return lm->point_sh;
}
-PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
+PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND_V(!lm, PackedInt32Array());
return lm->tetrahedra;
}
-PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
+PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND_V(!lm, PackedInt32Array());
return lm->bsp_tree;
}
-void RasterizerStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) {
+void RendererStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) {
lightmap_probe_capture_update_speed = p_speed;
}
-void RasterizerStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
+void RendererStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND(!lm);
@@ -5993,13 +6404,13 @@ void RasterizerStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p
}
}
-bool RasterizerStorageRD::lightmap_is_interior(RID p_lightmap) const {
+bool RendererStorageRD::lightmap_is_interior(RID p_lightmap) const {
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND_V(!lm, false);
return lm->interior;
}
-AABB RasterizerStorageRD::lightmap_get_aabb(RID p_lightmap) const {
+AABB RendererStorageRD::lightmap_get_aabb(RID p_lightmap) const {
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND_V(!lm, AABB());
return lm->bounds;
@@ -6007,7 +6418,7 @@ AABB RasterizerStorageRD::lightmap_get_aabb(RID p_lightmap) const {
/* RENDER TARGET API */
-void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
+void RendererStorageRD::_clear_render_target(RenderTarget *rt) {
//free in reverse dependency order
if (rt->framebuffer.is_valid()) {
RD::get_singleton()->free(rt->framebuffer);
@@ -6035,7 +6446,7 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
rt->color = RID();
}
-void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
+void RendererStorageRD::_update_render_target(RenderTarget *rt) {
if (rt->texture.is_null()) {
//create a placeholder until updated
rt->texture = texture_2d_placeholder_create();
@@ -6062,7 +6473,7 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
rd_format.depth = 1;
rd_format.array_layers = 1;
rd_format.mipmaps = 1;
- rd_format.type = RD::TEXTURE_TYPE_2D;
+ rd_format.texture_type = RD::TEXTURE_TYPE_2D;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
rd_format.shareable_formats.push_back(rt->color_format);
@@ -6123,7 +6534,7 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
}
}
-void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
+void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
ERR_FAIL_COND(rt->backbuffer.is_valid());
uint32_t mipmaps_required = Image::get_image_required_mipmaps(rt->size.width, rt->size.height, Image::FORMAT_RGBA8);
@@ -6131,7 +6542,7 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
tf.format = rt->color_format;
tf.width = rt->size.width;
tf.height = rt->size.height;
- tf.type = RD::TEXTURE_TYPE_2D;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tf.mipmaps = mipmaps_required;
@@ -6171,7 +6582,7 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
}
}
-RID RasterizerStorageRD::render_target_create() {
+RID RendererStorageRD::render_target_create() {
RenderTarget render_target;
render_target.was_used = false;
@@ -6184,11 +6595,11 @@ RID RasterizerStorageRD::render_target_create() {
return render_target_owner.make_rid(render_target);
}
-void RasterizerStorageRD::render_target_set_position(RID p_render_target, int p_x, int p_y) {
+void RendererStorageRD::render_target_set_position(RID p_render_target, int p_x, int p_y) {
//unused for this render target
}
-void RasterizerStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height) {
+void RendererStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->size.x = p_width;
@@ -6196,63 +6607,63 @@ void RasterizerStorageRD::render_target_set_size(RID p_render_target, int p_widt
_update_render_target(rt);
}
-RID RasterizerStorageRD::render_target_get_texture(RID p_render_target) {
+RID RendererStorageRD::render_target_get_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
return rt->texture;
}
-void RasterizerStorageRD::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
+void RendererStorageRD::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
}
-void RasterizerStorageRD::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
+void RendererStorageRD::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->flags[p_flag] = p_value;
_update_render_target(rt);
}
-bool RasterizerStorageRD::render_target_was_used(RID p_render_target) {
+bool RendererStorageRD::render_target_was_used(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, false);
return rt->was_used;
}
-void RasterizerStorageRD::render_target_set_as_unused(RID p_render_target) {
+void RendererStorageRD::render_target_set_as_unused(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->was_used = false;
}
-Size2 RasterizerStorageRD::render_target_get_size(RID p_render_target) {
+Size2 RendererStorageRD::render_target_get_size(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, Size2());
return rt->size;
}
-RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) {
+RID RendererStorageRD::render_target_get_rd_framebuffer(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
return rt->framebuffer;
}
-RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) {
+RID RendererStorageRD::render_target_get_rd_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
return rt->color;
}
-RID RasterizerStorageRD::render_target_get_rd_backbuffer(RID p_render_target) {
+RID RendererStorageRD::render_target_get_rd_backbuffer(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
return rt->backbuffer;
}
-RID RasterizerStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) {
+RID RendererStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@@ -6263,32 +6674,32 @@ RID RasterizerStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_rende
return rt->backbuffer_fb;
}
-void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
+void RendererStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->clear_requested = true;
rt->clear_color = p_clear_color;
}
-bool RasterizerStorageRD::render_target_is_clear_requested(RID p_render_target) {
+bool RendererStorageRD::render_target_is_clear_requested(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, false);
return rt->clear_requested;
}
-Color RasterizerStorageRD::render_target_get_clear_request_color(RID p_render_target) {
+Color RendererStorageRD::render_target_get_clear_request_color(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, Color());
return rt->clear_color;
}
-void RasterizerStorageRD::render_target_disable_clear_request(RID p_render_target) {
+void RendererStorageRD::render_target_disable_clear_request(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->clear_requested = false;
}
-void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) {
+void RendererStorageRD::render_target_do_clear_request(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
if (!rt->clear_requested) {
@@ -6301,7 +6712,7 @@ void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) {
rt->clear_requested = false;
}
-void RasterizerStorageRD::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
+void RendererStorageRD::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {
@@ -6314,7 +6725,7 @@ void RasterizerStorageRD::render_target_set_sdf_size_and_scale(RID p_render_targ
_render_target_clear_sdf(rt);
}
-Rect2i RasterizerStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) const {
+Rect2i RendererStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) const {
Size2i margin;
int scale;
switch (rt->sdf_oversize) {
@@ -6343,14 +6754,14 @@ Rect2i RasterizerStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt)
return r;
}
-Rect2i RasterizerStorageRD::render_target_get_sdf_rect(RID p_render_target) const {
+Rect2i RendererStorageRD::render_target_get_sdf_rect(RID p_render_target) const {
const RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, Rect2i());
return _render_target_get_sdf_rect(rt);
}
-RID RasterizerStorageRD::render_target_get_sdf_texture(RID p_render_target) {
+RID RendererStorageRD::render_target_get_sdf_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
if (rt->sdf_buffer_read.is_null()) {
@@ -6360,7 +6771,7 @@ RID RasterizerStorageRD::render_target_get_sdf_texture(RID p_render_target) {
tformat.width = 4;
tformat.height = 4;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
- tformat.type = RD::TEXTURE_TYPE_2D;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
Vector<uint8_t> pv;
pv.resize(16 * 4);
@@ -6373,7 +6784,7 @@ RID RasterizerStorageRD::render_target_get_sdf_texture(RID p_render_target) {
return rt->sdf_buffer_read;
}
-void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) {
+void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) {
ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_valid());
if (rt->sdf_buffer_read.is_valid()) {
RD::get_singleton()->free(rt->sdf_buffer_read);
@@ -6387,7 +6798,7 @@ void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) {
tformat.width = size.width;
tformat.height = size.height;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
- tformat.type = RD::TEXTURE_TYPE_2D;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
rt->sdf_buffer_write = RD::get_singleton()->texture_create(tformat, RD::TextureView());
@@ -6434,28 +6845,28 @@ void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
u.ids.push_back(rt->sdf_buffer_write);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
u.ids.push_back(rt->sdf_buffer_read);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 3;
u.ids.push_back(rt->sdf_buffer_process[0]);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 4;
u.ids.push_back(rt->sdf_buffer_process[1]);
uniforms.push_back(u);
@@ -6467,7 +6878,7 @@ void RasterizerStorageRD::_render_target_allocate_sdf(RenderTarget *rt) {
}
}
-void RasterizerStorageRD::_render_target_clear_sdf(RenderTarget *rt) {
+void RendererStorageRD::_render_target_clear_sdf(RenderTarget *rt) {
if (rt->sdf_buffer_read.is_valid()) {
RD::get_singleton()->free(rt->sdf_buffer_read);
rt->sdf_buffer_read = RID();
@@ -6485,7 +6896,7 @@ void RasterizerStorageRD::_render_target_clear_sdf(RenderTarget *rt) {
}
}
-RID RasterizerStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) {
+RID RendererStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@@ -6495,7 +6906,7 @@ RID RasterizerStorageRD::render_target_get_sdf_framebuffer(RID p_render_target)
return rt->sdf_buffer_write_fb;
}
-void RasterizerStorageRD::render_target_sdf_process(RID p_render_target) {
+void RendererStorageRD::render_target_sdf_process(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_null());
@@ -6570,7 +6981,7 @@ void RasterizerStorageRD::render_target_sdf_process(RID p_render_target) {
RD::get_singleton()->compute_list_end();
}
-void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
+void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
if (!rt->backbuffer.is_valid()) {
@@ -6581,7 +6992,7 @@ void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target,
if (p_region == Rect2i()) {
region.size = rt->size;
} else {
- region = Rect2i(Size2i(), rt->size).clip(p_region);
+ region = Rect2i(Size2i(), rt->size).intersection(p_region);
if (region.size == Size2i()) {
return; //nothing to do
}
@@ -6610,7 +7021,7 @@ void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target,
}
}
-void RasterizerStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
+void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
if (!rt->backbuffer.is_valid()) {
@@ -6621,7 +7032,7 @@ void RasterizerStorageRD::render_target_clear_back_buffer(RID p_render_target, c
if (p_region == Rect2i()) {
region.size = rt->size;
} else {
- region = Rect2i(Size2i(), rt->size).clip(p_region);
+ region = Rect2i(Size2i(), rt->size).intersection(p_region);
if (region.size == Size2i()) {
return; //nothing to do
}
@@ -6631,7 +7042,7 @@ void RasterizerStorageRD::render_target_clear_back_buffer(RID p_render_target, c
effects.set_color(rt->backbuffer_mipmap0, p_color, region, true);
}
-void RasterizerStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
+void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
if (!rt->backbuffer.is_valid()) {
@@ -6642,7 +7053,7 @@ void RasterizerStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_tar
if (p_region == Rect2i()) {
region.size = rt->size;
} else {
- region = Rect2i(Size2i(), rt->size).clip(p_region);
+ region = Rect2i(Size2i(), rt->size).intersection(p_region);
if (region.size == Size2i()) {
return; //nothing to do
}
@@ -6663,70 +7074,70 @@ void RasterizerStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_tar
}
}
-RID RasterizerStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) {
+RID RendererStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
return rt->framebuffer_uniform_set;
}
-RID RasterizerStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) {
+RID RendererStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
return rt->backbuffer_uniform_set;
}
-void RasterizerStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
+void RendererStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->framebuffer_uniform_set = p_uniform_set;
}
-void RasterizerStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
+void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->backbuffer_uniform_set = p_uniform_set;
}
-void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {
+void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
if (mesh_owner.owns(p_base)) {
Mesh *mesh = mesh_owner.getornull(p_base);
- p_instance->update_dependency(&mesh->instance_dependency);
+ p_instance->update_dependency(&mesh->dependency);
} else if (multimesh_owner.owns(p_base)) {
MultiMesh *multimesh = multimesh_owner.getornull(p_base);
- p_instance->update_dependency(&multimesh->instance_dependency);
+ p_instance->update_dependency(&multimesh->dependency);
if (multimesh->mesh.is_valid()) {
base_update_dependency(multimesh->mesh, p_instance);
}
} else if (reflection_probe_owner.owns(p_base)) {
ReflectionProbe *rp = reflection_probe_owner.getornull(p_base);
- p_instance->update_dependency(&rp->instance_dependency);
+ p_instance->update_dependency(&rp->dependency);
} else if (decal_owner.owns(p_base)) {
Decal *decal = decal_owner.getornull(p_base);
- p_instance->update_dependency(&decal->instance_dependency);
+ p_instance->update_dependency(&decal->dependency);
} else if (gi_probe_owner.owns(p_base)) {
GIProbe *gip = gi_probe_owner.getornull(p_base);
- p_instance->update_dependency(&gip->instance_dependency);
+ p_instance->update_dependency(&gip->dependency);
} else if (lightmap_owner.owns(p_base)) {
Lightmap *lm = lightmap_owner.getornull(p_base);
- p_instance->update_dependency(&lm->instance_dependency);
+ p_instance->update_dependency(&lm->dependency);
} else if (light_owner.owns(p_base)) {
Light *l = light_owner.getornull(p_base);
- p_instance->update_dependency(&l->instance_dependency);
+ p_instance->update_dependency(&l->dependency);
} else if (particles_owner.owns(p_base)) {
Particles *p = particles_owner.getornull(p_base);
- p_instance->update_dependency(&p->instance_dependency);
+ p_instance->update_dependency(&p->dependency);
} else if (particles_collision_owner.owns(p_base)) {
ParticlesCollision *pc = particles_collision_owner.getornull(p_base);
- p_instance->update_dependency(&pc->instance_dependency);
+ p_instance->update_dependency(&pc->dependency);
}
}
-void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) {
+void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
- p_instance->update_dependency(&skeleton->instance_dependency);
+ p_instance->update_dependency(&skeleton->dependency);
}
-RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
+RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
if (mesh_owner.owns(p_rid)) {
return RS::INSTANCE_MESH;
}
@@ -6758,7 +7169,7 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
return RS::INSTANCE_NONE;
}
-void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
+void RendererStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
if (!decal_atlas.textures.has(p_texture)) {
DecalAtlas::Texture t;
t.users = 1;
@@ -6774,7 +7185,7 @@ void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panor
}
}
-void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
+void RendererStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
ERR_FAIL_COND(!t);
t->users--;
@@ -6788,15 +7199,15 @@ void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_
}
}
-RID RasterizerStorageRD::decal_atlas_get_texture() const {
+RID RendererStorageRD::decal_atlas_get_texture() const {
return decal_atlas.texture;
}
-RID RasterizerStorageRD::decal_atlas_get_texture_srgb() const {
+RID RendererStorageRD::decal_atlas_get_texture_srgb() const {
return decal_atlas.texture_srgb;
}
-void RasterizerStorageRD::_update_decal_atlas() {
+void RendererStorageRD::_update_decal_atlas() {
if (!decal_atlas.dirty) {
return; //nothing to do
}
@@ -6923,7 +7334,7 @@ void RasterizerStorageRD::_update_decal_atlas() {
tformat.width = decal_atlas.size.width;
tformat.height = decal_atlas.size.height;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
- tformat.type = RD::TEXTURE_TYPE_2D;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
tformat.mipmaps = decal_atlas.mipmaps;
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
@@ -6988,7 +7399,7 @@ void RasterizerStorageRD::_update_decal_atlas() {
}
}
-int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) {
+int32_t RendererStorageRD::_global_variable_allocate(uint32_t p_elements) {
int32_t idx = 0;
while (idx + p_elements <= global_variables.buffer_size) {
if (global_variables.buffer_usage[idx].elements == 0) {
@@ -7014,7 +7425,7 @@ int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) {
return -1;
}
-void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) {
+void RendererStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) {
switch (p_type) {
case RS::GLOBAL_VAR_TYPE_BOOL: {
GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
@@ -7291,7 +7702,7 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::
}
}
-void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) {
+void RendererStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) {
int32_t prev_chunk = -1;
for (int32_t i = 0; i < p_elements; i++) {
@@ -7307,7 +7718,7 @@ void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, in
}
}
-void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
+void RendererStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
ERR_FAIL_COND(global_variables.variables.has(p_name));
GlobalVariables::Variable gv;
gv.type = p_type;
@@ -7345,7 +7756,7 @@ void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::Glob
global_variables.variables[p_name] = gv;
}
-void RasterizerStorageRD::global_variable_remove(const StringName &p_name) {
+void RendererStorageRD::global_variable_remove(const StringName &p_name) {
if (!global_variables.variables.has(p_name)) {
return;
}
@@ -7361,7 +7772,7 @@ void RasterizerStorageRD::global_variable_remove(const StringName &p_name) {
global_variables.variables.erase(p_name);
}
-Vector<StringName> RasterizerStorageRD::global_variable_get_list() const {
+Vector<StringName> RendererStorageRD::global_variable_get_list() const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance.");
}
@@ -7375,7 +7786,7 @@ Vector<StringName> RasterizerStorageRD::global_variable_get_list() const {
return names;
}
-void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Variant &p_value) {
+void RendererStorageRD::global_variable_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND(!global_variables.variables.has(p_name));
GlobalVariables::Variable &gv = global_variables.variables[p_name];
gv.value = p_value;
@@ -7395,7 +7806,7 @@ void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Va
}
}
-void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
+void RendererStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
if (!global_variables.variables.has(p_name)) {
return; //variable may not exist
}
@@ -7423,7 +7834,7 @@ void RasterizerStorageRD::global_variable_set_override(const StringName &p_name,
}
}
-Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const {
+Variant RendererStorageRD::global_variable_get(const StringName &p_name) const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance.");
}
@@ -7435,7 +7846,7 @@ Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const
return global_variables.variables[p_name].value;
}
-RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(const StringName &p_name) const {
+RS::GlobalVariableType RendererStorageRD::global_variable_get_type_internal(const StringName &p_name) const {
if (!global_variables.variables.has(p_name)) {
return RS::GLOBAL_VAR_TYPE_MAX;
}
@@ -7443,7 +7854,7 @@ RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(co
return global_variables.variables[p_name].type;
}
-RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const StringName &p_name) const {
+RS::GlobalVariableType RendererStorageRD::global_variable_get_type(const StringName &p_name) const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance.");
}
@@ -7451,7 +7862,7 @@ RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const Strin
return global_variable_get_type_internal(p_name);
}
-void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) {
+void RendererStorageRD::global_variables_load_settings(bool p_load_textures) {
List<PropertyInfo> settings;
ProjectSettings::get_singleton()->get_property_list(&settings);
@@ -7532,15 +7943,15 @@ void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) {
}
}
-void RasterizerStorageRD::global_variables_clear() {
+void RendererStorageRD::global_variables_clear() {
global_variables.variables.clear(); //not right but for now enough
}
-RID RasterizerStorageRD::global_variables_get_storage_buffer() const {
+RID RendererStorageRD::global_variables_get_storage_buffer() const {
return global_variables.buffer;
}
-int32_t RasterizerStorageRD::global_variables_instance_allocate(RID p_instance) {
+int32_t RendererStorageRD::global_variables_instance_allocate(RID p_instance) {
ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1);
int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
global_variables.instance_buffer_pos[p_instance] = pos; //save anyway
@@ -7549,7 +7960,7 @@ int32_t RasterizerStorageRD::global_variables_instance_allocate(RID p_instance)
return pos;
}
-void RasterizerStorageRD::global_variables_instance_free(RID p_instance) {
+void RendererStorageRD::global_variables_instance_free(RID p_instance) {
ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance));
int32_t pos = global_variables.instance_buffer_pos[p_instance];
if (pos >= 0) {
@@ -7558,7 +7969,7 @@ void RasterizerStorageRD::global_variables_instance_free(RID p_instance) {
global_variables.instance_buffer_pos.erase(p_instance);
}
-void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
+void RendererStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
if (!global_variables.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore
}
@@ -7601,7 +8012,7 @@ void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p
_global_variable_mark_buffer_dirty(pos, 1);
}
-void RasterizerStorageRD::_update_global_variables() {
+void RendererStorageRD::_update_global_variables() {
if (global_variables.buffer_dirty_region_count > 0) {
uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
if (total_regions / global_variables.buffer_dirty_region_count <= 4) {
@@ -7651,7 +8062,7 @@ void RasterizerStorageRD::_update_global_variables() {
}
}
-void RasterizerStorageRD::update_dirty_resources() {
+void RendererStorageRD::update_dirty_resources() {
_update_global_variables(); //must do before materials, so it can queue them for update
_update_queued_materials();
_update_dirty_multimeshes();
@@ -7659,7 +8070,7 @@ void RasterizerStorageRD::update_dirty_resources() {
_update_decal_atlas();
}
-bool RasterizerStorageRD::has_os_feature(const String &p_feature) const {
+bool RendererStorageRD::has_os_feature(const String &p_feature) const {
if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
return true;
}
@@ -7683,7 +8094,7 @@ bool RasterizerStorageRD::has_os_feature(const String &p_feature) const {
return false;
}
-bool RasterizerStorageRD::free(RID p_rid) {
+bool RendererStorageRD::free(RID p_rid) {
if (texture_owner.owns(p_rid)) {
Texture *t = texture_owner.getornull(p_rid);
@@ -7744,28 +8155,40 @@ bool RasterizerStorageRD::free(RID p_rid) {
_update_queued_materials();
}
material_set_shader(p_rid, RID()); //clean up shader
- material->instance_dependency.instance_notify_deleted(p_rid);
+ material->dependency.deleted_notify(p_rid);
+
material_owner.free(p_rid);
} else if (mesh_owner.owns(p_rid)) {
mesh_clear(p_rid);
Mesh *mesh = mesh_owner.getornull(p_rid);
- mesh->instance_dependency.instance_notify_deleted(p_rid);
+ mesh->dependency.deleted_notify(p_rid);
+ if (mesh->instances.size()) {
+ ERR_PRINT("deleting mesh with active instances");
+ }
mesh_owner.free(p_rid);
+ } else if (mesh_instance_owner.owns(p_rid)) {
+ MeshInstance *mi = mesh_instance_owner.getornull(p_rid);
+ _mesh_instance_clear(mi);
+ mi->mesh->instances.erase(mi->I);
+ mi->I = nullptr;
+ mesh_instance_owner.free(p_rid);
+ memdelete(mi);
+
} else if (multimesh_owner.owns(p_rid)) {
_update_dirty_multimeshes();
multimesh_allocate(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D);
MultiMesh *multimesh = multimesh_owner.getornull(p_rid);
- multimesh->instance_dependency.instance_notify_deleted(p_rid);
+ multimesh->dependency.deleted_notify(p_rid);
multimesh_owner.free(p_rid);
} else if (skeleton_owner.owns(p_rid)) {
_update_dirty_skeletons();
skeleton_allocate(p_rid, 0);
Skeleton *skeleton = skeleton_owner.getornull(p_rid);
- skeleton->instance_dependency.instance_notify_deleted(p_rid);
+ skeleton->dependency.deleted_notify(p_rid);
skeleton_owner.free(p_rid);
} else if (reflection_probe_owner.owns(p_rid)) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid);
- reflection_probe->instance_dependency.instance_notify_deleted(p_rid);
+ reflection_probe->dependency.deleted_notify(p_rid);
reflection_probe_owner.free(p_rid);
} else if (decal_owner.owns(p_rid)) {
Decal *decal = decal_owner.getornull(p_rid);
@@ -7774,30 +8197,30 @@ bool RasterizerStorageRD::free(RID p_rid) {
texture_remove_from_decal_atlas(decal->textures[i]);
}
}
- decal->instance_dependency.instance_notify_deleted(p_rid);
+ decal->dependency.deleted_notify(p_rid);
decal_owner.free(p_rid);
} else if (gi_probe_owner.owns(p_rid)) {
gi_probe_allocate(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
GIProbe *gi_probe = gi_probe_owner.getornull(p_rid);
- gi_probe->instance_dependency.instance_notify_deleted(p_rid);
+ gi_probe->dependency.deleted_notify(p_rid);
gi_probe_owner.free(p_rid);
} else if (lightmap_owner.owns(p_rid)) {
lightmap_set_textures(p_rid, RID(), false);
Lightmap *lightmap = lightmap_owner.getornull(p_rid);
- lightmap->instance_dependency.instance_notify_deleted(p_rid);
+ lightmap->dependency.deleted_notify(p_rid);
lightmap_owner.free(p_rid);
} else if (light_owner.owns(p_rid)) {
light_set_projector(p_rid, RID()); //clear projector
// delete the texture
Light *light = light_owner.getornull(p_rid);
- light->instance_dependency.instance_notify_deleted(p_rid);
+ light->dependency.deleted_notify(p_rid);
light_owner.free(p_rid);
} else if (particles_owner.owns(p_rid)) {
Particles *particles = particles_owner.getornull(p_rid);
_particles_free_data(particles);
- particles->instance_dependency.instance_notify_deleted(p_rid);
+ particles->dependency.deleted_notify(p_rid);
particles_owner.free(p_rid);
} else if (particles_collision_owner.owns(p_rid)) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_rid);
@@ -7805,8 +8228,10 @@ bool RasterizerStorageRD::free(RID p_rid) {
if (particles_collision->heightfield_texture.is_valid()) {
RD::get_singleton()->free(particles_collision->heightfield_texture);
}
- particles_collision->instance_dependency.instance_notify_deleted(p_rid);
+ particles_collision->dependency.deleted_notify(p_rid);
particles_collision_owner.free(p_rid);
+ } else if (particles_collision_instance_owner.owns(p_rid)) {
+ particles_collision_instance_owner.free(p_rid);
} else if (render_target_owner.owns(p_rid)) {
RenderTarget *rt = render_target_owner.getornull(p_rid);
@@ -7826,41 +8251,41 @@ bool RasterizerStorageRD::free(RID p_rid) {
return true;
}
-RasterizerEffectsRD *RasterizerStorageRD::get_effects() {
+EffectsRD *RendererStorageRD::get_effects() {
return &effects;
}
-void RasterizerStorageRD::capture_timestamps_begin() {
+void RendererStorageRD::capture_timestamps_begin() {
RD::get_singleton()->capture_timestamp("Frame Begin", false);
}
-void RasterizerStorageRD::capture_timestamp(const String &p_name) {
+void RendererStorageRD::capture_timestamp(const String &p_name) {
RD::get_singleton()->capture_timestamp(p_name, true);
}
-uint32_t RasterizerStorageRD::get_captured_timestamps_count() const {
+uint32_t RendererStorageRD::get_captured_timestamps_count() const {
return RD::get_singleton()->get_captured_timestamps_count();
}
-uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const {
+uint64_t RendererStorageRD::get_captured_timestamps_frame() const {
return RD::get_singleton()->get_captured_timestamps_frame();
}
-uint64_t RasterizerStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const {
+uint64_t RendererStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index);
}
-uint64_t RasterizerStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const {
+uint64_t RendererStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index);
}
-String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const {
+String RendererStorageRD::get_captured_timestamp_name(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_name(p_index);
}
-RasterizerStorageRD *RasterizerStorageRD::base_singleton = nullptr;
+RendererStorageRD *RendererStorageRD::base_singleton = nullptr;
-RasterizerStorageRD::RasterizerStorageRD() {
+RendererStorageRD::RendererStorageRD() {
base_singleton = this;
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
@@ -7886,7 +8311,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
tformat.width = 4;
tformat.height = 4;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
- tformat.type = RD::TEXTURE_TYPE_2D;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
Vector<uint8_t> pv;
pv.resize(16 * 4);
@@ -7978,7 +8403,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
tformat.height = 4;
tformat.array_layers = 6;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
- tformat.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ tformat.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
Vector<uint8_t> pv;
pv.resize(16 * 4);
@@ -8006,7 +8431,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
tformat.height = 4;
tformat.array_layers = 6;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
- tformat.type = RD::TEXTURE_TYPE_CUBE;
+ tformat.texture_type = RD::TEXTURE_TYPE_CUBE;
Vector<uint8_t> pv;
pv.resize(16 * 4);
@@ -8034,7 +8459,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
tformat.height = 4;
tformat.array_layers = 6;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
- tformat.type = RD::TEXTURE_TYPE_CUBE;
+ tformat.texture_type = RD::TEXTURE_TYPE_CUBE;
Vector<uint8_t> pv;
pv.resize(16 * 4);
@@ -8062,7 +8487,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
tformat.height = 4;
tformat.depth = 4;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
- tformat.type = RD::TEXTURE_TYPE_3D;
+ tformat.texture_type = RD::TEXTURE_TYPE_3D;
Vector<uint8_t> pv;
pv.resize(64 * 4);
@@ -8088,7 +8513,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
tformat.height = 4;
tformat.array_layers = 1;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
- tformat.type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
Vector<uint8_t> pv;
pv.resize(16 * 4);
@@ -8249,6 +8674,19 @@ RasterizerStorageRD::RasterizerStorageRD() {
mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
}
+ for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
+ buffer.resize(sizeof(float) * 4);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 0.0;
+ fptr[1] = 0.0;
+ fptr[2] = 0.0;
+ fptr[3] = 0.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_CUSTOM0 + i] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
+
{ //bones
buffer.resize(sizeof(uint32_t) * 4);
{
@@ -8311,8 +8749,8 @@ RasterizerStorageRD::RasterizerStorageRD() {
particles_modes.push_back("");
particles_shader.shader.initialize(particles_modes, String());
}
- shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_PARTICLES, _create_particles_shader_funcs);
- material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs);
+ shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_PARTICLES, _create_particles_shader_funcs);
+ material_set_data_request_function(RendererStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs);
{
ShaderCompilerRD::DefaultIdentifierActions actions;
@@ -8342,7 +8780,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
actions.renames["RESTART_VELOCITY"] = "restart_velocity";
actions.renames["RESTART_COLOR"] = "restart_color";
actions.renames["RESTART_CUSTOM"] = "restart_custom";
- actions.renames["emit_particle"] = "emit_particle";
+ actions.renames["emit_subparticle"] = "emit_subparticle";
actions.renames["COLLIDED"] = "collided";
actions.renames["COLLISION_NORMAL"] = "collision_normal";
actions.renames["COLLISION_DEPTH"] = "collision_depth";
@@ -8373,14 +8811,14 @@ RasterizerStorageRD::RasterizerStorageRD() {
particles_shader.default_material = material_create();
material_set_shader(particles_shader.default_material, particles_shader.default_shader);
- ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RasterizerStorageRD::SHADER_TYPE_PARTICLES);
+ ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RendererStorageRD::SHADER_TYPE_PARTICLES);
particles_shader.default_shader_rd = particles_shader.shader.version_get_shader(md->shader_data->version, 0);
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 1;
u.ids.resize(12);
RID *ids_ptr = u.ids.ptrw();
@@ -8401,7 +8839,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
u.ids.push_back(global_variables_get_storage_buffer());
uniforms.push_back(u);
@@ -8444,9 +8882,33 @@ RasterizerStorageRD::RasterizerStorageRD() {
rt_sdf.pipelines[i] = RD::get_singleton()->compute_pipeline_create(rt_sdf.shader.version_get_shader(rt_sdf.shader_version, i));
}
}
+ {
+ Vector<String> skeleton_modes;
+ skeleton_modes.push_back("\n#define MODE_2D\n");
+ skeleton_modes.push_back("");
+
+ skeleton_shader.shader.initialize(skeleton_modes);
+ skeleton_shader.version = skeleton_shader.shader.version_create();
+ for (int i = 0; i < SkeletonShader::SHADER_MODE_MAX; i++) {
+ skeleton_shader.version_shader[i] = skeleton_shader.shader.version_get_shader(skeleton_shader.version, i);
+ skeleton_shader.pipeline[i] = RD::get_singleton()->compute_pipeline_create(skeleton_shader.version_shader[i]);
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 0;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(default_rd_storage_buffer);
+ uniforms.push_back(u);
+ }
+ skeleton_shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON);
+ }
+ }
}
-RasterizerStorageRD::~RasterizerStorageRD() {
+RendererStorageRD::~RendererStorageRD() {
memdelete_arr(global_variables.buffer_values);
memdelete_arr(global_variables.buffer_usage);
memdelete_arr(global_variables.buffer_dirty_regions);
@@ -8471,6 +8933,9 @@ RasterizerStorageRD::~RasterizerStorageRD() {
giprobe_sdf_shader.version_free(giprobe_sdf_shader_version);
particles_shader.copy_shader.version_free(particles_shader.copy_shader_version);
+ rt_sdf.shader.version_free(rt_sdf.shader_version);
+
+ skeleton_shader.shader.version_free(skeleton_shader.version);
RenderingServer::get_singleton()->free(particles_shader.default_material);
RenderingServer::get_singleton()->free(particles_shader.default_shader);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index 4a708fc94f..5ef73f0db8 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer_storage_rd.h */
+/* renderer_storage_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,20 +28,23 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_STORAGE_RD_H
-#define RASTERIZER_STORAGE_RD_H
+#ifndef RENDERING_SERVER_STORAGE_RD_H
+#define RENDERING_SERVER_STORAGE_RD_H
+#include "core/templates/list.h"
+#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
-#include "servers/rendering/rasterizer.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_effects_rd.h"
-#include "servers/rendering/rasterizer_rd/shader_compiler_rd.h"
-#include "servers/rendering/rasterizer_rd/shaders/canvas_sdf.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/particles.glsl.gen.h"
-#include "servers/rendering/rasterizer_rd/shaders/particles_copy.glsl.gen.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/effects_rd.h"
+#include "servers/rendering/renderer_rd/shader_compiler_rd.h"
+#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
-
-class RasterizerStorageRD : public RasterizerStorage {
+class RendererStorageRD : public RendererStorage {
public:
static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_array) {
p_array[0] = p_mtx.basis.elements[0][0];
@@ -124,6 +127,8 @@ public:
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() {}
};
@@ -139,7 +144,7 @@ public:
virtual ~MaterialData();
private:
- friend class RasterizerStorageRD;
+ friend class RendererStorageRD;
RID self;
List<RID>::Element *global_buffer_E = nullptr;
List<RID>::Element *global_texture_E = nullptr;
@@ -170,6 +175,10 @@ public:
DEFAULT_RD_BUFFER_COLOR,
DEFAULT_RD_BUFFER_TEX_UV,
DEFAULT_RD_BUFFER_TEX_UV2,
+ DEFAULT_RD_BUFFER_CUSTOM0,
+ DEFAULT_RD_BUFFER_CUSTOM1,
+ DEFAULT_RD_BUFFER_CUSTOM2,
+ DEFAULT_RD_BUFFER_CUSTOM3,
DEFAULT_RD_BUFFER_BONES,
DEFAULT_RD_BUFFER_WEIGHTS,
DEFAULT_RD_BUFFER_MAX,
@@ -180,7 +189,7 @@ private:
struct CanvasTexture {
RID diffuse;
- RID normalmap;
+ RID normal_map;
RID specular;
Color specular_color = Color(1, 1, 1, 1);
float shininess = 1.0;
@@ -353,6 +362,7 @@ private:
Shader *shader;
//shortcut to shader data and type
ShaderType shader_type;
+ uint32_t shader_id = 0;
bool update_requested;
bool uniform_dirty;
bool texture_dirty;
@@ -360,7 +370,7 @@ private:
Map<StringName, Variant> params;
int32_t priority;
RID next_pass;
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX];
@@ -372,13 +382,19 @@ private:
/* Mesh */
+ struct MeshInstance;
+
struct Mesh {
struct Surface {
RS::PrimitiveType primitive = RS::PRIMITIVE_POINTS;
uint32_t format = 0;
RID vertex_buffer;
+ RID attribute_buffer;
+ RID skin_buffer;
uint32_t vertex_count = 0;
+ uint32_t vertex_buffer_size = 0;
+ uint32_t skin_buffer_size = 0;
// A different pipeline needs to be allocated
// depending on the inputs available in the
@@ -414,8 +430,7 @@ private:
Vector<AABB> bone_aabbs;
- Vector<RID> blend_shapes;
- RID blend_shape_base_buffer; //source buffer goes here when using blend shapes, and main one is uncompressed
+ RID blend_shape_buffer;
RID material;
@@ -427,6 +442,8 @@ private:
uint32_t particles_render_index = 0;
uint64_t particles_render_pass = 0;
+
+ RID uniform_set;
};
uint32_t blend_shape_count = 0;
@@ -437,17 +454,90 @@ private:
Vector<AABB> bone_aabbs;
+ bool has_bone_weights = false;
+
AABB aabb;
AABB custom_aabb;
Vector<RID> material_cache;
- RasterizerScene::InstanceDependency instance_dependency;
+ List<MeshInstance *> instances;
+
+ Dependency dependency;
};
mutable RID_Owner<Mesh> mesh_owner;
- void _mesh_surface_generate_version_for_input_mask(Mesh::Surface *s, uint32_t p_input_mask);
+ struct MeshInstance {
+ Mesh *mesh;
+ RID skeleton;
+ struct Surface {
+ RID vertex_buffer;
+ RID uniform_set;
+
+ Mesh::Surface::Version *versions = nullptr; //allocated on demand
+ uint32_t version_count = 0;
+ };
+ LocalVector<Surface> surfaces;
+ LocalVector<float> blend_weights;
+
+ RID blend_weights_buffer;
+ List<MeshInstance *>::Element *I = nullptr; //used to erase itself
+ uint64_t skeleton_version = 0;
+ bool dirty = false;
+ bool weights_dirty = false;
+ SelfList<MeshInstance> weight_update_list;
+ SelfList<MeshInstance> array_update_list;
+ MeshInstance() :
+ weight_update_list(this), array_update_list(this) {}
+ };
+
+ void _mesh_instance_clear(MeshInstance *mi);
+ void _mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface);
+
+ mutable RID_PtrOwner<MeshInstance> mesh_instance_owner;
+
+ SelfList<MeshInstance>::List dirty_mesh_instance_weights;
+ SelfList<MeshInstance>::List dirty_mesh_instance_arrays;
+
+ struct SkeletonShader {
+ struct PushConstant {
+ uint32_t has_normal;
+ uint32_t has_tangent;
+ uint32_t has_skeleton;
+ uint32_t has_blend_shape;
+
+ uint32_t vertex_count;
+ uint32_t vertex_stride;
+ uint32_t skin_stride;
+ uint32_t skin_weight_offset;
+
+ uint32_t blend_shape_count;
+ uint32_t normalized_blend_shapes;
+ uint32_t pad0;
+ uint32_t pad1;
+ };
+
+ enum {
+ UNIFORM_SET_INSTANCE = 0,
+ UNIFORM_SET_SURFACE = 1,
+ UNIFORM_SET_SKELETON = 2,
+ };
+ enum {
+ SHADER_MODE_2D,
+ SHADER_MODE_3D,
+ SHADER_MODE_MAX
+ };
+
+ SkeletonShaderRD shader;
+ RID version;
+ RID version_shader[SHADER_MODE_MAX];
+ RID pipeline[SHADER_MODE_MAX];
+
+ RID default_skeleton_uniform_set;
+ } skeleton_shader;
+
+ void _mesh_surface_generate_version_for_input_mask(Mesh::Surface::Version &v, Mesh::Surface *s, uint32_t p_input_mask, MeshInstance::Surface *mis = nullptr);
RID mesh_default_rd_buffers[DEFAULT_RD_BUFFER_MAX];
@@ -476,7 +566,7 @@ private:
bool dirty = false;
MultiMesh *dirty_list = nullptr;
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
mutable RID_Owner<MultiMesh> multimesh_owner;
@@ -647,7 +737,7 @@ private:
ParticleEmissionBuffer *emission_buffer = nullptr;
RID emission_storage_buffer;
- Set<RasterizerScene::InstanceBase *> collisions;
+ Set<RID> collisions;
Particles() :
inactive(true),
@@ -674,7 +764,7 @@ private:
clear(true) {
}
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
ParticlesFrameParams frame_params;
};
@@ -729,7 +819,7 @@ private:
bool valid;
RID version;
- //RenderPipelineVertexFormatCacheRD pipelines[SKY_VERSION_MAX];
+ //PipelineCacheRD pipelines[SKY_VERSION_MAX];
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
@@ -747,17 +837,19 @@ private:
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
+ virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
virtual bool is_param_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();
virtual ~ParticlesShaderData();
};
ShaderData *_create_particles_shader_func();
- static RasterizerStorageRD::ShaderData *_create_particles_shader_funcs() {
+ static RendererStorageRD::ShaderData *_create_particles_shader_funcs() {
return base_singleton->_create_particles_shader_func();
}
@@ -777,7 +869,7 @@ private:
};
MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader);
- static RasterizerStorageRD::MaterialData *_create_particles_material_funcs(ShaderData *p_shader) {
+ static RendererStorageRD::MaterialData *_create_particles_material_funcs(ShaderData *p_shader) {
return base_singleton->_create_particles_material_func(static_cast<ParticlesShaderData *>(p_shader));
}
@@ -802,11 +894,19 @@ private:
RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024;
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
mutable RID_Owner<ParticlesCollision> particles_collision_owner;
+ struct ParticlesCollisionInstance {
+ RID collision;
+ Transform transform;
+ bool active = false;
+ };
+
+ mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner;
+
/* Skeleton */
struct Skeleton {
@@ -820,8 +920,11 @@ private:
Transform2D base_transform_2d;
RID uniform_set_3d;
+ RID uniform_set_mi;
- RasterizerScene::InstanceDependency instance_dependency;
+ uint64_t version = 1;
+
+ Dependency dependency;
};
mutable RID_Owner<Skeleton> skeleton_owner;
@@ -850,9 +953,10 @@ private:
RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
RS::LightDirectionalShadowDepthRangeMode directional_range_mode = RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE;
bool directional_blend_splits = false;
+ bool directional_sky_only = false;
uint64_t version = 0;
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
mutable RID_Owner<Light> light_owner;
@@ -873,8 +977,9 @@ private:
bool box_projection = false;
bool enable_shadows = false;
uint32_t cull_mask = (1 << 20) - 1;
+ float lod_threshold = 0.01;
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
mutable RID_Owner<ReflectionProbe> reflection_probe_owner;
@@ -895,7 +1000,7 @@ private:
float distance_fade_length = 1;
float normal_fade = 0.0;
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
mutable RID_Owner<Decal> decal_owner;
@@ -933,7 +1038,7 @@ private:
uint32_t version = 1;
uint32_t data_version = 1;
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
GiprobeSdfShaderRD giprobe_sdf_shader;
@@ -962,7 +1067,7 @@ private:
int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
};
- RasterizerScene::InstanceDependency instance_dependency;
+ Dependency dependency;
};
bool using_lightmap_array; //high end uses this
@@ -1123,7 +1228,7 @@ private:
void _update_global_variables();
/* EFFECTS */
- RasterizerEffectsRD effects;
+ EffectsRD effects;
public:
/* TEXTURE API */
@@ -1238,6 +1343,8 @@ public:
Variant shader_get_param_default(RID p_shader, const StringName &p_param) const;
void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function);
+ virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const;
+
/* COMMON MATERIAL API */
RID material_create();
@@ -1255,11 +1362,16 @@ public:
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters);
- void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance);
+ void material_update_dependency(RID p_material, DependencyTracker *p_instance);
void material_force_update_textures(RID p_material, ShaderType p_shader_type);
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
+ _FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) {
+ Material *material = material_owner.getornull(p_material);
+ return material->shader_id;
+ }
+
_FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.getornull(p_material);
if (!material || material->shader_type != p_shader_type) {
@@ -1273,6 +1385,8 @@ public:
virtual RID mesh_create();
+ virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count);
+
/// Return stride
virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface);
@@ -1297,6 +1411,16 @@ public:
virtual void mesh_clear(RID p_mesh);
+ virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton);
+
+ /* MESH INSTANCE */
+
+ virtual RID mesh_instance_create(RID p_base);
+ virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton);
+ virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight);
+ virtual void mesh_instance_check_for_update(RID p_mesh_instance);
+ virtual void update_mesh_instances();
+
_FORCE_INLINE_ const RID *mesh_get_surface_count_and_materials(RID p_mesh, uint32_t &r_surface_count) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, nullptr);
@@ -1304,7 +1428,7 @@ public:
if (r_surface_count == 0) {
return nullptr;
}
- if (mesh->material_cache.empty()) {
+ if (mesh->material_cache.is_empty()) {
mesh->material_cache.resize(mesh->surface_count);
for (uint32_t i = 0; i < r_surface_count; i++) {
mesh->material_cache.write[i] = mesh->surfaces[i]->material;
@@ -1314,22 +1438,50 @@ public:
return mesh->material_cache.ptr();
}
- _FORCE_INLINE_ RS::PrimitiveType mesh_surface_get_primitive(RID p_mesh, uint32_t p_surface_index) {
+ _FORCE_INLINE_ void *mesh_get_surface(RID p_mesh, uint32_t p_surface_index) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!mesh, RS::PRIMITIVE_MAX);
- ERR_FAIL_UNSIGNED_INDEX_V(p_surface_index, mesh->surface_count, RS::PRIMITIVE_MAX);
+ ERR_FAIL_COND_V(!mesh, nullptr);
+ ERR_FAIL_UNSIGNED_INDEX_V(p_surface_index, mesh->surface_count, nullptr);
- return mesh->surfaces[p_surface_index]->primitive;
+ return mesh->surfaces[p_surface_index];
}
- _FORCE_INLINE_ void mesh_surface_get_arrays_and_format(RID p_mesh, uint32_t p_surface_index, uint32_t p_input_mask, RID &r_vertex_array_rd, RID &r_index_array_rd, RD::VertexFormatID &r_vertex_format) {
- Mesh *mesh = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_UNSIGNED_INDEX(p_surface_index, mesh->surface_count);
+ _FORCE_INLINE_ RS::PrimitiveType mesh_surface_get_primitive(void *p_surface) {
+ Mesh::Surface *surface = reinterpret_cast<Mesh::Surface *>(p_surface);
+ return surface->primitive;
+ }
- Mesh::Surface *s = mesh->surfaces[p_surface_index];
+ _FORCE_INLINE_ bool mesh_surface_has_lod(void *p_surface) const {
+ Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
+ return s->lod_count > 0;
+ }
+
+ _FORCE_INLINE_ RID mesh_surface_get_index_array(void *p_surface) const {
+ Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
+
+ return s->index_array;
+ }
+
+ _FORCE_INLINE_ RID mesh_surface_get_index_array_with_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const {
+ Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
+
+ int32_t current_lod = -1;
+ 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_lod_threshold) {
+ break;
+ }
+ current_lod = i;
+ }
+ if (current_lod == -1) {
+ return s->index_array;
+ } else {
+ return s->lods[current_lod].index_array;
+ }
+ }
- r_index_array_rd = s->index_array;
+ _FORCE_INLINE_ void mesh_surface_get_vertex_arrays_and_format(void *p_surface, uint32_t p_input_mask, RID &r_vertex_array_rd, RD::VertexFormatID &r_vertex_format) {
+ Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
s->version_lock.lock();
@@ -1346,9 +1498,11 @@ public:
return;
}
- uint32_t version = s->version_count; //gets added at the end
+ uint32_t version = s->version_count;
+ s->version_count++;
+ s->versions = (Mesh::Surface::Version *)memrealloc(s->versions, sizeof(Mesh::Surface::Version) * s->version_count);
- _mesh_surface_generate_version_for_input_mask(s, p_input_mask);
+ _mesh_surface_generate_version_for_input_mask(s->versions[version], s, p_input_mask);
r_vertex_format = s->versions[version].vertex_format;
r_vertex_array_rd = s->versions[version].vertex_array;
@@ -1356,6 +1510,42 @@ public:
s->version_lock.unlock();
}
+ _FORCE_INLINE_ void mesh_instance_surface_get_vertex_arrays_and_format(RID p_mesh_instance, uint32_t p_surface_index, uint32_t p_input_mask, RID &r_vertex_array_rd, RD::VertexFormatID &r_vertex_format) {
+ MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance);
+ ERR_FAIL_COND(!mi);
+ Mesh *mesh = mi->mesh;
+ ERR_FAIL_UNSIGNED_INDEX(p_surface_index, mesh->surface_count);
+
+ MeshInstance::Surface *mis = &mi->surfaces[p_surface_index];
+ Mesh::Surface *s = mesh->surfaces[p_surface_index];
+
+ s->version_lock.lock();
+
+ //there will never be more than, at much, 3 or 4 versions, so iterating is the fastest way
+
+ for (uint32_t i = 0; i < mis->version_count; i++) {
+ if (mis->versions[i].input_mask != p_input_mask) {
+ continue;
+ }
+ //we have this version, hooray
+ r_vertex_format = mis->versions[i].vertex_format;
+ r_vertex_array_rd = mis->versions[i].vertex_array;
+ s->version_lock.unlock();
+ return;
+ }
+
+ uint32_t version = mis->version_count;
+ mis->version_count++;
+ mis->versions = (Mesh::Surface::Version *)memrealloc(mis->versions, sizeof(Mesh::Surface::Version) * mis->version_count);
+
+ _mesh_surface_generate_version_for_input_mask(mis->versions[version], s, p_input_mask, mis);
+
+ r_vertex_format = mis->versions[version].vertex_format;
+ r_vertex_array_rd = mis->versions[version].vertex_array;
+
+ s->version_lock.unlock();
+ }
+
_FORCE_INLINE_ RID mesh_get_default_rd_buffer(DefaultRDBuffer p_buffer) {
ERR_FAIL_INDEX_V(p_buffer, DEFAULT_RD_BUFFER_MAX, RID());
return mesh_default_rd_buffers[p_buffer];
@@ -1456,7 +1646,7 @@ public:
if (!multimesh->uniform_set_3d.is_valid()) {
Vector<RD::Uniform> uniforms;
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 0;
u.ids.push_back(multimesh->buffer);
uniforms.push_back(u);
@@ -1494,6 +1684,10 @@ public:
void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
+ _FORCE_INLINE_ bool skeleton_is_valid(RID p_skeleton) {
+ return skeleton_owner.getornull(p_skeleton) != nullptr;
+ }
+
_FORCE_INLINE_ RID skeleton_get_3d_uniform_set(RID p_skeleton, RID p_shader, uint32_t p_set) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, RID());
@@ -1504,7 +1698,7 @@ public:
if (!skeleton->uniform_set_3d.is_valid()) {
Vector<RD::Uniform> uniforms;
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 0;
u.ids.push_back(skeleton->buffer);
uniforms.push_back(u);
@@ -1537,6 +1731,8 @@ public:
void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode);
void light_directional_set_blend_splits(RID p_light, bool p_enable);
bool light_directional_get_blend_splits(RID p_light) const;
+ void light_directional_set_sky_only(RID p_light, bool p_sky_only);
+ bool light_directional_is_sky_only(RID p_light) const;
void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode);
RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const;
@@ -1635,6 +1831,7 @@ public:
void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable);
void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers);
void reflection_probe_set_resolution(RID p_probe, int p_resolution);
+ void reflection_probe_set_lod_threshold(RID p_probe, float p_ratio);
AABB reflection_probe_get_aabb(RID p_probe) const;
RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const;
@@ -1642,6 +1839,8 @@ public:
Vector3 reflection_probe_get_extents(RID p_probe) const;
Vector3 reflection_probe_get_origin_offset(RID p_probe) const;
float reflection_probe_get_origin_max_distance(RID p_probe) const;
+ float reflection_probe_get_lod_threshold(RID p_probe) const;
+
int reflection_probe_get_resolution(RID p_probe) const;
bool reflection_probe_renders_shadows(RID p_probe) const;
@@ -1652,8 +1851,8 @@ public:
Color reflection_probe_get_ambient_color(RID p_probe) const;
float reflection_probe_get_ambient_color_energy(RID p_probe) const;
- void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance);
- void skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance);
+ void base_update_dependency(RID p_base, DependencyTracker *p_instance);
+ void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance);
/* DECAL API */
@@ -1802,7 +2001,11 @@ public:
_FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const {
return lightmap_probe_capture_update_speed;
}
-
+ _FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const {
+ const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, RID());
+ return lm->light_texture;
+ }
_FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const {
ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
@@ -1891,7 +2094,7 @@ public:
{
RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 0;
u.ids.push_back(particles->particle_instance_buffer);
uniforms.push_back(u);
@@ -1903,8 +2106,8 @@ public:
return particles->particles_transforms_buffer_uniform_set;
}
- virtual void particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance);
- virtual void particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance);
+ virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance);
+ virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance);
/* PARTICLES COLLISION */
@@ -1924,6 +2127,11 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const;
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
+ //used from 2D and 3D
+ virtual RID particles_collision_instance_create(RID p_collision);
+ virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform);
+ virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
+
/* GLOBAL VARIABLES API */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value);
@@ -2013,12 +2221,12 @@ public:
RID get_default_rd_storage_buffer() { return default_rd_storage_buffer; }
- static RasterizerStorageRD *base_singleton;
+ static RendererStorageRD *base_singleton;
- RasterizerEffectsRD *get_effects();
+ EffectsRD *get_effects();
- RasterizerStorageRD();
- ~RasterizerStorageRD();
+ RendererStorageRD();
+ ~RendererStorageRD();
};
#endif // RASTERIZER_STORAGE_RD_H
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
index df5513435a..e77141b26c 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -32,7 +32,7 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "rasterizer_storage_rd.h"
+#include "renderer_storage_rd.h"
#include "servers/rendering_server.h"
#define SL ShaderLanguage
@@ -920,7 +920,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
if (adnode->datatype == SL::TYPE_STRUCT) {
declaration += _mkid(adnode->struct_name);
} else {
- declaration = _prestr(adnode->precision) + _typestr(adnode->datatype);
+ declaration += _prestr(adnode->precision) + _typestr(adnode->datatype);
}
for (int i = 0; i < adnode->declarations.size(); i++) {
if (i > 0) {
@@ -930,7 +930,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
declaration += _mkid(adnode->declarations[i].name);
declaration += "[";
- declaration += itos(adnode->declarations[i].size);
+ if (adnode->size_expression != nullptr) {
+ declaration += _dump_node_code(adnode->size_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else {
+ declaration += itos(adnode->declarations[i].size);
+ }
declaration += "]";
int sz = adnode->declarations[i].initializer.size();
if (sz > 0) {
@@ -986,12 +990,13 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
if (anode->call_expression != nullptr) {
code += ".";
code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false);
- }
-
- if (anode->index_expression != nullptr) {
+ } else if (anode->index_expression != nullptr) {
code += "[";
code += _dump_node_code(anode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "]";
+ } else if (anode->assign_expression != nullptr) {
+ code += "=";
+ code += _dump_node_code(anode->assign_expression, p_level, r_gen_code, p_actions, p_default_actions, true, false);
}
if (anode->name == time_name) {
@@ -1229,8 +1234,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += "[";
code += _dump_node_code(mnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "]";
+ } else if (mnode->assign_expression != nullptr) {
+ code += "=";
+ code += _dump_node_code(mnode->assign_expression, p_level, r_gen_code, p_actions, p_default_actions, true, false);
}
-
} break;
}
@@ -1238,7 +1245,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &p_type) {
- RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RasterizerStorage::base_singleton))->global_variable_get_type_internal(p_type);
+ RS::GlobalVariableType gvt = ((RendererStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type);
return RS::global_variable_type_get_shader_datatype(gvt);
}
@@ -1333,8 +1340,8 @@ ShaderCompilerRD::ShaderCompilerRD() {
actions[RS::SHADER_SPATIAL].renames["FRAGCOORD"] = "gl_FragCoord";
actions[RS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrontFacing";
- actions[RS::SHADER_SPATIAL].renames["NORMALMAP"] = "normalmap";
- actions[RS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"] = "normaldepth";
+ actions[RS::SHADER_SPATIAL].renames["NORMAL_MAP"] = "normal_map";
+ actions[RS::SHADER_SPATIAL].renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
actions[RS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo";
actions[RS::SHADER_SPATIAL].renames["ALPHA"] = "alpha";
actions[RS::SHADER_SPATIAL].renames["METALLIC"] = "metallic";
@@ -1380,8 +1387,8 @@ ShaderCompilerRD::ShaderCompilerRD() {
actions[RS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n";
actions[RS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n";
actions[RS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n";
- actions[RS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n";
- actions[RS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
+ actions[RS::SHADER_SPATIAL].usage_defines["NORMAL_MAP"] = "#define ENABLE_NORMAL_MAP\n";
+ actions[RS::SHADER_SPATIAL].usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
actions[RS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions[RS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions[RS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n";
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/renderer_rd/shader_compiler_rd.h
index 694f8fff91..d127d8e01c 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/servers/rendering/rasterizer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 865a1e1bbe..2ae22a8a38 100644
--- a/servers/rendering/rasterizer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -31,7 +31,7 @@
#include "shader_rd.h"
#include "core/string/string_builder.h"
-#include "rasterizer_rd.h"
+#include "renderer_compositor_rd.h"
#include "servers/rendering/rendering_device.h"
void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) {
@@ -199,6 +199,10 @@ void ShaderRD::_clear_version(Version *p_version) {
}
void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
+ if (!variants_enabled[p_variant]) {
+ return; //variant is disabled, return
+ }
+
Vector<RD::ShaderStageData> stages;
String error;
@@ -347,6 +351,127 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
}
}
+RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_version) {
+ Version *version = version_owner.getornull(p_version);
+ RS::ShaderNativeSourceCode source_code;
+ ERR_FAIL_COND_V(!version, source_code);
+
+ source_code.versions.resize(variant_defines.size());
+
+ for (int i = 0; i < source_code.versions.size(); i++) {
+ if (!is_compute) {
+ //vertex stage
+
+ StringBuilder builder;
+
+ builder.append(vertex_codev.get_data()); // version info (if exists)
+ builder.append("\n"); //make sure defines begin at newline
+ builder.append(general_defines.get_data());
+ builder.append(variant_defines[i].get_data());
+
+ for (int j = 0; j < version->custom_defines.size(); j++) {
+ builder.append(version->custom_defines[j].get_data());
+ }
+
+ builder.append(vertex_code0.get_data()); //first part of vertex
+
+ builder.append(version->uniforms.get_data()); //uniforms (same for vertex and fragment)
+
+ builder.append(vertex_code1.get_data()); //second part of vertex
+
+ builder.append(version->vertex_globals.get_data()); // vertex globals
+
+ builder.append(vertex_code2.get_data()); //third part of vertex
+
+ builder.append(version->vertex_code.get_data()); // code
+
+ builder.append(vertex_code3.get_data()); //fourth of vertex
+
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "vertex";
+ stage.code = builder.as_string();
+
+ source_code.versions.write[i].stages.push_back(stage);
+ }
+
+ if (!is_compute) {
+ //fragment stage
+
+ StringBuilder builder;
+
+ builder.append(fragment_codev.get_data()); // version info (if exists)
+ builder.append("\n"); //make sure defines begin at newline
+
+ builder.append(general_defines.get_data());
+ builder.append(variant_defines[i].get_data());
+ for (int j = 0; j < version->custom_defines.size(); j++) {
+ builder.append(version->custom_defines[j].get_data());
+ }
+
+ builder.append(fragment_code0.get_data()); //first part of fragment
+
+ builder.append(version->uniforms.get_data()); //uniforms (same for fragment and fragment)
+
+ builder.append(fragment_code1.get_data()); //first part of fragment
+
+ builder.append(version->fragment_globals.get_data()); // fragment globals
+
+ builder.append(fragment_code2.get_data()); //third part of fragment
+
+ builder.append(version->fragment_light.get_data()); // fragment light
+
+ builder.append(fragment_code3.get_data()); //fourth part of fragment
+
+ builder.append(version->fragment_code.get_data()); // fragment code
+
+ builder.append(fragment_code4.get_data()); //fourth part of fragment
+
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "fragment";
+ stage.code = builder.as_string();
+
+ source_code.versions.write[i].stages.push_back(stage);
+ }
+
+ if (is_compute) {
+ //compute stage
+
+ StringBuilder builder;
+
+ builder.append(compute_codev.get_data()); // version info (if exists)
+ builder.append("\n"); //make sure defines begin at newline
+ builder.append(general_defines.get_data());
+ builder.append(variant_defines[i].get_data());
+
+ for (int j = 0; j < version->custom_defines.size(); j++) {
+ builder.append(version->custom_defines[j].get_data());
+ }
+
+ builder.append(compute_code0.get_data()); //first part of compute
+
+ builder.append(version->uniforms.get_data()); //uniforms (same for compute and fragment)
+
+ builder.append(compute_code1.get_data()); //second part of compute
+
+ builder.append(version->compute_globals.get_data()); // compute globals
+
+ builder.append(compute_code2.get_data()); //third part of compute
+
+ builder.append(version->compute_code.get_data()); // code
+
+ builder.append(compute_code3.get_data()); //fourth of compute
+
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "compute";
+ stage.code = builder.as_string();
+
+ source_code.versions.write[i].stages.push_back(stage);
+ }
+ }
+
+ return source_code;
+}
+
void ShaderRD::_compile_version(Version *p_version) {
_clear_version(p_version);
@@ -356,7 +481,7 @@ void ShaderRD::_compile_version(Version *p_version) {
p_version->variants = memnew_arr(RID, variant_defines.size());
#if 1
- RasterizerRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version);
+ RendererThreadPool::singleton->thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version);
#else
for (int i = 0; i < variant_defines.size(); i++) {
_compile_variant(i, p_version);
@@ -365,6 +490,9 @@ void ShaderRD::_compile_version(Version *p_version) {
bool all_valid = true;
for (int i = 0; i < variant_defines.size(); i++) {
+ if (!variants_enabled[i]) {
+ continue; //disabled
+ }
if (p_version->variants[i].is_null()) {
all_valid = false;
break;
@@ -374,6 +502,9 @@ void ShaderRD::_compile_version(Version *p_version) {
if (!all_valid) {
//clear versions if they exist
for (int i = 0; i < variant_defines.size(); i++) {
+ if (!variants_enabled[i]) {
+ continue; //disabled
+ }
if (!p_version->variants[i].is_null()) {
RD::get_singleton()->free(p_version->variants[i]);
}
@@ -454,12 +585,26 @@ bool ShaderRD::version_free(RID p_version) {
return true;
}
+void ShaderRD::set_variant_enabled(int p_variant, bool p_enabled) {
+ ERR_FAIL_COND(version_owner.get_rid_count() > 0); //versions exist
+ ERR_FAIL_INDEX(p_variant, variants_enabled.size());
+ variants_enabled.write[p_variant] = p_enabled;
+}
+
+bool ShaderRD::is_variant_enabled(int p_variant) const {
+ ERR_FAIL_INDEX_V(p_variant, variants_enabled.size(), false);
+ return variants_enabled[p_variant];
+}
+
void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) {
ERR_FAIL_COND(variant_defines.size());
ERR_FAIL_COND(p_variant_defines.size() == 0);
+
general_defines = p_general_defines.utf8();
+
for (int i = 0; i < p_variant_defines.size(); i++) {
variant_defines.push_back(p_variant_defines[i].utf8());
+ variants_enabled.push_back(true);
}
}
diff --git a/servers/rendering/rasterizer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h
index 0c379db6f2..a3474c6f93 100644
--- a/servers/rendering/rasterizer_rd/shader_rd.h
+++ b/servers/rendering/renderer_rd/shader_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -36,6 +36,7 @@
#include "core/templates/map.h"
#include "core/templates/rid_owner.h"
#include "core/variant/variant.h"
+#include "servers/rendering_server.h"
#include <stdio.h>
/**
@@ -46,6 +47,7 @@ class ShaderRD {
//versions
CharString general_defines;
Vector<CharString> variant_defines;
+ Vector<bool> variants_enabled;
struct Version {
CharString uniforms;
@@ -109,6 +111,7 @@ public:
_FORCE_INLINE_ RID version_get_shader(RID p_version, int p_variant) {
ERR_FAIL_INDEX_V(p_variant, variant_defines.size(), RID());
+ ERR_FAIL_COND_V(!variants_enabled[p_variant], RID());
Version *version = version_owner.getornull(p_version);
ERR_FAIL_COND_V(!version, RID());
@@ -128,6 +131,11 @@ public:
bool version_free(RID p_version);
+ void set_variant_enabled(int p_variant, bool p_enabled);
+ bool is_variant_enabled(int p_variant) const;
+
+ RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version);
+
void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
virtual ~ShaderRD();
};
diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub
index 4cddf0f685..deaa9668df 100644
--- a/servers/rendering/rasterizer_rd/shaders/SCsub
+++ b/servers/rendering/renderer_rd/shaders/SCsub
@@ -11,7 +11,7 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("cubemap_roughness.glsl")
env.RD_GLSL("cubemap_downsampler.glsl")
env.RD_GLSL("cubemap_filter.glsl")
- env.RD_GLSL("scene_high_end.glsl")
+ env.RD_GLSL("scene_forward.glsl")
env.RD_GLSL("sky.glsl")
env.RD_GLSL("tonemap.glsl")
env.RD_GLSL("cube_to_dp.glsl")
@@ -21,8 +21,10 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("luminance_reduce.glsl")
env.RD_GLSL("bokeh_dof.glsl")
env.RD_GLSL("ssao.glsl")
- env.RD_GLSL("ssao_minify.glsl")
+ env.RD_GLSL("ssao_downsample.glsl")
+ env.RD_GLSL("ssao_importance_map.glsl")
env.RD_GLSL("ssao_blur.glsl")
+ env.RD_GLSL("ssao_interleave.glsl")
env.RD_GLSL("roughness_limiter.glsl")
env.RD_GLSL("screen_space_reflection.glsl")
env.RD_GLSL("screen_space_reflection_filter.glsl")
@@ -41,3 +43,4 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("particles.glsl")
env.RD_GLSL("particles_copy.glsl")
env.RD_GLSL("sort.glsl")
+ env.RD_GLSL("skeleton.glsl")
diff --git a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl
index 63f086a83d..63f086a83d 100644
--- a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl
+++ b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index 51d7193a03..3b39edc70e 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -9,7 +9,8 @@ layout(location = 0) in vec2 vertex_attrib;
layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;
-layout(location = 6) in uvec4 bones_attrib;
+layout(location = 10) in uvec4 bone_attrib;
+layout(location = 11) in vec4 weight_attrib;
#endif
@@ -61,6 +62,7 @@ void main() {
color = vec4(unpackHalf2x16(draw_data.colors[4]), unpackHalf2x16(draw_data.colors[5]));
}
uvec4 bones = uvec4(0, 0, 0, 0);
+ vec4 bone_weights = vec4(0.0);
#elif defined(USE_ATTRIBUTES)
@@ -68,7 +70,8 @@ void main() {
vec4 color = color_attrib;
vec2 uv = uv_attrib;
- uvec4 bones = bones_attrib;
+ uvec4 bones = bone_attrib;
+ vec4 bone_weights = weight_attrib;
#else
vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
@@ -393,7 +396,7 @@ vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv
vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color);
#ifdef LIGHT_SHADER_CODE_USED
- shadow_color *= shadow_modulate;
+ shadow_color.rgb *= shadow_modulate;
#endif
shadow_color.a *= light_color.a; //respect light alpha
@@ -494,9 +497,9 @@ void main() {
vec2 shadow_vertex = vertex;
{
- float normal_depth = 1.0;
+ float normal_map_depth = 1.0;
-#if defined(NORMALMAP_USED)
+#if defined(NORMAL_MAP_USED)
vec3 normal_map = vec3(0.0, 0.0, 1.0);
normal_used = true;
#endif
@@ -507,8 +510,8 @@ FRAGMENT_SHADER_CODE
/* clang-format on */
-#if defined(NORMALMAP_USED)
- normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth);
+#if defined(NORMAL_MAP_USED)
+ normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_map_depth);
#endif
}
@@ -543,7 +546,7 @@ FRAGMENT_SHADER_CODE
#ifdef LIGHT_SHADER_CODE_USED
vec4 shadow_modulate = vec4(1.0);
- light_color = light_compute(light_vertex, direction, normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, true);
+ light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true);
#else
if (normal_used) {
@@ -560,7 +563,7 @@ FRAGMENT_SHADER_CODE
light_color = light_shadow_compute(light_base, light_color, shadow_uv
#ifdef LIGHT_SHADER_CODE_USED
,
- shadow_modulate
+ shadow_modulate.rgb
#endif
);
}
@@ -602,7 +605,7 @@ FRAGMENT_SHADER_CODE
vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height);
light_color.rgb *= light_base_color.rgb;
- light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, false);
+ light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false);
#else
light_color.rgb *= light_base_color.rgb * light_base_color.a;
@@ -656,7 +659,7 @@ FRAGMENT_SHADER_CODE
light_color = light_shadow_compute(light_base, light_color, shadow_uv
#ifdef LIGHT_SHADER_CODE_USED
,
- shadow_modulate
+ shadow_modulate.rgb
#endif
);
}
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl
index 5c25235c58..5c25235c58 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_sdf.glsl b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl
index 302ad03b41..302ad03b41 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_sdf.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
index cf7678ea31..cf7678ea31 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/cluster_data_inc.glsl b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl
index e723468dd8..e723468dd8 100644
--- a/servers/rendering/rasterizer_rd/shaders/cluster_data_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/renderer_rd/shaders/copy.glsl
index cdd35dfb3f..cdd35dfb3f 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy.glsl
+++ b/servers/rendering/renderer_rd/shaders/copy.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
index 9751e13b4e..9751e13b4e 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
+++ b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl
index 54d67db6c6..54d67db6c6 100644
--- a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
+++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl
index 7f269b7af3..7f269b7af3 100644
--- a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl b/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl
index 987545fb76..987545fb76 100644
--- a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
index 5cbb00baa4..5cbb00baa4 100644
--- a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl
index 8011dadc72..8011dadc72 100644
--- a/servers/rendering/rasterizer_rd/shaders/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/gi.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/giprobe.glsl
index ea4237a45e..4f4753d147 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe.glsl
@@ -208,6 +208,15 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
return occlusion; //max(0.0,distance);
}
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) {
if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) {
light_pos = pos - lights.data[light].direction * length(vec3(params.limits));
@@ -220,7 +229,7 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
return false;
}
- attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation);
+ attenuation = get_omni_attenuation(distance, 1.0 / lights.data[light].radius, lights.data[light].attenuation);
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(pos - light_pos);
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl b/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl
index 515cc35507..515cc35507 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl
index 5b3dec0ee7..5b3dec0ee7 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
index 9c794f1bcc..9c794f1bcc 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl
index 8a11c35b78..8a11c35b78 100644
--- a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl
+++ b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index 926c7ef9fc..cb6d8dc7f6 100644
--- a/servers/rendering/rasterizer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -173,7 +173,7 @@ uint hash(uint x) {
return x;
}
-bool emit_particle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom, uint p_flags) {
+bool emit_subparticle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom, uint p_flags) {
if (!params.can_emit) {
return false;
}
diff --git a/servers/rendering/rasterizer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl
index 6c782b6045..6c782b6045 100644
--- a/servers/rendering/rasterizer_rd/shaders/particles_copy.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl
index 9429a66dc9..9429a66dc9 100644
--- a/servers/rendering/rasterizer_rd/shaders/resolve.glsl
+++ b/servers/rendering/renderer_rd/shaders/resolve.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl
index 464895928a..464895928a 100644
--- a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl
+++ b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/renderer_rd/shaders/scene_forward.glsl
index 285698f060..0518976322 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward.glsl
@@ -4,13 +4,19 @@
VERSION_DEFINES
-#include "scene_high_end_inc.glsl"
+#include "scene_forward_inc.glsl"
/* INPUT ATTRIBS */
layout(location = 0) in vec3 vertex_attrib;
+
+//only for pure render depth when normal is not used
+
+#ifdef NORMAL_USED
layout(location = 1) in vec3 normal_attrib;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#endif
+
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 2) in vec4 tangent_attrib;
#endif
@@ -18,30 +24,59 @@ layout(location = 2) in vec4 tangent_attrib;
layout(location = 3) in vec4 color_attrib;
#endif
+#ifdef UV_USED
layout(location = 4) in vec2 uv_attrib;
+#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP) || defined(MODE_RENDER_MATERIAL)
layout(location = 5) in vec2 uv2_attrib;
#endif
-layout(location = 6) in uvec4 bone_attrib; // always bound, even if unused
+#if defined(CUSTOM0_USED)
+layout(location = 6) in vec4 custom0_attrib;
+#endif
+
+#if defined(CUSTOM1_USED)
+layout(location = 7) in vec4 custom1_attrib;
+#endif
+
+#if defined(CUSTOM2_USED)
+layout(location = 8) in vec4 custom2_attrib;
+#endif
+
+#if defined(CUSTOM3_USED)
+layout(location = 9) in vec4 custom3_attrib;
+#endif
+
+#if defined(BONES_USED)
+layout(location = 10) in uvec4 bone_attrib;
+#endif
+
+#if defined(WEIGHTS_USED)
+layout(location = 11) in vec4 weight_attrib;
+#endif
/* Varyings */
layout(location = 0) out vec3 vertex_interp;
+
+#ifdef NORMAL_USED
layout(location = 1) out vec3 normal_interp;
+#endif
#if defined(COLOR_USED)
layout(location = 2) out vec4 color_interp;
#endif
+#ifdef UV_USED
layout(location = 3) out vec2 uv_interp;
+#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 4) out vec2 uv2_interp;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 5) out vec3 tangent_interp;
layout(location = 6) out vec3 binormal_interp;
#endif
@@ -62,8 +97,6 @@ VERTEX_SHADER_GLOBALS
invariant gl_Position;
-layout(location = 7) flat out uint instance_index;
-
#ifdef MODE_DUAL_PARABOLOID
layout(location = 8) out float dp_clip;
@@ -71,22 +104,27 @@ layout(location = 8) out float dp_clip;
#endif
void main() {
- instance_index = draw_call.instance_index;
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
color_interp = color_attrib;
#endif
- mat4 world_matrix = instances.data[instance_index].transform;
- mat3 world_normal_matrix = mat3(instances.data[instance_index].normal_transform);
+ mat4 world_matrix = draw_call.transform;
+
+ mat3 world_normal_matrix;
+ if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
+ world_normal_matrix = inverse(mat3(world_matrix));
+ } else {
+ world_normal_matrix = mat3(world_matrix);
+ }
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH)) {
+ if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH)) {
//multimesh, instances are for it
- uint offset = (instances.data[instance_index].flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK;
+ uint offset = (draw_call.flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK;
offset *= gl_InstanceIndex;
mat4 matrix;
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
+ if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
offset += 2;
} else {
@@ -94,14 +132,14 @@ void main() {
offset += 3;
}
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
+ if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
#ifdef COLOR_USED
color_interp *= transforms.data[offset];
#endif
offset += 1;
}
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
+ if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
instance_custom = transforms.data[offset];
}
@@ -109,22 +147,21 @@ void main() {
matrix = transpose(matrix);
world_matrix = world_matrix * matrix;
world_normal_matrix = world_normal_matrix * mat3(matrix);
-
- } else {
- //not a multimesh, instances are for multiple draw calls
- instance_index += gl_InstanceIndex;
}
vec3 vertex = vertex_attrib;
- vec3 normal = normal_attrib;
+#ifdef NORMAL_USED
+ vec3 normal = normal_attrib * 2.0 - 1.0;
+#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
- vec3 tangent = tangent_attrib.xyz;
- float binormalf = tangent_attrib.a;
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+ vec3 tangent = tangent_attrib.xyz * 2.0 - 1.0;
+ float binormalf = tangent_attrib.a * 2.0 - 1.0;
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
#endif
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_SKELETON)) {
+#if 0
+ if (bool(draw_call.flags & INSTANCE_FLAGS_SKELETON)) {
//multimesh, instances are for it
uvec2 bones_01 = uvec2(bone_attrib.x & 0xFFFF, bone_attrib.x >> 16) * 3;
@@ -141,14 +178,17 @@ void main() {
vertex = (vec4(vertex, 1.0) * m).xyz;
normal = (vec4(normal, 0.0) * m).xyz;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
tangent = (vec4(tangent, 0.0) * m).xyz;
binormal = (vec4(binormal, 0.0) * m).xyz;
#endif
}
+#endif
+#ifdef UV_USED
uv_interp = uv_attrib;
+#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
uv2_interp = uv2_attrib;
@@ -167,7 +207,7 @@ void main() {
normal = world_normal_matrix * normal;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
tangent = world_normal_matrix * tangent;
binormal = world_normal_matrix * binormal;
@@ -192,10 +232,13 @@ VERTEX_SHADER_CODE
#if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED)
vertex = (modelview * vec4(vertex, 1.0)).xyz;
+#ifdef NORMAL_USED
normal = modelview_normal * normal;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#endif
+
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
binormal = modelview_normal * binormal;
tangent = modelview_normal * tangent;
@@ -207,7 +250,7 @@ VERTEX_SHADER_CODE
vertex = (scene_data.inv_camera_matrix * vec4(vertex, 1.0)).xyz;
normal = mat3(scene_data.inverse_normal_matrix) * normal;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
binormal = mat3(scene_data.camera_inverse_binormal_matrix) * binormal;
tangent = mat3(scene_data.camera_inverse_tangent_matrix) * tangent;
@@ -215,9 +258,11 @@ VERTEX_SHADER_CODE
#endif
vertex_interp = vertex;
+#ifdef NORMAL_USED
normal_interp = normal;
+#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
tangent_interp = tangent;
binormal_interp = binormal;
#endif
@@ -227,7 +272,6 @@ VERTEX_SHADER_CODE
#ifdef MODE_DUAL_PARABOLOID
vertex_interp.z *= scene_data.dual_paraboloid_side;
- normal_interp.z *= scene_data.dual_paraboloid_side;
dp_clip = vertex_interp.z; //this attempts to avoid noise caused by objects sent to the other parabolloid side due to bias
@@ -260,7 +304,7 @@ VERTEX_SHADER_CODE
#endif
#ifdef MODE_RENDER_MATERIAL
if (scene_data.material_uv2_mode) {
- gl_Position.xy = (uv2_attrib.xy + draw_call.bake_uv2_offset) * 2.0 - 1.0;
+ gl_Position.xy = (uv2_attrib.xy + draw_call.lightmap_uv_scale.xy) * 2.0 - 1.0;
gl_Position.z = 0.00001;
gl_Position.w = 1.0;
}
@@ -273,30 +317,33 @@ VERTEX_SHADER_CODE
VERSION_DEFINES
-#include "scene_high_end_inc.glsl"
+#include "scene_forward_inc.glsl"
/* Varyings */
layout(location = 0) in vec3 vertex_interp;
+
+#ifdef NORMAL_USED
layout(location = 1) in vec3 normal_interp;
+#endif
#if defined(COLOR_USED)
layout(location = 2) in vec4 color_interp;
#endif
+#ifdef UV_USED
layout(location = 3) in vec2 uv_interp;
+#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 4) in vec2 uv2_interp;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 5) in vec3 tangent_interp;
layout(location = 6) in vec3 binormal_interp;
#endif
-layout(location = 7) flat in uint instance_index;
-
#ifdef MODE_DUAL_PARABOLOID
layout(location = 8) in float dp_clip;
@@ -305,8 +352,7 @@ layout(location = 8) in float dp_clip;
//defines to keep compatibility with vertex
-#define world_matrix instances.data[instance_index].transform
-#define world_normal_matrix instances.data[instance_index].normal_transform
+#define world_matrix draw_call.transform
#define projection_matrix scene_data.projection_matrix
#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
@@ -845,6 +891,15 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex
#endif //USE_NO_SHADOWS
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
#ifdef LIGHT_BACKLIGHT_USED
vec3 backlight,
@@ -870,9 +925,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = lights.data[idx].position - vertex;
float light_length = length(light_rel_vec);
- float normalized_distance = light_length * lights.data[idx].inv_radius;
vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
- float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), attenuation_energy.x);
+ float omni_attenuation = get_omni_attenuation(light_length, lights.data[idx].inv_radius, attenuation_energy.x);
float light_attenuation = omni_attenuation;
vec3 shadow_attenuation = vec3(1.0);
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
@@ -1159,9 +1213,8 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
inout vec3 specular_light) {
vec3 light_rel_vec = lights.data[idx].position - vertex;
float light_length = length(light_rel_vec);
- float normalized_distance = light_length * lights.data[idx].inv_radius;
vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
- float spot_attenuation = pow(max(1.0 - normalized_distance, 0.001), attenuation_energy.x);
+ float spot_attenuation = get_omni_attenuation(light_length, lights.data[idx].inv_radius, attenuation_energy.x);
vec3 spot_dir = lights.data[idx].direction;
vec2 spot_att_angle = unpackHalf2x16(lights.data[idx].cone_attenuation_angle);
float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y);
@@ -1525,8 +1578,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
out_spec += vec4(irr_light.rgb * blend, blend);
}
-#endif //USE_FORWARD_GI
-
vec2 octahedron_wrap(vec2 v) {
vec2 signVal;
signVal.x = v.x >= 0.0 ? 1.0 : -1.0;
@@ -1660,10 +1711,14 @@ void sdfgi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal
}
}
+#endif //USE_FORWARD_GI
+
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
#ifndef MODE_RENDER_DEPTH
+#ifndef LOW_END_MODE
+
vec4 volumetric_fog_process(vec2 screen_uv, float z) {
vec3 fog_pos = vec3(screen_uv, z * scene_data.volumetric_fog_inv_length);
if (fog_pos.z < 0.0) {
@@ -1674,6 +1729,7 @@ vec4 volumetric_fog_process(vec2 screen_uv, float z) {
return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos);
}
+#endif
vec4 fog_process(vec3 vertex) {
vec3 fog_color = scene_data.fog_light_color;
@@ -1766,13 +1822,15 @@ void main() {
float alpha = 1.0;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
vec3 binormal = normalize(binormal_interp);
vec3 tangent = normalize(tangent_interp);
#else
vec3 binormal = vec3(0.0);
vec3 tangent = vec3(0.0);
#endif
+
+#ifdef NORMAL_USED
vec3 normal = normalize(normal_interp);
#if defined(DO_SIDE_CHECK)
@@ -1781,7 +1839,11 @@ void main() {
}
#endif
+#endif //NORMAL_USED
+
+#ifdef UV_USED
vec2 uv = uv_interp;
+#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
vec2 uv2 = uv2_interp;
@@ -1791,12 +1853,12 @@ void main() {
vec4 color = color_interp;
#endif
-#if defined(NORMALMAP_USED)
+#if defined(NORMAL_MAP_USED)
- vec3 normalmap = vec3(0.5);
+ vec3 normal_map = vec3(0.5);
#endif
- float normaldepth = 1.0;
+ float normal_map_depth = 1.0;
vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size + scene_data.screen_pixel_size * 0.5; //account for center
@@ -1867,12 +1929,12 @@ FRAGMENT_SHADER_CODE
#endif // !USE_SHADOW_TO_OPACITY
-#ifdef NORMALMAP_USED
+#ifdef NORMAL_MAP_USED
- normalmap.xy = normalmap.xy * 2.0 - 1.0;
- normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
+ normal_map.xy = normal_map.xy * 2.0 - 1.0;
+ normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
- normal = normalize(mix(normal, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth));
+ normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
#endif
@@ -1912,7 +1974,7 @@ FRAGMENT_SHADER_CODE
for (uint i = 0; i < decal_count; i++) {
uint decal_index = cluster_data.indices[decal_pointer + i];
- if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) {
+ if (!bool(decals.data[decal_index].mask & draw_call.layer_mask)) {
continue; //not masked
}
@@ -1968,6 +2030,7 @@ FRAGMENT_SHADER_CODE
#endif //not render depth
/////////////////////// LIGHTING //////////////////////////////
+#ifdef NORMAL_USED
if (scene_data.roughness_limiter_enabled) {
//http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
float roughness2 = roughness * roughness;
@@ -1977,6 +2040,7 @@ FRAGMENT_SHADER_CODE
float filteredRoughness2 = min(1.0, roughness2 + kernelRoughness2);
roughness = sqrt(filteredRoughness2);
}
+#endif
//apply energy conservation
vec3 specular_light = vec3(0.0, 0.0, 0.0);
@@ -2041,8 +2105,8 @@ FRAGMENT_SHADER_CODE
#ifdef USE_LIGHTMAP
//lightmap
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture
- uint index = instances.data[instance_index].gi_offset;
+ if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture
+ uint index = draw_call.gi_offset;
vec3 wnormal = mat3(scene_data.camera_matrix) * normal;
const float c1 = 0.429043;
@@ -2061,12 +2125,12 @@ FRAGMENT_SHADER_CODE
2.0 * c2 * lightmap_captures.data[index].sh[1].rgb * wnormal.y +
2.0 * c2 * lightmap_captures.data[index].sh[2].rgb * wnormal.z);
- } else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap
- bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP);
- uint ofs = instances.data[instance_index].gi_offset & 0xFFF;
+ } else if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap
+ bool uses_sh = bool(draw_call.flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP);
+ uint ofs = draw_call.gi_offset & 0xFFFF;
vec3 uvw;
- uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy;
- uvw.z = float((instances.data[instance_index].gi_offset >> 12) & 0xFF);
+ uvw.xy = uv2 * draw_call.lightmap_uv_scale.zw + draw_call.lightmap_uv_scale.xy;
+ uvw.z = float((draw_call.gi_offset >> 16) & 0xFFFF);
if (uses_sh) {
uvw.z *= 4.0; //SH textures use 4 times more data
@@ -2075,7 +2139,7 @@ FRAGMENT_SHADER_CODE
vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb;
- uint idx = instances.data[instance_index].gi_offset >> 20;
+ uint idx = draw_call.gi_offset >> 20;
vec3 n = normalize(lightmaps.data[idx].normal_xform * normal);
ambient_light += lm_light_l0 * 0.282095f;
@@ -2095,7 +2159,7 @@ FRAGMENT_SHADER_CODE
}
#elif defined(USE_FORWARD_GI)
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture
+ if (bool(draw_call.flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture
//make vertex orientation the world one, but still align to camera
vec3 cam_pos = mat3(scene_data.camera_matrix) * vertex;
@@ -2167,9 +2231,9 @@ FRAGMENT_SHADER_CODE
}
}
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
+ if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
- uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
+ uint index1 = draw_call.gi_offset & 0xFFFF;
vec3 ref_vec = normalize(reflect(normalize(vertex), 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);
@@ -2181,7 +2245,7 @@ FRAGMENT_SHADER_CODE
vec4 spec_accum = vec4(0.0);
gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
- uint index2 = instances.data[instance_index].gi_offset >> 16;
+ uint index2 = draw_call.gi_offset >> 16;
if (index2 != 0xFFFF) {
gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
@@ -2198,30 +2262,13 @@ FRAGMENT_SHADER_CODE
specular_light = spec_accum.rgb;
ambient_light = amb_accum.rgb;
}
-#else
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
+#elif !defined(LOW_END_MODE)
+
+ if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
ivec2 coord;
if (scene_data.gi_upscale_for_msaa) {
- /*
- //find the closest depth to upscale from, based on neighbours
- ivec2 base_coord = ivec2(gl_FragCoord.xy);
- float z_dist = gl_FragCoord.z;
- ivec2 closest_coord = base_coord;
- float closest_z_dist = abs(texelFetch(sampler2D(depth_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord,0).r-z_dist);
-
- for(int i=0;i<4;i++) {
- const ivec2 neighbours[4]=ivec2[](ivec2(-1,0),ivec2(1,0),ivec2(0,-1),ivec2(0,1));
- ivec2 neighbour_coord = base_coord + neighbours[i];
- float neighbour_z_dist = abs(texelFetch(sampler2D(depth_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord,0).r-z_dist);
- if (neighbour_z_dist < closest_z_dist) {
- closest_z_dist = neighbour_z_dist;
- closest_coord = neighbour_coord;
- }
- }
-
-*/
ivec2 base_coord = ivec2(gl_FragCoord.xy);
ivec2 closest_coord = base_coord;
float closest_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0).xyz * 2.0 - 1.0);
@@ -2299,7 +2346,7 @@ FRAGMENT_SHADER_CODE
{ //directional light
for (uint i = 0; i < scene_data.directional_light_count; i++) {
- if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) {
+ if (!bool(directional_lights.data[i].mask & draw_call.layer_mask)) {
continue; //not masked
}
@@ -2569,7 +2616,7 @@ FRAGMENT_SHADER_CODE
for (uint i = 0; i < omni_light_count; i++) {
uint light_index = cluster_data.indices[omni_light_pointer + i];
- if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ if (!bool(lights.data[light_index].mask & draw_call.layer_mask)) {
continue; //not masked
}
@@ -2607,7 +2654,7 @@ FRAGMENT_SHADER_CODE
for (uint i = 0; i < spot_light_count; i++) {
uint light_index = cluster_data.indices[spot_light_pointer + i];
- if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ if (!bool(lights.data[light_index].mask & draw_call.layer_mask)) {
continue; //not masked
}
@@ -2778,9 +2825,9 @@ FRAGMENT_SHADER_CODE
normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
#ifdef MODE_RENDER_GIPROBE
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
- uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
- uint index2 = instances.data[instance_index].gi_offset >> 16;
+ if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
+ uint index1 = draw_call.gi_offset & 0xFFFF;
+ uint index2 = draw_call.gi_offset >> 16;
giprobe_buffer.x = index1 & 0xFF;
giprobe_buffer.y = index2 & 0xFF;
} else {
@@ -2800,11 +2847,13 @@ FRAGMENT_SHADER_CODE
//ambient occlusion
#if defined(AO_USED)
+#ifndef LOW_END_MODE
if (scene_data.ssao_enabled && scene_data.ssao_ao_affect > 0.0) {
float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
ao = mix(ao, min(ao, ssao), scene_data.ssao_ao_affect);
ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect);
}
+#endif //LOW_END_MODE
ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao);
ao_light_affect = mix(1.0, ao, ao_light_affect);
@@ -2812,6 +2861,7 @@ FRAGMENT_SHADER_CODE
diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect);
#else
+#ifndef LOW_END_MODE
if (scene_data.ssao_enabled) {
float ao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao);
@@ -2819,6 +2869,7 @@ FRAGMENT_SHADER_CODE
specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect);
diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect);
}
+#endif //LOW_END_MODE
#endif // AO_USED
@@ -2848,11 +2899,13 @@ FRAGMENT_SHADER_CODE
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
}
+#ifndef LOW_END_MODE
if (scene_data.volumetric_fog_enabled) {
vec4 fog = volumetric_fog_process(screen_uv, -vertex.z);
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
}
+#endif // LOW_END_MODE
#if defined(CUSTOM_FOG_USED)
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, custom_fog.rgb, custom_fog.a);
@@ -2873,11 +2926,12 @@ FRAGMENT_SHADER_CODE
vec4 fog = fog_process(vertex);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
}
-
+#ifndef LOW_END_MODE
if (scene_data.volumetric_fog_enabled) {
vec4 fog = volumetric_fog_process(screen_uv, -vertex.z);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
}
+#endif
#if defined(CUSTOM_FOG_USED)
frag_color.rgb = mix(frag_color.rgb, custom_fog.rgb, custom_fog.a);
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl
index e29a490ca1..87ce74ba88 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl
@@ -5,10 +5,19 @@
#include "cluster_data_inc.glsl"
+#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_GIPROBE) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED)
+#ifndef NORMAL_USED
+#define NORMAL_USED
+#endif
+#endif
+
layout(push_constant, binding = 0, std430) uniform DrawCall {
- uint instance_index;
- uint pad; //16 bits minimum size
- vec2 bake_uv2_offset; //used for bake to uv2, ignored otherwise
+ mat4 transform;
+ uint flags;
+ uint instance_uniforms_ofs; //base offset in global buffer for instance variables
+ uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
+ uint layer_mask;
+ vec4 lightmap_uv_scale;
}
draw_call;
@@ -128,21 +137,7 @@ scene_data;
#define INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK 0x7
#define INSTANCE_FLAGS_SKELETON (1 << 19)
-
-struct InstanceData {
- mat4 transform;
- mat4 normal_transform;
- uint flags;
- uint instance_uniforms_ofs; //base offset in global buffer for instance variables
- uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
- uint layer_mask;
- vec4 lightmap_uv_scale;
-};
-
-layout(set = 0, binding = 4, std430) restrict readonly buffer Instances {
- InstanceData data[];
-}
-instances;
+#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20)
layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
LightData data[];
@@ -171,39 +166,39 @@ layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps {
}
lightmaps;
-layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
-
struct LightmapCapture {
vec4 sh[9];
};
-layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures {
+layout(set = 0, binding = 11, std140) restrict readonly buffer LightmapCaptures {
LightmapCapture data[];
}
lightmap_captures;
-layout(set = 0, binding = 13) uniform texture2D decal_atlas;
-layout(set = 0, binding = 14) uniform texture2D decal_atlas_srgb;
+layout(set = 0, binding = 12) uniform texture2D decal_atlas;
+layout(set = 0, binding = 13) uniform texture2D decal_atlas_srgb;
-layout(set = 0, binding = 15, std430) restrict readonly buffer Decals {
+layout(set = 0, binding = 14, std430) restrict readonly buffer Decals {
DecalData data[];
}
decals;
-layout(set = 0, binding = 16) uniform utexture3D cluster_texture;
+layout(set = 0, binding = 15) uniform utexture3D cluster_texture;
-layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData {
+layout(set = 0, binding = 16, std430) restrict readonly buffer ClusterData {
uint indices[];
}
cluster_data;
-layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas;
+layout(set = 0, binding = 17) uniform texture2D directional_shadow_atlas;
-layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData {
+layout(set = 0, binding = 18, std430) restrict readonly buffer GlobalVariableData {
vec4 data[];
}
global_variables;
+#ifndef LOW_END_MODE
+
struct SDFGIProbeCascadeData {
vec3 position;
float to_probe;
@@ -211,7 +206,7 @@ struct SDFGIProbeCascadeData {
float to_cell; // 1/bounds * grid_size
};
-layout(set = 0, binding = 20, std140) uniform SDFGI {
+layout(set = 0, binding = 19, std140) uniform SDFGI {
vec3 grid_size;
uint max_cascades;
@@ -239,6 +234,8 @@ layout(set = 0, binding = 20, std140) uniform SDFGI {
}
sdfgi;
+#endif //LOW_END_MODE
+
// decal atlas
/* Set 1, Radiance */
@@ -255,20 +252,24 @@ layout(set = 1, binding = 0) uniform textureCube radiance_cubemap;
/* Set 2, Reflection and Shadow Atlases (view dependent) */
-layout(set = 2, binding = 0) uniform textureCubeArray reflection_atlas;
+layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas;
+
+layout(set = 1, binding = 2) uniform texture2D shadow_atlas;
-layout(set = 2, binding = 1) uniform texture2D shadow_atlas;
+layout(set = 1, binding = 3) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
-layout(set = 2, binding = 2) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
+#ifndef LOW_END_MODE
+layout(set = 1, binding = 4) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
+#endif
/* Set 3, Render Buffers */
#ifdef MODE_RENDER_SDF
-layout(r16ui, set = 3, binding = 0) uniform restrict writeonly uimage3D albedo_volume_grid;
-layout(r32ui, set = 3, binding = 1) uniform restrict writeonly uimage3D emission_grid;
-layout(r32ui, set = 3, binding = 2) uniform restrict writeonly uimage3D emission_aniso_grid;
-layout(r32ui, set = 3, binding = 3) uniform restrict uimage3D geom_facing_grid;
+layout(r16ui, set = 1, binding = 5) uniform restrict writeonly uimage3D albedo_volume_grid;
+layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_grid;
+layout(r32ui, set = 1, binding = 7) uniform restrict writeonly uimage3D emission_aniso_grid;
+layout(r32ui, set = 1, binding = 8) uniform restrict uimage3D geom_facing_grid;
//still need to be present for shaders that use it, so remap them to something
#define depth_buffer shadow_atlas
@@ -277,14 +278,17 @@ layout(r32ui, set = 3, binding = 3) uniform restrict uimage3D geom_facing_grid;
#else
-layout(set = 3, binding = 0) uniform texture2D depth_buffer;
-layout(set = 3, binding = 1) uniform texture2D color_buffer;
-layout(set = 3, binding = 2) uniform texture2D normal_roughness_buffer;
-layout(set = 3, binding = 4) uniform texture2D ao_buffer;
-layout(set = 3, binding = 5) uniform texture2D ambient_buffer;
-layout(set = 3, binding = 6) uniform texture2D reflection_buffer;
-layout(set = 3, binding = 7) uniform texture2DArray sdfgi_lightprobe_texture;
-layout(set = 3, binding = 8) uniform texture3D sdfgi_occlusion_cascades;
+layout(set = 1, binding = 5) uniform texture2D depth_buffer;
+layout(set = 1, binding = 6) uniform texture2D color_buffer;
+
+#ifndef LOW_END_MODE
+
+layout(set = 1, binding = 7) uniform texture2D normal_roughness_buffer;
+layout(set = 1, binding = 8) uniform texture2D ao_buffer;
+layout(set = 1, binding = 9) uniform texture2D ambient_buffer;
+layout(set = 1, binding = 10) uniform texture2D reflection_buffer;
+layout(set = 1, binding = 11) uniform texture2DArray sdfgi_lightprobe_texture;
+layout(set = 1, binding = 12) uniform texture3D sdfgi_occlusion_cascades;
struct GIProbeData {
mat4 xform;
@@ -302,18 +306,20 @@ struct GIProbeData {
uint mipmaps;
};
-layout(set = 3, binding = 9, std140) uniform GIProbes {
+layout(set = 1, binding = 13, std140) uniform GIProbes {
GIProbeData data[MAX_GI_PROBES];
}
gi_probes;
-layout(set = 3, binding = 10) uniform texture3D volumetric_fog_texture;
+layout(set = 1, binding = 14) uniform texture3D volumetric_fog_texture;
+
+#endif // LOW_END_MODE
#endif
/* Set 4 Skeleton & Instancing (Multimesh) */
-layout(set = 4, binding = 0, std430) restrict readonly buffer Transforms {
+layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms {
vec4 data[];
}
transforms;
diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl
index 06dc4b13de..06dc4b13de 100644
--- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl
+++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl
index a5afe74cb2..a5afe74cb2 100644
--- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl
+++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl
index 218605a962..218605a962 100644
--- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl
+++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl
index 813ea29fa1..813ea29fa1 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl
index 08da283dad..08da283dad 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_debug_probes.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
index 61e4bf5e18..30dbf5871f 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
@@ -112,6 +112,15 @@ vec2 octahedron_encode(vec3 n) {
return n.xy;
}
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
void main() {
uint voxel_index = uint(gl_GlobalInvocationID.x);
@@ -184,14 +193,15 @@ void main() {
direction = normalize(rel_vec);
light_distance = length(rel_vec);
rel_vec.y /= params.y_mult;
- attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), lights.data[i].attenuation);
+ attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);
+
} break;
case LIGHT_TYPE_SPOT: {
vec3 rel_vec = lights.data[i].position - position;
direction = normalize(rel_vec);
light_distance = length(rel_vec);
rel_vec.y /= params.y_mult;
- attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), lights.data[i].attenuation);
+ attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);
float angle = acos(dot(normalize(rel_vec), -lights.data[i].direction));
if (angle > lights.data[i].spot_angle) {
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_fields.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl
index eec0a90c0d..69d8824d8a 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_fields.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl
@@ -14,7 +14,7 @@ layout(local_size_x = OCT_RES, local_size_y = OCT_RES, local_size_z = 1) in;
layout(rgba16f, set = 0, binding = 1) uniform restrict image2DArray irradiance_texture;
layout(rg16f, set = 0, binding = 2) uniform restrict image2DArray depth_texture;
-ayout(rgba32ui, set = 0, binding = 3) uniform restrict uimage2DArray irradiance_history_texture;
+layout(rgba32ui, set = 0, binding = 3) uniform restrict uimage2DArray irradiance_history_texture;
layout(rg32ui, set = 0, binding = 4) uniform restrict uimage2DArray depth_history_texture;
struct CascadeData {
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
index d516ab22c3..d516ab22c3 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl
index 916c60ac89..916c60ac89 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl
index 29443ae7db..29443ae7db 100644
--- a/servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl
+++ b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl
diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl
new file mode 100644
index 0000000000..b19f5a9ad3
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl
@@ -0,0 +1,199 @@
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
+
+layout(set = 0, binding = 1, std430) buffer restrict writeonly DstVertexData {
+ uint data[];
+}
+dst_vertices;
+
+layout(set = 0, binding = 2, std430) buffer restrict readonly BlendShapeWeights {
+ float data[];
+}
+blend_shape_weights;
+
+layout(set = 1, binding = 0, std430) buffer restrict readonly SrcVertexData {
+ uint data[];
+}
+src_vertices;
+
+layout(set = 1, binding = 1, std430) buffer restrict readonly BoneWeightData {
+ uint data[];
+}
+src_bone_weights;
+
+layout(set = 1, binding = 2, std430) buffer restrict readonly BlendShapeData {
+ uint data[];
+}
+src_blend_shapes;
+
+layout(set = 2, binding = 0, std430) buffer restrict readonly SkeletonData {
+ vec4 data[];
+}
+bone_transforms;
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ bool has_normal;
+ bool has_tangent;
+ bool has_skeleton;
+ bool has_blend_shape;
+
+ uint vertex_count;
+ uint vertex_stride;
+ uint skin_stride;
+ uint skin_weight_offset;
+
+ uint blend_shape_count;
+ bool normalized_blend_shapes;
+ uint pad0;
+ uint pad1;
+}
+params;
+
+vec4 decode_abgr_2_10_10_10(uint base) {
+ uvec4 abgr_2_10_10_10 = (uvec4(base) >> uvec4(0, 10, 20, 30)) & uvec4(0x3FF, 0x3FF, 0x3FF, 0x3);
+ return vec4(abgr_2_10_10_10) / vec4(1023.0, 1023.0, 1023.0, 3.0) * 2.0 - 1.0;
+}
+
+uint encode_abgr_2_10_10_10(vec4 base) {
+ uvec4 abgr_2_10_10_10 = uvec4(clamp(ivec4((base * 0.5 + 0.5) * vec4(1023.0, 1023.0, 1023.0, 3.0)), ivec4(0), ivec4(0x3FF, 0x3FF, 0x3FF, 0x3))) << uvec4(0, 10, 20, 30);
+ return abgr_2_10_10_10.x | abgr_2_10_10_10.y | abgr_2_10_10_10.z | abgr_2_10_10_10.w;
+}
+
+void main() {
+ uint index = gl_GlobalInvocationID.x;
+ if (index >= params.vertex_count) {
+ return;
+ }
+
+ uint src_offset = index * params.vertex_stride;
+
+#ifdef MODE_2D
+ vec2 vertex = uintBitsToFloat(uvec2(src_vertices.data[src_offset + 0], src_vertices.data[src_offset + 1]));
+#else
+ vec3 vertex;
+ vec3 normal;
+ vec4 tangent;
+
+ vertex = uintBitsToFloat(uvec3(src_vertices.data[src_offset + 0], src_vertices.data[src_offset + 1], src_vertices.data[src_offset + 2]));
+
+ src_offset += 3;
+
+ if (params.has_normal) {
+ normal = decode_abgr_2_10_10_10(src_vertices.data[src_offset]).rgb;
+ src_offset++;
+ }
+
+ if (params.has_tangent) {
+ tangent = decode_abgr_2_10_10_10(src_vertices.data[src_offset]);
+ }
+
+ if (params.has_blend_shape) {
+ float blend_total = 0.0;
+ vec3 blend_vertex = vec3(0.0);
+ vec3 blend_normal = vec3(0.0);
+ vec3 blend_tangent = vec3(0.0);
+
+ for (uint i = 0; i < params.blend_shape_count; i++) {
+ float w = blend_shape_weights.data[i];
+ if (w > 0.0001) {
+ uint base_offset = (params.vertex_count * i + index) * params.vertex_stride;
+
+ blend_vertex += uintBitsToFloat(uvec3(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1], src_blend_shapes.data[base_offset + 2])) * w;
+
+ base_offset += 3;
+
+ if (params.has_normal) {
+ blend_normal += decode_abgr_2_10_10_10(src_blend_shapes.data[base_offset]).rgb * w;
+ base_offset++;
+ }
+
+ if (params.has_tangent) {
+ blend_tangent += decode_abgr_2_10_10_10(src_blend_shapes.data[base_offset]).rgb;
+ }
+
+ blend_total += w;
+ }
+ }
+
+ if (params.normalized_blend_shapes) {
+ vertex = (1.0 - blend_total) * vertex;
+ normal = (1.0 - blend_total) * normal;
+ tangent.rgb = (1.0 - blend_total) * tangent.rgb;
+ }
+
+ vertex += blend_vertex;
+ normal += normalize(normal + blend_normal);
+ tangent.rgb += normalize(tangent.rgb + blend_tangent);
+ }
+
+ if (params.has_skeleton) {
+ 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;
+
+ skin_offset += params.skin_weight_offset;
+
+ uvec2 weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
+
+ vec2 weights_01 = unpackUnorm2x16(weights.x);
+ vec2 weights_23 = unpackUnorm2x16(weights.y);
+
+ mat4 m = mat4(bone_transforms.data[bones_01.x], bone_transforms.data[bones_01.x + 1], bone_transforms.data[bones_01.x + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.x;
+ m += mat4(bone_transforms.data[bones_01.y], bone_transforms.data[bones_01.y + 1], bone_transforms.data[bones_01.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.y;
+ m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], bone_transforms.data[bones_23.x + 2], 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], bone_transforms.data[bones_23.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y;
+
+ if (params.skin_weight_offset == 4) {
+ //using 8 bones/weights
+ skin_offset = params.skin_stride * index + 2;
+
+ bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
+ bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset
+ bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3;
+
+ skin_offset += params.skin_weight_offset;
+
+ weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
+
+ weights_01 = unpackUnorm2x16(weights.x);
+ weights_23 = unpackUnorm2x16(weights.y);
+
+ m += mat4(bone_transforms.data[bones_01.x], bone_transforms.data[bones_01.x + 1], bone_transforms.data[bones_01.x + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.x;
+ m += mat4(bone_transforms.data[bones_01.y], bone_transforms.data[bones_01.y + 1], bone_transforms.data[bones_01.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.y;
+ m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], bone_transforms.data[bones_23.x + 2], 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], bone_transforms.data[bones_23.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y;
+ }
+
+ //reverse order because its transposed
+ vertex = (vec4(vertex, 1.0) * m).xyz;
+ normal = normalize((vec4(normal, 0.0) * m).xyz);
+ tangent.xyz = normalize((vec4(tangent.xyz, 0.0) * m).xyz);
+ }
+
+ uint dst_offset = index * params.vertex_stride;
+
+ uvec3 uvertex = floatBitsToUint(vertex);
+ dst_vertices.data[dst_offset + 0] = uvertex.x;
+ dst_vertices.data[dst_offset + 1] = uvertex.y;
+ dst_vertices.data[dst_offset + 2] = uvertex.z;
+
+ dst_offset += 3;
+
+ if (params.has_normal) {
+ dst_vertices.data[dst_offset] = encode_abgr_2_10_10_10(vec4(normal, 0.0));
+ dst_offset++;
+ }
+
+ if (params.has_tangent) {
+ dst_vertices.data[dst_offset] = encode_abgr_2_10_10_10(tangent);
+ }
+
+#endif
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/sky.glsl
index 6c985e1f5c..6c985e1f5c 100644
--- a/servers/rendering/rasterizer_rd/shaders/sky.glsl
+++ b/servers/rendering/renderer_rd/shaders/sky.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/sort.glsl b/servers/rendering/renderer_rd/shaders/sort.glsl
index e5ebb9c64b..e5ebb9c64b 100644
--- a/servers/rendering/rasterizer_rd/shaders/sort.glsl
+++ b/servers/rendering/renderer_rd/shaders/sort.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/specular_merge.glsl
index 0b8f406213..0b8f406213 100644
--- a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl
+++ b/servers/rendering/renderer_rd/shaders/specular_merge.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/ssao.glsl
new file mode 100644
index 0000000000..231f8f91ec
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssao.glsl
@@ -0,0 +1,486 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2016, Intel Corporation
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+// the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2016-09-07: filip.strugar@intel.com: first commit
+// 2020-12-05: clayjohn: convert to Vulkan and Godot
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+#define SSAO_ADAPTIVE_TAP_BASE_COUNT 5
+
+#define INTELSSAO_MAIN_DISK_SAMPLE_COUNT (32)
+const vec4 sample_pattern[INTELSSAO_MAIN_DISK_SAMPLE_COUNT] = {
+ vec4(0.78488064, 0.56661671, 1.500000, -0.126083), vec4(0.26022232, -0.29575172, 1.500000, -1.064030), vec4(0.10459357, 0.08372527, 1.110000, -2.730563), vec4(-0.68286800, 0.04963045, 1.090000, -0.498827),
+ vec4(-0.13570161, -0.64190155, 1.250000, -0.532765), vec4(-0.26193795, -0.08205118, 0.670000, -1.783245), vec4(-0.61177456, 0.66664219, 0.710000, -0.044234), vec4(0.43675563, 0.25119025, 0.610000, -1.167283),
+ vec4(0.07884444, 0.86618668, 0.640000, -0.459002), vec4(-0.12790935, -0.29869005, 0.600000, -1.729424), vec4(-0.04031125, 0.02413622, 0.600000, -4.792042), vec4(0.16201244, -0.52851415, 0.790000, -1.067055),
+ vec4(-0.70991218, 0.47301072, 0.640000, -0.335236), vec4(0.03277707, -0.22349690, 0.600000, -1.982384), vec4(0.68921727, 0.36800742, 0.630000, -0.266718), vec4(0.29251814, 0.37775412, 0.610000, -1.422520),
+ vec4(-0.12224089, 0.96582592, 0.600000, -0.426142), vec4(0.11071457, -0.16131058, 0.600000, -2.165947), vec4(0.46562141, -0.59747696, 0.600000, -0.189760), vec4(-0.51548797, 0.11804193, 0.600000, -1.246800),
+ vec4(0.89141309, -0.42090443, 0.600000, 0.028192), vec4(-0.32402530, -0.01591529, 0.600000, -1.543018), vec4(0.60771245, 0.41635221, 0.600000, -0.605411), vec4(0.02379565, -0.08239821, 0.600000, -3.809046),
+ vec4(0.48951152, -0.23657045, 0.600000, -1.189011), vec4(-0.17611565, -0.81696892, 0.600000, -0.513724), vec4(-0.33930185, -0.20732205, 0.600000, -1.698047), vec4(-0.91974425, 0.05403209, 0.600000, 0.062246),
+ vec4(-0.15064627, -0.14949332, 0.600000, -1.896062), vec4(0.53180975, -0.35210401, 0.600000, -0.758838), vec4(0.41487166, 0.81442589, 0.600000, -0.505648), vec4(-0.24106961, -0.32721516, 0.600000, -1.665244)
+};
+
+// these values can be changed (up to SSAO_MAX_TAPS) with no changes required elsewhere; values for 4th and 5th preset are ignored but array needed to avoid compilation errors
+// the actual number of texture samples is two times this value (each "tap" has two symmetrical depth texture samples)
+const int num_taps[5] = { 3, 5, 12, 0, 0 };
+
+#define SSAO_TILT_SAMPLES_ENABLE_AT_QUALITY_PRESET (99) // to disable simply set to 99 or similar
+#define SSAO_TILT_SAMPLES_AMOUNT (0.4)
+//
+#define SSAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET (1) // to disable simply set to 99 or similar
+#define SSAO_HALOING_REDUCTION_AMOUNT (0.6) // values from 0.0 - 1.0, 1.0 means max weighting (will cause artifacts, 0.8 is more reasonable)
+//
+#define SSAO_NORMAL_BASED_EDGES_ENABLE_AT_QUALITY_PRESET (2) // to disable simply set to 99 or similar
+#define SSAO_NORMAL_BASED_EDGES_DOT_THRESHOLD (0.5) // use 0-0.1 for super-sharp normal-based edges
+//
+#define SSAO_DETAIL_AO_ENABLE_AT_QUALITY_PRESET (1) // whether to use detail; to disable simply set to 99 or similar
+//
+#define SSAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET (2) // !!warning!! the MIP generation on the C++ side will be enabled on quality preset 2 regardless of this value, so if changing here, change the C++ side too
+#define SSAO_DEPTH_MIPS_GLOBAL_OFFSET (-4.3) // best noise/quality/performance tradeoff, found empirically
+//
+// !!warning!! the edge handling is hard-coded to 'disabled' on quality level 0, and enabled above, on the C++ side; while toggling it here will work for
+// testing purposes, it will not yield performance gains (or correct results)
+#define SSAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET (1)
+//
+#define SSAO_REDUCE_RADIUS_NEAR_SCREEN_BORDER_ENABLE_AT_QUALITY_PRESET (1)
+
+#define SSAO_MAX_TAPS 32
+#define SSAO_MAX_REF_TAPS 512
+#define SSAO_ADAPTIVE_TAP_BASE_COUNT 5
+#define SSAO_ADAPTIVE_TAP_FLEXIBLE_COUNT (SSAO_MAX_TAPS - SSAO_ADAPTIVE_TAP_BASE_COUNT)
+#define SSAO_DEPTH_MIP_LEVELS 4
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+layout(set = 0, binding = 0) uniform sampler2DArray source_depth_mipmaps;
+layout(rgba8, set = 0, binding = 1) uniform restrict readonly image2D source_normal;
+layout(set = 0, binding = 2) uniform Constants { //get into a lower set
+ vec4 rotation_matrices[20];
+}
+constants;
+
+#ifdef ADAPTIVE
+layout(rg8, set = 1, binding = 0) uniform restrict readonly image2DArray source_ssao;
+layout(set = 1, binding = 1) uniform sampler2D source_importance;
+layout(set = 1, binding = 2, std430) buffer Counter {
+ uint sum;
+}
+counter;
+#endif
+
+layout(rg8, set = 2, binding = 0) uniform restrict writeonly image2D dest_image;
+
+// This push_constant is full - 128 bytes - if you need to add more data, consider adding to the uniform buffer instead
+layout(push_constant, binding = 3, std430) uniform Params {
+ ivec2 screen_size;
+ int pass;
+ int quality;
+
+ vec2 half_screen_pixel_size;
+ int size_multiplier;
+ float detail_intensity;
+
+ vec2 NDC_to_view_mul;
+ vec2 NDC_to_view_add;
+
+ vec2 pad2;
+ vec2 half_screen_pixel_size_x025;
+
+ float radius;
+ float intensity;
+ float shadow_power;
+ float shadow_clamp;
+
+ float fade_out_mul;
+ float fade_out_add;
+ float horizon_angle_threshold;
+ float inv_radius_near_limit;
+
+ bool is_orthogonal;
+ float neg_inv_radius;
+ float load_counter_avg_div;
+ float adaptive_sample_limit;
+
+ ivec2 pass_coord_offset;
+ vec2 pass_uv_offset;
+}
+params;
+
+// packing/unpacking for edges; 2 bits per edge mean 4 gradient values (0, 0.33, 0.66, 1) for smoother transitions!
+float pack_edges(vec4 p_edgesLRTB) {
+ p_edgesLRTB = round(clamp(p_edgesLRTB, 0.0, 1.0) * 3.05);
+ return dot(p_edgesLRTB, vec4(64.0 / 255.0, 16.0 / 255.0, 4.0 / 255.0, 1.0 / 255.0));
+}
+
+vec3 NDC_to_view_space(vec2 p_pos, float p_viewspace_depth) {
+ if (params.is_orthogonal) {
+ return vec3((params.NDC_to_view_mul * p_pos.xy + params.NDC_to_view_add), p_viewspace_depth);
+ } else {
+ return vec3((params.NDC_to_view_mul * p_pos.xy + params.NDC_to_view_add) * p_viewspace_depth, p_viewspace_depth);
+ }
+}
+
+// calculate effect radius and fit our screen sampling pattern inside it
+void calculate_radius_parameters(const float p_pix_center_length, const vec2 p_pixel_size_at_center, out float r_lookup_radius, out float r_radius, out float r_fallof_sq) {
+ r_radius = params.radius;
+
+ // when too close, on-screen sampling disk will grow beyond screen size; limit this to avoid closeup temporal artifacts
+ const float too_close_limit = clamp(p_pix_center_length * params.inv_radius_near_limit, 0.0, 1.0) * 0.8 + 0.2;
+
+ r_radius *= too_close_limit;
+
+ // 0.85 is to reduce the radius to allow for more samples on a slope to still stay within influence
+ r_lookup_radius = (0.85 * r_radius) / p_pixel_size_at_center.x;
+
+ // used to calculate falloff (both for AO samples and per-sample weights)
+ r_fallof_sq = -1.0 / (r_radius * r_radius);
+}
+
+vec4 calculate_edges(const float p_center_z, const float p_left_z, const float p_right_z, const float p_top_z, const float p_bottom_z) {
+ // slope-sensitive depth-based edge detection
+ vec4 edgesLRTB = vec4(p_left_z, p_right_z, p_top_z, p_bottom_z) - p_center_z;
+ vec4 edgesLRTB_slope_adjusted = edgesLRTB + edgesLRTB.yxwz;
+ edgesLRTB = min(abs(edgesLRTB), abs(edgesLRTB_slope_adjusted));
+ return clamp((1.3 - edgesLRTB / (p_center_z * 0.040)), 0.0, 1.0);
+}
+
+vec3 decode_normal(vec3 p_encoded_normal) {
+ vec3 normal = p_encoded_normal * 2.0 - 1.0;
+ return normal;
+}
+
+vec3 load_normal(ivec2 p_pos) {
+ vec3 encoded_normal = imageLoad(source_normal, p_pos).xyz;
+ encoded_normal.z = 1.0 - encoded_normal.z;
+ return decode_normal(encoded_normal);
+}
+
+vec3 load_normal(ivec2 p_pos, ivec2 p_offset) {
+ vec3 encoded_normal = imageLoad(source_normal, p_pos + p_offset).xyz;
+ encoded_normal.z = 1.0 - encoded_normal.z;
+ return decode_normal(encoded_normal);
+}
+
+// all vectors in viewspace
+float calculate_pixel_obscurance(vec3 p_pixel_normal, vec3 p_hit_delta, float p_fallof_sq) {
+ float length_sq = dot(p_hit_delta, p_hit_delta);
+ float NdotD = dot(p_pixel_normal, p_hit_delta) / sqrt(length_sq);
+
+ float falloff_mult = max(0.0, length_sq * p_fallof_sq + 1.0);
+
+ return max(0, NdotD - params.horizon_angle_threshold) * falloff_mult;
+}
+
+void SSAO_tap_inner(const int p_quality_level, inout float r_obscurance_sum, inout float r_weight_sum, const vec2 p_sampling_uv, const float p_mip_level, const vec3 p_pix_center_pos, vec3 p_pixel_normal, const float p_fallof_sq, const float p_weight_mod) {
+ // get depth at sample
+ float viewspace_sample_z = textureLod(source_depth_mipmaps, vec3(p_sampling_uv, params.pass), p_mip_level).x;
+
+ // convert to viewspace
+ vec3 hit_pos = NDC_to_view_space(p_sampling_uv.xy, viewspace_sample_z).xyz;
+ vec3 hit_delta = hit_pos - p_pix_center_pos;
+
+ float obscurance = calculate_pixel_obscurance(p_pixel_normal, hit_delta, p_fallof_sq);
+ float weight = 1.0;
+
+ if (p_quality_level >= SSAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET) {
+ float reduct = max(0, -hit_delta.z);
+ reduct = clamp(reduct * params.neg_inv_radius + 2.0, 0.0, 1.0);
+ weight = SSAO_HALOING_REDUCTION_AMOUNT * reduct + (1.0 - SSAO_HALOING_REDUCTION_AMOUNT);
+ }
+ weight *= p_weight_mod;
+ r_obscurance_sum += obscurance * weight;
+ r_weight_sum += weight;
+}
+
+void SSAOTap(const int p_quality_level, inout float r_obscurance_sum, inout float r_weight_sum, const int p_tap_index, const mat2 p_rot_scale, const vec3 p_pix_center_pos, vec3 p_pixel_normal, const vec2 p_normalized_screen_pos, const float p_mip_offset, const float p_fallof_sq, float p_weight_mod, vec2 p_norm_xy, float p_norm_xy_length) {
+ vec2 sample_offset;
+ float sample_pow_2_len;
+
+ // patterns
+ {
+ vec4 new_sample = sample_pattern[p_tap_index];
+ sample_offset = new_sample.xy * p_rot_scale;
+ sample_pow_2_len = new_sample.w; // precalculated, same as: sample_pow_2_len = log2( length( new_sample.xy ) );
+ p_weight_mod *= new_sample.z;
+ }
+
+ // 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
+ // 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);
+
+ vec2 sampling_uv = sample_offset * params.half_screen_pixel_size + p_normalized_screen_pos;
+
+ SSAO_tap_inner(p_quality_level, r_obscurance_sum, r_weight_sum, sampling_uv, mip_level, p_pix_center_pos, p_pixel_normal, p_fallof_sq, p_weight_mod);
+
+ // for the second tap, just use the mirrored offset
+ vec2 sample_offset_mirrored_uv = -sample_offset;
+
+ // tilt the second set of samples so that the disk is effectively rotated by the normal
+ // effective at removing one set of artifacts, but too expensive for lower quality settings
+ if (p_quality_level >= SSAO_TILT_SAMPLES_ENABLE_AT_QUALITY_PRESET) {
+ float dot_norm = dot(sample_offset_mirrored_uv, p_norm_xy);
+ sample_offset_mirrored_uv -= dot_norm * p_norm_xy_length * p_norm_xy;
+ sample_offset_mirrored_uv = round(sample_offset_mirrored_uv);
+ }
+
+ // snap to pixel center (more correct obscurance math, avoids artifacts)
+ vec2 sampling_mirrored_uv = sample_offset_mirrored_uv * params.half_screen_pixel_size + p_normalized_screen_pos;
+
+ SSAO_tap_inner(p_quality_level, r_obscurance_sum, r_weight_sum, sampling_mirrored_uv, mip_level, p_pix_center_pos, p_pixel_normal, p_fallof_sq, p_weight_mod);
+}
+
+void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, out float r_weight, const vec2 p_pos, int p_quality_level, bool p_adaptive_base) {
+ vec2 pos_rounded = trunc(p_pos);
+ uvec2 upos = uvec2(pos_rounded);
+
+ const int number_of_taps = (p_adaptive_base) ? (SSAO_ADAPTIVE_TAP_BASE_COUNT) : (num_taps[p_quality_level]);
+ float pix_z, pix_left_z, pix_top_z, pix_right_z, pix_bottom_z;
+
+ vec4 valuesUL = textureGather(source_depth_mipmaps, vec3(pos_rounded * params.half_screen_pixel_size, params.pass));
+ vec4 valuesBR = textureGather(source_depth_mipmaps, vec3((pos_rounded + vec2(1.0)) * params.half_screen_pixel_size, params.pass));
+
+ // 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)
+ pix_left_z = valuesUL.x;
+ pix_top_z = valuesUL.z;
+ pix_right_z = valuesBR.z;
+ pix_bottom_z = valuesBR.x;
+
+ vec2 normalized_screen_pos = pos_rounded * params.half_screen_pixel_size + params.half_screen_pixel_size_x025;
+ vec3 pix_center_pos = NDC_to_view_space(normalized_screen_pos, pix_z);
+
+ // Load this pixel's viewspace normal
+ uvec2 full_res_coord = upos * 2 * params.size_multiplier + params.pass_coord_offset.xy;
+ vec3 pixel_normal = load_normal(ivec2(full_res_coord));
+
+ const vec2 pixel_size_at_center = NDC_to_view_space(normalized_screen_pos.xy + params.half_screen_pixel_size, pix_center_pos.z).xy - pix_center_pos.xy;
+
+ float pixel_lookup_radius;
+ float fallof_sq;
+
+ // calculate effect radius and fit our screen sampling pattern inside it
+ float viewspace_radius;
+ calculate_radius_parameters(length(pix_center_pos), pixel_size_at_center, pixel_lookup_radius, viewspace_radius, fallof_sq);
+
+ // calculate samples rotation/scaling
+ mat2 rot_scale_matrix;
+ uint pseudo_random_index;
+
+ {
+ vec4 rotation_scale;
+ // reduce effect radius near the screen edges slightly; ideally, one would render a larger depth buffer (5% on each side) instead
+ if (!p_adaptive_base && (p_quality_level >= SSAO_REDUCE_RADIUS_NEAR_SCREEN_BORDER_ENABLE_AT_QUALITY_PRESET)) {
+ float near_screen_border = min(min(normalized_screen_pos.x, 1.0 - normalized_screen_pos.x), min(normalized_screen_pos.y, 1.0 - normalized_screen_pos.y));
+ near_screen_border = clamp(10.0 * near_screen_border + 0.6, 0.0, 1.0);
+ pixel_lookup_radius *= near_screen_border;
+ }
+
+ // load & update pseudo-random rotation matrix
+ pseudo_random_index = uint(pos_rounded.y * 2 + pos_rounded.x) % 5;
+ rotation_scale = constants.rotation_matrices[params.pass * 5 + pseudo_random_index];
+ rot_scale_matrix = mat2(rotation_scale.x * pixel_lookup_radius, rotation_scale.y * pixel_lookup_radius, rotation_scale.z * pixel_lookup_radius, rotation_scale.w * pixel_lookup_radius);
+ }
+
+ // the main obscurance & sample weight storage
+ 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)
+ 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
+ pix_center_pos *= 0.9992;
+
+ if (!p_adaptive_base && (p_quality_level >= SSAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET)) {
+ edgesLRTB = calculate_edges(pix_z, pix_left_z, pix_right_z, pix_top_z, pix_bottom_z);
+ }
+
+ // adds a more high definition sharp effect, which gets blurred out (reuses left/right/top/bottom samples that we used for edge detection)
+ 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" )
+ 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);
+ vec3 pixel_top_delta = vec3(0.0, -pixel_size_at_center.y, 0.0) + normalized_viewspace_dir * (pix_top_z - pix_center_pos.z);
+ vec3 pixel_bottom_delta = vec3(0.0, +pixel_size_at_center.y, 0.0) + normalized_viewspace_dir * (pix_bottom_z - pix_center_pos.z);
+
+ const float range_reduction = 4.0f; // this is to avoid various artifacts
+ const float modified_fallof_sq = range_reduction * fallof_sq;
+
+ vec4 additional_obscurance;
+ additional_obscurance.x = calculate_pixel_obscurance(pixel_normal, pixel_left_delta, modified_fallof_sq);
+ additional_obscurance.y = calculate_pixel_obscurance(pixel_normal, pixel_right_delta, modified_fallof_sq);
+ additional_obscurance.z = calculate_pixel_obscurance(pixel_normal, pixel_top_delta, modified_fallof_sq);
+ additional_obscurance.w = calculate_pixel_obscurance(pixel_normal, pixel_bottom_delta, modified_fallof_sq);
+
+ obscurance_sum += params.detail_intensity * dot(additional_obscurance, edgesLRTB);
+ }
+ }
+
+ // Sharp normals also create edges - but this adds to the cost as well
+ if (!p_adaptive_base && (p_quality_level >= SSAO_NORMAL_BASED_EDGES_ENABLE_AT_QUALITY_PRESET)) {
+ vec3 neighbour_normal_left = load_normal(ivec2(full_res_coord), ivec2(-2, 0));
+ vec3 neighbour_normal_right = load_normal(ivec2(full_res_coord), ivec2(2, 0));
+ vec3 neighbour_normal_top = load_normal(ivec2(full_res_coord), ivec2(0, -2));
+ vec3 neighbour_normal_bottom = load_normal(ivec2(full_res_coord), ivec2(0, 2));
+
+ const float dot_threshold = SSAO_NORMAL_BASED_EDGES_DOT_THRESHOLD;
+
+ vec4 normal_edgesLRTB;
+ normal_edgesLRTB.x = clamp((dot(pixel_normal, neighbour_normal_left) + dot_threshold), 0.0, 1.0);
+ normal_edgesLRTB.y = clamp((dot(pixel_normal, neighbour_normal_right) + dot_threshold), 0.0, 1.0);
+ normal_edgesLRTB.z = clamp((dot(pixel_normal, neighbour_normal_top) + dot_threshold), 0.0, 1.0);
+ normal_edgesLRTB.w = clamp((dot(pixel_normal, neighbour_normal_bottom) + dot_threshold), 0.0, 1.0);
+
+ edgesLRTB *= normal_edgesLRTB;
+ }
+
+ const float global_mip_offset = SSAO_DEPTH_MIPS_GLOBAL_OFFSET;
+ float mip_offset = (p_quality_level < SSAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (log2(pixel_lookup_radius) + global_mip_offset);
+
+ // Used to tilt the second set of samples so that the disk is effectively rotated by the normal
+ // effective at removing one set of artifacts, but too expensive for lower quality settings
+ vec2 norm_xy = vec2(pixel_normal.x, pixel_normal.y);
+ float norm_xy_length = length(norm_xy);
+ norm_xy /= vec2(norm_xy_length, -norm_xy_length);
+ norm_xy_length *= SSAO_TILT_SAMPLES_AMOUNT;
+
+ // standard, non-adaptive approach
+ if ((p_quality_level != 3) || p_adaptive_base) {
+ for (int i = 0; i < number_of_taps; i++) {
+ SSAOTap(p_quality_level, obscurance_sum, weight_sum, i, rot_scale_matrix, pix_center_pos, pixel_normal, normalized_screen_pos, mip_offset, fallof_sq, 1.0, norm_xy, norm_xy_length);
+ }
+ }
+#ifdef ADAPTIVE
+ else {
+ // add new ones if needed
+ vec2 full_res_uv = normalized_screen_pos + params.pass_uv_offset.xy;
+ float importance = textureLod(source_importance, full_res_uv, 0.0).x;
+
+ // this is to normalize SSAO_DETAIL_AO_AMOUNT across all pixel regardless of importance
+ obscurance_sum *= (SSAO_ADAPTIVE_TAP_BASE_COUNT / float(SSAO_MAX_TAPS)) + (importance * SSAO_ADAPTIVE_TAP_FLEXIBLE_COUNT / float(SSAO_MAX_TAPS));
+
+ // load existing base values
+ vec2 base_values = imageLoad(source_ssao, ivec3(upos, params.pass)).xy;
+ weight_sum += base_values.y * float(SSAO_ADAPTIVE_TAP_BASE_COUNT * 4.0);
+ obscurance_sum += (base_values.x) * weight_sum;
+
+ // increase importance around edges
+ float edge_count = dot(1.0 - edgesLRTB, vec4(1.0, 1.0, 1.0, 1.0));
+
+ float avg_total_importance = float(counter.sum) * params.load_counter_avg_div;
+
+ float importance_limiter = clamp(params.adaptive_sample_limit / avg_total_importance, 0.0, 1.0);
+ importance *= importance_limiter;
+
+ float additional_sample_count = SSAO_ADAPTIVE_TAP_FLEXIBLE_COUNT * importance;
+
+ const float blend_range = 3.0;
+ const float blend_range_inv = 1.0 / blend_range;
+
+ additional_sample_count += 0.5;
+ uint additional_samples = uint(additional_sample_count);
+ uint additional_samples_to = min(SSAO_MAX_TAPS, additional_samples + SSAO_ADAPTIVE_TAP_BASE_COUNT);
+
+ for (uint i = SSAO_ADAPTIVE_TAP_BASE_COUNT; i < additional_samples_to; i++) {
+ additional_sample_count -= 1.0f;
+ float weight_mod = clamp(additional_sample_count * blend_range_inv, 0.0, 1.0);
+ SSAOTap(p_quality_level, obscurance_sum, weight_sum, int(i), rot_scale_matrix, pix_center_pos, pixel_normal, normalized_screen_pos, mip_offset, fallof_sq, weight_mod, norm_xy, norm_xy_length);
+ }
+ }
+#endif
+
+ // early out for adaptive base - just output weight (used for the next pass)
+ if (p_adaptive_base) {
+ float obscurance = obscurance_sum / weight_sum;
+
+ r_shadow_term = obscurance;
+ r_edges = vec4(0.0);
+ r_weight = weight_sum;
+ return;
+ }
+
+ // calculate weighted average
+ float obscurance = obscurance_sum / weight_sum;
+
+ // calculate fadeout (1 close, gradient, 0 far)
+ float fade_out = clamp(pix_center_pos.z * params.fade_out_mul + params.fade_out_add, 0.0, 1.0);
+
+ // Reduce the SSAO shadowing if we're on the edge to remove artifacts on edges (we don't care for the lower quality one)
+ if (!p_adaptive_base && (p_quality_level >= SSAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET)) {
+ // when there's more than 2 opposite edges, start fading out the occlusion to reduce aliasing artifacts
+ float edge_fadeout_factor = clamp((1.0 - edgesLRTB.x - edgesLRTB.y) * 0.35, 0.0, 1.0) + clamp((1.0 - edgesLRTB.z - edgesLRTB.w) * 0.35, 0.0, 1.0);
+
+ fade_out *= clamp(1.0 - edge_fadeout_factor, 0.0, 1.0);
+ }
+
+ // strength
+ obscurance = params.intensity * obscurance;
+
+ // clamp
+ obscurance = min(obscurance, params.shadow_clamp);
+
+ // fadeout
+ obscurance *= fade_out;
+
+ // conceptually switch to occlusion with the meaning being visibility (grows with visibility, occlusion == 1 implies full visibility),
+ // to be in line with what is more commonly used.
+ float occlusion = 1.0 - obscurance;
+
+ // modify the gradient
+ // note: this cannot be moved to a later pass because of loss of precision after storing in the render target
+ occlusion = pow(clamp(occlusion, 0.0, 1.0), params.shadow_power);
+
+ // outputs!
+ r_shadow_term = occlusion; // Our final 'occlusion' term (0 means fully occluded, 1 means fully lit)
+ r_edges = edgesLRTB; // These are used to prevent blurring across edges, 1 means no edge, 0 means edge, 0.5 means half way there, etc.
+ r_weight = weight_sum;
+}
+
+void main() {
+ float out_shadow_term;
+ float out_weight;
+ vec4 out_edges;
+ ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
+ if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
+ return;
+ }
+
+ vec2 uv = vec2(gl_GlobalInvocationID) + vec2(0.5);
+#ifdef SSAO_BASE
+ generate_SSAO_shadows_internal(out_shadow_term, out_edges, out_weight, uv, params.quality, true);
+
+ imageStore(dest_image, ivec2(gl_GlobalInvocationID.xy), vec4(out_shadow_term, out_weight / (float(SSAO_ADAPTIVE_TAP_BASE_COUNT) * 4.0), 0.0, 0.0));
+#else
+ generate_SSAO_shadows_internal(out_shadow_term, out_edges, out_weight, uv, params.quality, false); // pass in quality levels
+ if (params.quality == 0) {
+ out_edges = vec4(1.0);
+ }
+
+ imageStore(dest_image, ivec2(gl_GlobalInvocationID.xy), vec4(out_shadow_term, pack_edges(out_edges), 0.0, 0.0));
+#endif
+}
diff --git a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl
new file mode 100644
index 0000000000..510a777048
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl
@@ -0,0 +1,154 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2016, Intel Corporation
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+// the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2016-09-07: filip.strugar@intel.com: first commit
+// 2020-12-05: clayjohn: convert to Vulkan and Godot
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+layout(set = 0, binding = 0) uniform sampler2D source_ssao;
+
+layout(rg8, set = 1, binding = 0) uniform restrict writeonly image2D dest_image;
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ float edge_sharpness;
+ float pad;
+ vec2 half_screen_pixel_size;
+}
+params;
+
+vec4 unpack_edges(float p_packed_val) {
+ uint packed_val = uint(p_packed_val * 255.5);
+ vec4 edgesLRTB;
+ edgesLRTB.x = float((packed_val >> 6) & 0x03) / 3.0;
+ edgesLRTB.y = float((packed_val >> 4) & 0x03) / 3.0;
+ edgesLRTB.z = float((packed_val >> 2) & 0x03) / 3.0;
+ edgesLRTB.w = float((packed_val >> 0) & 0x03) / 3.0;
+
+ return clamp(edgesLRTB + params.edge_sharpness, 0.0, 1.0);
+}
+
+void add_sample(float p_ssao_value, float p_edge_value, inout float r_sum, inout float r_sum_weight) {
+ float weight = p_edge_value;
+
+ r_sum += (weight * p_ssao_value);
+ r_sum_weight += weight;
+}
+
+#ifdef MODE_WIDE
+vec2 sample_blurred_wide(vec2 p_coord) {
+ vec2 vC = textureLodOffset(source_ssao, vec2(p_coord), 0.0, ivec2(0, 0)).xy;
+ vec2 vL = textureLodOffset(source_ssao, vec2(p_coord), 0.0, ivec2(-2, 0)).xy;
+ vec2 vT = textureLodOffset(source_ssao, vec2(p_coord), 0.0, ivec2(0, -2)).xy;
+ vec2 vR = textureLodOffset(source_ssao, vec2(p_coord), 0.0, ivec2(2, 0)).xy;
+ vec2 vB = textureLodOffset(source_ssao, vec2(p_coord), 0.0, ivec2(0, 2)).xy;
+
+ float packed_edges = vC.y;
+ vec4 edgesLRTB = unpack_edges(packed_edges);
+ edgesLRTB.x *= unpack_edges(vL.y).y;
+ edgesLRTB.z *= unpack_edges(vT.y).w;
+ edgesLRTB.y *= unpack_edges(vR.y).x;
+ edgesLRTB.w *= unpack_edges(vB.y).z;
+
+ float ssao_value = vC.x;
+ float ssao_valueL = vL.x;
+ float ssao_valueT = vT.x;
+ float ssao_valueR = vR.x;
+ float ssao_valueB = vB.x;
+
+ float sum_weight = 0.8f;
+ float sum = ssao_value * sum_weight;
+
+ add_sample(ssao_valueL, edgesLRTB.x, sum, sum_weight);
+ add_sample(ssao_valueR, edgesLRTB.y, sum, sum_weight);
+ add_sample(ssao_valueT, edgesLRTB.z, sum, sum_weight);
+ add_sample(ssao_valueB, edgesLRTB.w, sum, sum_weight);
+
+ float ssao_avg = sum / sum_weight;
+
+ ssao_value = ssao_avg;
+
+ return vec2(ssao_value, packed_edges);
+}
+#endif
+
+#ifdef MODE_SMART
+vec2 sample_blurred(vec3 p_pos, vec2 p_coord) {
+ float packed_edges = texelFetch(source_ssao, ivec2(p_pos.xy), 0).y;
+ vec4 edgesLRTB = unpack_edges(packed_edges);
+
+ vec4 valuesUL = textureGather(source_ssao, vec2(p_coord - params.half_screen_pixel_size * 0.5));
+ vec4 valuesBR = textureGather(source_ssao, vec2(p_coord + params.half_screen_pixel_size * 0.5));
+
+ float ssao_value = valuesUL.y;
+ float ssao_valueL = valuesUL.x;
+ float ssao_valueT = valuesUL.z;
+ float ssao_valueR = valuesBR.z;
+ float ssao_valueB = valuesBR.x;
+
+ float sum_weight = 0.5;
+ float sum = ssao_value * sum_weight;
+
+ add_sample(ssao_valueL, edgesLRTB.x, sum, sum_weight);
+ add_sample(ssao_valueR, edgesLRTB.y, sum, sum_weight);
+
+ add_sample(ssao_valueT, edgesLRTB.z, sum, sum_weight);
+ add_sample(ssao_valueB, edgesLRTB.w, sum, sum_weight);
+
+ float ssao_avg = sum / sum_weight;
+
+ ssao_value = ssao_avg;
+
+ return vec2(ssao_value, packed_edges);
+}
+#endif
+
+void main() {
+ // Pixel being shaded
+ ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
+
+#ifdef MODE_NON_SMART
+
+ vec2 halfPixel = params.half_screen_pixel_size * 0.5f;
+
+ vec2 uv = (vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size;
+
+ vec2 centre = textureLod(source_ssao, vec2(uv), 0.0).xy;
+
+ vec4 vals;
+ vals.x = textureLod(source_ssao, vec2(uv + vec2(-halfPixel.x * 3, -halfPixel.y)), 0.0).x;
+ vals.y = textureLod(source_ssao, vec2(uv + vec2(+halfPixel.x, -halfPixel.y * 3)), 0.0).x;
+ vals.z = textureLod(source_ssao, vec2(uv + vec2(-halfPixel.x, +halfPixel.y * 3)), 0.0).x;
+ vals.w = textureLod(source_ssao, vec2(uv + vec2(+halfPixel.x * 3, +halfPixel.y)), 0.0).x;
+
+ vec2 sampled = vec2(dot(vals, vec4(0.2)) + centre.x * 0.2, centre.y);
+
+#else
+#ifdef MODE_SMART
+ vec2 sampled = sample_blurred(vec3(gl_GlobalInvocationID), (vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size);
+#else // MODE_WIDE
+ vec2 sampled = sample_blurred_wide((vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size);
+#endif
+
+#endif
+ imageStore(dest_image, ivec2(ssC), vec4(sampled, 0.0, 0.0));
+}
diff --git a/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl b/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl
new file mode 100644
index 0000000000..cb2d31f70d
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl
@@ -0,0 +1,206 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2016, Intel Corporation
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+// the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2016-09-07: filip.strugar@intel.com: first commit
+// 2020-12-05: clayjohn: convert to Vulkan and Godot
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ vec2 pixel_size;
+ float z_far;
+ float z_near;
+ bool orthogonal;
+ float radius_sq;
+ uvec2 pad;
+}
+params;
+
+layout(set = 0, binding = 0) uniform sampler2D source_depth;
+
+layout(r16f, set = 1, binding = 0) uniform restrict writeonly image2DArray dest_image0; //rename
+#ifdef GENERATE_MIPS
+layout(r16f, set = 2, binding = 0) uniform restrict writeonly image2DArray dest_image1;
+layout(r16f, set = 2, binding = 1) uniform restrict writeonly image2DArray dest_image2;
+layout(r16f, set = 2, binding = 2) uniform restrict writeonly image2DArray dest_image3;
+#endif
+
+vec4 screen_space_to_view_space_depth(vec4 p_depth) {
+ if (params.orthogonal) {
+ vec4 depth = p_depth * 2.0 - 1.0;
+ return ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
+ }
+
+ float depth_linearize_mul = params.z_near;
+ float depth_linearize_add = params.z_far;
+
+ // Optimised 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 );
+ // depth_linearize_add = cameraClipFar / ( cameraClipFar - cameraClipNear );
+
+ return depth_linearize_mul / (depth_linearize_add - p_depth);
+}
+
+float screen_space_to_view_space_depth(float p_depth) {
+ if (params.orthogonal) {
+ float depth = p_depth * 2.0 - 1.0;
+ return ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / (2.0 * params.z_far);
+ }
+
+ float depth_linearize_mul = params.z_near;
+ float depth_linearize_add = params.z_far;
+
+ return depth_linearize_mul / (depth_linearize_add - p_depth);
+}
+
+#ifdef GENERATE_MIPS
+
+shared float depth_buffer[4][8][8];
+
+float mip_smart_average(vec4 p_depths) {
+ float closest = min(min(p_depths.x, p_depths.y), min(p_depths.z, p_depths.w));
+ float fallof_sq = -1.0f / params.radius_sq;
+ vec4 dists = p_depths - closest.xxxx;
+ vec4 weights = clamp(dists * dists * fallof_sq + 1.0, 0.0, 1.0);
+ return dot(weights, p_depths) / dot(weights, vec4(1.0, 1.0, 1.0, 1.0));
+}
+
+void prepare_depths_and_mips(vec4 p_samples, uvec2 p_output_coord, uvec2 p_gtid) {
+ p_samples = screen_space_to_view_space_depth(p_samples);
+
+ depth_buffer[0][p_gtid.x][p_gtid.y] = p_samples.w;
+ depth_buffer[1][p_gtid.x][p_gtid.y] = p_samples.z;
+ depth_buffer[2][p_gtid.x][p_gtid.y] = p_samples.x;
+ depth_buffer[3][p_gtid.x][p_gtid.y] = p_samples.y;
+
+ imageStore(dest_image0, ivec3(p_output_coord.x, p_output_coord.y, 0), vec4(p_samples.w));
+ imageStore(dest_image0, ivec3(p_output_coord.x, p_output_coord.y, 1), vec4(p_samples.z));
+ imageStore(dest_image0, ivec3(p_output_coord.x, p_output_coord.y, 2), vec4(p_samples.x));
+ imageStore(dest_image0, ivec3(p_output_coord.x, p_output_coord.y, 3), vec4(p_samples.y));
+
+ uint depth_array_index = 2 * (p_gtid.y % 2) + (p_gtid.x % 2);
+ uvec2 depth_array_offset = ivec2(p_gtid.x % 2, p_gtid.y % 2);
+ ivec2 buffer_coord = ivec2(p_gtid) - ivec2(depth_array_offset);
+
+ p_output_coord /= 2;
+ groupMemoryBarrier();
+ barrier();
+
+ // if (still_alive) <-- all threads alive here
+ {
+ float sample_00 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 0];
+ float sample_01 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 1];
+ float sample_10 = depth_buffer[depth_array_index][buffer_coord.x + 1][buffer_coord.y + 0];
+ float sample_11 = depth_buffer[depth_array_index][buffer_coord.x + 1][buffer_coord.y + 1];
+
+ float avg = mip_smart_average(vec4(sample_00, sample_01, sample_10, sample_11));
+ imageStore(dest_image1, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(avg));
+ depth_buffer[depth_array_index][buffer_coord.x][buffer_coord.y] = avg;
+ }
+
+ bool still_alive = p_gtid.x % 4 == depth_array_offset.x && p_gtid.y % 4 == depth_array_offset.y;
+
+ p_output_coord /= 2;
+ groupMemoryBarrier();
+ barrier();
+
+ if (still_alive) {
+ float sample_00 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 0];
+ float sample_01 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 2];
+ float sample_10 = depth_buffer[depth_array_index][buffer_coord.x + 2][buffer_coord.y + 0];
+ float sample_11 = depth_buffer[depth_array_index][buffer_coord.x + 2][buffer_coord.y + 2];
+
+ float avg = mip_smart_average(vec4(sample_00, sample_01, sample_10, sample_11));
+ imageStore(dest_image2, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(avg));
+ depth_buffer[depth_array_index][buffer_coord.x][buffer_coord.y] = avg;
+ }
+
+ still_alive = p_gtid.x % 8 == depth_array_offset.x && depth_array_offset.y % 8 == depth_array_offset.y;
+
+ p_output_coord /= 2;
+ groupMemoryBarrier();
+ barrier();
+
+ if (still_alive) {
+ float sample_00 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 0];
+ float sample_01 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 4];
+ float sample_10 = depth_buffer[depth_array_index][buffer_coord.x + 4][buffer_coord.y + 0];
+ float sample_11 = depth_buffer[depth_array_index][buffer_coord.x + 4][buffer_coord.y + 4];
+
+ float avg = mip_smart_average(vec4(sample_00, sample_01, sample_10, sample_11));
+ imageStore(dest_image3, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(avg));
+ }
+}
+#else
+#ifndef USE_HALF_BUFFERS
+void prepare_depths(vec4 p_samples, uvec2 p_tid) {
+ p_samples = screen_space_to_view_space_depth(p_samples);
+
+ imageStore(dest_image0, ivec3(p_tid, 0), vec4(p_samples.w));
+ imageStore(dest_image0, ivec3(p_tid, 1), vec4(p_samples.z));
+ imageStore(dest_image0, ivec3(p_tid, 2), vec4(p_samples.x));
+ imageStore(dest_image0, ivec3(p_tid, 3), vec4(p_samples.y));
+}
+#endif
+#endif
+
+void main() {
+#ifdef USE_HALF_BUFFERS
+#ifdef USE_HALF_SIZE
+ float sample_00 = texelFetch(source_depth, ivec2(4 * gl_GlobalInvocationID.x + 0, 4 * gl_GlobalInvocationID.y + 0), 0).x;
+ float sample_11 = texelFetch(source_depth, ivec2(4 * gl_GlobalInvocationID.x + 2, 4 * gl_GlobalInvocationID.y + 2), 0).x;
+#else
+ float sample_00 = texelFetch(source_depth, ivec2(2 * gl_GlobalInvocationID.x + 0, 2 * gl_GlobalInvocationID.y + 0), 0).x;
+ float sample_11 = texelFetch(source_depth, ivec2(2 * gl_GlobalInvocationID.x + 1, 2 * gl_GlobalInvocationID.y + 1), 0).x;
+#endif
+ sample_00 = screen_space_to_view_space_depth(sample_00);
+ sample_11 = screen_space_to_view_space_depth(sample_11);
+
+ imageStore(dest_image0, ivec3(gl_GlobalInvocationID.xy, 0), vec4(sample_00));
+ imageStore(dest_image0, ivec3(gl_GlobalInvocationID.xy, 3), vec4(sample_11));
+#else //!USE_HALF_BUFFERS
+#ifdef USE_HALF_SIZE
+ ivec2 depth_buffer_coord = 4 * ivec2(gl_GlobalInvocationID.xy);
+ ivec2 output_coord = ivec2(gl_GlobalInvocationID);
+
+ vec2 uv = (vec2(depth_buffer_coord) + 0.5f) * params.pixel_size;
+ vec4 samples;
+ samples.x = textureLodOffset(source_depth, uv, 0, ivec2(0, 2)).x;
+ samples.y = textureLodOffset(source_depth, uv, 0, ivec2(2, 2)).x;
+ samples.z = textureLodOffset(source_depth, uv, 0, ivec2(2, 0)).x;
+ samples.w = textureLodOffset(source_depth, uv, 0, ivec2(0, 0)).x;
+#else
+ ivec2 depth_buffer_coord = 2 * ivec2(gl_GlobalInvocationID.xy);
+ ivec2 output_coord = ivec2(gl_GlobalInvocationID);
+
+ vec2 uv = (vec2(depth_buffer_coord) + 0.5f) * params.pixel_size;
+ vec4 samples = textureGather(source_depth, uv);
+#endif
+#ifdef GENERATE_MIPS
+ prepare_depths_and_mips(samples, output_coord, gl_LocalInvocationID.xy);
+#else
+ prepare_depths(samples, gl_GlobalInvocationID.xy);
+#endif
+#endif
+}
diff --git a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl
new file mode 100644
index 0000000000..6aa7624261
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl
@@ -0,0 +1,126 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2016, Intel Corporation
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+// the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2016-09-07: filip.strugar@intel.com: first commit
+// 2020-12-05: clayjohn: convert to Vulkan and Godot
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+#ifdef GENERATE_MAP
+layout(set = 0, binding = 0) uniform sampler2DArray source_ssao;
+#else
+layout(set = 0, binding = 0) uniform sampler2D source_importance;
+#endif
+layout(r8, set = 1, binding = 0) uniform restrict writeonly image2D dest_image;
+
+#ifdef PROCESS_MAPB
+layout(set = 2, binding = 0, std430) buffer Counter {
+ uint sum;
+}
+counter;
+#endif
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ vec2 half_screen_pixel_size;
+ float intensity;
+ float power;
+}
+params;
+
+void main() {
+ // Pixel being shaded
+ ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
+
+#ifdef GENERATE_MAP
+ // importance map stuff
+ uvec2 base_position = ssC * 2;
+
+ vec2 base_uv = (vec2(base_position) + vec2(0.5f, 0.5f)) * params.half_screen_pixel_size;
+
+ float avg = 0.0;
+ float minV = 1.0;
+ float maxV = 0.0;
+ for (int i = 0; i < 4; i++) {
+ vec4 vals = textureGather(source_ssao, vec3(base_uv, i));
+
+ // apply the same modifications that would have been applied in the main shader
+ vals = params.intensity * vals;
+
+ vals = 1 - vals;
+
+ vals = pow(clamp(vals, 0.0, 1.0), vec4(params.power));
+
+ avg += dot(vec4(vals.x, vals.y, vals.z, vals.w), vec4(1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0));
+
+ maxV = max(maxV, max(max(vals.x, vals.y), max(vals.z, vals.w)));
+ minV = min(minV, min(min(vals.x, vals.y), min(vals.z, vals.w)));
+ }
+
+ float min_max_diff = maxV - minV;
+
+ imageStore(dest_image, ssC, vec4(pow(clamp(min_max_diff * 2.0, 0.0, 1.0), 0.8)));
+#endif
+
+#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;
+
+ vec2 half_pixel = params.half_screen_pixel_size;
+
+ vec4 vals;
+ vals.x = textureLod(source_importance, uv + vec2(-half_pixel.x * 3, -half_pixel.y), 0.0).x;
+ vals.y = textureLod(source_importance, uv + vec2(+half_pixel.x, -half_pixel.y * 3), 0.0).x;
+ vals.z = textureLod(source_importance, uv + vec2(+half_pixel.x * 3, +half_pixel.y), 0.0).x;
+ vals.w = textureLod(source_importance, uv + vec2(-half_pixel.x, +half_pixel.y * 3), 0.0).x;
+
+ float avg = dot(vals, vec4(0.25, 0.25, 0.25, 0.25));
+
+ imageStore(dest_image, ssC, vec4(avg));
+#endif
+
+#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;
+
+ vec2 half_pixel = params.half_screen_pixel_size;
+
+ vec4 vals;
+ vals.x = textureLod(source_importance, uv + vec2(-half_pixel.x, -half_pixel.y * 3), 0.0).x;
+ vals.y = textureLod(source_importance, uv + vec2(+half_pixel.x * 3, -half_pixel.y), 0.0).x;
+ vals.z = textureLod(source_importance, uv + vec2(+half_pixel.x, +half_pixel.y * 3), 0.0).x;
+ vals.w = textureLod(source_importance, uv + vec2(-half_pixel.x * 3, +half_pixel.y), 0.0).x;
+
+ float avg = dot(vals, vec4(0.25, 0.25, 0.25, 0.25));
+
+ imageStore(dest_image, ssC, vec4(avg));
+
+ // sum the average; to avoid overflowing we assume max AO resolution is not bigger than 16384x16384; so quarter res (used here) will be 4096x4096, which leaves us with 8 bits per pixel
+ uint sum = uint(clamp(avg, 0.0, 1.0) * 255.0 + 0.5);
+
+ // save every 9th to avoid InterlockedAdd congestion - since we're blurring, this is good enough; compensated by multiplying load_counter_avg_div by 9
+ if (((ssC.x % 3) + (ssC.y % 3)) == 0) {
+ atomicAdd(counter.sum, sum);
+ }
+#endif
+}
diff --git a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl b/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl
new file mode 100644
index 0000000000..4fdf334aa5
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl
@@ -0,0 +1,119 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2016, Intel Corporation
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+// the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2016-09-07: filip.strugar@intel.com: first commit
+// 2020-12-05: clayjohn: convert to Vulkan and Godot
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+layout(rgba8, set = 0, binding = 0) uniform restrict writeonly image2D dest_image;
+layout(set = 1, binding = 0) uniform sampler2DArray source_texture;
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ float inv_sharpness;
+ uint size_modifier;
+ vec2 pixel_size;
+}
+params;
+
+vec4 unpack_edges(float p_packed_val) {
+ uint packed_val = uint(p_packed_val * 255.5);
+ vec4 edgesLRTB;
+ edgesLRTB.x = float((packed_val >> 6) & 0x03) / 3.0;
+ edgesLRTB.y = float((packed_val >> 4) & 0x03) / 3.0;
+ edgesLRTB.z = float((packed_val >> 2) & 0x03) / 3.0;
+ edgesLRTB.w = float((packed_val >> 0) & 0x03) / 3.0;
+
+ return clamp(edgesLRTB + params.inv_sharpness, 0.0, 1.0);
+}
+
+void main() {
+ ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
+ if (any(greaterThanEqual(ssC, ivec2(1.0 / params.pixel_size)))) { //too large, do nothing
+ return;
+ }
+
+#ifdef MODE_SMART
+ float ao;
+ uvec2 pix_pos = uvec2(gl_GlobalInvocationID.xy);
+ vec2 uv = (gl_GlobalInvocationID.xy + vec2(0.5)) * params.pixel_size;
+
+ // calculate index in the four deinterleaved source array texture
+ 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_diagonal = (1 - mx) + (1 - my) * 2; // diagonal
+
+ vec2 center_val = texelFetch(source_texture, ivec3(pix_pos / uvec2(params.size_modifier), index_center), 0).xy;
+
+ ao = center_val.x;
+
+ vec4 edgesLRTB = unpack_edges(center_val.y);
+
+ // convert index shifts to sampling offsets
+ float fmx = float(mx);
+ float fmy = float(my);
+
+ // in case of an edge, push sampling offsets away from the edge (towards pixel center)
+ float fmxe = (edgesLRTB.y - edgesLRTB.x);
+ float fmye = (edgesLRTB.w - edgesLRTB.z);
+
+ // calculate final sampling offsets and sample using bilinear filter
+ vec2 uv_horizontal = (gl_GlobalInvocationID.xy + vec2(0.5) + vec2(fmx + fmxe - 0.5, 0.5 - fmy)) * params.pixel_size;
+ float ao_horizontal = textureLod(source_texture, vec3(uv_horizontal, index_horizontal), 0.0).x;
+ vec2 uv_vertical = (gl_GlobalInvocationID.xy + vec2(0.5) + vec2(0.5 - fmx, fmy - 0.5 + fmye)) * params.pixel_size;
+ float ao_vertical = textureLod(source_texture, vec3(uv_vertical, index_vertical), 0.0).x;
+ vec2 uv_diagonal = (gl_GlobalInvocationID.xy + vec2(0.5) + vec2(fmx - 0.5 + fmxe, fmy - 0.5 + fmye)) * params.pixel_size;
+ float ao_diagonal = textureLod(source_texture, vec3(uv_diagonal, index_diagonal), 0.0).x;
+
+ // reduce weight for samples near edge - if the edge is on both sides, weight goes to 0
+ vec4 blendWeights;
+ blendWeights.x = 1.0;
+ blendWeights.y = (edgesLRTB.x + edgesLRTB.y) * 0.5;
+ blendWeights.z = (edgesLRTB.z + edgesLRTB.w) * 0.5;
+ blendWeights.w = (blendWeights.y + blendWeights.z) * 0.5;
+
+ // calculate weighted average
+ float blendWeightsSum = dot(blendWeights, vec4(1.0, 1.0, 1.0, 1.0));
+ ao = dot(vec4(ao, ao_horizontal, ao_vertical, ao_diagonal), blendWeights) / blendWeightsSum;
+
+ imageStore(dest_image, ivec2(gl_GlobalInvocationID.xy), vec4(ao));
+#else // !MODE_SMART
+
+ vec2 uv = (gl_GlobalInvocationID.xy + vec2(0.5)) * params.pixel_size;
+#ifdef MODE_HALF
+ float a = textureLod(source_texture, vec3(uv, 0), 0.0).x;
+ float d = textureLod(source_texture, vec3(uv, 3), 0.0).x;
+ float avg = (a + d) * 0.5;
+
+#else
+ float a = textureLod(source_texture, vec3(uv, 0), 0.0).x;
+ float b = textureLod(source_texture, vec3(uv, 1), 0.0).x;
+ float c = textureLod(source_texture, vec3(uv, 2), 0.0).x;
+ float d = textureLod(source_texture, vec3(uv, 3), 0.0).x;
+ float avg = (a + b + c + d) * 0.25;
+
+#endif
+ imageStore(dest_image, ivec2(gl_GlobalInvocationID.xy), vec4(avg));
+#endif
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl
index 88a953562f..88a953562f 100644
--- a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl
+++ b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl
diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl
index 4cc4fd3f64..7de91fd541 100644
--- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
+++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl
@@ -23,7 +23,11 @@ layout(location = 0) in vec2 uv_interp;
layout(set = 0, binding = 0) uniform sampler2D source_color;
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
layout(set = 2, binding = 0) uniform sampler2D source_glow;
-layout(set = 3, binding = 0) uniform sampler3D color_correction;
+#ifdef USE_1D_LUT
+layout(set = 3, binding = 0) uniform sampler2D source_color_correction;
+#else
+layout(set = 3, binding = 0) uniform sampler3D source_color_correction;
+#endif
layout(push_constant, binding = 1, std430) uniform Params {
vec3 bcs;
@@ -35,9 +39,9 @@ layout(push_constant, binding = 1, std430) uniform Params {
uint tonemapper;
uvec2 glow_texture_size;
-
float glow_intensity;
uint pad3;
+
uint glow_mode;
float glow_levels[7];
@@ -255,10 +259,18 @@ vec3 apply_bcs(vec3 color, vec3 bcs) {
return color;
}
-
-vec3 apply_color_correction(vec3 color, sampler3D correction_tex) {
- return texture(correction_tex, color).rgb;
+#ifdef USE_1D_LUT
+vec3 apply_color_correction(vec3 color) {
+ color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r;
+ color.g = texture(source_color_correction, vec2(color.g, 0.0f)).g;
+ color.b = texture(source_color_correction, vec2(color.b, 0.0f)).b;
+ return color;
+}
+#else
+vec3 apply_color_correction(vec3 color) {
+ return textureLod(source_color_correction, color, 0.0).rgb;
}
+#endif
vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
const float FXAA_REDUCE_MIN = (1.0 / 128.0);
@@ -367,7 +379,7 @@ void main() {
}
if (params.use_color_correction) {
- color = apply_color_correction(color, color_correction);
+ color = apply_color_correction(color);
}
frag_color = vec4(color, 1.0f);
diff --git a/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index 13b162f0c9..498a6ddb5b 100644
--- a/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -169,6 +169,15 @@ vec3 hash3f(uvec3 x) {
return vec3(x & 0xFFFFF) / vec3(float(0xFFFFF));
}
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
void main() {
vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size);
@@ -270,14 +279,14 @@ void main() {
uint light_index = cluster_data.indices[omni_light_pointer + i];
vec3 light_pos = lights.data[i].position;
- float d = distance(lights.data[i].position, view_pos) * lights.data[i].inv_radius;
+ float d = distance(lights.data[i].position, view_pos);
vec3 shadow_attenuation = vec3(1.0);
- if (d < 1.0) {
+ if (d * lights.data[i].inv_radius < 1.0) {
vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);
- float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.x);
+ float attenuation = get_omni_attenuation(d, lights.data[i].inv_radius, attenuation_energy.x);
vec3 light = attenuation_energy.y * color_specular.rgb / M_PI;
@@ -326,14 +335,14 @@ void main() {
vec3 light_pos = lights.data[i].position;
vec3 light_rel_vec = lights.data[i].position - view_pos;
- float d = length(light_rel_vec) * lights.data[i].inv_radius;
+ float d = length(light_rel_vec);
vec3 shadow_attenuation = vec3(1.0);
- if (d < 1.0) {
+ if (d * lights.data[i].inv_radius < 1.0) {
vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);
- float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.x);
+ float attenuation = get_omni_attenuation(d, lights.data[i].inv_radius, attenuation_energy.x);
vec3 spot_dir = lights.data[i].direction;
vec2 spot_att_angle = unpackHalf2x16(lights.data[i].cone_attenuation_angle);
diff --git a/servers/rendering/renderer_scene.cpp b/servers/rendering/renderer_scene.cpp
new file mode 100644
index 0000000000..dd544d4f3f
--- /dev/null
+++ b/servers/rendering/renderer_scene.cpp
@@ -0,0 +1,37 @@
+/*************************************************************************/
+/* renderer_scene.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_scene.h"
+
+RendererScene::RendererScene() {
+}
+
+RendererScene::~RendererScene() {
+}
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
new file mode 100644
index 0000000000..c483898fed
--- /dev/null
+++ b/servers/rendering/renderer_scene.h
@@ -0,0 +1,203 @@
+/*************************************************************************/
+/* renderer_scene.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERINGSERVERSCENE_H
+#define RENDERINGSERVERSCENE_H
+
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/xr/xr_interface.h"
+
+class RendererScene {
+public:
+ virtual RID camera_create() = 0;
+
+ virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0;
+ virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0;
+ virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0;
+ virtual void camera_set_transform(RID p_camera, const Transform &p_transform) = 0;
+ virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0;
+ virtual void camera_set_environment(RID p_camera, RID p_env) = 0;
+ virtual void camera_set_camera_effects(RID p_camera, RID p_fx) = 0;
+ virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0;
+ virtual bool is_camera(RID p_camera) const = 0;
+
+ virtual RID scenario_create() = 0;
+
+ virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) = 0;
+ virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0;
+ virtual void scenario_set_camera_effects(RID p_scenario, RID p_fx) = 0;
+ virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0;
+ virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) = 0;
+ virtual bool is_scenario(RID p_scenario) const = 0;
+ virtual RID scenario_get_environment(RID p_scenario) = 0;
+
+ virtual RID instance_create() = 0;
+
+ 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_transform(RID p_instance, const Transform &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;
+ virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material) = 0;
+ virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
+
+ virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb) = 0;
+
+ virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0;
+ virtual void instance_set_exterior(RID p_instance, bool p_enabled) = 0;
+
+ virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0;
+
+ // don't use these in a game!
+ virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0;
+ virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0;
+ virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0;
+
+ virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) = 0;
+ virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) = 0;
+ virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0;
+
+ virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0;
+ virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0;
+ virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) = 0;
+ virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0;
+
+ virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0;
+ virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0;
+ virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0;
+ virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0;
+
+ virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+
+ /* SKY API */
+
+ virtual RID sky_create() = 0;
+ virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
+ virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0;
+ virtual void sky_set_material(RID p_sky, RID p_material) = 0;
+ virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
+
+ /* ENVIRONMENT API */
+
+ virtual RID environment_create() = 0;
+
+ virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0;
+ virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
+ virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0;
+ virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0;
+ virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
+ virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
+ virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) = 0;
+
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 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;
+
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+
+ virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
+ virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
+ virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
+ virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
+
+ virtual 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) = 0;
+ virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
+
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) = 0;
+
+ virtual void environment_set_ssao_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) = 0;
+
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
+
+ virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
+ virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
+
+ virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
+
+ virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0;
+
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
+
+ virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
+
+ virtual RS::EnvironmentBG environment_get_background(RID p_Env) const = 0;
+ virtual int environment_get_canvas_max_layer(RID p_env) const = 0;
+
+ virtual bool is_environment(RID p_environment) const = 0;
+
+ virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0;
+ virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0;
+ virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0;
+
+ /* Camera Effects */
+
+ virtual RID camera_effects_create() = 0;
+
+ virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0;
+ virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0;
+
+ virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0;
+ virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0;
+
+ virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
+ virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
+
+ virtual RID shadow_atlas_create() = 0;
+ virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
+ virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
+
+ /* Render Buffers */
+
+ virtual RID render_buffers_create() = 0;
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0;
+
+ virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
+
+ virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0;
+ virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
+
+ virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0;
+
+ virtual void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) = 0;
+ virtual void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_lod_threshold, RID p_shadow_atlas) = 0;
+ virtual void render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_lod_threshold, RID p_shadow_atlas) = 0;
+
+ virtual void update() = 0;
+ virtual void render_probes() = 0;
+
+ virtual bool free(RID p_rid) = 0;
+
+ RendererScene();
+ virtual ~RendererScene();
+};
+
+#endif // RENDERINGSERVERSCENE_H
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
new file mode 100644
index 0000000000..d3979521b1
--- /dev/null
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -0,0 +1,3508 @@
+/*************************************************************************/
+/* renderer_scene_cull.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_scene_cull.h"
+
+#include "core/config/project_settings.h"
+#include "core/os/os.h"
+#include "rendering_server_default.h"
+#include "rendering_server_globals.h"
+
+#include <new>
+
+/* CAMERA API */
+
+RID RendererSceneCull::camera_create() {
+ Camera *camera = memnew(Camera);
+ return camera_owner.make_rid(camera);
+}
+
+void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+ camera->type = Camera::PERSPECTIVE;
+ camera->fov = p_fovy_degrees;
+ camera->znear = p_z_near;
+ camera->zfar = p_z_far;
+}
+
+void RendererSceneCull::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+ camera->type = Camera::ORTHOGONAL;
+ camera->size = p_size;
+ camera->znear = p_z_near;
+ camera->zfar = p_z_far;
+}
+
+void RendererSceneCull::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+ camera->type = Camera::FRUSTUM;
+ camera->size = p_size;
+ camera->offset = p_offset;
+ camera->znear = p_z_near;
+ camera->zfar = p_z_far;
+}
+
+void RendererSceneCull::camera_set_transform(RID p_camera, const Transform &p_transform) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+ camera->transform = p_transform.orthonormalized();
+}
+
+void RendererSceneCull::camera_set_cull_mask(RID p_camera, uint32_t p_layers) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+
+ camera->visible_layers = p_layers;
+}
+
+void RendererSceneCull::camera_set_environment(RID p_camera, RID p_env) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+ camera->env = p_env;
+}
+
+void RendererSceneCull::camera_set_camera_effects(RID p_camera, RID p_fx) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+ camera->effects = p_fx;
+}
+
+void RendererSceneCull::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+ camera->vaspect = p_enable;
+}
+
+bool RendererSceneCull::is_camera(RID p_camera) const {
+ return camera_owner.owns(p_camera);
+}
+
+/* SCENARIO API */
+
+void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
+ RendererSceneCull *self = (RendererSceneCull *)singleton;
+ Instance *A = p_A;
+ Instance *B = p_B;
+
+ //instance indices are designed so greater always contains lesser
+ if (A->base_type > B->base_type) {
+ SWAP(A, B); //lesser always first
+ }
+
+ if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->lights.insert(B);
+ light->geometries.insert(A);
+
+ if (geom->can_cast_shadows) {
+ light->shadow_dirty = true;
+ }
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->reflection_probes.insert(B);
+ reflection_probe->geometries.insert(A);
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->decals.insert(B);
+ decal->geometries.insert(A);
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_DECAL_DIRTY;
+ }
+
+ } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ if (A->dynamic_gi) {
+ geom->lightmap_captures.insert(A);
+ lightmap_data->geometries.insert(B);
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_LIGHTMAP_CAPTURE;
+ }
+ ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->gi_probes.insert(B);
+
+ if (A->dynamic_gi) {
+ gi_probe->dynamic_geometries.insert(A);
+ } else {
+ gi_probe->geometries.insert(A);
+ }
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_GI_PROBE_DIRTY;
+ }
+
+ } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
+ gi_probe->lights.insert(A);
+ } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
+ RSG::storage->particles_add_collision(A->base, collision->instance);
+ }
+}
+
+void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
+ RendererSceneCull *self = (RendererSceneCull *)singleton;
+ Instance *A = p_A;
+ Instance *B = p_B;
+
+ //instance indices are designed so greater always contains lesser
+ if (A->base_type > B->base_type) {
+ SWAP(A, B); //lesser always first
+ }
+
+ if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->lights.erase(B);
+ light->geometries.erase(A);
+
+ if (geom->can_cast_shadows) {
+ light->shadow_dirty = true;
+ }
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->reflection_probes.erase(B);
+ reflection_probe->geometries.erase(A);
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->decals.erase(B);
+ decal->geometries.erase(A);
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_DECAL_DIRTY;
+ }
+
+ } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+ if (A->dynamic_gi) {
+ geom->lightmap_captures.erase(B);
+
+ if (geom->lightmap_captures.is_empty() && A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags &= ~uint32_t(InstanceData::FLAG_LIGHTMAP_CAPTURE);
+ }
+
+ lightmap_data->geometries.erase(A);
+ ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+
+ geom->gi_probes.erase(B);
+ if (A->dynamic_gi) {
+ gi_probe->dynamic_geometries.erase(A);
+ } else {
+ gi_probe->geometries.erase(A);
+ }
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_GI_PROBE_DIRTY;
+ }
+
+ } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
+ gi_probe->lights.erase(A);
+ } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
+ RSG::storage->particles_remove_collision(A->base, collision->instance);
+ }
+}
+
+RID RendererSceneCull::scenario_create() {
+ Scenario *scenario = memnew(Scenario);
+ ERR_FAIL_COND_V(!scenario, RID());
+ RID scenario_rid = scenario_owner.make_rid(scenario);
+ scenario->self = scenario_rid;
+
+ scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create();
+ scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest
+ scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 0, 4);
+ scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4);
+ scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4);
+ scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8);
+ scenario->reflection_atlas = scene_render->reflection_atlas_create();
+
+ scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool);
+ scenario->instance_data.set_page_pool(&instance_data_page_pool);
+
+ return scenario_rid;
+}
+
+void RendererSceneCull::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND(!scenario);
+ scenario->debug = p_debug_mode;
+}
+
+void RendererSceneCull::scenario_set_environment(RID p_scenario, RID p_environment) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND(!scenario);
+ scenario->environment = p_environment;
+}
+
+void RendererSceneCull::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND(!scenario);
+ scenario->camera_effects = p_camera_effects;
+}
+
+void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND(!scenario);
+ scenario->fallback_environment = p_environment;
+}
+
+void RendererSceneCull::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND(!scenario);
+ scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count);
+}
+
+bool RendererSceneCull::is_scenario(RID p_scenario) const {
+ return scenario_owner.owns(p_scenario);
+}
+
+RID RendererSceneCull::scenario_get_environment(RID p_scenario) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND_V(!scenario, RID());
+ return scenario->environment;
+}
+
+/* INSTANCING API */
+
+void RendererSceneCull::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) {
+ if (p_update_aabb) {
+ p_instance->update_aabb = true;
+ }
+ if (p_update_dependencies) {
+ p_instance->update_dependencies = true;
+ }
+
+ if (p_instance->update_item.in_list()) {
+ return;
+ }
+
+ _instance_update_list.add(&p_instance->update_item);
+}
+
+RID RendererSceneCull::instance_create() {
+ Instance *instance = memnew(Instance);
+ ERR_FAIL_COND_V(!instance, RID());
+
+ RID instance_rid = instance_owner.make_rid(instance);
+ instance->self = instance_rid;
+
+ return instance_rid;
+}
+
+void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
+ bool needs_instance = RSG::storage->mesh_needs_instance(p_instance->base, p_instance->skeleton.is_valid());
+ if (needs_instance != p_instance->mesh_instance.is_valid()) {
+ if (needs_instance) {
+ p_instance->mesh_instance = RSG::storage->mesh_instance_create(p_instance->base);
+
+ } else {
+ RSG::storage->free(p_instance->mesh_instance);
+ p_instance->mesh_instance = RID();
+ }
+
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ scene_render->geometry_instance_set_mesh_instance(geom->geometry_instance, p_instance->mesh_instance);
+
+ if (p_instance->scenario && p_instance->array_index >= 0) {
+ InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
+ if (p_instance->mesh_instance.is_valid()) {
+ idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_USES_MESH_INSTANCE);
+ }
+ }
+ }
+
+ if (p_instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_set_skeleton(p_instance->mesh_instance, p_instance->skeleton);
+ }
+}
+
+void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ Scenario *scenario = instance->scenario;
+
+ if (instance->base_type != RS::INSTANCE_NONE) {
+ //free anything related to that base
+
+ if (scenario && instance->indexer_id.is_valid()) {
+ _unpair_instance(instance);
+ }
+
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->free(instance->mesh_instance);
+ instance->mesh_instance = RID();
+ // no need to set instance data flag here, as it was freed above
+ }
+
+ switch (instance->base_type) {
+ case RS::INSTANCE_MESH:
+ case RS::INSTANCE_MULTIMESH:
+ case RS::INSTANCE_IMMEDIATE:
+ case RS::INSTANCE_PARTICLES: {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_free(geom->geometry_instance);
+ } break;
+ case RS::INSTANCE_LIGHT: {
+ InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
+
+ if (scenario && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ scenario->dynamic_lights.erase(light->instance);
+ }
+
+#ifdef DEBUG_ENABLED
+ if (light->geometries.size()) {
+ ERR_PRINT("BUG, indexing did not unpair geometries from light.");
+ }
+#endif
+ if (scenario && light->D) {
+ scenario->directional_lights.erase(light->D);
+ light->D = nullptr;
+ }
+ scene_render->free(light->instance);
+ } break;
+ case RS::INSTANCE_PARTICLES_COLLISION: {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
+ RSG::storage->free(collision->instance);
+ } break;
+ case RS::INSTANCE_REFLECTION_PROBE: {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
+ scene_render->free(reflection_probe->instance);
+ if (reflection_probe->update_list.in_list()) {
+ reflection_probe_render_list.remove(&reflection_probe->update_list);
+ }
+ } break;
+ case RS::INSTANCE_DECAL: {
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
+ scene_render->free(decal->instance);
+
+ } break;
+ case RS::INSTANCE_LIGHTMAP: {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data);
+ //erase dependencies, since no longer a lightmap
+ while (lightmap_data->users.front()) {
+ instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0);
+ }
+ scene_render->free(lightmap_data->instance);
+ } break;
+ case RS::INSTANCE_GI_PROBE: {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
+#ifdef DEBUG_ENABLED
+ if (gi_probe->geometries.size()) {
+ ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe.");
+ }
+#endif
+#ifdef DEBUG_ENABLED
+ if (gi_probe->lights.size()) {
+ ERR_PRINT("BUG, indexing did not unpair lights from GIProbe.");
+ }
+#endif
+ if (gi_probe->update_element.in_list()) {
+ gi_probe_update_list.remove(&gi_probe->update_element);
+ }
+
+ scene_render->free(gi_probe->probe_instance);
+
+ } break;
+ default: {
+ }
+ }
+
+ if (instance->base_data) {
+ memdelete(instance->base_data);
+ instance->base_data = nullptr;
+ }
+
+ instance->materials.clear();
+ }
+
+ instance->base_type = RS::INSTANCE_NONE;
+ instance->base = RID();
+
+ if (p_base.is_valid()) {
+ instance->base_type = RSG::storage->get_base_type(p_base);
+ ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE);
+
+ switch (instance->base_type) {
+ case RS::INSTANCE_LIGHT: {
+ InstanceLightData *light = memnew(InstanceLightData);
+
+ if (scenario && RSG::storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) {
+ light->D = scenario->directional_lights.push_back(instance);
+ }
+
+ light->instance = scene_render->light_instance_create(p_base);
+
+ instance->base_data = light;
+ } break;
+ case RS::INSTANCE_MESH:
+ case RS::INSTANCE_MULTIMESH:
+ case RS::INSTANCE_IMMEDIATE:
+ case RS::INSTANCE_PARTICLES: {
+ InstanceGeometryData *geom = memnew(InstanceGeometryData);
+ instance->base_data = geom;
+ geom->geometry_instance = scene_render->geometry_instance_create(p_base);
+
+ scene_render->geometry_instance_set_skeleton(geom->geometry_instance, instance->skeleton);
+ scene_render->geometry_instance_set_material_override(geom->geometry_instance, instance->material_override);
+ scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, instance->materials);
+ scene_render->geometry_instance_set_transform(geom->geometry_instance, instance->transform, instance->aabb, instance->transformed_aabb);
+ scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, instance->layer_mask);
+ scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, instance->lod_bias);
+ scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, instance->baked_light);
+ scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, instance->dynamic_gi);
+ scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
+ scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index);
+ if (instance->lightmap_sh.size() == 9) {
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr());
+ }
+
+ } break;
+ case RS::INSTANCE_PARTICLES_COLLISION: {
+ InstanceParticlesCollisionData *collision = memnew(InstanceParticlesCollisionData);
+ collision->instance = RSG::storage->particles_collision_instance_create(p_base);
+ RSG::storage->particles_collision_instance_set_active(collision->instance, instance->visible);
+ instance->base_data = collision;
+ } break;
+ case RS::INSTANCE_REFLECTION_PROBE: {
+ InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
+ reflection_probe->owner = instance;
+ instance->base_data = reflection_probe;
+
+ reflection_probe->instance = scene_render->reflection_probe_instance_create(p_base);
+ } break;
+ case RS::INSTANCE_DECAL: {
+ InstanceDecalData *decal = memnew(InstanceDecalData);
+ decal->owner = instance;
+ instance->base_data = decal;
+
+ decal->instance = scene_render->decal_instance_create(p_base);
+ } break;
+ case RS::INSTANCE_LIGHTMAP: {
+ InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
+ instance->base_data = lightmap_data;
+ lightmap_data->instance = scene_render->lightmap_instance_create(p_base);
+ } break;
+ case RS::INSTANCE_GI_PROBE: {
+ InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData);
+ instance->base_data = gi_probe;
+ gi_probe->owner = instance;
+
+ if (scenario && !gi_probe->update_element.in_list()) {
+ gi_probe_update_list.add(&gi_probe->update_element);
+ }
+
+ gi_probe->probe_instance = scene_render->gi_probe_instance_create(p_base);
+
+ } break;
+ default: {
+ }
+ }
+
+ instance->base = p_base;
+
+ if (instance->base_type == RS::INSTANCE_MESH) {
+ _instance_update_mesh_instance(instance);
+ }
+
+ //forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
+ RSG::storage->base_update_dependency(p_base, &instance->dependency_tracker);
+ }
+
+ _instance_queue_update(instance, true, true);
+}
+
+void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->scenario) {
+ instance->scenario->instances.remove(&instance->scenario_item);
+
+ if (instance->indexer_id.is_valid()) {
+ _unpair_instance(instance);
+ }
+
+ switch (instance->base_type) {
+ case RS::INSTANCE_LIGHT: {
+ InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
+#ifdef DEBUG_ENABLED
+ if (light->geometries.size()) {
+ ERR_PRINT("BUG, indexing did not unpair geometries from light.");
+ }
+#endif
+ if (light->D) {
+ instance->scenario->directional_lights.erase(light->D);
+ light->D = nullptr;
+ }
+ } break;
+ case RS::INSTANCE_REFLECTION_PROBE: {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
+ scene_render->reflection_probe_release_atlas_index(reflection_probe->instance);
+
+ } break;
+ case RS::INSTANCE_PARTICLES_COLLISION: {
+ heightfield_particle_colliders_update_list.erase(instance);
+ } break;
+ case RS::INSTANCE_GI_PROBE: {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
+
+#ifdef DEBUG_ENABLED
+ if (gi_probe->geometries.size()) {
+ ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe.");
+ }
+#endif
+#ifdef DEBUG_ENABLED
+ if (gi_probe->lights.size()) {
+ ERR_PRINT("BUG, indexing did not unpair lights from GIProbe.");
+ }
+#endif
+
+ if (gi_probe->update_element.in_list()) {
+ gi_probe_update_list.remove(&gi_probe->update_element);
+ }
+ } break;
+ default: {
+ }
+ }
+
+ instance->scenario = nullptr;
+ }
+
+ if (p_scenario.is_valid()) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND(!scenario);
+
+ instance->scenario = scenario;
+
+ scenario->instances.add(&instance->scenario_item);
+
+ switch (instance->base_type) {
+ case RS::INSTANCE_LIGHT: {
+ InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
+
+ if (RSG::storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) {
+ light->D = scenario->directional_lights.push_back(instance);
+ }
+ } break;
+ case RS::INSTANCE_GI_PROBE: {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
+ if (!gi_probe->update_element.in_list()) {
+ gi_probe_update_list.add(&gi_probe->update_element);
+ }
+ } break;
+ default: {
+ }
+ }
+
+ _instance_queue_update(instance, true, true);
+ }
+}
+
+void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->layer_mask = p_mask;
+ if (instance->scenario && instance->array_index >= 0) {
+ instance->scenario->instance_data[instance->array_index].layer_mask = p_mask;
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, p_mask);
+ }
+}
+
+void RendererSceneCull::instance_set_transform(RID p_instance, const Transform &p_transform) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->transform == p_transform) {
+ return; //must be checked to avoid worst evil
+ }
+
+#ifdef DEBUG_ENABLED
+
+ for (int i = 0; i < 4; i++) {
+ const Vector3 &v = i < 3 ? p_transform.basis.elements[i] : p_transform.origin;
+ ERR_FAIL_COND(Math::is_inf(v.x));
+ ERR_FAIL_COND(Math::is_nan(v.x));
+ ERR_FAIL_COND(Math::is_inf(v.y));
+ ERR_FAIL_COND(Math::is_nan(v.y));
+ ERR_FAIL_COND(Math::is_inf(v.z));
+ ERR_FAIL_COND(Math::is_nan(v.z));
+ }
+
+#endif
+ instance->transform = p_transform;
+ _instance_queue_update(instance, true);
+}
+
+void RendererSceneCull::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->object_id = p_id;
+}
+
+void RendererSceneCull::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->update_item.in_list()) {
+ _update_dirty_instance(instance);
+ }
+
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_set_blend_shape_weight(instance->mesh_instance, p_shape, p_weight);
+ }
+}
+
+void RendererSceneCull::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->base_type == RS::INSTANCE_MESH) {
+ //may not have been updated yet, may also have not been set yet. When updated will be correcte, worst case
+ instance->materials.resize(MAX(p_surface + 1, RSG::storage->mesh_get_surface_count(instance->base)));
+ }
+
+ ERR_FAIL_INDEX(p_surface, instance->materials.size());
+
+ instance->materials.write[p_surface] = p_material;
+
+ _instance_queue_update(instance, false, true);
+}
+
+void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->visible == p_visible) {
+ return;
+ }
+
+ instance->visible = p_visible;
+
+ if (p_visible) {
+ if (instance->scenario != nullptr) {
+ _instance_queue_update(instance, true, false);
+ }
+ } else if (instance->indexer_id.is_valid()) {
+ _unpair_instance(instance);
+ }
+
+ if (instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
+ RSG::storage->particles_collision_instance_set_active(collision->instance, p_visible);
+ }
+}
+
+inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
+ return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES || p_type == RS::INSTANCE_IMMEDIATE;
+}
+
+void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+ ERR_FAIL_COND(!is_geometry_instance(instance->base_type));
+
+ if (p_aabb != AABB()) {
+ // Set custom AABB
+ if (instance->custom_aabb == nullptr) {
+ instance->custom_aabb = memnew(AABB);
+ }
+ *instance->custom_aabb = p_aabb;
+
+ } else {
+ // Clear custom AABB
+ if (instance->custom_aabb != nullptr) {
+ memdelete(instance->custom_aabb);
+ instance->custom_aabb = nullptr;
+ }
+ }
+
+ if (instance->scenario) {
+ _instance_queue_update(instance, true, false);
+ }
+}
+
+void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->skeleton == p_skeleton) {
+ return;
+ }
+
+ instance->skeleton = p_skeleton;
+
+ if (p_skeleton.is_valid()) {
+ //update the dependency now, so if cleared, we remove it
+ RSG::storage->skeleton_update_dependency(p_skeleton, &instance->dependency_tracker);
+ }
+
+ _instance_queue_update(instance, true, true);
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ _instance_update_mesh_instance(instance);
+
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_skeleton(geom->geometry_instance, p_skeleton);
+ }
+}
+
+void RendererSceneCull::instance_set_exterior(RID p_instance, bool p_enabled) {
+}
+
+void RendererSceneCull::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->extra_margin = p_margin;
+ _instance_queue_update(instance, true, false);
+}
+
+Vector<ObjectID> RendererSceneCull::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const {
+ Vector<ObjectID> instances;
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND_V(!scenario, instances);
+
+ const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling
+
+ struct CullAABB {
+ Vector<ObjectID> instances;
+ _FORCE_INLINE_ bool operator()(void *p_data) {
+ Instance *p_instance = (Instance *)p_data;
+ if (!p_instance->object_id.is_null()) {
+ instances.push_back(p_instance->object_id);
+ }
+ return false;
+ }
+ };
+
+ CullAABB cull_aabb;
+ scenario->indexers[Scenario::INDEXER_GEOMETRY].aabb_query(p_aabb, cull_aabb);
+ scenario->indexers[Scenario::INDEXER_VOLUMES].aabb_query(p_aabb, cull_aabb);
+ return cull_aabb.instances;
+}
+
+Vector<ObjectID> RendererSceneCull::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const {
+ Vector<ObjectID> instances;
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND_V(!scenario, instances);
+ const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling
+
+ struct CullRay {
+ Vector<ObjectID> instances;
+ _FORCE_INLINE_ bool operator()(void *p_data) {
+ Instance *p_instance = (Instance *)p_data;
+ if (!p_instance->object_id.is_null()) {
+ instances.push_back(p_instance->object_id);
+ }
+ return false;
+ }
+ };
+
+ CullRay cull_ray;
+ scenario->indexers[Scenario::INDEXER_GEOMETRY].ray_query(p_from, p_to, cull_ray);
+ scenario->indexers[Scenario::INDEXER_VOLUMES].ray_query(p_from, p_to, cull_ray);
+ return cull_ray.instances;
+}
+
+Vector<ObjectID> RendererSceneCull::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const {
+ Vector<ObjectID> instances;
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ ERR_FAIL_COND_V(!scenario, instances);
+ const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling
+
+ Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size());
+
+ struct CullConvex {
+ Vector<ObjectID> instances;
+ _FORCE_INLINE_ bool operator()(void *p_data) {
+ Instance *p_instance = (Instance *)p_data;
+ if (!p_instance->object_id.is_null()) {
+ instances.push_back(p_instance->object_id);
+ }
+ return false;
+ }
+ };
+
+ CullConvex cull_convex;
+ scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(p_convex.ptr(), p_convex.size(), points.ptr(), points.size(), cull_convex);
+ scenario->indexers[Scenario::INDEXER_VOLUMES].convex_query(p_convex.ptr(), p_convex.size(), points.ptr(), points.size(), cull_convex);
+ return cull_convex.instances;
+}
+
+void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ //ERR_FAIL_COND(((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK));
+
+ switch (p_flags) {
+ case RS::INSTANCE_FLAG_USE_BAKED_LIGHT: {
+ instance->baked_light = p_enabled;
+
+ if (instance->scenario && instance->array_index >= 0) {
+ InstanceData &idata = instance->scenario->instance_data[instance->array_index];
+ if (instance->baked_light) {
+ idata.flags |= InstanceData::FLAG_USES_BAKED_LIGHT;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_USES_BAKED_LIGHT);
+ }
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, p_enabled);
+ }
+
+ } break;
+ case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: {
+ if (p_enabled == instance->dynamic_gi) {
+ //bye, redundant
+ return;
+ }
+
+ if (instance->indexer_id.is_valid()) {
+ _unpair_instance(instance);
+ _instance_queue_update(instance, true, true);
+ }
+
+ //once out of octree, can be changed
+ instance->dynamic_gi = p_enabled;
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, p_enabled);
+ }
+
+ } break;
+ case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: {
+ instance->redraw_if_visible = p_enabled;
+
+ if (instance->scenario && instance->array_index >= 0) {
+ InstanceData &idata = instance->scenario->instance_data[instance->array_index];
+ if (instance->redraw_if_visible) {
+ idata.flags |= InstanceData::FLAG_REDRAW_IF_VISIBLE;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_REDRAW_IF_VISIBLE);
+ }
+ }
+
+ } break;
+ default: {
+ }
+ }
+}
+
+void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->cast_shadows = p_shadow_casting_setting;
+
+ if (instance->scenario && instance->array_index >= 0) {
+ InstanceData &idata = instance->scenario->instance_data[instance->array_index];
+
+ if (instance->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_CAST_SHADOWS);
+ }
+
+ if (instance->cast_shadows == RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS_ONLY;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_CAST_SHADOWS_ONLY);
+ }
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
+ }
+
+ _instance_queue_update(instance, false, true);
+}
+
+void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, RID p_material) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->material_override = p_material;
+ _instance_queue_update(instance, false, true);
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_material_override(geom->geometry_instance, p_material);
+ }
+}
+
+void RendererSceneCull::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) {
+}
+
+void RendererSceneCull::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) {
+}
+
+void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->lightmap) {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(((Instance *)instance->lightmap)->base_data);
+ lightmap_data->users.erase(instance);
+ instance->lightmap = nullptr;
+ }
+
+ Instance *lightmap_instance = instance_owner.getornull(p_lightmap);
+
+ instance->lightmap = lightmap_instance;
+ instance->lightmap_uv_scale = p_lightmap_uv_scale;
+ instance->lightmap_slice_index = p_slice_index;
+
+ RID lightmap_instance_rid;
+
+ if (lightmap_instance) {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data);
+ lightmap_data->users.insert(instance);
+ lightmap_instance_rid = lightmap_data->instance;
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index);
+ }
+}
+
+void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ instance->lod_bias = p_lod_bias;
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, p_lod_bias);
+ }
+}
+
+void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
+
+ if (!E) {
+ Instance::InstanceShaderParameter isp;
+ isp.index = -1;
+ isp.info = PropertyInfo();
+ isp.value = p_value;
+ instance->instance_shader_parameters[p_parameter] = isp;
+ } else {
+ E->get().value = p_value;
+ if (E->get().index >= 0 && instance->instance_allocated_shader_parameters) {
+ //update directly
+ RSG::storage->global_variables_instance_update(p_instance, E->get().index, p_value);
+ }
+ }
+}
+
+Variant RendererSceneCull::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const {
+ const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance);
+ ERR_FAIL_COND_V(!instance, Variant());
+
+ if (instance->instance_shader_parameters.has(p_parameter)) {
+ return instance->instance_shader_parameters[p_parameter].value;
+ }
+ return Variant();
+}
+
+Variant RendererSceneCull::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const {
+ const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance);
+ ERR_FAIL_COND_V(!instance, Variant());
+
+ if (instance->instance_shader_parameters.has(p_parameter)) {
+ return instance->instance_shader_parameters[p_parameter].default_value;
+ }
+ return Variant();
+}
+
+void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const {
+ const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ const_cast<RendererSceneCull *>(this)->update_dirty_instances();
+
+ Vector<StringName> names;
+ for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) {
+ names.push_back(E->key());
+ }
+ names.sort_custom<StringName::AlphCompare>();
+ for (int i = 0; i < names.size(); i++) {
+ PropertyInfo pinfo = instance->instance_shader_parameters[names[i]].info;
+ p_parameters->push_back(pinfo);
+ }
+}
+
+void RendererSceneCull::_update_instance(Instance *p_instance) {
+ p_instance->version++;
+
+ if (p_instance->base_type == RS::INSTANCE_LIGHT) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
+
+ scene_render->light_instance_set_transform(light->instance, p_instance->transform);
+ scene_render->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb));
+ light->shadow_dirty = true;
+
+ RS::LightBakeMode bake_mode = RSG::storage->light_get_bake_mode(p_instance->base);
+ if (RSG::storage->light_get_type(p_instance->base) != RS::LIGHT_DIRECTIONAL && bake_mode != light->bake_mode) {
+ if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ p_instance->scenario->dynamic_lights.erase(light->instance);
+ }
+
+ light->bake_mode = bake_mode;
+
+ if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ p_instance->scenario->dynamic_lights.push_back(light->instance);
+ }
+ }
+
+ uint32_t max_sdfgi_cascade = RSG::storage->light_get_max_sdfgi_cascade(p_instance->base);
+ if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
+ light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
+ }
+ } else if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
+
+ scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform);
+
+ if (p_instance->scenario && p_instance->array_index >= 0) {
+ InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
+ idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY;
+ }
+ } else if (p_instance->base_type == RS::INSTANCE_DECAL) {
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
+
+ scene_render->decal_instance_set_transform(decal->instance, p_instance->transform);
+ } else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
+ InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data);
+
+ scene_render->lightmap_instance_set_transform(lightmap->instance, p_instance->transform);
+ } else if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data);
+
+ scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform);
+ } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
+ RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
+ } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(p_instance->base_data);
+
+ //remove materials no longer used and un-own them
+ if (RSG::storage->particles_collision_is_heightfield(p_instance->base)) {
+ heightfield_particle_colliders_update_list.insert(p_instance);
+ }
+ RSG::storage->particles_collision_instance_set_transform(collision->instance, p_instance->transform);
+ }
+
+ if (p_instance->aabb.has_no_surface()) {
+ return;
+ }
+
+ if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
+ //if this moved, update the captured objects
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
+ //erase dependencies, since no longer a lightmap
+
+ for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
+ Instance *geom = E->get();
+ _instance_queue_update(geom, true, false);
+ }
+ }
+
+ AABB new_aabb;
+ new_aabb = p_instance->transform.xform(p_instance->aabb);
+ p_instance->transformed_aabb = new_aabb;
+
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ //make sure lights are updated if it casts shadow
+
+ if (geom->can_cast_shadows) {
+ for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ light->shadow_dirty = true;
+ }
+ }
+
+ if (!p_instance->lightmap && geom->lightmap_captures.size()) {
+ //affected by lightmap captures, must update capture info!
+ _update_instance_lightmap_captures(p_instance);
+ } else {
+ if (!p_instance->lightmap_sh.is_empty()) {
+ p_instance->lightmap_sh.clear(); //don't need SH
+ p_instance->lightmap_target_sh.clear(); //don't need SH
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, nullptr);
+ }
+ }
+
+ scene_render->geometry_instance_set_transform(geom->geometry_instance, p_instance->transform, p_instance->aabb, p_instance->transformed_aabb);
+ }
+
+ if (p_instance->scenario == nullptr || !p_instance->visible || Math::is_zero_approx(p_instance->transform.basis.determinant())) {
+ p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
+ return;
+ }
+
+ //quantize to improve moving object performance
+ AABB bvh_aabb = p_instance->transformed_aabb;
+
+ if (p_instance->indexer_id.is_valid() && bvh_aabb != p_instance->prev_transformed_aabb) {
+ //assume motion, see if bounds need to be quantized
+ AABB motion_aabb = bvh_aabb.merge(p_instance->prev_transformed_aabb);
+ float motion_longest_axis = motion_aabb.get_longest_axis_size();
+ float longest_axis = p_instance->transformed_aabb.get_longest_axis_size();
+
+ if (motion_longest_axis < longest_axis * 2) {
+ //moved but not a lot, use motion aabb quantizing
+ float quantize_size = Math::pow(2.0, Math::ceil(Math::log(motion_longest_axis) / Math::log(2.0))) * 0.5; //one fifth
+ bvh_aabb.quantize(quantize_size);
+ }
+ }
+
+ if (!p_instance->indexer_id.is_valid()) {
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].insert(bvh_aabb, p_instance);
+ } else {
+ p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].insert(bvh_aabb, p_instance);
+ }
+
+ p_instance->array_index = p_instance->scenario->instance_data.size();
+ InstanceData idata;
+ idata.instance = p_instance;
+ idata.layer_mask = p_instance->layer_mask;
+ idata.flags = p_instance->base_type; //changing it means de-indexing, so this never needs to be changed later
+ idata.base_rid = p_instance->base;
+ switch (p_instance->base_type) {
+ case RS::INSTANCE_MESH:
+ case RS::INSTANCE_MULTIMESH:
+ case RS::INSTANCE_IMMEDIATE:
+ case RS::INSTANCE_PARTICLES: {
+ idata.instance_geometry = static_cast<InstanceGeometryData *>(p_instance->base_data)->geometry_instance;
+ } break;
+ case RS::INSTANCE_LIGHT: {
+ idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_REFLECTION_PROBE: {
+ idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_DECAL: {
+ idata.instance_data_rid = static_cast<InstanceDecalData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_LIGHTMAP: {
+ idata.instance_data_rid = static_cast<InstanceLightmapData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_GI_PROBE: {
+ idata.instance_data_rid = static_cast<InstanceGIProbeData *>(p_instance->base_data)->probe_instance.get_id();
+ } break;
+ default: {
+ }
+ }
+
+ if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
+ //always dirty when added
+ idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY;
+ }
+ if (p_instance->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS;
+ }
+ if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS_ONLY;
+ }
+ if (p_instance->redraw_if_visible) {
+ idata.flags |= InstanceData::FLAG_REDRAW_IF_VISIBLE;
+ }
+ // dirty flags should not be set here, since no pairing has happened
+ if (p_instance->baked_light) {
+ idata.flags |= InstanceData::FLAG_USES_BAKED_LIGHT;
+ }
+ if (p_instance->mesh_instance.is_valid()) {
+ idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
+ }
+
+ p_instance->scenario->instance_data.push_back(idata);
+ p_instance->scenario->instance_aabbs.push_back(InstanceBounds(p_instance->transformed_aabb));
+ } else {
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].update(p_instance->indexer_id, bvh_aabb);
+ } else {
+ p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].update(p_instance->indexer_id, bvh_aabb);
+ }
+ p_instance->scenario->instance_aabbs[p_instance->array_index] = InstanceBounds(p_instance->transformed_aabb);
+ }
+
+ //move instance and repair
+ pair_pass++;
+
+ PairInstances pair;
+
+ pair.instance = p_instance;
+ pair.pair_allocator = &pair_allocator;
+ pair.pair_pass = pair_pass;
+ pair.pair_mask = 0;
+
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ pair.pair_mask |= 1 << RS::INSTANCE_LIGHT;
+ pair.pair_mask |= 1 << RS::INSTANCE_GI_PROBE;
+ pair.pair_mask |= 1 << RS::INSTANCE_LIGHTMAP;
+
+ pair.pair_mask |= geometry_instance_pair_mask;
+
+ pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
+ } else if (p_instance->base_type == RS::INSTANCE_LIGHT) {
+ pair.pair_mask |= RS::INSTANCE_GEOMETRY_MASK;
+ pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
+
+ if (RSG::storage->light_get_bake_mode(p_instance->base) == RS::LIGHT_BAKE_DYNAMIC) {
+ pair.pair_mask |= (1 << RS::INSTANCE_GI_PROBE);
+ pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
+ }
+ } 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];
+ } 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];
+ } else if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
+ //lights and geometries
+ pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK | (1 << RS::INSTANCE_LIGHT);
+ pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
+ pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
+ }
+
+ pair.pair();
+
+ p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
+}
+
+void RendererSceneCull::_unpair_instance(Instance *p_instance) {
+ if (!p_instance->indexer_id.is_valid()) {
+ return; //nothing to do
+ }
+
+ while (p_instance->pairs.first()) {
+ InstancePair *pair = p_instance->pairs.first()->self();
+ Instance *other_instance = p_instance == pair->a ? pair->b : pair->a;
+ _instance_unpair(p_instance, other_instance);
+ pair_allocator.free(pair);
+ }
+
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].remove(p_instance->indexer_id);
+ } else {
+ p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].remove(p_instance->indexer_id);
+ }
+
+ p_instance->indexer_id = DynamicBVH::ID();
+
+ //replace this by last
+ int32_t swap_with_index = p_instance->scenario->instance_data.size() - 1;
+ if (swap_with_index != p_instance->array_index) {
+ p_instance->scenario->instance_data[swap_with_index].instance->array_index = p_instance->array_index; //swap
+ p_instance->scenario->instance_data[p_instance->array_index] = p_instance->scenario->instance_data[swap_with_index];
+ p_instance->scenario->instance_aabbs[p_instance->array_index] = p_instance->scenario->instance_aabbs[swap_with_index];
+ }
+
+ // pop last
+ p_instance->scenario->instance_data.pop_back();
+ p_instance->scenario->instance_aabbs.pop_back();
+
+ //uninitialize
+ p_instance->array_index = -1;
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ // Clear these now because the InstanceData containing the dirty flags is gone
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+
+ scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, nullptr, 0);
+ scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0);
+ scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0);
+ scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, nullptr, 0);
+ }
+}
+
+void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
+ AABB new_aabb;
+
+ ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid());
+
+ switch (p_instance->base_type) {
+ case RenderingServer::INSTANCE_NONE: {
+ // do nothing
+ } break;
+ case RenderingServer::INSTANCE_MESH: {
+ if (p_instance->custom_aabb) {
+ new_aabb = *p_instance->custom_aabb;
+ } else {
+ new_aabb = RSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton);
+ }
+
+ } break;
+
+ case RenderingServer::INSTANCE_MULTIMESH: {
+ if (p_instance->custom_aabb) {
+ new_aabb = *p_instance->custom_aabb;
+ } else {
+ new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base);
+ }
+
+ } break;
+ case RenderingServer::INSTANCE_IMMEDIATE: {
+ if (p_instance->custom_aabb) {
+ new_aabb = *p_instance->custom_aabb;
+ } else {
+ new_aabb = RSG::storage->immediate_get_aabb(p_instance->base);
+ }
+
+ } break;
+ case RenderingServer::INSTANCE_PARTICLES: {
+ if (p_instance->custom_aabb) {
+ new_aabb = *p_instance->custom_aabb;
+ } else {
+ new_aabb = RSG::storage->particles_get_aabb(p_instance->base);
+ }
+
+ } break;
+ case RenderingServer::INSTANCE_PARTICLES_COLLISION: {
+ new_aabb = RSG::storage->particles_collision_get_aabb(p_instance->base);
+
+ } break;
+ case RenderingServer::INSTANCE_LIGHT: {
+ new_aabb = RSG::storage->light_get_aabb(p_instance->base);
+
+ } break;
+ case RenderingServer::INSTANCE_REFLECTION_PROBE: {
+ new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base);
+
+ } break;
+ case RenderingServer::INSTANCE_DECAL: {
+ new_aabb = RSG::storage->decal_get_aabb(p_instance->base);
+
+ } break;
+ case RenderingServer::INSTANCE_GI_PROBE: {
+ new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base);
+
+ } break;
+ case RenderingServer::INSTANCE_LIGHTMAP: {
+ new_aabb = RSG::storage->lightmap_get_aabb(p_instance->base);
+
+ } break;
+ default: {
+ }
+ }
+
+ // <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs
+ if (p_instance->extra_margin) {
+ new_aabb.grow_by(p_instance->extra_margin);
+ }
+
+ p_instance->aabb = new_aabb;
+}
+
+void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) {
+ bool first_set = p_instance->lightmap_sh.size() == 0;
+ p_instance->lightmap_sh.resize(9); //using SH
+ p_instance->lightmap_target_sh.resize(9); //using SH
+ Color *instance_sh = p_instance->lightmap_target_sh.ptrw();
+ bool inside = false;
+ Color accum_sh[9];
+ float accum_blend = 0.0;
+
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ for (Set<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) {
+ Instance *lightmap = E->get();
+
+ bool interior = RSG::storage->lightmap_is_interior(lightmap->base);
+
+ if (inside && !interior) {
+ continue; //we are inside, ignore exteriors
+ }
+
+ Transform to_bounds = lightmap->transform.affine_inverse();
+ Vector3 center = p_instance->transform.xform(p_instance->aabb.position + p_instance->aabb.size * 0.5); //use aabb center
+
+ Vector3 lm_pos = to_bounds.xform(center);
+
+ AABB bounds = RSG::storage->lightmap_get_aabb(lightmap->base);
+ if (!bounds.has_point(lm_pos)) {
+ continue; //not in this lightmap
+ }
+
+ Color sh[9];
+ RSG::storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh);
+
+ //rotate it
+ Basis rot = lightmap->transform.basis.orthonormalized();
+ for (int i = 0; i < 3; i++) {
+ float csh[9];
+ for (int j = 0; j < 9; j++) {
+ csh[j] = sh[j][i];
+ }
+ rot.rotate_sh(csh);
+ for (int j = 0; j < 9; j++) {
+ sh[j][i] = csh[j];
+ }
+ }
+
+ Vector3 inner_pos = ((lm_pos - bounds.position) / bounds.size) * 2.0 - Vector3(1.0, 1.0, 1.0);
+
+ float blend = MAX(inner_pos.x, MAX(inner_pos.y, inner_pos.z));
+ //make blend more rounded
+ blend = Math::lerp(inner_pos.length(), blend, blend);
+ blend *= blend;
+ blend = MAX(0.0, 1.0 - blend);
+
+ if (interior && !inside) {
+ //do not blend, just replace
+ for (int j = 0; j < 9; j++) {
+ accum_sh[j] = sh[j] * blend;
+ }
+ accum_blend = blend;
+ inside = true;
+ } else {
+ for (int j = 0; j < 9; j++) {
+ accum_sh[j] += sh[j] * blend;
+ }
+ accum_blend += blend;
+ }
+ }
+
+ if (accum_blend > 0.0) {
+ for (int j = 0; j < 9; j++) {
+ instance_sh[j] = accum_sh[j] / accum_blend;
+ if (first_set) {
+ p_instance->lightmap_sh.write[j] = instance_sh[j];
+ }
+ }
+ }
+
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr());
+}
+
+void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
+
+ Transform light_transform = p_instance->transform;
+ light_transform.orthonormalize(); //scale does not count on lights
+
+ real_t max_distance = p_cam_projection.get_z_far();
+ real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
+ if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
+ max_distance = MIN(shadow_max, max_distance);
+ }
+ max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001);
+ real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
+
+ RS::LightDirectionalShadowDepthRangeMode depth_range_mode = RSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base);
+
+ real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
+
+ real_t range = max_distance - min_distance;
+
+ int splits = 0;
+ switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) {
+ case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
+ splits = 1;
+ break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
+ splits = 2;
+ break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
+ splits = 4;
+ break;
+ }
+
+ real_t distances[5];
+
+ distances[0] = min_distance;
+ for (int i = 0; i < splits; i++) {
+ distances[i + 1] = min_distance + RSG::storage->light_get_param(p_instance->base, RS::LightParam(RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range;
+ };
+
+ distances[splits] = max_distance;
+
+ real_t texture_size = scene_render->get_directional_light_shadow_size(light->instance);
+
+ bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base);
+
+ real_t first_radius = 0.0;
+
+ real_t min_distance_bias_scale = distances[1];
+
+ cull.shadow_count = p_shadow_index + 1;
+ cull.shadows[p_shadow_index].cascade_count = splits;
+ cull.shadows[p_shadow_index].light_instance = light->instance;
+
+ for (int i = 0; i < splits; i++) {
+ RENDER_TIMESTAMP("Culling Directional Light split" + itos(i));
+
+ // setup a camera matrix for that range!
+ CameraMatrix camera_matrix;
+
+ real_t aspect = p_cam_projection.get_aspect();
+
+ if (p_cam_orthogonal) {
+ Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
+
+ camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
+ } else {
+ real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it
+ camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ }
+
+ //obtain the frustum endpoints
+
+ Vector3 endpoints[8]; // frustum plane endpoints
+ bool res = camera_matrix.get_endpoints(p_cam_transform, endpoints);
+ ERR_CONTINUE(!res);
+
+ // obtain the light frustum ranges (given endpoints)
+
+ Transform transform = light_transform; //discard scale and stabilize light
+
+ Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized();
+ Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized();
+ Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
+ //z_vec points against the camera, like in default opengl
+
+ real_t x_min = 0.f, x_max = 0.f;
+ real_t y_min = 0.f, y_max = 0.f;
+ real_t z_min = 0.f, z_max = 0.f;
+
+ // FIXME: z_max_cam is defined, computed, but not used below when setting up
+ // ortho_camera. Commented out for now to fix warnings but should be investigated.
+ real_t x_min_cam = 0.f, x_max_cam = 0.f;
+ real_t y_min_cam = 0.f, y_max_cam = 0.f;
+ real_t z_min_cam = 0.f;
+ //real_t z_max_cam = 0.f;
+
+ real_t bias_scale = 1.0;
+ real_t aspect_bias_scale = 1.0;
+
+ //used for culling
+
+ for (int j = 0; j < 8; j++) {
+ real_t d_x = x_vec.dot(endpoints[j]);
+ real_t d_y = y_vec.dot(endpoints[j]);
+ real_t d_z = z_vec.dot(endpoints[j]);
+
+ if (j == 0 || d_x < x_min) {
+ x_min = d_x;
+ }
+ if (j == 0 || d_x > x_max) {
+ x_max = d_x;
+ }
+
+ if (j == 0 || d_y < y_min) {
+ y_min = d_y;
+ }
+ if (j == 0 || d_y > y_max) {
+ y_max = d_y;
+ }
+
+ if (j == 0 || d_z < z_min) {
+ z_min = d_z;
+ }
+ if (j == 0 || d_z > z_max) {
+ z_max = d_z;
+ }
+ }
+
+ real_t radius = 0;
+ real_t soft_shadow_expand = 0;
+ Vector3 center;
+
+ {
+ //camera viewport stuff
+
+ for (int j = 0; j < 8; j++) {
+ center += endpoints[j];
+ }
+ center /= 8.0;
+
+ //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5;
+
+ for (int j = 0; j < 8; j++) {
+ real_t d = center.distance_to(endpoints[j]);
+ if (d > radius) {
+ radius = d;
+ }
+ }
+
+ radius *= texture_size / (texture_size - 2.0); //add a texel by each side
+
+ if (i == 0) {
+ first_radius = radius;
+ } else {
+ bias_scale = radius / first_radius;
+ }
+
+ z_min_cam = z_vec.dot(center) - radius;
+
+ {
+ float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
+
+ if (soft_shadow_angle > 0.0) {
+ float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
+ soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range;
+
+ x_max += soft_shadow_expand;
+ y_max += soft_shadow_expand;
+
+ x_min -= soft_shadow_expand;
+ y_min -= soft_shadow_expand;
+ }
+ }
+
+ x_max_cam = x_vec.dot(center) + radius + soft_shadow_expand;
+ x_min_cam = x_vec.dot(center) - radius - soft_shadow_expand;
+ y_max_cam = y_vec.dot(center) + radius + soft_shadow_expand;
+ y_min_cam = y_vec.dot(center) - radius - soft_shadow_expand;
+
+ if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
+ //this trick here is what stabilizes the shadow (make potential jaggies to not move)
+ //at the cost of some wasted resolution. Still the quality increase is very well worth it
+
+ real_t unit = radius * 2.0 / texture_size;
+
+ x_max_cam = Math::snapped(x_max_cam, unit);
+ x_min_cam = Math::snapped(x_min_cam, unit);
+ y_max_cam = Math::snapped(y_max_cam, unit);
+ y_min_cam = Math::snapped(y_min_cam, unit);
+ }
+ }
+
+ //now that we know all ranges, we can proceed to make the light frustum planes, for culling octree
+
+ Vector<Plane> light_frustum_planes;
+ light_frustum_planes.resize(6);
+
+ //right/left
+ light_frustum_planes.write[0] = Plane(x_vec, x_max);
+ light_frustum_planes.write[1] = Plane(-x_vec, -x_min);
+ //top/bottom
+ light_frustum_planes.write[2] = Plane(y_vec, y_max);
+ light_frustum_planes.write[3] = Plane(-y_vec, -y_min);
+ //near/far
+ light_frustum_planes.write[4] = Plane(z_vec, z_max + 1e6);
+ light_frustum_planes.write[5] = Plane(-z_vec, -z_min); // z_min is ok, since casters further than far-light plane are not needed
+
+ // a pre pass will need to be needed to determine the actual z-near to be used
+
+ if (pancake_size > 0) {
+ z_max = z_vec.dot(center) + radius + pancake_size;
+ }
+
+ if (aspect != 1.0) {
+ // if the aspect is different, then the radius will become larger.
+ // if this happens, then bias needs to be adjusted too, as depth will increase
+ // to do this, compare the depth of one that would have resulted from a square frustum
+
+ CameraMatrix camera_matrix_square;
+ if (p_cam_orthogonal) {
+ Vector2 vp_he = camera_matrix.get_viewport_half_extents();
+ if (p_cam_vaspect) {
+ camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ } else {
+ camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
+ }
+ } else {
+ Vector2 vp_he = camera_matrix.get_viewport_half_extents();
+ if (p_cam_vaspect) {
+ camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ } else {
+ camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
+ }
+ }
+
+ Vector3 endpoints_square[8]; // frustum plane endpoints
+ res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square);
+ ERR_CONTINUE(!res);
+ Vector3 center_square;
+
+ for (int j = 0; j < 8; j++) {
+ center_square += endpoints_square[j];
+ }
+
+ center_square /= 8.0;
+
+ real_t radius_square = 0;
+
+ for (int j = 0; j < 8; j++) {
+ real_t d = center_square.distance_to(endpoints_square[j]);
+ if (d > radius_square) {
+ radius_square = d;
+ }
+ }
+
+ radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side
+
+ float z_max_square = z_vec.dot(center_square) + radius_square + pancake_size;
+
+ real_t z_min_cam_square = z_vec.dot(center_square) - radius_square;
+
+ aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square);
+
+ // this is not entirely perfect, because the cull-adjusted z-max may be different
+ // but at least it's warranted that it results in a greater bias, so no acne should be present either way.
+ // pancaking also helps with this.
+ }
+
+ {
+ CameraMatrix ortho_camera;
+ real_t half_x = (x_max_cam - x_min_cam) * 0.5;
+ real_t half_y = (y_max_cam - y_min_cam) * 0.5;
+
+ ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
+
+ Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam));
+
+ Transform ortho_transform;
+ ortho_transform.basis = transform.basis;
+ ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
+
+ cull.shadows[p_shadow_index].cascades[i].frustum = Frustum(light_frustum_planes);
+ cull.shadows[p_shadow_index].cascades[i].projection = ortho_camera;
+ cull.shadows[p_shadow_index].cascades[i].transform = ortho_transform;
+ cull.shadows[p_shadow_index].cascades[i].zfar = z_max - z_min_cam;
+ cull.shadows[p_shadow_index].cascades[i].split = distances[i + 1];
+ cull.shadows[p_shadow_index].cascades[i].shadow_texel_size = radius * 2.0 / texture_size;
+ cull.shadows[p_shadow_index].cascades[i].bias_scale = bias_scale * aspect_bias_scale * min_distance_bias_scale;
+ cull.shadows[p_shadow_index].cascades[i].range_begin = z_max;
+ cull.shadows[p_shadow_index].cascades[i].uv_scale = uv_scale;
+ }
+ }
+}
+
+bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_lod_threshold) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
+
+ Transform light_transform = p_instance->transform;
+ light_transform.orthonormalize(); //scale does not count on lights
+
+ bool animated_material_found = false;
+
+ switch (RSG::storage->light_get_type(p_instance->base)) {
+ case RS::LIGHT_DIRECTIONAL: {
+ } break;
+ case RS::LIGHT_OMNI: {
+ RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base);
+
+ if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !scene_render->light_instances_can_render_shadow_cube()) {
+ for (int i = 0; i < 2; i++) {
+ //using this one ensures that raster deferred will have it
+ RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i));
+
+ real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+
+ real_t z = i == 0 ? -1 : 1;
+ Vector<Plane> planes;
+ planes.resize(6);
+ planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
+ planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
+ planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
+ planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
+ planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
+ planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0));
+
+ geometry_instances_to_shadow_render.clear();
+ instance_shadow_cull_result.clear();
+
+ Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
+
+ struct CullConvex {
+ PagedArray<Instance *> *result;
+ _FORCE_INLINE_ bool operator()(void *p_data) {
+ Instance *p_instance = (Instance *)p_data;
+ result->push_back(p_instance);
+ return false;
+ }
+ };
+
+ CullConvex cull_convex;
+ cull_convex.result = &instance_shadow_cull_result;
+
+ p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
+
+ Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
+
+ 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) {
+ continue;
+ } else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
+ }
+ }
+
+ geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
+ }
+
+ RSG::storage->update_mesh_instances();
+
+ scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0);
+ scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render);
+ }
+ } else { //shadow cube
+
+ real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+ CameraMatrix cm;
+ cm.set_perspective(90, 1, 0.01, radius);
+
+ for (int i = 0; i < 6; i++) {
+ RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i));
+ //using this one ensures that raster deferred will have it
+
+ static const Vector3 view_normals[6] = {
+ Vector3(+1, 0, 0),
+ Vector3(-1, 0, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, +1, 0),
+ Vector3(0, 0, +1),
+ Vector3(0, 0, -1)
+ };
+ static const Vector3 view_up[6] = {
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, -1),
+ Vector3(0, 0, +1),
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0)
+ };
+
+ Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]);
+
+ Vector<Plane> planes = cm.get_projection_planes(xform);
+
+ geometry_instances_to_shadow_render.clear();
+ instance_shadow_cull_result.clear();
+
+ Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
+
+ struct CullConvex {
+ PagedArray<Instance *> *result;
+ _FORCE_INLINE_ bool operator()(void *p_data) {
+ Instance *p_instance = (Instance *)p_data;
+ result->push_back(p_instance);
+ return false;
+ }
+ };
+
+ CullConvex cull_convex;
+ cull_convex.result = &instance_shadow_cull_result;
+
+ p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
+
+ Plane near_plane(xform.origin, -xform.basis.get_axis(2));
+
+ 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) {
+ continue;
+ } else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
+ }
+ }
+
+ geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
+ }
+
+ RSG::storage->update_mesh_instances();
+ scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
+ scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render);
+ }
+
+ //restore the regular DP matrix
+ scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0);
+ }
+
+ } break;
+ case RS::LIGHT_SPOT: {
+ RENDER_TIMESTAMP("Culling Spot Light");
+
+ real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
+ real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+
+ CameraMatrix cm;
+ cm.set_perspective(angle * 2.0, 1.0, 0.01, radius);
+
+ Vector<Plane> planes = cm.get_projection_planes(light_transform);
+
+ geometry_instances_to_shadow_render.clear();
+ instance_shadow_cull_result.clear();
+
+ Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
+
+ struct CullConvex {
+ PagedArray<Instance *> *result;
+ _FORCE_INLINE_ bool operator()(void *p_data) {
+ Instance *p_instance = (Instance *)p_data;
+ result->push_back(p_instance);
+ return false;
+ }
+ };
+
+ CullConvex cull_convex;
+ cull_convex.result = &instance_shadow_cull_result;
+
+ p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
+
+ Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
+
+ 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) {
+ continue;
+ } else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
+ if (instance->mesh_instance.is_valid()) {
+ RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
+ }
+ }
+ geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
+ }
+
+ RSG::storage->update_mesh_instances();
+
+ scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
+ scene_render->render_shadow(light->instance, p_shadow_atlas, 0, geometry_instances_to_shadow_render);
+
+ } break;
+ }
+
+ return animated_material_found;
+}
+
+void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) {
+// render to mono camera
+#ifndef _3D_DISABLED
+
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+
+ /* STEP 1 - SETUP CAMERA */
+ CameraMatrix camera_matrix;
+ bool ortho = false;
+
+ switch (camera->type) {
+ case Camera::ORTHOGONAL: {
+ camera_matrix.set_orthogonal(
+ camera->size,
+ p_viewport_size.width / (float)p_viewport_size.height,
+ camera->znear,
+ camera->zfar,
+ camera->vaspect);
+ ortho = true;
+ } break;
+ case Camera::PERSPECTIVE: {
+ camera_matrix.set_perspective(
+ camera->fov,
+ p_viewport_size.width / (float)p_viewport_size.height,
+ camera->znear,
+ camera->zfar,
+ camera->vaspect);
+ ortho = false;
+
+ } break;
+ case Camera::FRUSTUM: {
+ camera_matrix.set_frustum(
+ camera->size,
+ p_viewport_size.width / (float)p_viewport_size.height,
+ camera->offset,
+ camera->znear,
+ camera->zfar,
+ camera->vaspect);
+ ortho = false;
+ } break;
+ }
+
+ RID environment = _render_get_environment(p_camera, p_scenario);
+
+ _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), p_screen_lod_threshold);
+ _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold);
+#endif
+}
+
+void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) {
+ // render for AR/VR interface
+
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+
+ /* SETUP CAMERA, we are ignoring type and FOV here */
+ float aspect = p_viewport_size.width / (float)p_viewport_size.height;
+ CameraMatrix camera_matrix = p_interface->get_projection_for_eye(p_eye, aspect, camera->znear, camera->zfar);
+
+ // We also ignore our camera position, it will have been positioned with a slightly old tracking position.
+ // Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo!
+ Transform world_origin = XRServer::get_singleton()->get_world_origin();
+ Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin);
+
+ RID environment = _render_get_environment(p_camera, p_scenario);
+
+ // For stereo render we only prepare for our left eye and then reuse the outcome for our right eye
+ if (p_eye == XRInterface::EYE_LEFT) {
+ // Center our transform, we assume basis is equal.
+ Transform mono_transform = cam_transform;
+ Transform right_transform = p_interface->get_transform_for_eye(XRInterface::EYE_RIGHT, world_origin);
+ mono_transform.origin += right_transform.origin;
+ mono_transform.origin *= 0.5;
+
+ // We need to combine our projection frustums for culling.
+ // Ideally we should use our clipping planes for this and combine them,
+ // however our shadow map logic uses our projection matrix.
+ // Note: as our left and right frustums should be mirrored, we don't need our right projection matrix.
+
+ // - get some base values we need
+ float eye_dist = (mono_transform.origin - cam_transform.origin).length();
+ float z_near = camera_matrix.get_z_near(); // get our near plane
+ float z_far = camera_matrix.get_z_far(); // get our far plane
+ float width = (2.0 * z_near) / camera_matrix.matrix[0][0];
+ float x_shift = width * camera_matrix.matrix[2][0];
+ float height = (2.0 * z_near) / camera_matrix.matrix[1][1];
+ float y_shift = height * camera_matrix.matrix[2][1];
+
+ // printf("Eye_dist = %f, Near = %f, Far = %f, Width = %f, Shift = %f\n", eye_dist, z_near, z_far, width, x_shift);
+
+ // - calculate our near plane size (horizontal only, right_near is mirrored)
+ float left_near = -eye_dist - ((width - x_shift) * 0.5);
+
+ // - calculate our far plane size (horizontal only, right_far is mirrored)
+ float left_far = -eye_dist - (z_far * (width - x_shift) * 0.5 / z_near);
+ float left_far_right_eye = eye_dist - (z_far * (width + x_shift) * 0.5 / z_near);
+ if (left_far > left_far_right_eye) {
+ // on displays smaller then double our iod, the right eye far frustrum can overtake the left eyes.
+ left_far = left_far_right_eye;
+ }
+
+ // - figure out required z-shift
+ float slope = (left_far - left_near) / (z_far - z_near);
+ float z_shift = (left_near / slope) - z_near;
+
+ // - figure out new vertical near plane size (this will be slightly oversized thanks to our z-shift)
+ float top_near = (height - y_shift) * 0.5;
+ top_near += (top_near / z_near) * z_shift;
+ float bottom_near = -(height + y_shift) * 0.5;
+ bottom_near += (bottom_near / z_near) * z_shift;
+
+ // printf("Left_near = %f, Left_far = %f, Top_near = %f, Bottom_near = %f, Z_shift = %f\n", left_near, left_far, top_near, bottom_near, z_shift);
+
+ // - generate our frustum
+ CameraMatrix combined_matrix;
+ combined_matrix.set_frustum(left_near, -left_near, bottom_near, top_near, z_near + z_shift, z_far + z_shift);
+
+ // and finally move our camera back
+ Transform apply_z_shift;
+ apply_z_shift.origin = Vector3(0.0, 0.0, z_shift); // z negative is forward so this moves it backwards
+ mono_transform *= apply_z_shift;
+
+ // now prepare our scene with our adjusted transform projection matrix
+ _prepare_scene(mono_transform, combined_matrix, false, false, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), p_screen_lod_threshold);
+ } else if (p_eye == XRInterface::EYE_MONO) {
+ // For mono render, prepare as per usual
+ _prepare_scene(cam_transform, camera_matrix, false, false, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), p_screen_lod_threshold);
+ }
+
+ // And render our scene...
+ _render_scene(p_render_buffers, cam_transform, camera_matrix, false, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold);
+};
+
+void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data) {
+ uint32_t cull_total = cull_data->scenario->instance_data.size();
+ uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
+ uint32_t cull_from = p_thread * cull_total / total_threads;
+ uint32_t cull_to = (p_thread + 1 == total_threads) ? cull_total : ((p_thread + 1) * cull_total / total_threads);
+
+ _frustum_cull(*cull_data, frustum_cull_result_threads[p_thread], cull_from, cull_to);
+}
+
+void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to) {
+ uint64_t frame_number = RSG::rasterizer->get_frame_number();
+ float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
+
+ uint32_t sdfgi_last_light_index = 0xFFFFFFFF;
+ uint32_t sdfgi_last_light_cascade = 0xFFFFFFFF;
+
+ RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
+
+ for (uint64_t i = p_from; i < p_to; i++) {
+ bool mesh_visible = false;
+
+ if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->frustum)) {
+ InstanceData &idata = cull_data.scenario->instance_data[i];
+ uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
+
+ if ((cull_data.visible_layers & idata.layer_mask) == 0) {
+ //failure
+ } else if (base_type == RS::INSTANCE_LIGHT) {
+ cull_result.lights.push_back(idata.instance);
+ cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid));
+ if (cull_data.shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) {
+ scene_render->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later
+ }
+
+ } else if (base_type == RS::INSTANCE_REFLECTION_PROBE) {
+ if (cull_data.render_reflection_probe != idata.instance) {
+ //avoid entering The Matrix
+
+ if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data);
+ cull_data.cull->lock.lock();
+ if (!reflection_probe->update_list.in_list()) {
+ reflection_probe->render_step = 0;
+ reflection_probe_render_list.add_last(&reflection_probe->update_list);
+ }
+ cull_data.cull->lock.unlock();
+
+ idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY);
+ }
+
+ if (scene_render->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) {
+ cull_result.reflections.push_back(RID::from_uint64(idata.instance_data_rid));
+ }
+ }
+ } else if (base_type == RS::INSTANCE_DECAL) {
+ cull_result.decals.push_back(RID::from_uint64(idata.instance_data_rid));
+
+ } else if (base_type == RS::INSTANCE_GI_PROBE) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(idata.instance->base_data);
+ cull_data.cull->lock.lock();
+ if (!gi_probe->update_element.in_list()) {
+ gi_probe_update_list.add(&gi_probe->update_element);
+ }
+ cull_data.cull->lock.unlock();
+ cull_result.gi_probes.push_back(RID::from_uint64(idata.instance_data_rid));
+
+ } else if (base_type == RS::INSTANCE_LIGHTMAP) {
+ cull_result.gi_probes.push_back(RID::from_uint64(idata.instance_data_rid));
+ } else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) {
+ bool keep = true;
+
+ if (idata.flags & InstanceData::FLAG_REDRAW_IF_VISIBLE) {
+ RenderingServerDefault::redraw_request();
+ }
+
+ if (base_type == RS::INSTANCE_MESH) {
+ mesh_visible = true;
+ } else if (base_type == RS::INSTANCE_PARTICLES) {
+ //particles visible? process them
+ if (RSG::storage->particles_is_inactive(idata.base_rid)) {
+ //but if nothing is going on, don't do it.
+ keep = false;
+ } else {
+ cull_data.cull->lock.lock();
+ RSG::storage->particles_request_process(idata.base_rid);
+ cull_data.cull->lock.unlock();
+ RSG::storage->particles_set_view_axis(idata.base_rid, -cull_data.cam_transform.basis.get_axis(2).normalized());
+ //particles visible? request redraw
+ RenderingServerDefault::redraw_request();
+ }
+ }
+
+ if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ uint32_t idx = 0;
+
+ for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ instance_pair_buffer[idx++] = light->instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }
+
+ scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx);
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY);
+ }
+
+ if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ uint32_t idx = 0;
+
+ for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
+
+ instance_pair_buffer[idx++] = reflection_probe->instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }
+
+ scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY);
+ }
+
+ if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) {
+ //InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ //todo for GLES3
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY);
+ /*for (Set<Instance *>::Element *E = geom->dec.front(); E; E = E->next()) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
+
+ instance_pair_buffer[idx++] = reflection_probe->instance;
+ if (idx==MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }*/
+ //scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, light_instances, idx);
+ }
+
+ if (idata.flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ uint32_t idx = 0;
+ for (Set<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data);
+
+ instance_pair_buffer[idx++] = gi_probe->probe_instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }
+
+ scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY);
+ }
+
+ if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ Color *sh = idata.instance->lightmap_sh.ptrw();
+ const Color *target_sh = idata.instance->lightmap_target_sh.ptr();
+ for (uint32_t j = 0; j < 9; j++) {
+ sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
+ }
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh);
+ idata.instance->last_frame_pass = frame_number;
+ }
+
+ if (keep) {
+ cull_result.geometry_instances.push_back(idata.instance_geometry);
+ }
+ }
+ }
+
+ for (uint32_t j = 0; j < cull_data.cull->shadow_count; j++) {
+ for (uint32_t k = 0; k < cull_data.cull->shadows[j].cascade_count; k++) {
+ if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->shadows[j].cascades[k].frustum)) {
+ InstanceData &idata = cull_data.scenario->instance_data[i];
+ 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) {
+ cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry);
+ mesh_visible = true;
+ }
+ }
+ }
+ }
+
+ for (uint32_t j = 0; j < cull_data.cull->sdfgi.region_count; j++) {
+ if (cull_data.scenario->instance_aabbs[i].in_aabb(cull_data.cull->sdfgi.region_aabb[j])) {
+ InstanceData &idata = cull_data.scenario->instance_data[i];
+ uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
+
+ if (base_type == RS::INSTANCE_LIGHT) {
+ InstanceLightData *instance_light = (InstanceLightData *)idata.instance->base_data;
+ if (instance_light->bake_mode == RS::LIGHT_BAKE_STATIC && cull_data.cull->sdfgi.region_cascade[j] <= instance_light->max_sdfgi_cascade) {
+ if (sdfgi_last_light_index != i || sdfgi_last_light_cascade != cull_data.cull->sdfgi.region_cascade[j]) {
+ sdfgi_last_light_index = i;
+ sdfgi_last_light_cascade = cull_data.cull->sdfgi.region_cascade[j];
+ cull_result.sdfgi_cascade_lights[sdfgi_last_light_cascade].push_back(instance_light->instance);
+ }
+ }
+ } else if ((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ if (idata.flags & InstanceData::FLAG_USES_BAKED_LIGHT) {
+ cull_result.sdfgi_region_geometry_instances[j].push_back(idata.instance_geometry);
+ mesh_visible = true;
+ }
+ }
+ }
+ }
+
+ if (mesh_visible && cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_USES_MESH_INSTANCE) {
+ cull_result.mesh_instances.push_back(cull_data.scenario->instance_data[i].instance->mesh_instance);
+ }
+ }
+}
+
+void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows) {
+ // Note, in stereo rendering:
+ // - p_cam_transform will be a transform in the middle of our two eyes
+ // - p_cam_projection is a wider frustrum that encompasses both eyes
+
+ Instance *render_reflection_probe = instance_owner.getornull(p_reflection_probe); //if null, not rendering to it
+
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+
+ render_pass++;
+
+ scene_render->set_scene_pass(render_pass);
+
+ if (p_render_buffers.is_valid()) {
+ scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not)
+ }
+
+ RENDER_TIMESTAMP("Frustum Culling");
+
+ //rasterizer->set_camera(camera->transform, camera_matrix,ortho);
+
+ Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
+
+ Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2).normalized());
+
+ /* STEP 2 - CULL */
+
+ cull.frustum = Frustum(planes);
+
+ Vector<RID> directional_lights;
+ // directional lights
+ {
+ cull.shadow_count = 0;
+
+ Vector<Instance *> lights_with_shadow;
+
+ for (List<Instance *>::Element *E = scenario->directional_lights.front(); E; E = E->next()) {
+ if (!E->get()->visible) {
+ continue;
+ }
+
+ if (directional_lights.size() > RendererSceneRender::MAX_DIRECTIONAL_LIGHTS) {
+ break;
+ }
+
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+
+ //check shadow..
+
+ if (light) {
+ if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base) && !(RSG::storage->light_get_type(E->get()->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_is_sky_only(E->get()->base))) {
+ lights_with_shadow.push_back(E->get());
+ }
+ //add to list
+ directional_lights.push_back(light->instance);
+ }
+ }
+
+ scene_render->set_directional_shadow_count(lights_with_shadow.size());
+
+ for (int i = 0; i < lights_with_shadow.size(); i++) {
+ _light_instance_setup_directional_shadow(i, lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect);
+ }
+ }
+
+ { //sdfgi
+ cull.sdfgi.region_count = 0;
+
+ if (p_render_buffers.is_valid()) {
+ cull.sdfgi.cascade_light_count = 0;
+
+ uint32_t prev_cascade = 0xFFFFFFFF;
+ uint32_t pending_region_count = scene_render->sdfgi_get_pending_region_count(p_render_buffers);
+
+ for (uint32_t i = 0; i < pending_region_count; i++) {
+ cull.sdfgi.region_aabb[i] = scene_render->sdfgi_get_pending_region_bounds(p_render_buffers, i);
+ uint32_t region_cascade = scene_render->sdfgi_get_pending_region_cascade(p_render_buffers, i);
+ cull.sdfgi.region_cascade[i] = region_cascade;
+
+ if (region_cascade != prev_cascade) {
+ cull.sdfgi.cascade_light_index[cull.sdfgi.cascade_light_count] = region_cascade;
+ cull.sdfgi.cascade_light_count++;
+ prev_cascade = region_cascade;
+ }
+ }
+
+ cull.sdfgi.region_count = pending_region_count;
+ }
+ }
+
+ frustum_cull_result.clear();
+
+ {
+ uint64_t cull_from = 0;
+ uint64_t cull_to = scenario->instance_data.size();
+
+ FrustumCullData cull_data;
+
+ //prepare for eventual thread usage
+ cull_data.cull = &cull;
+ cull_data.scenario = scenario;
+ cull_data.shadow_atlas = p_shadow_atlas;
+ cull_data.cam_transform = p_cam_transform;
+ cull_data.visible_layers = p_visible_layers;
+ cull_data.render_reflection_probe = render_reflection_probe;
+//#define DEBUG_CULL_TIME
+#ifdef DEBUG_CULL_TIME
+ uint64_t time_from = OS::get_singleton()->get_ticks_usec();
+#endif
+ if (cull_to > thread_cull_threshold) {
+ //multiple threads
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result_threads[i].clear();
+ }
+
+ RendererThreadPool::singleton->thread_work_pool.do_work(frustum_cull_result_threads.size(), this, &RendererSceneCull::_frustum_cull_threaded, &cull_data);
+
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result.append_from(frustum_cull_result_threads[i]);
+ }
+
+ } else {
+ //single threaded
+ _frustum_cull(cull_data, frustum_cull_result, cull_from, cull_to);
+ }
+
+#ifdef DEBUG_CULL_TIME
+ static float time_avg = 0;
+ static uint32_t time_count = 0;
+ time_avg += double(OS::get_singleton()->get_ticks_usec() - time_from) / 1000.0;
+ time_count++;
+ print_line("time taken: " + rtos(time_avg / time_count));
+#endif
+
+ if (frustum_cull_result.mesh_instances.size()) {
+ for (uint64_t i = 0; i < frustum_cull_result.mesh_instances.size(); i++) {
+ RSG::storage->mesh_instance_check_for_update(frustum_cull_result.mesh_instances[i]);
+ }
+ RSG::storage->update_mesh_instances();
+ }
+ }
+
+ //render shadows
+
+ for (uint32_t i = 0; i < cull.shadow_count; i++) {
+ for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) {
+ const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j];
+ // print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size()));
+ scene_render->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale);
+ scene_render->render_shadow(cull.shadows[i].light_instance, p_shadow_atlas, j, frustum_cull_result.directional_shadows[i].cascade_geometry_instances[j], near_plane, p_cam_projection.get_lod_multiplier(), p_screen_lod_threshold);
+ }
+ }
+
+ //render SDFGI
+
+ {
+ if (cull.sdfgi.region_count > 0) {
+ //update regions
+ for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) {
+ scene_render->render_sdfgi(p_render_buffers, i, frustum_cull_result.sdfgi_region_geometry_instances[i]);
+ }
+ //check if static lights were culled
+ bool static_lights_culled = false;
+ for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) {
+ if (frustum_cull_result.sdfgi_cascade_lights[i].size()) {
+ static_lights_culled = true;
+ break;
+ }
+ }
+
+ if (static_lights_culled) {
+ scene_render->render_sdfgi_static_lights(p_render_buffers, cull.sdfgi.cascade_light_count, cull.sdfgi.cascade_light_index, frustum_cull_result.sdfgi_cascade_lights);
+ }
+ }
+
+ if (p_render_buffers.is_valid()) {
+ scene_render->sdfgi_update_probes(p_render_buffers, p_environment, directional_lights, scenario->dynamic_lights.ptr(), scenario->dynamic_lights.size());
+ }
+ }
+
+ //light_samplers_culled=0;
+
+ /*
+ print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0));
+ print_line("OTO: "+itos(p_scenario->octree.get_octant_count()));
+ print_line("OTE: "+itos(p_scenario->octree.get_elem_count()));
+ print_line("OTP: "+itos(p_scenario->octree.get_pair_count()));
+ */
+
+ /* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */
+ //removed, will replace with culling
+
+ /* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */
+
+ /* STEP 5 - PROCESS POSITIONAL LIGHTS */
+
+ if (p_using_shadows) { //setup shadow maps
+
+ //SortArray<Instance*,_InstanceLightsort> sorter;
+ //sorter.sort(light_cull_result,light_cull_count);
+ for (uint32_t i = 0; i < (uint32_t)frustum_cull_result.lights.size(); i++) {
+ Instance *ins = frustum_cull_result.lights[i];
+
+ if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) {
+ continue;
+ }
+
+ InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
+
+ float coverage = 0.f;
+
+ { //compute coverage
+
+ Transform cam_xf = p_cam_transform;
+ float zn = p_cam_projection.get_z_near();
+ Plane p(cam_xf.origin + cam_xf.basis.get_axis(2) * -zn, -cam_xf.basis.get_axis(2)); //camera near plane
+
+ // near plane half width and height
+ Vector2 vp_half_extents = p_cam_projection.get_viewport_half_extents();
+
+ switch (RSG::storage->light_get_type(ins->base)) {
+ case RS::LIGHT_OMNI: {
+ float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
+
+ //get two points parallel to near plane
+ Vector3 points[2] = {
+ ins->transform.origin,
+ ins->transform.origin + cam_xf.basis.get_axis(0) * radius
+ };
+
+ if (!p_cam_orthogonal) {
+ //if using perspetive, map them to near plane
+ for (int j = 0; j < 2; j++) {
+ if (p.distance_to(points[j]) < 0) {
+ points[j].z = -zn; //small hack to keep size constant when hitting the screen
+ }
+
+ p.intersects_segment(cam_xf.origin, points[j], &points[j]); //map to plane
+ }
+ }
+
+ float screen_diameter = points[0].distance_to(points[1]) * 2;
+ coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
+ } break;
+ case RS::LIGHT_SPOT: {
+ float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
+ float angle = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+
+ float w = radius * Math::sin(Math::deg2rad(angle));
+ float d = radius * Math::cos(Math::deg2rad(angle));
+
+ Vector3 base = ins->transform.origin - ins->transform.basis.get_axis(2).normalized() * d;
+
+ Vector3 points[2] = {
+ base,
+ base + cam_xf.basis.get_axis(0) * w
+ };
+
+ if (!p_cam_orthogonal) {
+ //if using perspetive, map them to near plane
+ for (int j = 0; j < 2; j++) {
+ if (p.distance_to(points[j]) < 0) {
+ points[j].z = -zn; //small hack to keep size constant when hitting the screen
+ }
+
+ p.intersects_segment(cam_xf.origin, points[j], &points[j]); //map to plane
+ }
+ }
+
+ float screen_diameter = points[0].distance_to(points[1]) * 2;
+ coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
+
+ } break;
+ default: {
+ ERR_PRINT("Invalid Light Type");
+ }
+ }
+ }
+
+ if (light->shadow_dirty) {
+ light->last_version++;
+ light->shadow_dirty = false;
+ }
+
+ bool redraw = scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version);
+
+ if (redraw) {
+ //must redraw!
+ RENDER_TIMESTAMP(">Rendering Light " + itos(i));
+ light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario, p_screen_lod_threshold);
+ RENDER_TIMESTAMP("<Rendering Light " + itos(i));
+ }
+ }
+ }
+
+ //append the directional lights to the lights culled
+ for (int i = 0; i < directional_lights.size(); i++) {
+ frustum_cull_result.light_instances.push_back(directional_lights[i]);
+ }
+}
+
+RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
+ Camera *camera = camera_owner.getornull(p_camera);
+ if (camera && scene_render->is_environment(camera->env)) {
+ return camera->env;
+ }
+
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+ if (!scenario) {
+ return RID();
+ }
+ if (scene_render->is_environment(scenario->environment)) {
+ return scenario->environment;
+ }
+
+ if (scene_render->is_environment(scenario->fallback_environment)) {
+ return scenario->fallback_environment;
+ }
+
+ return RID();
+}
+
+void RendererSceneCull::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+
+ RID camera_effects;
+ if (p_force_camera_effects.is_valid()) {
+ camera_effects = p_force_camera_effects;
+ } else {
+ camera_effects = scenario->camera_effects;
+ }
+ /* PROCESS GEOMETRY AND DRAW SCENE */
+
+ RENDER_TIMESTAMP("Render Scene ");
+ scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold);
+}
+
+void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
+#ifndef _3D_DISABLED
+
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+
+ RID environment;
+ if (scenario->environment.is_valid()) {
+ environment = scenario->environment;
+ } else {
+ environment = scenario->fallback_environment;
+ }
+ RENDER_TIMESTAMP("Render Empty Scene ");
+ scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0);
+#endif
+}
+
+bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int p_step) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
+ Scenario *scenario = p_instance->scenario;
+ ERR_FAIL_COND_V(!scenario, true);
+
+ RenderingServerDefault::redraw_request(); //update, so it updates in editor
+
+ if (p_step == 0) {
+ if (!scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
+ return true; //all full
+ }
+ }
+
+ if (p_step >= 0 && p_step < 6) {
+ static const Vector3 view_normals[6] = {
+ Vector3(+1, 0, 0),
+ Vector3(-1, 0, 0),
+ Vector3(0, +1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, +1),
+ Vector3(0, 0, -1)
+ };
+ static const Vector3 view_up[6] = {
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, +1),
+ Vector3(0, 0, -1),
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0)
+ };
+
+ Vector3 extents = RSG::storage->reflection_probe_get_extents(p_instance->base);
+ Vector3 origin_offset = RSG::storage->reflection_probe_get_origin_offset(p_instance->base);
+ float max_distance = RSG::storage->reflection_probe_get_origin_max_distance(p_instance->base);
+ float size = scene_render->reflection_atlas_get_size(scenario->reflection_atlas);
+ float lod_threshold = RSG::storage->reflection_probe_get_lod_threshold(p_instance->base) / size;
+
+ Vector3 edge = view_normals[p_step] * extents;
+ 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);
+
+ //render cubemap side
+ CameraMatrix cm;
+ cm.set_perspective(90, 1, 0.01, max_distance);
+
+ Transform local_view;
+ local_view.set_look_at(origin_offset, origin_offset + view_normals[p_step], view_up[p_step]);
+
+ Transform xform = p_instance->transform * local_view;
+
+ RID shadow_atlas;
+
+ bool use_shadows = RSG::storage->reflection_probe_renders_shadows(p_instance->base);
+ if (use_shadows) {
+ shadow_atlas = scenario->reflection_probe_shadow_atlas;
+ }
+
+ RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step));
+ _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, lod_threshold, use_shadows);
+ _render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold);
+
+ } else {
+ //do roughness postprocess step until it believes it's done
+ RENDER_TIMESTAMP("Post-Process Reflection Probe, Step " + itos(p_step));
+ return scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance);
+ }
+
+ return false;
+}
+
+void RendererSceneCull::render_probes() {
+ /* REFLECTION PROBES */
+
+ SelfList<InstanceReflectionProbeData> *ref_probe = reflection_probe_render_list.first();
+
+ bool busy = false;
+
+ while (ref_probe) {
+ SelfList<InstanceReflectionProbeData> *next = ref_probe->next();
+ RID base = ref_probe->self()->owner->base;
+
+ switch (RSG::storage->reflection_probe_get_update_mode(base)) {
+ case RS::REFLECTION_PROBE_UPDATE_ONCE: {
+ if (busy) { //already rendering something
+ break;
+ }
+
+ bool done = _render_reflection_probe_step(ref_probe->self()->owner, ref_probe->self()->render_step);
+ if (done) {
+ reflection_probe_render_list.remove(ref_probe);
+ } else {
+ ref_probe->self()->render_step++;
+ }
+
+ busy = true; //do not render another one of this kind
+ } break;
+ case RS::REFLECTION_PROBE_UPDATE_ALWAYS: {
+ int step = 0;
+ bool done = false;
+ while (!done) {
+ done = _render_reflection_probe_step(ref_probe->self()->owner, step);
+ step++;
+ }
+
+ reflection_probe_render_list.remove(ref_probe);
+ } break;
+ }
+
+ ref_probe = next;
+ }
+
+ /* GI PROBES */
+
+ SelfList<InstanceGIProbeData> *gi_probe = gi_probe_update_list.first();
+
+ if (gi_probe) {
+ RENDER_TIMESTAMP("Render GI Probes");
+ }
+
+ while (gi_probe) {
+ SelfList<InstanceGIProbeData> *next = gi_probe->next();
+
+ InstanceGIProbeData *probe = gi_probe->self();
+ //Instance *instance_probe = probe->owner;
+
+ //check if probe must be setup, but don't do if on the lighting thread
+
+ bool cache_dirty = false;
+ int cache_count = 0;
+ {
+ int light_cache_size = probe->light_cache.size();
+ const InstanceGIProbeData::LightCache *caches = probe->light_cache.ptr();
+ const RID *instance_caches = probe->light_instances.ptr();
+
+ int idx = 0; //must count visible lights
+ for (Set<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) {
+ Instance *instance = E->get();
+ InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
+ if (!instance->visible) {
+ continue;
+ }
+ if (cache_dirty) {
+ //do nothing, since idx must count all visible lights anyway
+ } else if (idx >= light_cache_size) {
+ cache_dirty = true;
+ } else {
+ const InstanceGIProbeData::LightCache *cache = &caches[idx];
+
+ if (
+ instance_caches[idx] != instance_light->instance ||
+ cache->has_shadow != RSG::storage->light_has_shadow(instance->base) ||
+ cache->type != RSG::storage->light_get_type(instance->base) ||
+ cache->transform != instance->transform ||
+ cache->color != RSG::storage->light_get_color(instance->base) ||
+ cache->energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
+ cache->bake_energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
+ cache->radius != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
+ cache->attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
+ cache->spot_angle != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
+ cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION)) {
+ cache_dirty = true;
+ }
+ }
+
+ idx++;
+ }
+
+ for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) {
+ Instance *instance = E->get();
+ InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
+ if (!instance->visible) {
+ continue;
+ }
+ if (cache_dirty) {
+ //do nothing, since idx must count all visible lights anyway
+ } else if (idx >= light_cache_size) {
+ cache_dirty = true;
+ } else {
+ const InstanceGIProbeData::LightCache *cache = &caches[idx];
+
+ if (
+ instance_caches[idx] != instance_light->instance ||
+ cache->has_shadow != RSG::storage->light_has_shadow(instance->base) ||
+ cache->type != RSG::storage->light_get_type(instance->base) ||
+ cache->transform != instance->transform ||
+ cache->color != RSG::storage->light_get_color(instance->base) ||
+ cache->energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
+ cache->bake_energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
+ cache->radius != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
+ cache->attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
+ cache->spot_angle != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
+ cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION) ||
+ cache->sky_only != RSG::storage->light_directional_is_sky_only(instance->base)) {
+ cache_dirty = true;
+ }
+ }
+
+ idx++;
+ }
+
+ if (idx != light_cache_size) {
+ cache_dirty = true;
+ }
+
+ cache_count = idx;
+ }
+
+ bool update_lights = scene_render->gi_probe_needs_update(probe->probe_instance);
+
+ if (cache_dirty) {
+ probe->light_cache.resize(cache_count);
+ probe->light_instances.resize(cache_count);
+
+ if (cache_count) {
+ InstanceGIProbeData::LightCache *caches = probe->light_cache.ptrw();
+ RID *instance_caches = probe->light_instances.ptrw();
+
+ int idx = 0; //must count visible lights
+ for (Set<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) {
+ Instance *instance = E->get();
+ InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
+ if (!instance->visible) {
+ continue;
+ }
+
+ InstanceGIProbeData::LightCache *cache = &caches[idx];
+
+ instance_caches[idx] = instance_light->instance;
+ cache->has_shadow = RSG::storage->light_has_shadow(instance->base);
+ cache->type = RSG::storage->light_get_type(instance->base);
+ cache->transform = instance->transform;
+ cache->color = RSG::storage->light_get_color(instance->base);
+ cache->energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
+ cache->bake_energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+ cache->radius = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
+ cache->attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
+ cache->spot_angle = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+ cache->spot_attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+
+ idx++;
+ }
+ for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) {
+ Instance *instance = E->get();
+ InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
+ if (!instance->visible) {
+ continue;
+ }
+
+ InstanceGIProbeData::LightCache *cache = &caches[idx];
+
+ instance_caches[idx] = instance_light->instance;
+ cache->has_shadow = RSG::storage->light_has_shadow(instance->base);
+ cache->type = RSG::storage->light_get_type(instance->base);
+ cache->transform = instance->transform;
+ cache->color = RSG::storage->light_get_color(instance->base);
+ cache->energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
+ cache->bake_energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+ cache->radius = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
+ cache->attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
+ cache->spot_angle = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
+ cache->spot_attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+ cache->sky_only = RSG::storage->light_directional_is_sky_only(instance->base);
+
+ idx++;
+ }
+ }
+
+ update_lights = true;
+ }
+
+ frustum_cull_result.geometry_instances.clear();
+
+ RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
+
+ for (Set<Instance *>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) {
+ Instance *ins = E->get();
+ if (!ins->visible) {
+ continue;
+ }
+ InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data;
+
+ if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY)) {
+ uint32_t idx = 0;
+ for (Set<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) {
+ InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data);
+
+ instance_pair_buffer[idx++] = gi_probe2->probe_instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }
+
+ scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
+
+ ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY);
+ }
+
+ frustum_cull_result.geometry_instances.push_back(geom->geometry_instance);
+ }
+
+ scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, frustum_cull_result.geometry_instances);
+
+ gi_probe_update_list.remove(gi_probe);
+
+ gi_probe = next;
+ }
+}
+
+void RendererSceneCull::render_particle_colliders() {
+ while (heightfield_particle_colliders_update_list.front()) {
+ Instance *hfpc = heightfield_particle_colliders_update_list.front()->get();
+
+ if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::storage->particles_collision_is_heightfield(hfpc->base)) {
+ //update heightfield
+ instance_cull_result.clear();
+ frustum_cull_result.geometry_instances.clear();
+
+ struct CullAABB {
+ PagedArray<Instance *> *result;
+ _FORCE_INLINE_ bool operator()(void *p_data) {
+ Instance *p_instance = (Instance *)p_data;
+ result->push_back(p_instance);
+ return false;
+ }
+ };
+
+ CullAABB cull_aabb;
+ cull_aabb.result = &instance_cull_result;
+ hfpc->scenario->indexers[Scenario::INDEXER_GEOMETRY].aabb_query(hfpc->transformed_aabb, cull_aabb);
+ hfpc->scenario->indexers[Scenario::INDEXER_VOLUMES].aabb_query(hfpc->transformed_aabb, cull_aabb);
+
+ for (int i = 0; i < (int)instance_cull_result.size(); i++) {
+ Instance *instance = instance_cull_result[i];
+ if (!instance || !((1 << instance->base_type) & (RS::INSTANCE_GEOMETRY_MASK & (~(1 << RS::INSTANCE_PARTICLES))))) { //all but particles to avoid self collision
+ continue;
+ }
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ frustum_cull_result.geometry_instances.push_back(geom->geometry_instance);
+ }
+
+ scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, frustum_cull_result.geometry_instances);
+ }
+ heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front());
+ }
+}
+
+void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) {
+ List<RendererStorage::InstanceShaderParam> plist;
+ RSG::storage->material_get_instance_shader_parameters(p_material, &plist);
+ for (List<RendererStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) {
+ StringName name = E->get().info.name;
+ if (isparams.has(name)) {
+ if (isparams[name].info.type != E->get().info.type) {
+ WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different data types. Only the first one (in order) will display correctly.");
+ }
+ if (isparams[name].index != E->get().index) {
+ WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different indices. Only the first one (in order) will display correctly.");
+ }
+ continue; //first one found always has priority
+ }
+
+ Instance::InstanceShaderParameter isp;
+ isp.index = E->get().index;
+ isp.info = E->get().info;
+ isp.default_value = E->get().default_value;
+ if (existing_isparams.has(name)) {
+ isp.value = existing_isparams[name].value;
+ } else {
+ isp.value = E->get().default_value;
+ }
+ isparams[name] = isp;
+ }
+}
+
+void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
+ if (p_instance->update_aabb) {
+ _update_instance_aabb(p_instance);
+ }
+
+ if (p_instance->update_dependencies) {
+ p_instance->dependency_tracker.update_begin();
+
+ if (p_instance->base.is_valid()) {
+ RSG::storage->base_update_dependency(p_instance->base, &p_instance->dependency_tracker);
+ }
+
+ if (p_instance->material_override.is_valid()) {
+ RSG::storage->material_update_dependency(p_instance->material_override, &p_instance->dependency_tracker);
+ }
+
+ if (p_instance->base_type == RS::INSTANCE_MESH) {
+ //remove materials no longer used and un-own them
+
+ int new_mat_count = RSG::storage->mesh_get_surface_count(p_instance->base);
+ p_instance->materials.resize(new_mat_count);
+
+ _instance_update_mesh_instance(p_instance);
+ }
+
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+
+ bool can_cast_shadows = true;
+ bool is_animated = false;
+ Map<StringName, Instance::InstanceShaderParameter> isparams;
+
+ if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
+ can_cast_shadows = false;
+ }
+
+ if (p_instance->material_override.is_valid()) {
+ if (!RSG::storage->material_casts_shadows(p_instance->material_override)) {
+ can_cast_shadows = false;
+ }
+ is_animated = RSG::storage->material_is_animated(p_instance->material_override);
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override);
+ } else {
+ if (p_instance->base_type == RS::INSTANCE_MESH) {
+ RID mesh = p_instance->base;
+
+ if (mesh.is_valid()) {
+ bool cast_shadows = false;
+
+ for (int i = 0; i < p_instance->materials.size(); i++) {
+ RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::storage->mesh_surface_get_material(mesh, i);
+
+ if (!mat.is_valid()) {
+ cast_shadows = true;
+ } else {
+ if (RSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (RSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
+
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
+ }
+ }
+
+ if (!cast_shadows) {
+ can_cast_shadows = false;
+ }
+ }
+
+ } else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) {
+ RID mesh = RSG::storage->multimesh_get_mesh(p_instance->base);
+ if (mesh.is_valid()) {
+ bool cast_shadows = false;
+
+ int sc = RSG::storage->mesh_get_surface_count(mesh);
+ for (int i = 0; i < sc; i++) {
+ RID mat = RSG::storage->mesh_surface_get_material(mesh, i);
+
+ if (!mat.is_valid()) {
+ cast_shadows = true;
+
+ } else {
+ if (RSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+ if (RSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
+
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
+ }
+ }
+
+ if (!cast_shadows) {
+ can_cast_shadows = false;
+ }
+
+ RSG::storage->base_update_dependency(mesh, &p_instance->dependency_tracker);
+ }
+ } else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) {
+ RID mat = RSG::storage->immediate_get_material(p_instance->base);
+
+ if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) {
+ can_cast_shadows = false;
+ }
+
+ if (mat.is_valid() && RSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
+
+ if (mat.is_valid()) {
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+ }
+
+ if (mat.is_valid()) {
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
+ }
+
+ } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
+ bool cast_shadows = false;
+
+ int dp = RSG::storage->particles_get_draw_passes(p_instance->base);
+
+ for (int i = 0; i < dp; i++) {
+ RID mesh = RSG::storage->particles_get_draw_pass_mesh(p_instance->base, i);
+ if (!mesh.is_valid()) {
+ continue;
+ }
+
+ int sc = RSG::storage->mesh_get_surface_count(mesh);
+ for (int j = 0; j < sc; j++) {
+ RID mat = RSG::storage->mesh_surface_get_material(mesh, j);
+
+ if (!mat.is_valid()) {
+ cast_shadows = true;
+ } else {
+ if (RSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (RSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
+
+ _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
+
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
+ }
+ }
+ }
+
+ if (!cast_shadows) {
+ can_cast_shadows = false;
+ }
+ }
+ }
+
+ if (can_cast_shadows != geom->can_cast_shadows) {
+ //ability to cast shadows change, let lights now
+ for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ light->shadow_dirty = true;
+ }
+
+ geom->can_cast_shadows = can_cast_shadows;
+ }
+
+ geom->material_is_animated = is_animated;
+ p_instance->instance_shader_parameters = isparams;
+
+ if (p_instance->instance_allocated_shader_parameters != (p_instance->instance_shader_parameters.size() > 0)) {
+ p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0);
+ if (p_instance->instance_allocated_shader_parameters) {
+ p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self);
+ scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset);
+
+ for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) {
+ if (E->get().value.get_type() != Variant::NIL) {
+ RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value);
+ }
+ }
+ } else {
+ RSG::storage->global_variables_instance_free(p_instance->self);
+ p_instance->instance_allocated_shader_parameters_offset = -1;
+ scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, -1);
+ }
+ }
+ }
+
+ if (p_instance->skeleton.is_valid()) {
+ RSG::storage->skeleton_update_dependency(p_instance->skeleton, &p_instance->dependency_tracker);
+ }
+
+ p_instance->dependency_tracker.update_end();
+
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, p_instance->materials);
+ }
+ }
+
+ _instance_update_list.remove(&p_instance->update_item);
+
+ _update_instance(p_instance);
+
+ p_instance->update_aabb = false;
+ p_instance->update_dependencies = false;
+}
+
+void RendererSceneCull::update_dirty_instances() {
+ RSG::storage->update_dirty_resources();
+
+ while (_instance_update_list.first()) {
+ _update_dirty_instance(_instance_update_list.first()->self());
+ }
+}
+
+void RendererSceneCull::update() {
+ //optimize bvhs
+ for (uint32_t i = 0; i < scenario_owner.get_rid_count(); i++) {
+ Scenario *s = scenario_owner.get_ptr_by_index(i);
+ s->indexers[Scenario::INDEXER_GEOMETRY].optimize_incremental(indexer_update_iterations);
+ s->indexers[Scenario::INDEXER_VOLUMES].optimize_incremental(indexer_update_iterations);
+ }
+ scene_render->update();
+ update_dirty_instances();
+ render_particle_colliders();
+}
+
+bool RendererSceneCull::free(RID p_rid) {
+ if (scene_render->free(p_rid)) {
+ return true;
+ }
+
+ if (camera_owner.owns(p_rid)) {
+ Camera *camera = camera_owner.getornull(p_rid);
+
+ camera_owner.free(p_rid);
+ memdelete(camera);
+
+ } else if (scenario_owner.owns(p_rid)) {
+ Scenario *scenario = scenario_owner.getornull(p_rid);
+
+ while (scenario->instances.first()) {
+ instance_set_scenario(scenario->instances.first()->self()->self, RID());
+ }
+ scenario->instance_aabbs.reset();
+ scenario->instance_data.reset();
+
+ scene_render->free(scenario->reflection_probe_shadow_atlas);
+ scene_render->free(scenario->reflection_atlas);
+ scenario_owner.free(p_rid);
+ memdelete(scenario);
+
+ } else if (instance_owner.owns(p_rid)) {
+ // delete the instance
+
+ update_dirty_instances();
+
+ Instance *instance = instance_owner.getornull(p_rid);
+
+ instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0);
+ instance_set_scenario(p_rid, RID());
+ instance_set_base(p_rid, RID());
+ instance_geometry_set_material_override(p_rid, RID());
+ instance_attach_skeleton(p_rid, RID());
+
+ if (instance->instance_allocated_shader_parameters) {
+ //free the used shader parameters
+ RSG::storage->global_variables_instance_free(instance->self);
+ }
+ update_dirty_instances(); //in case something changed this
+
+ instance_owner.free(p_rid);
+ memdelete(instance);
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) {
+ return scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size);
+}
+
+/*******************************/
+/* Passthrough to Scene Render */
+/*******************************/
+
+/* ENVIRONMENT API */
+
+RendererSceneCull *RendererSceneCull::singleton = nullptr;
+
+void RendererSceneCull::set_scene_render(RendererSceneRender *p_scene_render) {
+ scene_render = p_scene_render;
+ geometry_instance_pair_mask = scene_render->geometry_instance_get_pair_mask();
+}
+
+RendererSceneCull::RendererSceneCull() {
+ render_pass = 1;
+ singleton = this;
+
+ instance_cull_result.set_page_pool(&instance_cull_page_pool);
+ instance_shadow_cull_result.set_page_pool(&instance_cull_page_pool);
+
+ geometry_instances_to_shadow_render.set_page_pool(&geometry_instance_cull_page_pool);
+
+ frustum_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
+ frustum_cull_result_threads.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count());
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result_threads[i].init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
+ }
+
+ indexer_update_iterations = GLOBAL_GET("rendering/spatial_indexer/update_iterations_per_frame");
+ thread_cull_threshold = GLOBAL_GET("rendering/spatial_indexer/threaded_cull_minimum_instances");
+ thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)RendererThreadPool::singleton->thread_work_pool.get_thread_count()); //make sure there is at least one thread per CPU
+}
+
+RendererSceneCull::~RendererSceneCull() {
+ instance_cull_result.reset();
+ instance_shadow_cull_result.reset();
+
+ geometry_instances_to_shadow_render.reset();
+
+ frustum_cull_result.reset();
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result_threads[i].reset();
+ }
+ frustum_cull_result_threads.clear();
+}
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
new file mode 100644
index 0000000000..796fb14743
--- /dev/null
+++ b/servers/rendering/renderer_scene_cull.h
@@ -0,0 +1,1045 @@
+/*************************************************************************/
+/* renderer_scene_cull.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERING_SERVER_SCENE_CULL_H
+#define RENDERING_SERVER_SCENE_CULL_H
+
+#include "core/templates/pass_func.h"
+#include "servers/rendering/renderer_compositor.h"
+
+#include "core/math/dynamic_bvh.h"
+#include "core/math/geometry_3d.h"
+#include "core/math/octree.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
+#include "core/templates/local_vector.h"
+#include "core/templates/paged_allocator.h"
+#include "core/templates/paged_array.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/self_list.h"
+#include "servers/rendering/renderer_scene.h"
+#include "servers/rendering/renderer_scene_render.h"
+#include "servers/xr/xr_interface.h"
+class RendererSceneCull : public RendererScene {
+public:
+ RendererSceneRender *scene_render;
+
+ enum {
+ SDFGI_MAX_CASCADES = 8,
+ SDFGI_MAX_REGIONS_PER_CASCADE = 3,
+ MAX_INSTANCE_PAIRS = 32
+ };
+
+ uint64_t render_pass;
+
+ static RendererSceneCull *singleton;
+
+ /* CAMERA API */
+
+ struct Camera {
+ enum Type {
+ PERSPECTIVE,
+ ORTHOGONAL,
+ FRUSTUM
+ };
+ Type type;
+ float fov;
+ float znear, zfar;
+ float size;
+ Vector2 offset;
+ uint32_t visible_layers;
+ bool vaspect;
+ RID env;
+ RID effects;
+
+ Transform transform;
+
+ Camera() {
+ visible_layers = 0xFFFFFFFF;
+ fov = 75;
+ type = PERSPECTIVE;
+ znear = 0.05;
+ zfar = 4000;
+ size = 1.0;
+ offset = Vector2();
+ vaspect = false;
+ }
+ };
+
+ mutable RID_PtrOwner<Camera> camera_owner;
+
+ virtual RID camera_create();
+ virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far);
+ virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
+ virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far);
+ virtual void camera_set_transform(RID p_camera, const Transform &p_transform);
+ virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers);
+ virtual void camera_set_environment(RID p_camera, RID p_env);
+ virtual void camera_set_camera_effects(RID p_camera, RID p_fx);
+ virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable);
+ virtual bool is_camera(RID p_camera) const;
+
+ /* SCENARIO API */
+
+ struct Instance;
+
+ struct PlaneSign {
+ _ALWAYS_INLINE_ PlaneSign() {}
+ _ALWAYS_INLINE_ PlaneSign(const Plane &p_plane) {
+ if (p_plane.normal.x > 0) {
+ signs[0] = 0;
+ } else {
+ signs[0] = 3;
+ }
+ if (p_plane.normal.y > 0) {
+ signs[1] = 1;
+ } else {
+ signs[1] = 4;
+ }
+ if (p_plane.normal.z > 0) {
+ signs[2] = 2;
+ } else {
+ signs[2] = 5;
+ }
+ }
+
+ uint32_t signs[3];
+ };
+
+ struct Frustum {
+ Vector<Plane> planes;
+ Vector<PlaneSign> plane_signs;
+ const Plane *planes_ptr;
+ const PlaneSign *plane_signs_ptr;
+ uint32_t plane_count;
+
+ _ALWAYS_INLINE_ Frustum() {}
+ _ALWAYS_INLINE_ Frustum(const Frustum &p_frustum) {
+ planes = p_frustum.planes;
+ plane_signs = p_frustum.plane_signs;
+
+ planes_ptr = planes.ptr();
+ plane_signs_ptr = plane_signs.ptr();
+ plane_count = p_frustum.plane_count;
+ }
+ _ALWAYS_INLINE_ void operator=(const Frustum &p_frustum) {
+ planes = p_frustum.planes;
+ plane_signs = p_frustum.plane_signs;
+
+ planes_ptr = planes.ptr();
+ plane_signs_ptr = plane_signs.ptr();
+ plane_count = p_frustum.plane_count;
+ }
+ _ALWAYS_INLINE_ Frustum(const Vector<Plane> &p_planes) {
+ planes = p_planes;
+ planes_ptr = planes.ptrw();
+ plane_count = planes.size();
+ for (int i = 0; i < planes.size(); i++) {
+ PlaneSign ps(p_planes[i]);
+ plane_signs.push_back(ps);
+ }
+
+ plane_signs_ptr = plane_signs.ptr();
+ }
+ };
+
+ struct InstanceBounds {
+ // Efficiently store instance bounds.
+ // Because bounds checking is performed first,
+ // keep it separated from data.
+
+ real_t bounds[6];
+ _ALWAYS_INLINE_ InstanceBounds() {}
+
+ _ALWAYS_INLINE_ InstanceBounds(const AABB &p_aabb) {
+ bounds[0] = p_aabb.position.x;
+ bounds[1] = p_aabb.position.y;
+ bounds[2] = p_aabb.position.z;
+ bounds[3] = p_aabb.position.x + p_aabb.size.x;
+ bounds[4] = p_aabb.position.y + p_aabb.size.y;
+ bounds[5] = p_aabb.position.z + p_aabb.size.z;
+ }
+ _ALWAYS_INLINE_ bool in_frustum(const Frustum &p_frustum) const {
+ // This is not a full SAT check and the possibility of false positives exist,
+ // but the tradeoff vs performance is still very good.
+
+ for (uint32_t i = 0; i < p_frustum.plane_count; i++) {
+ Vector3 min(
+ bounds[p_frustum.plane_signs_ptr[i].signs[0]],
+ bounds[p_frustum.plane_signs_ptr[i].signs[1]],
+ bounds[p_frustum.plane_signs_ptr[i].signs[2]]);
+
+ if (p_frustum.planes_ptr[i].distance_to(min) >= 0.0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ _ALWAYS_INLINE_ bool in_aabb(const AABB &p_aabb) const {
+ Vector3 end = p_aabb.position + p_aabb.size;
+
+ if (bounds[0] >= end.x) {
+ return false;
+ }
+ if (bounds[3] <= p_aabb.position.x) {
+ return false;
+ }
+ if (bounds[1] >= end.y) {
+ return false;
+ }
+ if (bounds[4] <= p_aabb.position.y) {
+ return false;
+ }
+ if (bounds[2] >= end.z) {
+ return false;
+ }
+ if (bounds[5] <= p_aabb.position.z) {
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ struct InstanceData {
+ // Store instance pointer as well as common instance processing information,
+ // to make processing more cache friendly.
+ enum Flags {
+ FLAG_BASE_TYPE_MASK = 0xFF,
+ FLAG_CAST_SHADOWS = (1 << 8),
+ FLAG_CAST_SHADOWS_ONLY = (1 << 9),
+ FLAG_REDRAW_IF_VISIBLE = (1 << 10),
+ FLAG_GEOM_LIGHTING_DIRTY = (1 << 11),
+ FLAG_GEOM_REFLECTION_DIRTY = (1 << 12),
+ FLAG_GEOM_DECAL_DIRTY = (1 << 13),
+ FLAG_GEOM_GI_PROBE_DIRTY = (1 << 14),
+ FLAG_LIGHTMAP_CAPTURE = (1 << 15),
+ FLAG_USES_BAKED_LIGHT = (1 << 16),
+ FLAG_USES_MESH_INSTANCE = (1 << 17),
+ FLAG_REFLECTION_PROBE_DIRTY = (1 << 18),
+ };
+
+ uint32_t flags = 0;
+ uint32_t layer_mask = 0; //for fast layer-mask discard
+ RID base_rid;
+ union {
+ uint64_t instance_data_rid;
+ RendererSceneRender::GeometryInstance *instance_geometry;
+ };
+ Instance *instance = nullptr;
+ };
+
+ PagedArrayPool<InstanceBounds> instance_aabb_page_pool;
+ PagedArrayPool<InstanceData> instance_data_page_pool;
+
+ struct Scenario {
+ enum IndexerType {
+ INDEXER_GEOMETRY, //for geometry
+ INDEXER_VOLUMES, //for everything else
+ INDEXER_MAX
+ };
+
+ DynamicBVH indexers[INDEXER_MAX];
+
+ RS::ScenarioDebugMode debug;
+ RID self;
+
+ List<Instance *> directional_lights;
+ RID environment;
+ RID fallback_environment;
+ RID camera_effects;
+ RID reflection_probe_shadow_atlas;
+ RID reflection_atlas;
+
+ SelfList<Instance>::List instances;
+
+ LocalVector<RID> dynamic_lights;
+
+ PagedArray<InstanceBounds> instance_aabbs;
+ PagedArray<InstanceData> instance_data;
+
+ Scenario() {
+ indexers[INDEXER_GEOMETRY].set_index(INDEXER_GEOMETRY);
+ indexers[INDEXER_VOLUMES].set_index(INDEXER_VOLUMES);
+ debug = RS::SCENARIO_DEBUG_DISABLED;
+ }
+ };
+
+ int indexer_update_iterations = 0;
+
+ mutable RID_PtrOwner<Scenario> scenario_owner;
+
+ static void _instance_pair(Instance *p_A, Instance *p_B);
+ static void _instance_unpair(Instance *p_A, Instance *p_B);
+
+ void _instance_update_mesh_instance(Instance *p_instance);
+
+ virtual RID scenario_create();
+
+ virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode);
+ virtual void scenario_set_environment(RID p_scenario, RID p_environment);
+ virtual void scenario_set_camera_effects(RID p_scenario, RID p_fx);
+ virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
+ virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count);
+ virtual bool is_scenario(RID p_scenario) const;
+ virtual RID scenario_get_environment(RID p_scenario);
+
+ /* INSTANCING API */
+
+ struct InstancePair {
+ Instance *a;
+ Instance *b;
+ SelfList<InstancePair> list_a;
+ SelfList<InstancePair> list_b;
+ InstancePair() :
+ list_a(this), list_b(this) {}
+ };
+
+ PagedAllocator<InstancePair> pair_allocator;
+
+ struct InstanceBaseData {
+ virtual ~InstanceBaseData() {}
+ };
+
+ struct Instance {
+ RS::InstanceType base_type;
+ RID base;
+
+ RID skeleton;
+ RID material_override;
+
+ RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
+
+ Transform transform;
+
+ float lod_bias;
+
+ Vector<RID> materials;
+
+ RS::ShadowCastingSetting cast_shadows;
+
+ uint32_t layer_mask;
+ //fit in 32 bits
+ bool mirror : 8;
+ bool receive_shadows : 8;
+ bool visible : 8;
+ bool baked_light : 2; //this flag is only to know if it actually did use baked light
+ bool dynamic_gi : 2; //same above for dynamic objects
+ bool redraw_if_visible : 4;
+
+ Instance *lightmap;
+ Rect2 lightmap_uv_scale;
+ int lightmap_slice_index;
+ uint32_t lightmap_cull_index;
+ Vector<Color> lightmap_sh; //spherical harmonic
+
+ AABB aabb;
+ AABB transformed_aabb;
+ AABB prev_transformed_aabb;
+
+ struct InstanceShaderParameter {
+ int32_t index = -1;
+ Variant value;
+ Variant default_value;
+ PropertyInfo info;
+ };
+
+ Map<StringName, InstanceShaderParameter> instance_shader_parameters;
+ bool instance_allocated_shader_parameters = false;
+ int32_t instance_allocated_shader_parameters_offset = -1;
+
+ //
+
+ RID self;
+ //scenario stuff
+ DynamicBVH::ID indexer_id;
+ int32_t array_index;
+ Scenario *scenario;
+ SelfList<Instance> scenario_item;
+
+ //aabb stuff
+ bool update_aabb;
+ bool update_dependencies;
+
+ SelfList<Instance> update_item;
+
+ AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better?
+ float extra_margin;
+ ObjectID object_id;
+
+ float lod_begin;
+ float lod_end;
+ float lod_begin_hysteresis;
+ float lod_end_hysteresis;
+ RID lod_instance;
+
+ 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;
+
+ uint64_t version; // changes to this, and changes to base increase version
+
+ InstanceBaseData *base_data;
+
+ SelfList<InstancePair>::List pairs;
+ uint64_t pair_check;
+
+ RendererStorage::DependencyTracker dependency_tracker;
+
+ static void dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *tracker) {
+ Instance *instance = (Instance *)tracker->userdata;
+ switch (p_notification) {
+ case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA:
+ case RendererStorage::DEPENDENCY_CHANGED_AABB: {
+ singleton->_instance_queue_update(instance, true, false);
+
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: {
+ singleton->_instance_queue_update(instance, false, true);
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MESH:
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
+ case RendererStorage::DEPENDENCY_CHANGED_DECAL:
+ case RendererStorage::DEPENDENCY_CHANGED_LIGHT:
+ case RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
+ singleton->_instance_queue_update(instance, true, true);
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
+ case RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES: {
+ //ignored
+ } break;
+ }
+ }
+
+ static void dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *tracker) {
+ Instance *instance = (Instance *)tracker->userdata;
+
+ if (p_dependency == instance->base) {
+ singleton->instance_set_base(instance->self, RID());
+ } else if (p_dependency == instance->skeleton) {
+ singleton->instance_attach_skeleton(instance->self, RID());
+ } else {
+ singleton->_instance_queue_update(instance, false, true);
+ }
+ }
+
+ Instance() :
+ scenario_item(this),
+ update_item(this) {
+ base_type = RS::INSTANCE_NONE;
+ cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
+ receive_shadows = true;
+ visible = true;
+ layer_mask = 1;
+ baked_light = false;
+ dynamic_gi = false;
+ redraw_if_visible = false;
+ lightmap_slice_index = 0;
+ lightmap = nullptr;
+ lightmap_cull_index = 0;
+ lod_bias = 1.0;
+
+ scenario = nullptr;
+
+ update_aabb = false;
+ update_dependencies = false;
+
+ extra_margin = 0;
+
+ visible = true;
+
+ lod_begin = 0;
+ lod_end = 0;
+ lod_begin_hysteresis = 0;
+ lod_end_hysteresis = 0;
+
+ last_frame_pass = 0;
+ version = 1;
+ base_data = nullptr;
+
+ custom_aabb = nullptr;
+
+ pair_check = 0;
+ array_index = -1;
+
+ dependency_tracker.userdata = this;
+ dependency_tracker.changed_callback = dependency_changed;
+ dependency_tracker.deleted_callback = dependency_deleted;
+ }
+
+ ~Instance() {
+ if (base_data) {
+ memdelete(base_data);
+ }
+ if (custom_aabb) {
+ memdelete(custom_aabb);
+ }
+ }
+ };
+
+ SelfList<Instance>::List _instance_update_list;
+ void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
+
+ struct InstanceGeometryData : public InstanceBaseData {
+ RendererSceneRender::GeometryInstance *geometry_instance = nullptr;
+ Set<Instance *> lights;
+ bool can_cast_shadows;
+ bool material_is_animated;
+
+ Set<Instance *> decals;
+ Set<Instance *> reflection_probes;
+ Set<Instance *> gi_probes;
+ Set<Instance *> lightmap_captures;
+
+ InstanceGeometryData() {
+ can_cast_shadows = true;
+ material_is_animated = true;
+ }
+ };
+
+ struct InstanceReflectionProbeData : public InstanceBaseData {
+ Instance *owner;
+
+ Set<Instance *> geometries;
+
+ RID instance;
+ SelfList<InstanceReflectionProbeData> update_list;
+
+ int render_step;
+
+ InstanceReflectionProbeData() :
+ update_list(this) {
+ render_step = -1;
+ }
+ };
+
+ struct InstanceDecalData : public InstanceBaseData {
+ Instance *owner;
+ RID instance;
+
+ Set<Instance *> geometries;
+
+ InstanceDecalData() {
+ }
+ };
+
+ SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
+
+ struct InstanceParticlesCollisionData : public InstanceBaseData {
+ RID instance;
+ };
+
+ struct InstanceLightData : public InstanceBaseData {
+ RID instance;
+ uint64_t last_version;
+ List<Instance *>::Element *D; // directional light in scenario
+
+ bool shadow_dirty;
+
+ Set<Instance *> geometries;
+
+ Instance *baked_light;
+
+ RS::LightBakeMode bake_mode;
+ uint32_t max_sdfgi_cascade = 2;
+
+ InstanceLightData() {
+ bake_mode = RS::LIGHT_BAKE_DISABLED;
+ shadow_dirty = true;
+ D = nullptr;
+ last_version = 0;
+ baked_light = nullptr;
+ }
+ };
+
+ struct InstanceGIProbeData : public InstanceBaseData {
+ Instance *owner;
+
+ Set<Instance *> geometries;
+ Set<Instance *> dynamic_geometries;
+
+ Set<Instance *> lights;
+
+ struct LightCache {
+ RS::LightType type;
+ Transform transform;
+ Color color;
+ float energy;
+ float bake_energy;
+ float radius;
+ float attenuation;
+ float spot_angle;
+ float spot_attenuation;
+ bool has_shadow;
+ bool sky_only;
+ };
+
+ Vector<LightCache> light_cache;
+ Vector<RID> light_instances;
+
+ RID probe_instance;
+
+ bool invalid;
+ uint32_t base_version;
+
+ SelfList<InstanceGIProbeData> update_element;
+
+ InstanceGIProbeData() :
+ update_element(this) {
+ invalid = true;
+ base_version = 0;
+ }
+ };
+
+ SelfList<InstanceGIProbeData>::List gi_probe_update_list;
+
+ struct InstanceLightmapData : public InstanceBaseData {
+ RID instance;
+ Set<Instance *> geometries;
+ Set<Instance *> users;
+
+ InstanceLightmapData() {
+ }
+ };
+
+ uint64_t pair_pass = 1;
+
+ struct PairInstances {
+ Instance *instance = nullptr;
+ PagedAllocator<InstancePair> *pair_allocator = nullptr;
+ SelfList<InstancePair>::List pairs_found;
+ DynamicBVH *bvh = nullptr;
+ DynamicBVH *bvh2 = nullptr; //some may need to cull in two
+ uint32_t pair_mask;
+ uint64_t pair_pass;
+
+ _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))) {
+ //test is more coarse in indexer
+ p_instance->pair_check = pair_pass;
+ InstancePair *pair = pair_allocator->alloc();
+ pair->a = instance;
+ pair->b = p_instance;
+ pairs_found.add(&pair->list_a);
+ }
+ return false;
+ }
+
+ void pair() {
+ if (bvh) {
+ bvh->aabb_query(instance->transformed_aabb, *this);
+ }
+ if (bvh2) {
+ bvh2->aabb_query(instance->transformed_aabb, *this);
+ }
+ while (instance->pairs.first()) {
+ InstancePair *pair = instance->pairs.first()->self();
+ Instance *other_instance = instance == pair->a ? pair->b : pair->a;
+ if (other_instance->pair_check != pair_pass) {
+ //unpaired
+ _instance_unpair(instance, other_instance);
+ } else {
+ //kept
+ other_instance->pair_check = 0; // if kept, then put pair check to zero, so we can distinguish with the newly added ones
+ }
+
+ pair_allocator->free(pair);
+ }
+ while (pairs_found.first()) {
+ InstancePair *pair = pairs_found.first()->self();
+ pairs_found.remove(pairs_found.first());
+
+ if (pair->b->pair_check == pair_pass) {
+ //paired
+ _instance_pair(instance, pair->b);
+ }
+ pair->a->pairs.add(&pair->list_a);
+ pair->b->pairs.add(&pair->list_b);
+ }
+ }
+ };
+
+ Set<Instance *> heightfield_particle_colliders_update_list;
+
+ PagedArrayPool<Instance *> instance_cull_page_pool;
+ PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool;
+ PagedArrayPool<RID> rid_cull_page_pool;
+
+ PagedArray<Instance *> instance_cull_result;
+ PagedArray<Instance *> instance_shadow_cull_result;
+ PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances_to_shadow_render;
+
+ struct FrustumCullResult {
+ PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances;
+ PagedArray<Instance *> lights;
+ PagedArray<RID> light_instances;
+ PagedArray<RID> lightmaps;
+ PagedArray<RID> reflections;
+ PagedArray<RID> decals;
+ PagedArray<RID> gi_probes;
+ PagedArray<RID> mesh_instances;
+
+ struct DirectionalShadow {
+ PagedArray<RendererSceneRender::GeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES];
+ } directional_shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS];
+
+ PagedArray<RendererSceneRender::GeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE];
+ PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES];
+
+ void clear() {
+ geometry_instances.clear();
+ lights.clear();
+ light_instances.clear();
+ lightmaps.clear();
+ reflections.clear();
+ decals.clear();
+ gi_probes.clear();
+ mesh_instances.clear();
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].clear();
+ }
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].clear();
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].clear();
+ }
+ }
+
+ void reset() {
+ geometry_instances.reset();
+ lights.reset();
+ light_instances.reset();
+ lightmaps.reset();
+ reflections.reset();
+ decals.reset();
+ gi_probes.reset();
+ mesh_instances.reset();
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].reset();
+ }
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].reset();
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].reset();
+ }
+ }
+
+ void append_from(FrustumCullResult &p_cull_result) {
+ geometry_instances.merge_unordered(p_cull_result.geometry_instances);
+ lights.merge_unordered(p_cull_result.lights);
+ light_instances.merge_unordered(p_cull_result.light_instances);
+ lightmaps.merge_unordered(p_cull_result.lightmaps);
+ reflections.merge_unordered(p_cull_result.reflections);
+ decals.merge_unordered(p_cull_result.decals);
+ gi_probes.merge_unordered(p_cull_result.gi_probes);
+ mesh_instances.merge_unordered(p_cull_result.mesh_instances);
+
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].merge_unordered(p_cull_result.directional_shadows[i].cascade_geometry_instances[j]);
+ }
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].merge_unordered(p_cull_result.sdfgi_region_geometry_instances[i]);
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].merge_unordered(p_cull_result.sdfgi_cascade_lights[i]);
+ }
+ }
+
+ void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RendererSceneRender::GeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) {
+ geometry_instances.set_page_pool(p_geometry_instance_pool);
+ light_instances.set_page_pool(p_rid_pool);
+ lights.set_page_pool(p_instance_pool);
+ lightmaps.set_page_pool(p_rid_pool);
+ reflections.set_page_pool(p_rid_pool);
+ decals.set_page_pool(p_rid_pool);
+ mesh_instances.set_page_pool(p_rid_pool);
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].set_page_pool(p_geometry_instance_pool);
+ }
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].set_page_pool(p_geometry_instance_pool);
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].set_page_pool(p_rid_pool);
+ }
+ }
+ };
+
+ FrustumCullResult frustum_cull_result;
+ LocalVector<FrustumCullResult> frustum_cull_result_threads;
+
+ uint32_t thread_cull_threshold = 200;
+
+ RID_PtrOwner<Instance> instance_owner;
+
+ uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered
+
+ virtual RID instance_create();
+
+ 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_transform(RID p_instance, const Transform &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);
+ virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material);
+ virtual void instance_set_visible(RID p_instance, bool p_visible);
+
+ virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb);
+
+ virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton);
+ virtual void instance_set_exterior(RID p_instance, bool p_enabled);
+
+ virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin);
+
+ // don't use these in a game!
+ virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const;
+ virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const;
+ virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const;
+
+ virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled);
+ virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting);
+ virtual void instance_geometry_set_material_override(RID p_instance, RID p_material);
+
+ virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin);
+ virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance);
+ virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
+ virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias);
+
+ void _update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material);
+
+ virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value);
+ virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const;
+ virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const;
+ virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const;
+
+ _FORCE_INLINE_ void _update_instance(Instance *p_instance);
+ _FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance);
+ _FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
+ _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
+ void _unpair_instance(Instance *p_instance);
+
+ void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect);
+
+ _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_lod_threshold);
+
+ RID _render_get_environment(RID p_camera, RID p_scenario);
+
+ struct Cull {
+ struct Shadow {
+ RID light_instance;
+ struct Cascade {
+ Frustum frustum;
+
+ CameraMatrix projection;
+ Transform transform;
+ real_t zfar;
+ real_t split;
+ real_t shadow_texel_size;
+ real_t bias_scale;
+ real_t range_begin;
+ Vector2 uv_scale;
+
+ } cascades[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; //max 4 cascades
+ uint32_t cascade_count;
+
+ } shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS];
+
+ uint32_t shadow_count;
+
+ struct SDFGI {
+ //have arrays here because SDFGI functions expects this, plus regions can have areas
+ AABB region_aabb[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
+ uint32_t region_cascade[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
+ uint32_t region_count = 0;
+
+ uint32_t cascade_light_index[SDFGI_MAX_CASCADES];
+ uint32_t cascade_light_count = 0;
+
+ } sdfgi;
+
+ SpinLock lock;
+
+ Frustum frustum;
+ } cull;
+
+ struct FrustumCullData {
+ Cull *cull;
+ Scenario *scenario;
+ RID shadow_atlas;
+ Transform cam_transform;
+ uint32_t visible_layers;
+ Instance *render_reflection_probe;
+ };
+
+ void _frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data);
+ void _frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to);
+
+ bool _render_reflection_probe_step(Instance *p_instance, int p_step);
+ void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows = true);
+ void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
+ void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas);
+
+ void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas);
+ void render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas);
+ void update_dirty_instances();
+
+ void render_particle_colliders();
+ virtual void render_probes();
+
+ TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size);
+
+ //pass to scene render
+
+ /* ENVIRONMENT API */
+
+#ifdef PASSBASE
+#undef PASSBASE
+#endif
+
+#define PASSBASE scene_render
+
+ PASS1(directional_shadow_atlas_set_size, int)
+ PASS1(gi_probe_set_quality, RS::GIProbeQuality)
+
+ /* SKY API */
+
+ PASS0R(RID, sky_create)
+ PASS2(sky_set_radiance_size, RID, int)
+ PASS2(sky_set_mode, RID, RS::SkyMode)
+ PASS2(sky_set_material, RID, RID)
+ PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
+
+ PASS0R(RID, environment_create)
+
+ PASS1RC(bool, is_environment, RID)
+
+ PASS2(environment_set_background, RID, RS::EnvironmentBG)
+ PASS2(environment_set_sky, RID, RID)
+ PASS2(environment_set_sky_custom_fov, RID, float)
+ PASS2(environment_set_sky_orientation, RID, const Basis &)
+ PASS2(environment_set_bg_color, RID, const Color &)
+ PASS2(environment_set_bg_energy, RID, float)
+ PASS2(environment_set_canvas_max_layer, RID, int)
+ PASS7(environment_set_ambient_light, RID, const Color &, RS::EnvironmentAmbientSource, float, float, RS::EnvironmentReflectionSource, const Color &)
+
+ PASS6(environment_set_ssr, RID, bool, int, float, float, float)
+ PASS1(environment_set_ssr_roughness_quality, RS::EnvironmentSSRRoughnessQuality)
+
+ PASS10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float)
+ PASS6(environment_set_ssao_quality, RS::EnvironmentSSAOQuality, bool, float, int, float, float)
+
+ PASS11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float)
+ PASS1(environment_glow_set_use_bicubic_upscale, bool)
+ PASS1(environment_glow_set_use_high_quality, bool)
+
+ PASS9(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float, bool, float, float, float, float)
+
+ PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
+
+ PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
+ PASS9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter)
+
+ PASS2(environment_set_volumetric_fog_volume_size, int, int)
+ PASS1(environment_set_volumetric_fog_filter_active, bool)
+ PASS1(environment_set_volumetric_fog_directional_shadow_shrink_size, int)
+ PASS1(environment_set_volumetric_fog_positional_shadow_shrink_size, int)
+
+ PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
+ PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount)
+ PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge)
+
+ PASS1RC(RS::EnvironmentBG, environment_get_background, RID)
+ PASS1RC(int, environment_get_canvas_max_layer, RID)
+
+ PASS3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
+
+ PASS3(screen_space_roughness_limiter_set_active, bool, float, float)
+ PASS1(sub_surface_scattering_set_quality, RS::SubSurfaceScatteringQuality)
+ PASS2(sub_surface_scattering_set_scale, float, float)
+
+ /* CAMERA EFFECTS */
+
+ PASS0R(RID, camera_effects_create)
+
+ PASS2(camera_effects_set_dof_blur_quality, RS::DOFBlurQuality, bool)
+ PASS1(camera_effects_set_dof_blur_bokeh_shape, RS::DOFBokehShape)
+
+ PASS8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
+ PASS3(camera_effects_set_custom_exposure, RID, bool, float)
+
+ PASS1(shadows_quality_set, RS::ShadowQuality)
+ PASS1(directional_shadow_quality_set, RS::ShadowQuality)
+
+ PASS2(sdfgi_set_debug_probe_select, const Vector3 &, const Vector3 &)
+
+ /* Render Buffers */
+
+ PASS0R(RID, render_buffers_create)
+ PASS7(render_buffers_configure, RID, RID, int, int, RS::ViewportMSAA, RS::ViewportScreenSpaceAA, bool)
+
+ /* Shadow Atlas */
+ PASS0R(RID, shadow_atlas_create)
+ PASS2(shadow_atlas_set_size, RID, int)
+ PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int)
+
+ PASS1(set_debug_draw_mode, RS::ViewportDebugDraw)
+
+ virtual void update();
+
+ bool free(RID p_rid);
+
+ void set_scene_render(RendererSceneRender *p_scene_render);
+
+ RendererSceneCull();
+ virtual ~RendererSceneCull();
+};
+
+#endif // VISUALSERVERSCENE_H
diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp
new file mode 100644
index 0000000000..f27bdc6798
--- /dev/null
+++ b/servers/rendering/renderer_scene_render.cpp
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* renderer_scene_render.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_scene_render.h"
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
new file mode 100644
index 0000000000..85353c400d
--- /dev/null
+++ b/servers/rendering/renderer_scene_render.h
@@ -0,0 +1,230 @@
+/*************************************************************************/
+/* renderer_scene_render.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERINGSERVERSCENERENDER_H
+#define RENDERINGSERVERSCENERENDER_H
+
+#include "core/math/camera_matrix.h"
+#include "core/templates/paged_array.h"
+#include "servers/rendering/renderer_storage.h"
+
+class RendererSceneRender {
+public:
+ enum {
+ MAX_DIRECTIONAL_LIGHTS = 8,
+ MAX_DIRECTIONAL_LIGHT_CASCADES = 4
+ };
+
+ struct GeometryInstance {
+ virtual ~GeometryInstance() {}
+ };
+
+ virtual GeometryInstance *geometry_instance_create(RID p_base) = 0;
+ virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0;
+ virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0;
+ virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0;
+ virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0;
+ virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0;
+ virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0;
+ virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0;
+ virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
+ virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
+ virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0;
+ virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) = 0;
+ virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) = 0;
+ virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
+
+ virtual uint32_t geometry_instance_get_pair_mask() = 0;
+ virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0;
+ virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0;
+ virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0;
+ virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) = 0;
+
+ virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0;
+
+ /* SHADOW ATLAS API */
+
+ virtual RID
+ shadow_atlas_create() = 0;
+ virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
+ virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
+ virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
+
+ virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+ virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
+ virtual void set_directional_shadow_count(int p_count) = 0;
+
+ /* SDFGI UPDATE */
+
+ virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0;
+ virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0;
+ virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0;
+ virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0;
+ virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0;
+
+ /* SKY API */
+
+ virtual RID sky_create() = 0;
+ virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
+ virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0;
+ virtual void sky_set_material(RID p_sky, RID p_material) = 0;
+ virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
+
+ /* ENVIRONMENT API */
+
+ virtual RID environment_create() = 0;
+
+ virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0;
+ virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
+ virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0;
+ virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0;
+ virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
+ virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
+ virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) = 0;
+// FIXME: Disabled during Vulkan refactoring, should be ported.
+#if 0
+ virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
+#endif
+
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 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;
+
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+
+ virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
+ virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
+ virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
+ virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
+
+ virtual 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) = 0;
+ virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
+
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) = 0;
+
+ virtual void environment_set_ssao_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) = 0;
+
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
+
+ virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
+ virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
+
+ virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
+
+ virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0;
+
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
+
+ virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
+
+ virtual bool is_environment(RID p_env) const = 0;
+ virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0;
+ virtual int environment_get_canvas_max_layer(RID p_env) const = 0;
+
+ virtual RID camera_effects_create() = 0;
+
+ virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0;
+ virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0;
+
+ virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0;
+ virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0;
+
+ virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
+ virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
+
+ virtual RID light_instance_create(RID p_light) = 0;
+ virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
+ virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0;
+ virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0;
+ virtual void light_instance_mark_visible(RID p_light_instance) = 0;
+ virtual bool light_instances_can_render_shadow_cube() const {
+ return true;
+ }
+
+ virtual RID reflection_atlas_create() = 0;
+ virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0;
+ virtual int reflection_atlas_get_size(RID p_ref_atlas) const = 0;
+
+ virtual RID reflection_probe_instance_create(RID p_probe) = 0;
+ virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) = 0;
+ virtual void reflection_probe_release_atlas_index(RID p_instance) = 0;
+ 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 bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
+
+ virtual RID decal_instance_create(RID p_decal) = 0;
+ virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0;
+
+ virtual RID lightmap_instance_create(RID p_lightmap) = 0;
+ virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) = 0;
+
+ virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
+ virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
+ virtual bool gi_probe_needs_update(RID p_probe) const = 0;
+ virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0;
+
+ virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
+
+ virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
+
+ virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
+ virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) = 0;
+ virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) = 0;
+ virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0;
+
+ virtual void set_scene_pass(uint64_t p_pass) = 0;
+ virtual void set_time(double p_time, double p_step) = 0;
+ virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
+
+ virtual RID render_buffers_create() = 0;
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0;
+
+ virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0;
+ virtual bool screen_space_roughness_limiter_is_active() const = 0;
+
+ virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0;
+ virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0;
+
+ virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0;
+
+ virtual bool free(RID p_rid) = 0;
+
+ virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0;
+
+ virtual bool is_low_end() const = 0;
+
+ virtual void update() = 0;
+ virtual ~RendererSceneRender() {}
+};
+
+#endif // RENDERINGSERVERSCENERENDER_H
diff --git a/servers/rendering/rasterizer.cpp b/servers/rendering/renderer_storage.cpp
index 32084c8a3e..a402ecc668 100644
--- a/servers/rendering/rasterizer.cpp
+++ b/servers/rendering/renderer_storage.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rasterizer.cpp */
+/* renderer_storage.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,49 +28,41 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rasterizer.h"
+#include "renderer_storage.h"
-#include "core/os/os.h"
-#include "core/string/print_string.h"
+RendererStorage *RendererStorage::base_singleton = nullptr;
-Rasterizer *(*Rasterizer::_create_func)() = nullptr;
-
-void RasterizerScene::InstanceDependency::instance_notify_changed(bool p_aabb, bool p_dependencies) {
- for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
- E->key()->dependency_changed(p_aabb, p_dependencies);
+void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p_notification) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ if (E->key()->changed_callback) {
+ E->key()->changed_callback(p_notification, E->key());
+ }
}
}
-void RasterizerScene::InstanceDependency::instance_notify_deleted(RID p_deleted) {
- for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
- E->key()->dependency_deleted(p_deleted);
+void RendererStorage::Dependency::deleted_notify(const RID &p_rid) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ if (E->key()->deleted_callback) {
+ E->key()->deleted_callback(p_rid, E->key());
+ }
}
- for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
E->key()->dependencies.erase(this);
}
-
instances.clear();
}
-RasterizerScene::InstanceDependency::~InstanceDependency() {
+RendererStorage::Dependency::~Dependency() {
#ifdef DEBUG_ENABLED
if (instances.size()) {
WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing.");
- for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
E->key()->dependencies.erase(this);
}
}
#endif
}
-Rasterizer *Rasterizer::create() {
- return _create_func();
-}
-
-RasterizerCanvas *RasterizerCanvas::singleton = nullptr;
-
-RasterizerStorage *RasterizerStorage::base_singleton = nullptr;
-
-RasterizerStorage::RasterizerStorage() {
+RendererStorage::RendererStorage() {
base_singleton = this;
}
diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h
new file mode 100644
index 0000000000..64c23c7803
--- /dev/null
+++ b/servers/rendering/renderer_storage.h
@@ -0,0 +1,623 @@
+/*************************************************************************/
+/* renderer_storage.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERINGSERVERSTORAGE_H
+#define RENDERINGSERVERSTORAGE_H
+
+#include "servers/rendering_server.h"
+
+class RendererStorage {
+ Color default_clear_color;
+
+public:
+ enum DependencyChangedNotification {
+ DEPENDENCY_CHANGED_AABB,
+ DEPENDENCY_CHANGED_MATERIAL,
+ DEPENDENCY_CHANGED_MESH,
+ DEPENDENCY_CHANGED_MULTIMESH,
+ DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES,
+ DEPENDENCY_CHANGED_DECAL,
+ DEPENDENCY_CHANGED_SKELETON_DATA,
+ DEPENDENCY_CHANGED_SKELETON_BONES,
+ DEPENDENCY_CHANGED_LIGHT,
+ DEPENDENCY_CHANGED_REFLECTION_PROBE,
+ };
+
+ struct DependencyTracker;
+
+protected:
+ struct Dependency {
+ void changed_notify(DependencyChangedNotification p_notification);
+ void deleted_notify(const RID &p_rid);
+
+ ~Dependency();
+
+ private:
+ friend struct DependencyTracker;
+ Map<DependencyTracker *, uint32_t> instances;
+ };
+
+public:
+ struct DependencyTracker {
+ void *userdata = nullptr;
+ typedef void (*ChangedCallback)(DependencyChangedNotification, DependencyTracker *);
+ typedef void (*DeletedCallback)(const RID &, DependencyTracker *);
+
+ ChangedCallback changed_callback = nullptr;
+ DeletedCallback deleted_callback = nullptr;
+
+ void update_begin() { // call before updating dependencies
+ instance_version++;
+ }
+
+ void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage
+ dependencies.insert(p_dependency);
+ p_dependency->instances[this] = instance_version;
+ }
+
+ void update_end() { //call after updating dependencies
+ List<Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *>> to_clean_up;
+ for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
+ Dependency *dep = E->get();
+ Map<DependencyTracker *, uint32_t>::Element *F = dep->instances.find(this);
+ ERR_CONTINUE(!F);
+ if (F->get() != instance_version) {
+ Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *> p;
+ p.first = dep;
+ p.second = F;
+ to_clean_up.push_back(p);
+ }
+ }
+
+ while (to_clean_up.size()) {
+ to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second);
+ to_clean_up.pop_front();
+ }
+ }
+
+ void clear() { // clear all dependencies
+ for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
+ Dependency *dep = E->get();
+ dep->instances.erase(this);
+ }
+ dependencies.clear();
+ }
+
+ ~DependencyTracker() { clear(); }
+
+ private:
+ friend struct Dependency;
+ uint32_t instance_version = 0;
+ Set<Dependency *> dependencies;
+ };
+
+ /* TEXTURE API */
+
+ virtual RID texture_2d_create(const Ref<Image> &p_image) = 0;
+ virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0;
+ virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0;
+ virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent
+
+ virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming
+ virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
+ virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
+ virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0;
+
+ //these two APIs can be used together or in combination with the others.
+ virtual RID texture_2d_placeholder_create() = 0;
+ virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0;
+ virtual RID texture_3d_placeholder_create() = 0;
+
+ virtual Ref<Image> texture_2d_get(RID p_texture) const = 0;
+ virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0;
+ virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0;
+
+ virtual void texture_replace(RID p_texture, RID p_by_texture) = 0;
+ virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
+
+ virtual void texture_set_path(RID p_texture, const String &p_path) = 0;
+ virtual String texture_get_path(RID p_texture) const = 0;
+
+ virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0;
+ virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0;
+ virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) = 0;
+
+ virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) = 0;
+
+ virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
+
+ virtual Size2 texture_size_with_proxy(RID p_proxy) = 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;
+
+ /* CANVAS TEXTURE API */
+
+ virtual RID canvas_texture_create() = 0;
+ virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
+ virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
+
+ virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0;
+ virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0;
+
+ /* SHADER API */
+
+ virtual RID shader_create() = 0;
+
+ virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
+ virtual String shader_get_code(RID p_shader) const = 0;
+ virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0;
+
+ virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0;
+ virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0;
+ virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0;
+
+ virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0;
+
+ /* COMMON MATERIAL API */
+
+ virtual RID material_create() = 0;
+
+ virtual void material_set_render_priority(RID p_material, int priority) = 0;
+ virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
+
+ virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0;
+ virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
+
+ virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0;
+
+ virtual bool material_is_animated(RID p_material) = 0;
+ virtual bool material_casts_shadows(RID p_material) = 0;
+
+ struct InstanceShaderParam {
+ PropertyInfo info;
+ int index;
+ Variant default_value;
+ };
+
+ virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
+
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0;
+
+ /* MESH API */
+
+ virtual RID mesh_create() = 0;
+
+ virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) = 0;
+
+ /// Returns stride
+ virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) = 0;
+
+ virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0;
+
+ virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) = 0;
+ virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0;
+
+ virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) = 0;
+
+ virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0;
+ virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0;
+
+ virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const = 0;
+
+ virtual int mesh_get_surface_count(RID p_mesh) const = 0;
+
+ virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0;
+ virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0;
+
+ virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) = 0;
+
+ virtual void mesh_clear(RID p_mesh) = 0;
+
+ virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) = 0;
+
+ /* MESH INSTANCE */
+
+ virtual RID mesh_instance_create(RID p_base) = 0;
+ 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 update_mesh_instances() = 0;
+
+ /* MULTIMESH API */
+
+ virtual RID multimesh_create() = 0;
+
+ virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0;
+
+ virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
+
+ virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0;
+ virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0;
+ virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0;
+ virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0;
+ virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0;
+
+ virtual RID multimesh_get_mesh(RID p_multimesh) const = 0;
+
+ virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0;
+ virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0;
+ virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0;
+ virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0;
+
+ virtual void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) = 0;
+ virtual Vector<float> multimesh_get_buffer(RID p_multimesh) const = 0;
+
+ virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
+ virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
+
+ virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0;
+
+ /* IMMEDIATE API */
+
+ virtual RID immediate_create() = 0;
+ virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0;
+ virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0;
+ virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0;
+ virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) = 0;
+ virtual void immediate_color(RID p_immediate, const Color &p_color) = 0;
+ virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) = 0;
+ virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) = 0;
+ virtual void immediate_end(RID p_immediate) = 0;
+ virtual void immediate_clear(RID p_immediate) = 0;
+ virtual void immediate_set_material(RID p_immediate, RID p_material) = 0;
+ virtual RID immediate_get_material(RID p_immediate) const = 0;
+ virtual AABB immediate_get_aabb(RID p_immediate) const = 0;
+
+ /* SKELETON API */
+
+ virtual RID skeleton_create() = 0;
+ virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0;
+ virtual int skeleton_get_bone_count(RID p_skeleton) const = 0;
+ virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0;
+ virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0;
+ virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
+ virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
+ virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
+
+ /* Light API */
+
+ virtual RID light_create(RS::LightType p_type) = 0;
+
+ RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); }
+ RID omni_light_create() { return light_create(RS::LIGHT_OMNI); }
+ RID spot_light_create() { return light_create(RS::LIGHT_SPOT); }
+
+ virtual void light_set_color(RID p_light, const Color &p_color) = 0;
+ virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0;
+ virtual void light_set_shadow(RID p_light, bool p_enabled) = 0;
+ virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0;
+ virtual void light_set_projector(RID p_light, RID p_texture) = 0;
+ virtual void light_set_negative(RID p_light, bool p_enable) = 0;
+ virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0;
+ virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0;
+ virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) = 0;
+ virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0;
+
+ virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) = 0;
+
+ virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) = 0;
+ virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
+ virtual bool light_directional_get_blend_splits(RID p_light) const = 0;
+ virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0;
+ virtual bool light_directional_is_sky_only(RID p_light) const = 0;
+ virtual void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) = 0;
+ virtual RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const = 0;
+
+ virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0;
+ virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0;
+
+ virtual bool light_has_shadow(RID p_light) const = 0;
+
+ virtual RS::LightType light_get_type(RID p_light) const = 0;
+ virtual AABB light_get_aabb(RID p_light) const = 0;
+ virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0;
+ virtual Color light_get_color(RID p_light) = 0;
+ 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;
+
+ /* PROBE API */
+
+ virtual RID reflection_probe_create() = 0;
+
+ virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0;
+ virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
+ virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) = 0;
+ virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) = 0;
+ 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_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;
+ virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0;
+ virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
+ virtual void reflection_probe_set_lod_threshold(RID p_probe, float p_ratio) = 0;
+
+ 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_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;
+ virtual float reflection_probe_get_lod_threshold(RID p_probe) const = 0;
+
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
+ virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
+
+ /* DECAL API */
+
+ virtual RID decal_create() = 0;
+ virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 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;
+ virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
+ virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
+ virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
+ virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
+ virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
+
+ virtual AABB decal_get_aabb(RID p_decal) const = 0;
+
+ /* GI PROBE API */
+
+ virtual RID gi_probe_create() = 0;
+
+ virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
+
+ virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0;
+ virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0;
+ virtual Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const = 0;
+ virtual Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const = 0;
+ virtual Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const = 0;
+
+ virtual Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const = 0;
+ virtual Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) = 0;
+ virtual float gi_probe_get_dynamic_range(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_propagation(RID p_gi_probe, float p_range) = 0;
+ virtual float gi_probe_get_propagation(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_energy(RID p_gi_probe, float p_energy) = 0;
+ virtual float gi_probe_get_energy(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_ao(RID p_gi_probe, float p_ao) = 0;
+ virtual float gi_probe_get_ao(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) = 0;
+ virtual float gi_probe_get_ao_size(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_bias(RID p_gi_probe, float p_bias) = 0;
+ virtual float gi_probe_get_bias(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) = 0;
+ virtual float gi_probe_get_normal_bias(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_interior(RID p_gi_probe, bool p_enable) = 0;
+ virtual bool gi_probe_is_interior(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) = 0;
+ virtual bool gi_probe_is_using_two_bounces(RID p_gi_probe) const = 0;
+
+ virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0;
+ virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0;
+
+ virtual uint32_t gi_probe_get_version(RID p_probe) = 0;
+
+ /* LIGHTMAP CAPTURE */
+
+ virtual RID lightmap_create() = 0;
+
+ virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0;
+ virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0;
+ virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0;
+ virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0;
+ virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0;
+ virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0;
+ virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0;
+ virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0;
+ virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0;
+ virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0;
+ virtual bool lightmap_is_interior(RID p_lightmap) const = 0;
+ virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0;
+ virtual float lightmap_get_probe_capture_update_speed() const = 0;
+
+ /* PARTICLES */
+
+ virtual RID particles_create() = 0;
+
+ virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
+ virtual bool particles_get_emitting(RID p_particles) = 0;
+
+ virtual void particles_set_amount(RID p_particles, int p_amount) = 0;
+ virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0;
+ virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0;
+ virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0;
+ virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0;
+ virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0;
+ virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0;
+ virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0;
+ virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0;
+ virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
+ virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
+ virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
+ virtual void particles_set_collision_base_size(RID p_particles, float p_size) = 0;
+ virtual void particles_restart(RID p_particles) = 0;
+ virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0;
+ virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) = 0;
+
+ virtual bool particles_is_inactive(RID p_particles) const = 0;
+
+ virtual void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) = 0;
+
+ virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0;
+ virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0;
+
+ virtual void particles_request_process(RID p_particles) = 0;
+ virtual AABB particles_get_current_aabb(RID p_particles) = 0;
+ virtual AABB particles_get_aabb(RID p_particles) const = 0;
+
+ virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0;
+
+ virtual int particles_get_draw_passes(RID p_particles) const = 0;
+ virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0;
+
+ virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0;
+
+ 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 update_particles() = 0;
+
+ /* PARTICLES COLLISION */
+
+ virtual RID particles_collision_create() = 0;
+ virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) = 0;
+ virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0;
+ virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) = 0; //for spheres
+ virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; //for non-spheres
+ virtual void particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) = 0;
+ virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, float p_directionality) = 0;
+ virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, float p_curve) = 0;
+ virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; //for SDF and vector field, heightfield is dynamic
+ virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; //for SDF and vector field
+ 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;
+ virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) = 0;
+ virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0;
+
+ /* GLOBAL VARIABLES */
+
+ virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
+ virtual void global_variable_remove(const StringName &p_name) = 0;
+ virtual Vector<StringName> global_variable_get_list() const = 0;
+
+ virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0;
+ virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0;
+ virtual Variant global_variable_get(const StringName &p_name) const = 0;
+ virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0;
+
+ virtual void global_variables_load_settings(bool p_load_textures = true) = 0;
+ virtual void global_variables_clear() = 0;
+
+ virtual int32_t global_variables_instance_allocate(RID p_instance) = 0;
+ virtual void global_variables_instance_free(RID p_instance) = 0;
+ virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0;
+
+ /* RENDER TARGET */
+
+ enum RenderTargetFlags {
+ RENDER_TARGET_TRANSPARENT,
+ RENDER_TARGET_DIRECT_TO_SCREEN,
+ RENDER_TARGET_FLAG_MAX
+ };
+
+ virtual RID render_target_create() = 0;
+ virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
+ virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0;
+ virtual RID render_target_get_texture(RID p_render_target) = 0;
+ virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
+ virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
+ virtual bool render_target_was_used(RID p_render_target) = 0;
+ virtual void render_target_set_as_unused(RID p_render_target) = 0;
+
+ virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0;
+ virtual bool render_target_is_clear_requested(RID p_render_target) = 0;
+ virtual Color render_target_get_clear_request_color(RID p_render_target) = 0;
+ virtual void render_target_disable_clear_request(RID p_render_target) = 0;
+ virtual void render_target_do_clear_request(RID p_render_target) = 0;
+
+ virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0;
+ virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0;
+
+ virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
+ virtual bool free(RID p_rid) = 0;
+
+ virtual bool has_os_feature(const String &p_feature) const = 0;
+
+ virtual void update_dirty_resources() = 0;
+
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
+ virtual void render_info_begin_capture() = 0;
+ virtual void render_info_end_capture() = 0;
+ virtual int get_captured_render_info(RS::RenderInfo p_info) = 0;
+
+ virtual int get_render_info(RS::RenderInfo p_info) = 0;
+ virtual String get_video_adapter_name() const = 0;
+ virtual String get_video_adapter_vendor() const = 0;
+
+ static RendererStorage *base_singleton;
+
+ void set_default_clear_color(const Color &p_color) {
+ default_clear_color = p_color;
+ }
+
+ Color get_default_clear_color() const {
+ return default_clear_color;
+ }
+#define TIMESTAMP_BEGIN() \
+ { \
+ if (RSG::storage->capturing_timestamps) \
+ RSG::storage->capture_timestamps_begin(); \
+ }
+
+#define RENDER_TIMESTAMP(m_text) \
+ { \
+ if (RSG::storage->capturing_timestamps) \
+ RSG::storage->capture_timestamp(m_text); \
+ }
+
+ bool capturing_timestamps = false;
+
+ virtual void capture_timestamps_begin() = 0;
+ virtual void capture_timestamp(const String &p_name) = 0;
+ virtual uint32_t get_captured_timestamps_count() const = 0;
+ virtual uint64_t get_captured_timestamps_frame() const = 0;
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0;
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0;
+ virtual String get_captured_timestamp_name(uint32_t p_index) const = 0;
+
+ RendererStorage();
+ virtual ~RendererStorage() {}
+};
+
+#endif // RENDERINGSERVERSTORAGE_H
diff --git a/servers/rendering/renderer_thread_pool.cpp b/servers/rendering/renderer_thread_pool.cpp
new file mode 100644
index 0000000000..98050dd508
--- /dev/null
+++ b/servers/rendering/renderer_thread_pool.cpp
@@ -0,0 +1,42 @@
+/*************************************************************************/
+/* renderer_thread_pool.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_thread_pool.h"
+
+RendererThreadPool *RendererThreadPool::singleton = nullptr;
+
+RendererThreadPool::RendererThreadPool() {
+ singleton = this;
+ thread_work_pool.init();
+}
+
+RendererThreadPool::~RendererThreadPool() {
+ thread_work_pool.finish();
+}
diff --git a/servers/rendering/renderer_thread_pool.h b/servers/rendering/renderer_thread_pool.h
new file mode 100644
index 0000000000..ae25415a0d
--- /dev/null
+++ b/servers/rendering/renderer_thread_pool.h
@@ -0,0 +1,45 @@
+/*************************************************************************/
+/* renderer_thread_pool.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef RENDERERTHREADPOOL_H
+#define RENDERERTHREADPOOL_H
+
+#include "core/templates/thread_work_pool.h"
+
+class RendererThreadPool {
+public:
+ ThreadWorkPool thread_work_pool;
+
+ static RendererThreadPool *singleton;
+ RendererThreadPool();
+ ~RendererThreadPool();
+};
+
+#endif // RENDERERTHREADPOOL_H
diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index c048aa381f..9956e4050b 100644
--- a/servers/rendering/rendering_server_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rendering_server_viewport.cpp */
+/* renderer_viewport.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rendering_server_viewport.h"
+#include "renderer_viewport.h"
#include "core/config/project_settings.h"
-#include "rendering_server_canvas.h"
+#include "renderer_canvas_cull.h"
+#include "renderer_scene_cull.h"
#include "rendering_server_globals.h"
-#include "rendering_server_scene.h"
-static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_viewport, RenderingServerCanvas::Canvas *p_canvas, RenderingServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
+static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport, RendererCanvasCull::Canvas *p_canvas, RendererViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
Transform2D xf = p_viewport->global_transform;
float scale = 1.0;
@@ -71,7 +71,7 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi
return xf;
}
-void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) {
+void RendererViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) {
RENDER_TIMESTAMP(">Begin Rendering 3D Scene");
Ref<XRInterface> xr_interface;
@@ -79,15 +79,16 @@ void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p
xr_interface = XRServer::get_singleton()->get_primary_interface();
}
+ float screen_lod_threshold = p_viewport->lod_threshold / float(p_viewport->size.width);
if (p_viewport->use_xr && xr_interface.is_valid()) {
- RSG::scene->render_camera(p_viewport->render_buffers, xr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ RSG::scene->render_camera(p_viewport->render_buffers, xr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, screen_lod_threshold, p_viewport->shadow_atlas);
} else {
- RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->size, screen_lod_threshold, p_viewport->shadow_atlas);
}
RENDER_TIMESTAMP("<End Rendering 3D Scene");
}
-void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) {
+void RendererViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) {
if (p_viewport->measure_render_time) {
String rt_id = "vp_begin_" + itos(p_viewport->self.get_id());
RSG::storage->capture_timestamp(rt_id);
@@ -101,17 +102,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
Color bgcolor = RSG::storage->get_default_clear_color();
- if (!p_viewport->hide_canvas && !p_viewport->disable_environment && RSG::scene->scenario_owner.owns(p_viewport->scenario)) {
- RenderingServerScene::Scenario *scenario = RSG::scene->scenario_owner.getornull(p_viewport->scenario);
- ERR_FAIL_COND(!scenario);
- if (RSG::scene_render->is_environment(scenario->environment)) {
- scenario_draw_canvas_bg = RSG::scene_render->environment_get_background(scenario->environment) == RS::ENV_BG_CANVAS;
-
- scenario_canvas_max_layer = RSG::scene_render->environment_get_canvas_max_layer(scenario->environment);
+ if (!p_viewport->hide_canvas && !p_viewport->disable_environment && 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);
}
}
- bool can_draw_3d = RSG::scene->camera_owner.owns(p_viewport->camera);
+ bool can_draw_3d = RSG::scene->is_camera(p_viewport->camera);
if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) {
if (p_viewport->transparent_bg) {
@@ -124,8 +123,8 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) {
//wants to draw 3D but there is no render buffer, create
- p_viewport->render_buffers = RSG::scene_render->render_buffers_create();
- RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding);
+ p_viewport->render_buffers = RSG::scene->render_buffers_create();
+ RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding);
}
RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor);
@@ -140,25 +139,25 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
Map<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map;
Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y);
- RasterizerCanvas::Light *lights = nullptr;
- RasterizerCanvas::Light *lights_with_shadow = nullptr;
+ RendererCanvasRender::Light *lights = nullptr;
+ RendererCanvasRender::Light *lights_with_shadow = nullptr;
- RasterizerCanvas::Light *directional_lights = nullptr;
- RasterizerCanvas::Light *directional_lights_with_shadow = nullptr;
+ RendererCanvasRender::Light *directional_lights = nullptr;
+ RendererCanvasRender::Light *directional_lights_with_shadow = nullptr;
if (p_viewport->sdf_active) {
//process SDF
Rect2 sdf_rect = RSG::storage->render_target_get_sdf_rect(p_viewport->render_target);
- RasterizerCanvas::LightOccluderInstance *occluders = nullptr;
+ RendererCanvasRender::LightOccluderInstance *occluders = nullptr;
//make list of occluders
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
- RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
+ RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
- for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
+ for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
if (!F->get()->enabled) {
continue;
}
@@ -184,14 +183,14 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
RENDER_TIMESTAMP("Cull Canvas Lights");
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
- RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
+ RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
//find lights in canvas
- for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) {
- RasterizerCanvas::Light *cl = F->get();
+ for (Set<RendererCanvasRender::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) {
+ RendererCanvasRender::Light *cl = F->get();
if (cl->enabled && cl->texture.is_valid()) {
//not super efficient..
Size2 tsize = RSG::storage->texture_size_with_proxy(cl->texture);
@@ -228,8 +227,8 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
}
- for (Set<RasterizerCanvas::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) {
- RasterizerCanvas::Light *cl = F->get();
+ for (Set<RendererCanvasRender::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) {
+ RendererCanvasRender::Light *cl = F->get();
if (cl->enabled) {
cl->filter_next_ptr = directional_lights;
directional_lights = cl;
@@ -254,17 +253,17 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
if (lights_with_shadow) {
//update shadows if any
- RasterizerCanvas::LightOccluderInstance *occluders = nullptr;
+ RendererCanvasRender::LightOccluderInstance *occluders = nullptr;
RENDER_TIMESTAMP(">Render 2D Shadows");
RENDER_TIMESTAMP("Cull Occluders");
//make list of occluders
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
- RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
+ RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
- for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
+ for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
if (!F->get()->enabled) {
continue;
}
@@ -277,7 +276,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
//update the light shadowmaps with them
- RasterizerCanvas::Light *light = lights_with_shadow;
+ RendererCanvasRender::Light *light = lights_with_shadow;
while (light) {
RENDER_TIMESTAMP("Render Shadow");
@@ -290,7 +289,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
if (directional_lights_with_shadow) {
//update shadows if any
- RasterizerCanvas::Light *light = directional_lights_with_shadow;
+ RendererCanvasRender::Light *light = directional_lights_with_shadow;
while (light) {
Vector2 light_dir = -light->xform_cache.elements[1].normalized(); // Y is light direction
float cull_distance = light->directional_distance;
@@ -335,17 +334,17 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
Vector2 xf_points[6];
- RasterizerCanvas::LightOccluderInstance *occluders = nullptr;
+ RendererCanvasRender::LightOccluderInstance *occluders = nullptr;
RENDER_TIMESTAMP(">Render Directional 2D Shadows");
//make list of occluders
int occ_cullded = 0;
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
- RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
+ RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
- for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
+ for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
if (!F->get()->enabled) {
continue;
}
@@ -381,14 +380,14 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) {
- RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get()->canvas);
+ RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get()->canvas);
Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size);
- RasterizerCanvas::Light *canvas_lights = nullptr;
- RasterizerCanvas::Light *canvas_directional_lights = nullptr;
+ RendererCanvasRender::Light *canvas_lights = nullptr;
+ RendererCanvasRender::Light *canvas_directional_lights = nullptr;
- RasterizerCanvas::Light *ptr = lights;
+ RendererCanvasRender::Light *ptr = lights;
while (ptr) {
if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) {
ptr->next_ptr = canvas_lights;
@@ -444,7 +443,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
}
-void RenderingServerViewport::draw_viewports() {
+void RendererViewport::draw_viewports() {
timestamp_vp_map.clear();
// get our xr interface in case we need it
@@ -464,7 +463,7 @@ void RenderingServerViewport::draw_viewports() {
//sort viewports
active_viewports.sort_custom<ViewportSort>();
- Map<DisplayServer::WindowID, Vector<Rasterizer::BlitToScreen>> blit_to_screen_list;
+ Map<DisplayServer::WindowID, Vector<RendererCompositor::BlitToScreen>> blit_to_screen_list;
//draw viewports
RENDER_TIMESTAMP(">Render Viewports");
@@ -559,7 +558,7 @@ void RenderingServerViewport::draw_viewports() {
{
RSG::storage->render_target_set_external_texture(vp->render_target, 0);
- RSG::scene_render->set_debug_draw_mode(vp->debug_draw);
+ RSG::scene->set_debug_draw_mode(vp->debug_draw);
RSG::storage->render_info_begin_capture();
// render standard mono camera
@@ -575,7 +574,7 @@ void RenderingServerViewport::draw_viewports() {
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && (!vp->viewport_render_direct_to_screen || !RSG::rasterizer->is_low_end())) {
//copy to screen if set as such
- Rasterizer::BlitToScreen blit;
+ RendererCompositor::BlitToScreen blit;
blit.render_target = vp->render_target;
if (vp->viewport_to_screen_rect != Rect2()) {
blit.rect = vp->viewport_to_screen_rect;
@@ -585,7 +584,7 @@ void RenderingServerViewport::draw_viewports() {
}
if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
- blit_to_screen_list[vp->viewport_to_screen] = Vector<Rasterizer::BlitToScreen>();
+ blit_to_screen_list[vp->viewport_to_screen] = Vector<RendererCompositor::BlitToScreen>();
}
blit_to_screen_list[vp->viewport_to_screen].push_back(blit);
@@ -598,18 +597,18 @@ void RenderingServerViewport::draw_viewports() {
RENDER_TIMESTAMP("<Rendering Viewport " + itos(i));
}
- RSG::scene_render->set_debug_draw_mode(RS::VIEWPORT_DEBUG_DRAW_DISABLED);
+ RSG::scene->set_debug_draw_mode(RS::VIEWPORT_DEBUG_DRAW_DISABLED);
RENDER_TIMESTAMP("<Render Viewports");
//this needs to be called to make screen swapping more efficient
RSG::rasterizer->prepare_for_blitting_render_targets();
- for (Map<int, Vector<Rasterizer::BlitToScreen>>::Element *E = blit_to_screen_list.front(); E; E = E->next()) {
+ for (Map<int, Vector<RendererCompositor::BlitToScreen>>::Element *E = blit_to_screen_list.front(); E; E = E->next()) {
RSG::rasterizer->blit_render_targets_to_screen(E->key(), E->get().ptr(), E->get().size());
}
}
-RID RenderingServerViewport::viewport_create() {
+RID RendererViewport::viewport_create() {
Viewport *viewport = memnew(Viewport);
RID rid = viewport_owner.make_rid(viewport);
@@ -618,20 +617,20 @@ RID RenderingServerViewport::viewport_create() {
viewport->hide_scenario = false;
viewport->hide_canvas = false;
viewport->render_target = RSG::storage->render_target_create();
- viewport->shadow_atlas = RSG::scene_render->shadow_atlas_create();
+ viewport->shadow_atlas = RSG::scene->shadow_atlas_create();
viewport->viewport_render_direct_to_screen = false;
return rid;
}
-void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
+void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->use_xr = p_use_xr;
}
-void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
+void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
ERR_FAIL_COND(p_width < 0 && p_height < 0);
Viewport *viewport = viewport_owner.getornull(p_viewport);
@@ -641,15 +640,15 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int
RSG::storage->render_target_set_size(viewport->render_target, p_width, p_height);
if (viewport->render_buffers.is_valid()) {
if (p_width == 0 || p_height == 0) {
- RSG::scene_render->free(viewport->render_buffers);
+ RSG::scene->free(viewport->render_buffers);
viewport->render_buffers = RID();
} else {
- RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding);
+ RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding);
}
}
}
-void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) {
+void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -661,21 +660,21 @@ void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active)
}
}
-void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) {
+void RendererViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->parent = p_parent_viewport;
}
-void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) {
+void RendererViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->clear_mode = p_clear_mode;
}
-void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) {
+void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -701,7 +700,7 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re
}
}
-void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) {
+void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -715,7 +714,7 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor
RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y);
}
- RSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
+ RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
viewport->viewport_render_direct_to_screen = p_enable;
// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
@@ -725,61 +724,61 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor
}
}
-void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) {
+void RendererViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->update_mode = p_mode;
}
-RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const {
+RID RendererViewport::viewport_get_texture(RID p_viewport) const {
const Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND_V(!viewport, RID());
return RSG::storage->render_target_get_texture(viewport->render_target);
}
-void RenderingServerViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) {
+void RendererViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->hide_scenario = p_hide;
}
-void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) {
+void RendererViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->hide_canvas = p_hide;
}
-void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) {
+void RendererViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->disable_environment = p_disable;
}
-void RenderingServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
+void RendererViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->camera = p_camera;
}
-void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) {
+void RendererViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->scenario = p_scenario;
}
-void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) {
+void RendererViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
ERR_FAIL_COND(viewport->canvas_map.has(p_canvas));
- RenderingServerCanvas::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas);
+ RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
canvas->viewports.insert(p_viewport);
@@ -789,18 +788,18 @@ void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canva
viewport->canvas_map[p_canvas].canvas = canvas;
}
-void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) {
+void RendererViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
- RenderingServerCanvas::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas);
+ RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
viewport->canvas_map.erase(p_canvas);
canvas->viewports.erase(p_viewport);
}
-void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) {
+void RendererViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -808,22 +807,22 @@ void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID
viewport->canvas_map[p_canvas].transform = p_offset;
}
-void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) {
+void RendererViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
- RSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
+ RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
viewport->transparent_bg = p_enabled;
}
-void RenderingServerViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) {
+void RendererViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->global_transform = p_transform;
}
-void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) {
+void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -832,23 +831,23 @@ void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p
viewport->canvas_map[p_canvas].sublayer = p_sublayer;
}
-void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
+void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->shadow_atlas_size = p_size;
- RSG::scene_render->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size);
+ RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size);
}
-void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
+void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
- RSG::scene_render->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv);
+ RSG::scene->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv);
}
-void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) {
+void RendererViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -857,11 +856,11 @@ void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA
}
viewport->msaa = p_msaa;
if (viewport->render_buffers.is_valid()) {
- RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding);
+ RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding);
}
}
-void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) {
+void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -870,11 +869,11 @@ void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::V
}
viewport->screen_space_aa = p_mode;
if (viewport->render_buffers.is_valid()) {
- RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding);
+ RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding);
}
}
-void RenderingServerViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) {
+void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -883,11 +882,18 @@ void RenderingServerViewport::viewport_set_use_debanding(RID p_viewport, bool p_
}
viewport->use_debanding = p_use_debanding;
if (viewport->render_buffers.is_valid()) {
- RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding);
+ RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding);
}
}
-int RenderingServerViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) {
+void RendererViewport::viewport_set_lod_threshold(RID p_viewport, float p_pixels) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->lod_threshold = p_pixels;
+}
+
+int RendererViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) {
ERR_FAIL_INDEX_V(p_info, RS::VIEWPORT_RENDER_INFO_MAX, -1);
Viewport *viewport = viewport_owner.getornull(p_viewport);
@@ -898,54 +904,54 @@ int RenderingServerViewport::viewport_get_render_info(RID p_viewport, RS::Viewpo
return viewport->render_info[p_info];
}
-void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) {
+void RendererViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->debug_draw = p_draw;
}
-void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) {
+void RendererViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->measure_render_time = p_enable;
}
-float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const {
+float RendererViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND_V(!viewport, 0);
return double(viewport->time_cpu_end - viewport->time_cpu_begin) / 1000.0;
}
-float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const {
+float RendererViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND_V(!viewport, 0);
return double((viewport->time_gpu_end - viewport->time_gpu_begin) / 1000) / 1000.0;
}
-void RenderingServerViewport::viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled) {
+void RendererViewport::viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->snap_2d_transforms_to_pixel = p_enabled;
}
-void RenderingServerViewport::viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) {
+void RendererViewport::viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->snap_2d_vertices_to_pixel = p_enabled;
}
-void RenderingServerViewport::viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter) {
+void RendererViewport::viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter) {
ERR_FAIL_COND_MSG(p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, "Viewport does not accept DEFAULT as texture filter (it's the topmost choice already).)");
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->texture_filter = p_filter;
}
-void RenderingServerViewport::viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat) {
+void RendererViewport::viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat) {
ERR_FAIL_COND_MSG(p_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, "Viewport does not accept DEFAULT as texture repeat (it's the topmost choice already).)");
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -953,21 +959,21 @@ void RenderingServerViewport::viewport_set_default_canvas_item_texture_repeat(RI
viewport->texture_repeat = p_repeat;
}
-void RenderingServerViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
+void RendererViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
RSG::storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale);
}
-bool RenderingServerViewport::free(RID p_rid) {
+bool RendererViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
Viewport *viewport = viewport_owner.getornull(p_rid);
RSG::storage->free(viewport->render_target);
- RSG::scene_render->free(viewport->shadow_atlas);
+ RSG::scene->free(viewport->shadow_atlas);
if (viewport->render_buffers.is_valid()) {
- RSG::scene_render->free(viewport->render_buffers);
+ RSG::scene->free(viewport->render_buffers);
}
while (viewport->canvas_map.front()) {
@@ -986,7 +992,7 @@ bool RenderingServerViewport::free(RID p_rid) {
return false;
}
-void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) {
+void RendererViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) {
RID *vp = timestamp_vp_map.getptr(p_timestamp);
if (!vp) {
return;
@@ -1008,9 +1014,9 @@ void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cp
}
}
-void RenderingServerViewport::set_default_clear_color(const Color &p_color) {
+void RendererViewport::set_default_clear_color(const Color &p_color) {
RSG::storage->set_default_clear_color(p_color);
}
-RenderingServerViewport::RenderingServerViewport() {
+RendererViewport::RendererViewport() {
}
diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/renderer_viewport.h
index ba55b2e66e..c3ff52a836 100644
--- a/servers/rendering/rendering_server_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rendering_server_viewport.h */
+/* renderer_viewport.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -33,11 +33,11 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
-#include "rasterizer.h"
+#include "renderer_compositor.h"
#include "servers/rendering_server.h"
#include "servers/xr/xr_interface.h"
-class RenderingServerViewport {
+class RendererViewport {
public:
struct CanvasBase {
};
@@ -84,6 +84,8 @@ public:
bool sdf_active;
+ float lod_threshold = 1.0;
+
uint64_t last_pass = 0;
int render_info[RS::VIEWPORT_RENDER_INFO_MAX];
@@ -222,6 +224,8 @@ public:
void viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode);
void viewport_set_use_debanding(RID p_viewport, bool p_use_debanding);
+ void viewport_set_lod_threshold(RID p_viewport, float p_pixels);
+
virtual int viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info);
virtual void viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw);
@@ -244,8 +248,8 @@ public:
bool free(RID p_rid);
- RenderingServerViewport();
- virtual ~RenderingServerViewport() {}
+ RendererViewport();
+ virtual ~RendererViewport() {}
};
#endif // VISUALSERVERVIEWPORT_H
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index 1259b161bd..73c86a0a1d 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -68,7 +68,7 @@ RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const
Vector<Vector<uint8_t>> data;
for (int i = 0; i < p_data.size(); i++) {
Vector<uint8_t> byte_slice = p_data[i];
- ERR_FAIL_COND_V(byte_slice.empty(), RID());
+ ERR_FAIL_COND_V(byte_slice.is_empty(), RID());
data.push_back(byte_slice);
}
return texture_create(p_format->base, p_view->base, data);
@@ -154,7 +154,7 @@ RID RenderingDevice::shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_
String error = p_bytecode->get_stage_compile_error(stage);
ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
sd.spir_v = p_bytecode->get_stage_bytecode(stage);
- if (sd.spir_v.empty()) {
+ if (sd.spir_v.is_empty()) {
continue;
}
stage_data.push_back(sd);
@@ -270,7 +270,7 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create);
- ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()));
+ 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("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index f1f8b3cda0..787805ea6a 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -392,7 +392,7 @@ public:
uint32_t depth;
uint32_t array_layers;
uint32_t mipmaps;
- TextureType type;
+ TextureType texture_type;
TextureSamples samples;
uint32_t usage_bits;
Vector<DataFormat> shareable_formats;
@@ -404,7 +404,7 @@ public:
depth = 1;
array_layers = 1;
mipmaps = 1;
- type = TEXTURE_TYPE_2D;
+ texture_type = TEXTURE_TYPE_2D;
samples = TEXTURE_SAMPLES_1;
usage_bits = 0;
}
@@ -433,6 +433,7 @@ public:
TEXTURE_SLICE_2D,
TEXTURE_SLICE_CUBEMAP,
TEXTURE_SLICE_3D,
+ 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, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0;
@@ -564,7 +565,7 @@ public:
frequency = VERTEX_FREQUENCY_VERTEX;
}
};
- virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>()) = 0;
+ virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_as_storage = false) = 0;
typedef int64_t VertexFormatID;
@@ -629,7 +630,7 @@ public:
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 {
- UniformType type;
+ UniformType uniform_type;
int binding; //binding index as specified in shader
//for single items, provide one ID, for
@@ -640,7 +641,7 @@ public:
Vector<RID> ids;
Uniform() {
- type = UNIFORM_TYPE_IMAGE;
+ uniform_type = UNIFORM_TYPE_IMAGE;
binding = 0;
}
};
diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp
index af9ecef0dd..2f11360364 100644
--- a/servers/rendering/rendering_device_binds.cpp
+++ b/servers/rendering/rendering_device_binds.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -163,7 +163,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present.");
}
- if (version_texts.empty()) {
+ if (version_texts.is_empty()) {
version_texts[""] = ""; //make sure a default version exists
}
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index 66c6a1c3a9..e43c3669b5 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -64,7 +64,7 @@ public:
RD_SETGET(uint32_t, depth)
RD_SETGET(uint32_t, array_layers)
RD_SETGET(uint32_t, mipmaps)
- RD_SETGET(RD::TextureType, type)
+ RD_SETGET(RD::TextureType, texture_type)
RD_SETGET(RD::TextureSamples, samples)
RD_SETGET(uint32_t, usage_bits)
@@ -79,7 +79,7 @@ protected:
RD_BIND(Variant::INT, RDTextureFormat, depth);
RD_BIND(Variant::INT, RDTextureFormat, array_layers);
RD_BIND(Variant::INT, RDTextureFormat, mipmaps);
- RD_BIND(Variant::INT, RDTextureFormat, type);
+ RD_BIND(Variant::INT, RDTextureFormat, texture_type);
RD_BIND(Variant::INT, RDTextureFormat, samples);
RD_BIND(Variant::INT, RDTextureFormat, usage_bits);
ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format);
@@ -392,7 +392,7 @@ class RDUniform : public Reference {
RD::Uniform base;
public:
- RD_SETGET(RD::UniformType, type)
+ RD_SETGET(RD::UniformType, uniform_type)
RD_SETGET(int32_t, binding)
void add_id(const RID &p_id) { base.ids.push_back(p_id); }
@@ -415,7 +415,7 @@ protected:
}
}
static void _bind_methods() {
- RD_BIND(Variant::INT, RDUniform, type);
+ RD_BIND(Variant::INT, RDUniform, uniform_type);
RD_BIND(Variant::INT, RDUniform, binding);
ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id);
ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids);
diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_default.cpp
index 94cfb6b752..8c6e97a0af 100644
--- a/servers/rendering/rendering_server_raster.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rendering_server_raster.cpp */
+/* rendering_server_default.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,43 +28,43 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rendering_server_raster.h"
+#include "rendering_server_default.h"
#include "core/config/project_settings.h"
#include "core/io/marshalls.h"
#include "core/os/os.h"
#include "core/templates/sort_array.h"
-#include "rendering_server_canvas.h"
+#include "renderer_canvas_cull.h"
+#include "renderer_scene_cull.h"
#include "rendering_server_globals.h"
-#include "rendering_server_scene.h"
// careful, these may run in different threads than the visual server
-int RenderingServerRaster::changes = 0;
+int RenderingServerDefault::changes = 0;
/* BLACK BARS */
-void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) {
- black_margin[MARGIN_LEFT] = p_left;
- black_margin[MARGIN_TOP] = p_top;
- black_margin[MARGIN_RIGHT] = p_right;
- black_margin[MARGIN_BOTTOM] = p_bottom;
+void RenderingServerDefault::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) {
+ black_margin[SIDE_LEFT] = p_left;
+ black_margin[SIDE_TOP] = p_top;
+ black_margin[SIDE_RIGHT] = p_right;
+ black_margin[SIDE_BOTTOM] = p_bottom;
}
-void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) {
- black_image[MARGIN_LEFT] = p_left;
- black_image[MARGIN_TOP] = p_top;
- black_image[MARGIN_RIGHT] = p_right;
- black_image[MARGIN_BOTTOM] = p_bottom;
+void RenderingServerDefault::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) {
+ black_image[SIDE_LEFT] = p_left;
+ black_image[SIDE_TOP] = p_top;
+ black_image[SIDE_RIGHT] = p_right;
+ black_image[SIDE_BOTTOM] = p_bottom;
}
-void RenderingServerRaster::_draw_margins() {
+void RenderingServerDefault::_draw_margins() {
RSG::canvas_render->draw_window_margins(black_margin, black_image);
};
/* FREE */
-void RenderingServerRaster::free(RID p_rid) {
+void RenderingServerDefault::free(RID p_rid) {
if (RSG::storage->free(p_rid)) {
return;
}
@@ -77,14 +77,11 @@ void RenderingServerRaster::free(RID p_rid) {
if (RSG::scene->free(p_rid)) {
return;
}
- if (RSG::scene_render->free(p_rid)) {
- return;
- }
}
/* EVENT QUEUING */
-void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) {
+void RenderingServerDefault::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) {
ERR_FAIL_NULL(p_where);
FrameDrawnCallbacks fdc;
fdc.object = p_where->get_instance_id();
@@ -94,7 +91,7 @@ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const
frame_drawn_callbacks.push_back(fdc);
}
-void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
+void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
//needs to be done before changes is reset to 0, to not force the editor to redraw
RS::get_singleton()->emit_signal("frame_pre_draw");
@@ -104,14 +101,16 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
TIMESTAMP_BEGIN()
- RSG::scene_render->update(); //update scenes stuff before updating instances
+ uint64_t time_usec = OS::get_singleton()->get_ticks_usec();
+
+ RSG::scene->update(); //update scenes stuff before updating instances
- RSG::scene->update_dirty_instances(); //update scene stuff
+ frame_setup_time = double(OS::get_singleton()->get_ticks_usec() - time_usec) / 1000.0;
- RSG::scene->render_particle_colliders();
RSG::storage->update_particles(); //need to be done after instances are updated (colliders and particle transforms), and colliders are rendered
RSG::scene->render_probes();
+
RSG::viewport->draw_viewports();
RSG::canvas_render->update();
@@ -165,18 +164,22 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
frame_profile_frame = RSG::storage->get_captured_timestamps_frame();
}
-void RenderingServerRaster::sync() {
+float RenderingServerDefault::get_frame_setup_time_cpu() const {
+ return frame_setup_time;
+}
+
+void RenderingServerDefault::sync() {
}
-bool RenderingServerRaster::has_changed() const {
+bool RenderingServerDefault::has_changed() const {
return changes > 0;
}
-void RenderingServerRaster::init() {
+void RenderingServerDefault::init() {
RSG::rasterizer->initialize();
}
-void RenderingServerRaster::finish() {
+void RenderingServerDefault::finish() {
if (test_cube.is_valid()) {
free(test_cube);
}
@@ -186,69 +189,69 @@ void RenderingServerRaster::finish() {
/* STATUS INFORMATION */
-int RenderingServerRaster::get_render_info(RenderInfo p_info) {
+int RenderingServerDefault::get_render_info(RenderInfo p_info) {
return RSG::storage->get_render_info(p_info);
}
-String RenderingServerRaster::get_video_adapter_name() const {
+String RenderingServerDefault::get_video_adapter_name() const {
return RSG::storage->get_video_adapter_name();
}
-String RenderingServerRaster::get_video_adapter_vendor() const {
+String RenderingServerDefault::get_video_adapter_vendor() const {
return RSG::storage->get_video_adapter_vendor();
}
-void RenderingServerRaster::set_frame_profiling_enabled(bool p_enable) {
+void RenderingServerDefault::set_frame_profiling_enabled(bool p_enable) {
RSG::storage->capturing_timestamps = p_enable;
}
-uint64_t RenderingServerRaster::get_frame_profile_frame() {
+uint64_t RenderingServerDefault::get_frame_profile_frame() {
return frame_profile_frame;
}
-Vector<RenderingServer::FrameProfileArea> RenderingServerRaster::get_frame_profile() {
+Vector<RenderingServer::FrameProfileArea> RenderingServerDefault::get_frame_profile() {
return frame_profile;
}
/* TESTING */
-void RenderingServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
+void RenderingServerDefault::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
redraw_request();
RSG::rasterizer->set_boot_image(p_image, p_color, p_scale, p_use_filter);
}
-void RenderingServerRaster::set_default_clear_color(const Color &p_color) {
+void RenderingServerDefault::set_default_clear_color(const Color &p_color) {
RSG::viewport->set_default_clear_color(p_color);
}
-bool RenderingServerRaster::has_feature(Features p_feature) const {
+bool RenderingServerDefault::has_feature(Features p_feature) const {
return false;
}
-void RenderingServerRaster::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {
- RSG::scene_render->sdfgi_set_debug_probe_select(p_position, p_dir);
+void RenderingServerDefault::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {
+ RSG::scene->sdfgi_set_debug_probe_select(p_position, p_dir);
}
-RID RenderingServerRaster::get_test_cube() {
+RID RenderingServerDefault::get_test_cube() {
if (!test_cube.is_valid()) {
test_cube = _make_test_cube();
}
return test_cube;
}
-bool RenderingServerRaster::has_os_feature(const String &p_feature) const {
+bool RenderingServerDefault::has_os_feature(const String &p_feature) const {
return RSG::storage->has_os_feature(p_feature);
}
-void RenderingServerRaster::set_debug_generate_wireframes(bool p_generate) {
+void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) {
RSG::storage->set_debug_generate_wireframes(p_generate);
}
-void RenderingServerRaster::call_set_use_vsync(bool p_enable) {
+void RenderingServerDefault::call_set_use_vsync(bool p_enable) {
DisplayServer::get_singleton()->_set_use_vsync(p_enable);
}
-bool RenderingServerRaster::is_low_end() const {
+bool RenderingServerDefault::is_low_end() const {
// FIXME: Commented out when rebasing vulkan branch on master,
// causes a crash, it seems rasterizer is not initialized yet the
// first time it's called.
@@ -256,14 +259,15 @@ bool RenderingServerRaster::is_low_end() const {
return false;
}
-RenderingServerRaster::RenderingServerRaster() {
- RSG::canvas = memnew(RenderingServerCanvas);
- RSG::viewport = memnew(RenderingServerViewport);
- RSG::scene = memnew(RenderingServerScene);
- RSG::rasterizer = Rasterizer::create();
+RenderingServerDefault::RenderingServerDefault() {
+ RSG::canvas = memnew(RendererCanvasCull);
+ RSG::viewport = memnew(RendererViewport);
+ RendererSceneCull *sr = memnew(RendererSceneCull);
+ RSG::scene = sr;
+ RSG::rasterizer = RendererCompositor::create();
RSG::storage = RSG::rasterizer->get_storage();
RSG::canvas_render = RSG::rasterizer->get_canvas();
- RSG::scene_render = RSG::rasterizer->get_scene();
+ sr->set_scene_render(RSG::rasterizer->get_scene());
frame_profile_frame = 0;
@@ -273,7 +277,7 @@ RenderingServerRaster::RenderingServerRaster() {
}
}
-RenderingServerRaster::~RenderingServerRaster() {
+RenderingServerDefault::~RenderingServerDefault() {
memdelete(RSG::canvas);
memdelete(RSG::viewport);
memdelete(RSG::rasterizer);
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_default.h
index 413fcda581..71f459f34a 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_default.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rendering_server_raster.h */
+/* rendering_server_default.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,18 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RENDERING_SERVER_RASTER_H
-#define RENDERING_SERVER_RASTER_H
+#ifndef RENDERING_SERVER_DEFAULT_H
+#define RENDERING_SERVER_DEFAULT_H
#include "core/math/octree.h"
-#include "rendering_server_canvas.h"
+#include "renderer_canvas_cull.h"
+#include "renderer_scene_cull.h"
+#include "renderer_viewport.h"
#include "rendering_server_globals.h"
-#include "rendering_server_scene.h"
-#include "rendering_server_viewport.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
-class RenderingServerRaster : public RenderingServer {
+class RenderingServerDefault : public RenderingServer {
enum {
MAX_INSTANCE_CULL = 8192,
MAX_INSTANCE_LIGHTS = 4,
@@ -72,6 +72,8 @@ class RenderingServerRaster : public RenderingServer {
uint64_t frame_profile_frame;
Vector<FrameProfileArea> frame_profile;
+ float frame_setup_time = 0;
+
public:
//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed()
//#define DEBUG_CHANGES
@@ -217,6 +219,8 @@ public:
BIND2RC(RID, shader_get_default_texture_param, RID, const StringName &)
BIND2RC(Variant, shader_get_param_default, RID, const StringName &)
+ BIND1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID)
+
/* COMMON MATERIAL API */
BIND0R(RID, material_create)
@@ -231,14 +235,17 @@ public:
/* MESH API */
- virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces) {
+ virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) {
RID mesh = mesh_create();
+ mesh_set_blend_shape_count(mesh, p_blend_shape_count);
for (int i = 0; i < p_surfaces.size(); i++) {
mesh_add_surface(mesh, p_surfaces[i]);
}
return mesh;
}
+ BIND2(mesh_set_blend_shape_count, RID, int)
+
BIND0R(RID, mesh_create)
BIND2(mesh_add_surface, RID, const SurfaceData &)
@@ -336,6 +343,7 @@ public:
BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
BIND2(light_directional_set_blend_splits, RID, bool)
+ BIND2(light_directional_set_sky_only, RID, bool)
BIND2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
/* PROBE API */
@@ -355,6 +363,7 @@ public:
BIND2(reflection_probe_set_enable_shadows, RID, bool)
BIND2(reflection_probe_set_cull_mask, RID, uint32_t)
BIND2(reflection_probe_set_resolution, RID, int)
+ BIND2(reflection_probe_set_lod_threshold, RID, float)
/* DECAL API */
@@ -541,6 +550,7 @@ public:
BIND2(viewport_set_msaa, RID, ViewportMSAA)
BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
BIND2(viewport_set_use_debanding, RID, bool)
+ BIND2(viewport_set_lod_threshold, RID, float)
BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
@@ -553,7 +563,7 @@ public:
#undef BINDBASE
//from now on, calls forwarded to this singleton
-#define BINDBASE RSG::scene_render
+#define BINDBASE RSG::scene
BIND1(directional_shadow_atlas_set_size, int)
BIND1(gi_probe_set_quality, GIProbeQuality)
@@ -584,8 +594,8 @@ public:
BIND6(environment_set_ssr, RID, bool, int, float, float, float)
BIND1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality)
- BIND9(environment_set_ssao, RID, bool, float, float, float, float, float, EnvironmentSSAOBlur, float)
- BIND2(environment_set_ssao_quality, EnvironmentSSAOQuality, bool)
+ BIND10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float)
+ BIND6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float)
BIND11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
BIND1(environment_glow_set_use_bicubic_upscale, bool)
@@ -593,7 +603,7 @@ public:
BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
- BIND6(environment_set_adjustment, RID, bool, float, float, float, RID)
+ BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
BIND9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter)
@@ -669,6 +679,7 @@ public:
BIND5(instance_geometry_set_draw_range, RID, float, float, float, float)
BIND2(instance_geometry_set_as_instance_lod, RID, RID)
BIND4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
+ BIND2(instance_geometry_set_lod_bias, RID, float)
BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
@@ -717,7 +728,7 @@ public:
BIND2(canvas_item_set_draw_behind_parent, RID, bool)
BIND5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
- BIND4(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float)
+ BIND5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
BIND4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float)
BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
@@ -838,6 +849,8 @@ public:
/* TESTING */
+ virtual float get_frame_setup_time_cpu() const;
+
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true);
virtual void set_default_clear_color(const Color &p_color);
@@ -852,8 +865,8 @@ public:
virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir);
- RenderingServerRaster();
- ~RenderingServerRaster();
+ RenderingServerDefault();
+ ~RenderingServerDefault();
#undef DISPLAY_CHANGED
diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp
index 5a270520a9..c0d9988e85 100644
--- a/servers/rendering/rendering_server_globals.cpp
+++ b/servers/rendering/rendering_server_globals.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -30,11 +30,10 @@
#include "rendering_server_globals.h"
-RasterizerStorage *RenderingServerGlobals::storage = nullptr;
-RasterizerCanvas *RenderingServerGlobals::canvas_render = nullptr;
-RasterizerScene *RenderingServerGlobals::scene_render = nullptr;
-Rasterizer *RenderingServerGlobals::rasterizer = nullptr;
+RendererStorage *RenderingServerGlobals::storage = nullptr;
+RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr;
+RendererCompositor *RenderingServerGlobals::rasterizer = nullptr;
-RenderingServerCanvas *RenderingServerGlobals::canvas = nullptr;
-RenderingServerViewport *RenderingServerGlobals::viewport = nullptr;
-RenderingServerScene *RenderingServerGlobals::scene = nullptr;
+RendererCanvasCull *RenderingServerGlobals::canvas = nullptr;
+RendererViewport *RenderingServerGlobals::viewport = nullptr;
+RendererScene *RenderingServerGlobals::scene = nullptr;
diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h
index b33f328b69..a28a0f5180 100644
--- a/servers/rendering/rendering_server_globals.h
+++ b/servers/rendering/rendering_server_globals.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -31,22 +31,23 @@
#ifndef RENDERING_SERVER_GLOBALS_H
#define RENDERING_SERVER_GLOBALS_H
-#include "rasterizer.h"
+#include "servers/rendering/renderer_canvas_cull.h"
+#include "servers/rendering/renderer_canvas_render.h"
+#include "servers/rendering/renderer_scene.h"
-class RenderingServerCanvas;
-class RenderingServerViewport;
-class RenderingServerScene;
+class RendererCanvasCull;
+class RendererViewport;
+class RendererScene;
class RenderingServerGlobals {
public:
- static RasterizerStorage *storage;
- static RasterizerCanvas *canvas_render;
- static RasterizerScene *scene_render;
- static Rasterizer *rasterizer;
+ static RendererStorage *storage;
+ static RendererCanvasRender *canvas_render;
+ static RendererCompositor *rasterizer;
- static RenderingServerCanvas *canvas;
- static RenderingServerViewport *viewport;
- static RenderingServerScene *scene;
+ static RendererCanvasCull *canvas;
+ static RendererViewport *viewport;
+ static RendererScene *scene;
};
#define RSG RenderingServerGlobals
diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp
deleted file mode 100644
index ae6786090a..0000000000
--- a/servers/rendering/rendering_server_scene.cpp
+++ /dev/null
@@ -1,3040 +0,0 @@
-/*************************************************************************/
-/* rendering_server_scene.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "rendering_server_scene.h"
-
-#include "core/os/os.h"
-#include "rendering_server_globals.h"
-#include "rendering_server_raster.h"
-
-#include <new>
-
-/* CAMERA API */
-
-RID RenderingServerScene::camera_create() {
- Camera *camera = memnew(Camera);
- return camera_owner.make_rid(camera);
-}
-
-void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
- camera->type = Camera::PERSPECTIVE;
- camera->fov = p_fovy_degrees;
- camera->znear = p_z_near;
- camera->zfar = p_z_far;
-}
-
-void RenderingServerScene::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
- camera->type = Camera::ORTHOGONAL;
- camera->size = p_size;
- camera->znear = p_z_near;
- camera->zfar = p_z_far;
-}
-
-void RenderingServerScene::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
- camera->type = Camera::FRUSTUM;
- camera->size = p_size;
- camera->offset = p_offset;
- camera->znear = p_z_near;
- camera->zfar = p_z_far;
-}
-
-void RenderingServerScene::camera_set_transform(RID p_camera, const Transform &p_transform) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
- camera->transform = p_transform.orthonormalized();
-}
-
-void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
-
- camera->visible_layers = p_layers;
-}
-
-void RenderingServerScene::camera_set_environment(RID p_camera, RID p_env) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
- camera->env = p_env;
-}
-
-void RenderingServerScene::camera_set_camera_effects(RID p_camera, RID p_fx) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
- camera->effects = p_fx;
-}
-
-void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
- camera->vaspect = p_enable;
-}
-
-/* SCENARIO API */
-
-void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int) {
- //RenderingServerScene *self = (RenderingServerScene*)p_self;
- Instance *A = p_A;
- Instance *B = p_B;
-
- //instance indices are designed so greater always contains lesser
- if (A->base_type > B->base_type) {
- SWAP(A, B); //lesser always first
- }
-
- if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- InstanceLightData::PairInfo pinfo;
- pinfo.geometry = A;
- pinfo.L = geom->lighting.push_back(B);
-
- List<InstanceLightData::PairInfo>::Element *E = light->geometries.push_back(pinfo);
-
- if (geom->can_cast_shadows) {
- light->shadow_dirty = true;
- }
- geom->lighting_dirty = true;
-
- return E; //this element should make freeing faster
- } else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- InstanceReflectionProbeData::PairInfo pinfo;
- pinfo.geometry = A;
- pinfo.L = geom->reflection_probes.push_back(B);
-
- List<InstanceReflectionProbeData::PairInfo>::Element *E = reflection_probe->geometries.push_back(pinfo);
-
- geom->reflection_dirty = true;
-
- return E; //this element should make freeing faster
- } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- InstanceDecalData::PairInfo pinfo;
- pinfo.geometry = A;
- pinfo.L = geom->decals.push_back(B);
-
- List<InstanceDecalData::PairInfo>::Element *E = decal->geometries.push_back(pinfo);
-
- geom->decal_dirty = true;
-
- return E; //this element should make freeing faster
- } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- if (A->dynamic_gi) {
- InstanceLightmapData::PairInfo pinfo;
- pinfo.geometry = A;
- pinfo.L = geom->lightmap_captures.push_back(B);
- List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.push_back(pinfo);
- ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture
- return E; //this element should make freeing faster
- } else {
- return nullptr;
- }
-
- } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- InstanceGIProbeData::PairInfo pinfo;
- pinfo.geometry = A;
- pinfo.L = geom->gi_probes.push_back(B);
-
- List<InstanceGIProbeData::PairInfo>::Element *E;
- if (A->dynamic_gi) {
- E = gi_probe->dynamic_geometries.push_back(pinfo);
- } else {
- E = gi_probe->geometries.push_back(pinfo);
- }
-
- geom->gi_probes_dirty = true;
-
- return E; //this element should make freeing faster
-
- } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
- return gi_probe->lights.insert(A);
- } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
- RSG::storage->particles_add_collision(A->base, B);
- }
-
- return nullptr;
-}
-
-void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) {
- //RenderingServerScene *self = (RenderingServerScene*)p_self;
- Instance *A = p_A;
- Instance *B = p_B;
-
- //instance indices are designed so greater always contains lesser
- if (A->base_type > B->base_type) {
- SWAP(A, B); //lesser always first
- }
-
- if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- List<InstanceLightData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightData::PairInfo>::Element *>(udata);
-
- geom->lighting.erase(E->get().L);
- light->geometries.erase(E);
-
- if (geom->can_cast_shadows) {
- light->shadow_dirty = true;
- }
- geom->lighting_dirty = true;
-
- } else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- List<InstanceReflectionProbeData::PairInfo>::Element *E = reinterpret_cast<List<InstanceReflectionProbeData::PairInfo>::Element *>(udata);
-
- geom->reflection_probes.erase(E->get().L);
- reflection_probe->geometries.erase(E);
-
- geom->reflection_dirty = true;
- } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- List<InstanceDecalData::PairInfo>::Element *E = reinterpret_cast<List<InstanceDecalData::PairInfo>::Element *>(udata);
-
- geom->decals.erase(E->get().L);
- decal->geometries.erase(E);
-
- geom->decal_dirty = true;
- } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- if (udata) { //only for dynamic geometries
- InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- List<InstanceLightmapData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightmapData::PairInfo>::Element *>(udata);
-
- geom->lightmap_captures.erase(E->get().L);
- lightmap_data->geometries.erase(E);
- ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture
- }
-
- } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
-
- List<InstanceGIProbeData::PairInfo>::Element *E = reinterpret_cast<List<InstanceGIProbeData::PairInfo>::Element *>(udata);
-
- geom->gi_probes.erase(E->get().L);
- if (A->dynamic_gi) {
- gi_probe->dynamic_geometries.erase(E);
- } else {
- gi_probe->geometries.erase(E);
- }
-
- geom->gi_probes_dirty = true;
-
- } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
- Set<Instance *>::Element *E = reinterpret_cast<Set<Instance *>::Element *>(udata);
-
- gi_probe->lights.erase(E);
- } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
- RSG::storage->particles_remove_collision(A->base, B);
- }
-}
-
-RID RenderingServerScene::scenario_create() {
- Scenario *scenario = memnew(Scenario);
- ERR_FAIL_COND_V(!scenario, RID());
- RID scenario_rid = scenario_owner.make_rid(scenario);
- scenario->self = scenario_rid;
-
- scenario->octree.set_pair_callback(_instance_pair, this);
- scenario->octree.set_unpair_callback(_instance_unpair, this);
- scenario->reflection_probe_shadow_atlas = RSG::scene_render->shadow_atlas_create();
- RSG::scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest
- RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 0, 4);
- RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4);
- RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4);
- RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8);
- scenario->reflection_atlas = RSG::scene_render->reflection_atlas_create();
- return scenario_rid;
-}
-
-void RenderingServerScene::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND(!scenario);
- scenario->debug = p_debug_mode;
-}
-
-void RenderingServerScene::scenario_set_environment(RID p_scenario, RID p_environment) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND(!scenario);
- scenario->environment = p_environment;
-}
-
-void RenderingServerScene::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND(!scenario);
- scenario->camera_effects = p_camera_effects;
-}
-
-void RenderingServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND(!scenario);
- scenario->fallback_environment = p_environment;
-}
-
-void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND(!scenario);
- RSG::scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count);
-}
-
-/* INSTANCING API */
-
-void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) {
- if (p_update_aabb) {
- p_instance->update_aabb = true;
- }
- if (p_update_dependencies) {
- p_instance->update_dependencies = true;
- }
-
- if (p_instance->update_item.in_list()) {
- return;
- }
-
- _instance_update_list.add(&p_instance->update_item);
-}
-
-RID RenderingServerScene::instance_create() {
- Instance *instance = memnew(Instance);
- ERR_FAIL_COND_V(!instance, RID());
-
- RID instance_rid = instance_owner.make_rid(instance);
- instance->self = instance_rid;
-
- return instance_rid;
-}
-
-void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- Scenario *scenario = instance->scenario;
-
- if (instance->base_type != RS::INSTANCE_NONE) {
- //free anything related to that base
-
- if (scenario && instance->octree_id) {
- scenario->octree.erase(instance->octree_id); //make dependencies generated by the octree go away
- instance->octree_id = 0;
- }
-
- switch (instance->base_type) {
- case RS::INSTANCE_LIGHT: {
- InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
-
- if (scenario && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
- scenario->dynamic_lights.erase(light->instance);
- }
-
-#ifdef DEBUG_ENABLED
- if (light->geometries.size()) {
- ERR_PRINT("BUG, indexing did not unpair geometries from light.");
- }
-#endif
- if (scenario && light->D) {
- scenario->directional_lights.erase(light->D);
- light->D = nullptr;
- }
- RSG::scene_render->free(light->instance);
- } break;
- case RS::INSTANCE_REFLECTION_PROBE: {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
- RSG::scene_render->free(reflection_probe->instance);
- if (reflection_probe->update_list.in_list()) {
- reflection_probe_render_list.remove(&reflection_probe->update_list);
- }
- } break;
- case RS::INSTANCE_DECAL: {
- InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
- RSG::scene_render->free(decal->instance);
-
- } break;
- case RS::INSTANCE_LIGHTMAP: {
- InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data);
- //erase dependencies, since no longer a lightmap
- while (lightmap_data->users.front()) {
- instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0);
- }
- } break;
- case RS::INSTANCE_GI_PROBE: {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
-#ifdef DEBUG_ENABLED
- if (gi_probe->geometries.size()) {
- ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe.");
- }
-#endif
-#ifdef DEBUG_ENABLED
- if (gi_probe->lights.size()) {
- ERR_PRINT("BUG, indexing did not unpair lights from GIProbe.");
- }
-#endif
- if (gi_probe->update_element.in_list()) {
- gi_probe_update_list.remove(&gi_probe->update_element);
- }
-
- RSG::scene_render->free(gi_probe->probe_instance);
-
- } break;
- default: {
- }
- }
-
- if (instance->base_data) {
- memdelete(instance->base_data);
- instance->base_data = nullptr;
- }
-
- instance->blend_values.clear();
- instance->materials.clear();
- }
-
- instance->base_type = RS::INSTANCE_NONE;
- instance->base = RID();
-
- if (p_base.is_valid()) {
- instance->base_type = RSG::storage->get_base_type(p_base);
- ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE);
-
- switch (instance->base_type) {
- case RS::INSTANCE_LIGHT: {
- InstanceLightData *light = memnew(InstanceLightData);
-
- if (scenario && RSG::storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) {
- light->D = scenario->directional_lights.push_back(instance);
- }
-
- light->instance = RSG::scene_render->light_instance_create(p_base);
-
- instance->base_data = light;
- } break;
- case RS::INSTANCE_MESH:
- case RS::INSTANCE_MULTIMESH:
- case RS::INSTANCE_IMMEDIATE:
- case RS::INSTANCE_PARTICLES: {
- InstanceGeometryData *geom = memnew(InstanceGeometryData);
- instance->base_data = geom;
- if (instance->base_type == RS::INSTANCE_MESH) {
- instance->blend_values.resize(RSG::storage->mesh_get_blend_shape_count(p_base));
- }
- } break;
- case RS::INSTANCE_REFLECTION_PROBE: {
- InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
- reflection_probe->owner = instance;
- instance->base_data = reflection_probe;
-
- reflection_probe->instance = RSG::scene_render->reflection_probe_instance_create(p_base);
- } break;
- case RS::INSTANCE_DECAL: {
- InstanceDecalData *decal = memnew(InstanceDecalData);
- decal->owner = instance;
- instance->base_data = decal;
-
- decal->instance = RSG::scene_render->decal_instance_create(p_base);
- } break;
- case RS::INSTANCE_LIGHTMAP: {
- InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
- instance->base_data = lightmap_data;
- //lightmap_data->instance = RSG::scene_render->lightmap_data_instance_create(p_base);
- } break;
- case RS::INSTANCE_GI_PROBE: {
- InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData);
- instance->base_data = gi_probe;
- gi_probe->owner = instance;
-
- if (scenario && !gi_probe->update_element.in_list()) {
- gi_probe_update_list.add(&gi_probe->update_element);
- }
-
- gi_probe->probe_instance = RSG::scene_render->gi_probe_instance_create(p_base);
-
- } break;
- default: {
- }
- }
-
- instance->base = p_base;
-
- //forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
- RSG::storage->base_update_dependency(p_base, instance);
- }
-
- _instance_queue_update(instance, true, true);
-}
-
-void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->scenario) {
- instance->scenario->instances.remove(&instance->scenario_item);
-
- if (instance->octree_id) {
- instance->scenario->octree.erase(instance->octree_id); //make dependencies generated by the octree go away
- instance->octree_id = 0;
- }
-
- switch (instance->base_type) {
- case RS::INSTANCE_LIGHT: {
- InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
-#ifdef DEBUG_ENABLED
- if (light->geometries.size()) {
- ERR_PRINT("BUG, indexing did not unpair geometries from light.");
- }
-#endif
- if (light->D) {
- instance->scenario->directional_lights.erase(light->D);
- light->D = nullptr;
- }
- } break;
- case RS::INSTANCE_REFLECTION_PROBE: {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
- RSG::scene_render->reflection_probe_release_atlas_index(reflection_probe->instance);
-
- } break;
- case RS::INSTANCE_PARTICLES_COLLISION: {
- heightfield_particle_colliders_update_list.erase(instance);
- } break;
- case RS::INSTANCE_GI_PROBE: {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
-
-#ifdef DEBUG_ENABLED
- if (gi_probe->geometries.size()) {
- ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe.");
- }
-#endif
-#ifdef DEBUG_ENABLED
- if (gi_probe->lights.size()) {
- ERR_PRINT("BUG, indexing did not unpair lights from GIProbe.");
- }
-#endif
-
- if (gi_probe->update_element.in_list()) {
- gi_probe_update_list.remove(&gi_probe->update_element);
- }
- } break;
- default: {
- }
- }
-
- instance->scenario = nullptr;
- }
-
- if (p_scenario.is_valid()) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND(!scenario);
-
- instance->scenario = scenario;
-
- scenario->instances.add(&instance->scenario_item);
-
- switch (instance->base_type) {
- case RS::INSTANCE_LIGHT: {
- InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
-
- if (RSG::storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) {
- light->D = scenario->directional_lights.push_back(instance);
- }
- } break;
- case RS::INSTANCE_GI_PROBE: {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
- if (!gi_probe->update_element.in_list()) {
- gi_probe_update_list.add(&gi_probe->update_element);
- }
- } break;
- default: {
- }
- }
-
- _instance_queue_update(instance, true, true);
- }
-}
-
-void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- instance->layer_mask = p_mask;
-}
-
-void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->transform == p_transform) {
- return; //must be checked to avoid worst evil
- }
-
-#ifdef DEBUG_ENABLED
-
- for (int i = 0; i < 4; i++) {
- const Vector3 &v = i < 3 ? p_transform.basis.elements[i] : p_transform.origin;
- ERR_FAIL_COND(Math::is_inf(v.x));
- ERR_FAIL_COND(Math::is_nan(v.x));
- ERR_FAIL_COND(Math::is_inf(v.y));
- ERR_FAIL_COND(Math::is_nan(v.y));
- ERR_FAIL_COND(Math::is_inf(v.z));
- ERR_FAIL_COND(Math::is_nan(v.z));
- }
-
-#endif
- instance->transform = p_transform;
- _instance_queue_update(instance, true);
-}
-
-void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- instance->object_id = p_id;
-}
-
-void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->update_item.in_list()) {
- _update_dirty_instance(instance);
- }
-
- ERR_FAIL_INDEX(p_shape, instance->blend_values.size());
- instance->blend_values.write[p_shape] = p_weight;
-}
-
-void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->base_type == RS::INSTANCE_MESH) {
- //may not have been updated yet, may also have not been set yet. When updated will be correcte, worst case
- instance->materials.resize(MAX(p_surface + 1, RSG::storage->mesh_get_surface_count(instance->base)));
- }
-
- ERR_FAIL_INDEX(p_surface, instance->materials.size());
-
- instance->materials.write[p_surface] = p_material;
-
- _instance_queue_update(instance, false, true);
-}
-
-void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->visible == p_visible) {
- return;
- }
-
- instance->visible = p_visible;
-
- switch (instance->base_type) {
- case RS::INSTANCE_LIGHT: {
- if (RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && instance->octree_id && instance->scenario) {
- instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHT, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
- }
-
- } break;
- case RS::INSTANCE_REFLECTION_PROBE: {
- if (instance->octree_id && instance->scenario) {
- instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_REFLECTION_PROBE, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
- }
-
- } break;
- case RS::INSTANCE_DECAL: {
- if (instance->octree_id && instance->scenario) {
- instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_DECAL, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
- }
-
- } break;
- case RS::INSTANCE_LIGHTMAP: {
- if (instance->octree_id && instance->scenario) {
- instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
- }
-
- } break;
- case RS::INSTANCE_GI_PROBE: {
- if (instance->octree_id && instance->scenario) {
- instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_GI_PROBE, p_visible ? (RS::INSTANCE_GEOMETRY_MASK | (1 << RS::INSTANCE_LIGHT)) : 0);
- }
-
- } break;
- case RS::INSTANCE_PARTICLES_COLLISION: {
- if (instance->octree_id && instance->scenario) {
- instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_PARTICLES_COLLISION, p_visible ? (1 << RS::INSTANCE_PARTICLES) : 0);
- }
-
- } break;
- default: {
- }
- }
-}
-
-inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
- return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES || p_type == RS::INSTANCE_IMMEDIATE;
-}
-
-void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
- ERR_FAIL_COND(!is_geometry_instance(instance->base_type));
-
- if (p_aabb != AABB()) {
- // Set custom AABB
- if (instance->custom_aabb == nullptr) {
- instance->custom_aabb = memnew(AABB);
- }
- *instance->custom_aabb = p_aabb;
-
- } else {
- // Clear custom AABB
- if (instance->custom_aabb != nullptr) {
- memdelete(instance->custom_aabb);
- instance->custom_aabb = nullptr;
- }
- }
-
- if (instance->scenario) {
- _instance_queue_update(instance, true, false);
- }
-}
-
-void RenderingServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->skeleton == p_skeleton) {
- return;
- }
-
- instance->skeleton = p_skeleton;
-
- if (p_skeleton.is_valid()) {
- //update the dependency now, so if cleared, we remove it
- RSG::storage->skeleton_update_dependency(p_skeleton, instance);
- }
- _instance_queue_update(instance, true, true);
-}
-
-void RenderingServerScene::instance_set_exterior(RID p_instance, bool p_enabled) {
-}
-
-void RenderingServerScene::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- instance->extra_margin = p_margin;
- _instance_queue_update(instance, true, false);
-}
-
-Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const {
- Vector<ObjectID> instances;
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND_V(!scenario, instances);
-
- const_cast<RenderingServerScene *>(this)->update_dirty_instances(); // check dirty instances before culling
-
- int culled = 0;
- Instance *cull[1024];
- culled = scenario->octree.cull_aabb(p_aabb, cull, 1024);
-
- for (int i = 0; i < culled; i++) {
- Instance *instance = cull[i];
- ERR_CONTINUE(!instance);
- if (instance->object_id.is_null()) {
- continue;
- }
-
- instances.push_back(instance->object_id);
- }
-
- return instances;
-}
-
-Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const {
- Vector<ObjectID> instances;
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND_V(!scenario, instances);
- const_cast<RenderingServerScene *>(this)->update_dirty_instances(); // check dirty instances before culling
-
- int culled = 0;
- Instance *cull[1024];
- culled = scenario->octree.cull_segment(p_from, p_from + p_to * 10000, cull, 1024);
-
- for (int i = 0; i < culled; i++) {
- Instance *instance = cull[i];
- ERR_CONTINUE(!instance);
- if (instance->object_id.is_null()) {
- continue;
- }
-
- instances.push_back(instance->object_id);
- }
-
- return instances;
-}
-
-Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const {
- Vector<ObjectID> instances;
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- ERR_FAIL_COND_V(!scenario, instances);
- const_cast<RenderingServerScene *>(this)->update_dirty_instances(); // check dirty instances before culling
-
- int culled = 0;
- Instance *cull[1024];
-
- culled = scenario->octree.cull_convex(p_convex, cull, 1024);
-
- for (int i = 0; i < culled; i++) {
- Instance *instance = cull[i];
- ERR_CONTINUE(!instance);
- if (instance->object_id.is_null()) {
- continue;
- }
-
- instances.push_back(instance->object_id);
- }
-
- return instances;
-}
-
-void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- //ERR_FAIL_COND(((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK));
-
- switch (p_flags) {
- case RS::INSTANCE_FLAG_USE_BAKED_LIGHT: {
- instance->baked_light = p_enabled;
-
- } break;
- case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: {
- if (p_enabled == instance->dynamic_gi) {
- //bye, redundant
- return;
- }
-
- if (instance->octree_id != 0) {
- //remove from octree, it needs to be re-paired
- instance->scenario->octree.erase(instance->octree_id);
- instance->octree_id = 0;
- _instance_queue_update(instance, true, true);
- }
-
- //once out of octree, can be changed
- instance->dynamic_gi = p_enabled;
-
- } break;
- case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: {
- instance->redraw_if_visible = p_enabled;
-
- } break;
- default: {
- }
- }
-}
-
-void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- instance->cast_shadows = p_shadow_casting_setting;
- _instance_queue_update(instance, false, true);
-}
-
-void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- instance->material_override = p_material;
- _instance_queue_update(instance, false, true);
-}
-
-void RenderingServerScene::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) {
-}
-
-void RenderingServerScene::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) {
-}
-
-void RenderingServerScene::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->lightmap) {
- InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(((Instance *)instance->lightmap)->base_data);
- lightmap_data->users.erase(instance);
- instance->lightmap = nullptr;
- }
-
- Instance *lightmap_instance = instance_owner.getornull(p_lightmap);
-
- instance->lightmap = lightmap_instance;
- instance->lightmap_uv_scale = p_lightmap_uv_scale;
- instance->lightmap_slice_index = p_slice_index;
-
- if (lightmap_instance) {
- InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data);
- lightmap_data->users.insert(instance);
- }
-}
-
-void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
-
- if (!E) {
- RasterizerScene::InstanceBase::InstanceShaderParameter isp;
- isp.index = -1;
- isp.info = PropertyInfo();
- isp.value = p_value;
- instance->instance_shader_parameters[p_parameter] = isp;
- } else {
- E->get().value = p_value;
- if (E->get().index >= 0 && instance->instance_allocated_shader_parameters) {
- //update directly
- RSG::storage->global_variables_instance_update(p_instance, E->get().index, p_value);
- }
- }
-}
-
-Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const {
- const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
- ERR_FAIL_COND_V(!instance, Variant());
-
- if (instance->instance_shader_parameters.has(p_parameter)) {
- return instance->instance_shader_parameters[p_parameter].value;
- }
- return Variant();
-}
-
-Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const {
- const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
- ERR_FAIL_COND_V(!instance, Variant());
-
- if (instance->instance_shader_parameters.has(p_parameter)) {
- return instance->instance_shader_parameters[p_parameter].default_value;
- }
- return Variant();
-}
-
-void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const {
- const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- const_cast<RenderingServerScene *>(this)->update_dirty_instances();
-
- Vector<StringName> names;
- for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) {
- names.push_back(E->key());
- }
- names.sort_custom<StringName::AlphCompare>();
- for (int i = 0; i < names.size(); i++) {
- PropertyInfo pinfo = instance->instance_shader_parameters[names[i]].info;
- p_parameters->push_back(pinfo);
- }
-}
-
-void RenderingServerScene::_update_instance(Instance *p_instance) {
- p_instance->version++;
-
- if (p_instance->base_type == RS::INSTANCE_LIGHT) {
- InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
-
- RSG::scene_render->light_instance_set_transform(light->instance, p_instance->transform);
- RSG::scene_render->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb));
- light->shadow_dirty = true;
-
- RS::LightBakeMode bake_mode = RSG::storage->light_get_bake_mode(p_instance->base);
- if (RSG::storage->light_get_type(p_instance->base) != RS::LIGHT_DIRECTIONAL && bake_mode != light->bake_mode) {
- if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
- p_instance->scenario->dynamic_lights.erase(light->instance);
- }
-
- light->bake_mode = bake_mode;
-
- if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
- p_instance->scenario->dynamic_lights.push_back(light->instance);
- }
- }
-
- uint32_t max_sdfgi_cascade = RSG::storage->light_get_max_sdfgi_cascade(p_instance->base);
- if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
- light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
- }
- }
-
- if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
-
- RSG::scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform);
- reflection_probe->reflection_dirty = true;
- }
-
- if (p_instance->base_type == RS::INSTANCE_DECAL) {
- InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
-
- RSG::scene_render->decal_instance_set_transform(decal->instance, p_instance->transform);
- }
-
- if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data);
-
- RSG::scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform);
- }
-
- if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
- RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
- }
-
- if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
- //remove materials no longer used and un-own them
- if (RSG::storage->particles_collision_is_heightfield(p_instance->base)) {
- heightfield_particle_colliders_update_list.insert(p_instance);
- }
- }
-
- if (p_instance->aabb.has_no_surface()) {
- return;
- }
-
- if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
- //make sure lights are updated if it casts shadow
-
- if (geom->can_cast_shadows) {
- for (List<Instance *>::Element *E = geom->lighting.front(); E; E = E->next()) {
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
- light->shadow_dirty = true;
- }
- }
-
- if (!p_instance->lightmap && geom->lightmap_captures.size()) {
- //affected by lightmap captures, must update capture info!
- _update_instance_lightmap_captures(p_instance);
- } else {
- if (!p_instance->lightmap_sh.empty()) {
- p_instance->lightmap_sh.clear(); //don't need SH
- p_instance->lightmap_target_sh.clear(); //don't need SH
- }
- }
- }
-
- if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
- //if this moved, update the captured objects
- InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
- //erase dependencies, since no longer a lightmap
-
- for (List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
- Instance *geom = E->get().geometry;
- _instance_queue_update(geom, true, false);
- }
- }
-
- p_instance->mirror = p_instance->transform.basis.determinant() < 0.0;
-
- AABB new_aabb;
-
- new_aabb = p_instance->transform.xform(p_instance->aabb);
-
- p_instance->transformed_aabb = new_aabb;
-
- if (!p_instance->scenario) {
- return;
- }
-
- if (p_instance->octree_id == 0) {
- uint32_t base_type = 1 << p_instance->base_type;
- uint32_t pairable_mask = 0;
- bool pairable = false;
-
- if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
- pairable_mask = p_instance->visible ? RS::INSTANCE_GEOMETRY_MASK : 0;
- pairable = true;
- }
-
- if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
- pairable_mask = p_instance->visible ? (1 << RS::INSTANCE_PARTICLES) : 0;
- pairable = true;
- }
-
- if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
- //lights and geometries
- pairable_mask = p_instance->visible ? RS::INSTANCE_GEOMETRY_MASK | (1 << RS::INSTANCE_LIGHT) : 0;
- pairable = true;
- }
-
- // not inside octree
- p_instance->octree_id = p_instance->scenario->octree.create(p_instance, new_aabb, 0, pairable, base_type, pairable_mask);
-
- } else {
- /*
- if (new_aabb==p_instance->data.transformed_aabb)
- return;
- */
-
- p_instance->scenario->octree.move(p_instance->octree_id, new_aabb);
- }
-}
-
-void RenderingServerScene::_update_instance_aabb(Instance *p_instance) {
- AABB new_aabb;
-
- ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid());
-
- switch (p_instance->base_type) {
- case RenderingServer::INSTANCE_NONE: {
- // do nothing
- } break;
- case RenderingServer::INSTANCE_MESH: {
- if (p_instance->custom_aabb) {
- new_aabb = *p_instance->custom_aabb;
- } else {
- new_aabb = RSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton);
- }
-
- } break;
-
- case RenderingServer::INSTANCE_MULTIMESH: {
- if (p_instance->custom_aabb) {
- new_aabb = *p_instance->custom_aabb;
- } else {
- new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base);
- }
-
- } break;
- case RenderingServer::INSTANCE_IMMEDIATE: {
- if (p_instance->custom_aabb) {
- new_aabb = *p_instance->custom_aabb;
- } else {
- new_aabb = RSG::storage->immediate_get_aabb(p_instance->base);
- }
-
- } break;
- case RenderingServer::INSTANCE_PARTICLES: {
- if (p_instance->custom_aabb) {
- new_aabb = *p_instance->custom_aabb;
- } else {
- new_aabb = RSG::storage->particles_get_aabb(p_instance->base);
- }
-
- } break;
- case RenderingServer::INSTANCE_PARTICLES_COLLISION: {
- new_aabb = RSG::storage->particles_collision_get_aabb(p_instance->base);
-
- } break;
- case RenderingServer::INSTANCE_LIGHT: {
- new_aabb = RSG::storage->light_get_aabb(p_instance->base);
-
- } break;
- case RenderingServer::INSTANCE_REFLECTION_PROBE: {
- new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base);
-
- } break;
- case RenderingServer::INSTANCE_DECAL: {
- new_aabb = RSG::storage->decal_get_aabb(p_instance->base);
-
- } break;
- case RenderingServer::INSTANCE_GI_PROBE: {
- new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base);
-
- } break;
- case RenderingServer::INSTANCE_LIGHTMAP: {
- new_aabb = RSG::storage->lightmap_get_aabb(p_instance->base);
-
- } break;
- default: {
- }
- }
-
- // <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs
- if (p_instance->extra_margin) {
- new_aabb.grow_by(p_instance->extra_margin);
- }
-
- p_instance->aabb = new_aabb;
-}
-
-void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) {
- bool first_set = p_instance->lightmap_sh.size() == 0;
- p_instance->lightmap_sh.resize(9); //using SH
- p_instance->lightmap_target_sh.resize(9); //using SH
- Color *instance_sh = p_instance->lightmap_target_sh.ptrw();
- bool inside = false;
- Color accum_sh[9];
- float accum_blend = 0.0;
-
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
- for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) {
- Instance *lightmap = E->get();
-
- bool interior = RSG::storage->lightmap_is_interior(lightmap->base);
-
- if (inside && !interior) {
- continue; //we are inside, ignore exteriors
- }
-
- Transform to_bounds = lightmap->transform.affine_inverse();
- Vector3 center = p_instance->transform.xform(p_instance->aabb.position + p_instance->aabb.size * 0.5); //use aabb center
-
- Vector3 lm_pos = to_bounds.xform(center);
-
- AABB bounds = RSG::storage->lightmap_get_aabb(lightmap->base);
- if (!bounds.has_point(lm_pos)) {
- continue; //not in this lightmap
- }
-
- Color sh[9];
- RSG::storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh);
-
- //rotate it
- Basis rot = lightmap->transform.basis.orthonormalized();
- for (int i = 0; i < 3; i++) {
- float csh[9];
- for (int j = 0; j < 9; j++) {
- csh[j] = sh[j][i];
- }
- rot.rotate_sh(csh);
- for (int j = 0; j < 9; j++) {
- sh[j][i] = csh[j];
- }
- }
-
- Vector3 inner_pos = ((lm_pos - bounds.position) / bounds.size) * 2.0 - Vector3(1.0, 1.0, 1.0);
-
- float blend = MAX(inner_pos.x, MAX(inner_pos.y, inner_pos.z));
- //make blend more rounded
- blend = Math::lerp(inner_pos.length(), blend, blend);
- blend *= blend;
- blend = MAX(0.0, 1.0 - blend);
-
- if (interior && !inside) {
- //do not blend, just replace
- for (int j = 0; j < 9; j++) {
- accum_sh[j] = sh[j] * blend;
- }
- accum_blend = blend;
- inside = true;
- } else {
- for (int j = 0; j < 9; j++) {
- accum_sh[j] += sh[j] * blend;
- }
- accum_blend += blend;
- }
- }
-
- if (accum_blend > 0.0) {
- for (int j = 0; j < 9; j++) {
- instance_sh[j] = accum_sh[j] / accum_blend;
- if (first_set) {
- p_instance->lightmap_sh.write[j] = instance_sh[j];
- }
- }
- }
-}
-
-bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) {
- InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
-
- Transform light_transform = p_instance->transform;
- light_transform.orthonormalize(); //scale does not count on lights
-
- bool animated_material_found = false;
-
- switch (RSG::storage->light_get_type(p_instance->base)) {
- case RS::LIGHT_DIRECTIONAL: {
- real_t max_distance = p_cam_projection.get_z_far();
- real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
- if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
- max_distance = MIN(shadow_max, max_distance);
- }
- max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001);
- real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
-
- RS::LightDirectionalShadowDepthRangeMode depth_range_mode = RSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base);
-
- real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
-
- if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED) {
- //optimize min/max
- Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, RS::INSTANCE_GEOMETRY_MASK);
- Plane base(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2));
- //check distance max and min
-
- bool found_items = false;
- real_t z_max = -1e20;
- real_t z_min = 1e20;
-
- for (int i = 0; i < cull_count; i++) {
- Instance *instance = instance_shadow_cull_result[i];
- if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
- continue;
- }
-
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
-
- real_t max, min;
- instance->transformed_aabb.project_range_in_plane(base, min, max);
-
- if (max > z_max) {
- z_max = max;
- }
-
- if (min < z_min) {
- z_min = min;
- }
-
- found_items = true;
- }
-
- if (found_items) {
- min_distance = MAX(min_distance, z_min);
- max_distance = MIN(max_distance, z_max);
- }
- }
-
- real_t range = max_distance - min_distance;
-
- int splits = 0;
- switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) {
- case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
- splits = 1;
- break;
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
- splits = 2;
- break;
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
- splits = 4;
- break;
- }
-
- real_t distances[5];
-
- distances[0] = min_distance;
- for (int i = 0; i < splits; i++) {
- distances[i + 1] = min_distance + RSG::storage->light_get_param(p_instance->base, RS::LightParam(RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range;
- };
-
- distances[splits] = max_distance;
-
- real_t texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance);
-
- bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base);
-
- real_t first_radius = 0.0;
-
- real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0;
-
- for (int i = 0; i < splits; i++) {
- RENDER_TIMESTAMP("Culling Directional Light split" + itos(i));
-
- // setup a camera matrix for that range!
- CameraMatrix camera_matrix;
-
- real_t aspect = p_cam_projection.get_aspect();
-
- if (p_cam_orthogonal) {
- Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
-
- camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
- } else {
- real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it
- camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
- }
-
- //obtain the frustum endpoints
-
- Vector3 endpoints[8]; // frustum plane endpoints
- bool res = camera_matrix.get_endpoints(p_cam_transform, endpoints);
- ERR_CONTINUE(!res);
-
- // obtain the light frustm ranges (given endpoints)
-
- Transform transform = light_transform; //discard scale and stabilize light
-
- Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized();
- Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized();
- Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
- //z_vec points agsint the camera, like in default opengl
-
- real_t x_min = 0.f, x_max = 0.f;
- real_t y_min = 0.f, y_max = 0.f;
- real_t z_min = 0.f, z_max = 0.f;
-
- // FIXME: z_max_cam is defined, computed, but not used below when setting up
- // ortho_camera. Commented out for now to fix warnings but should be investigated.
- real_t x_min_cam = 0.f, x_max_cam = 0.f;
- real_t y_min_cam = 0.f, y_max_cam = 0.f;
- real_t z_min_cam = 0.f;
- //real_t z_max_cam = 0.f;
-
- real_t bias_scale = 1.0;
- real_t aspect_bias_scale = 1.0;
-
- //used for culling
-
- for (int j = 0; j < 8; j++) {
- real_t d_x = x_vec.dot(endpoints[j]);
- real_t d_y = y_vec.dot(endpoints[j]);
- real_t d_z = z_vec.dot(endpoints[j]);
-
- if (j == 0 || d_x < x_min) {
- x_min = d_x;
- }
- if (j == 0 || d_x > x_max) {
- x_max = d_x;
- }
-
- if (j == 0 || d_y < y_min) {
- y_min = d_y;
- }
- if (j == 0 || d_y > y_max) {
- y_max = d_y;
- }
-
- if (j == 0 || d_z < z_min) {
- z_min = d_z;
- }
- if (j == 0 || d_z > z_max) {
- z_max = d_z;
- }
- }
-
- real_t radius = 0;
- real_t soft_shadow_expand = 0;
- Vector3 center;
-
- {
- //camera viewport stuff
-
- for (int j = 0; j < 8; j++) {
- center += endpoints[j];
- }
- center /= 8.0;
-
- //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5;
-
- for (int j = 0; j < 8; j++) {
- real_t d = center.distance_to(endpoints[j]);
- if (d > radius) {
- radius = d;
- }
- }
-
- radius *= texture_size / (texture_size - 2.0); //add a texel by each side
-
- if (i == 0) {
- first_radius = radius;
- } else {
- bias_scale = radius / first_radius;
- }
-
- z_min_cam = z_vec.dot(center) - radius;
-
- {
- float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
-
- if (soft_shadow_angle > 0.0 && pancake_size > 0.0) {
- float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
- soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range;
-
- x_max += soft_shadow_expand;
- y_max += soft_shadow_expand;
-
- x_min -= soft_shadow_expand;
- y_min -= soft_shadow_expand;
- }
- }
-
- x_max_cam = x_vec.dot(center) + radius + soft_shadow_expand;
- x_min_cam = x_vec.dot(center) - radius - soft_shadow_expand;
- y_max_cam = y_vec.dot(center) + radius + soft_shadow_expand;
- y_min_cam = y_vec.dot(center) - radius - soft_shadow_expand;
-
- if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
- //this trick here is what stabilizes the shadow (make potential jaggies to not move)
- //at the cost of some wasted resolution. Still the quality increase is very well worth it
-
- real_t unit = radius * 2.0 / texture_size;
-
- x_max_cam = Math::stepify(x_max_cam, unit);
- x_min_cam = Math::stepify(x_min_cam, unit);
- y_max_cam = Math::stepify(y_max_cam, unit);
- y_min_cam = Math::stepify(y_min_cam, unit);
- }
- }
-
- //now that we now all ranges, we can proceed to make the light frustum planes, for culling octree
-
- Vector<Plane> light_frustum_planes;
- light_frustum_planes.resize(6);
-
- //right/left
- light_frustum_planes.write[0] = Plane(x_vec, x_max);
- light_frustum_planes.write[1] = Plane(-x_vec, -x_min);
- //top/bottom
- light_frustum_planes.write[2] = Plane(y_vec, y_max);
- light_frustum_planes.write[3] = Plane(-y_vec, -y_min);
- //near/far
- light_frustum_planes.write[4] = Plane(z_vec, z_max + 1e6);
- light_frustum_planes.write[5] = Plane(-z_vec, -z_min); // z_min is ok, since casters further than far-light plane are not needed
-
- int cull_count = p_scenario->octree.cull_convex(light_frustum_planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, RS::INSTANCE_GEOMETRY_MASK);
-
- // a pre pass will need to be needed to determine the actual z-near to be used
-
- Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
-
- real_t cull_max = 0;
- for (int j = 0; j < cull_count; j++) {
- real_t min, max;
- 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) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- continue;
- }
-
- instance->transformed_aabb.project_range_in_plane(Plane(z_vec, 0), min, max);
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
- if (j == 0 || max > cull_max) {
- cull_max = max;
- }
- }
-
- if (cull_max > z_max) {
- z_max = cull_max;
- }
-
- if (pancake_size > 0) {
- z_max = z_vec.dot(center) + radius + pancake_size;
- }
-
- if (aspect != 1.0) {
- // if the aspect is different, then the radius will become larger.
- // if this happens, then bias needs to be adjusted too, as depth will increase
- // to do this, compare the depth of one that would have resulted from a square frustum
-
- CameraMatrix camera_matrix_square;
- if (p_cam_orthogonal) {
- Vector2 vp_he = camera_matrix.get_viewport_half_extents();
- if (p_cam_vaspect) {
- camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
- } else {
- camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
- }
- } else {
- Vector2 vp_he = camera_matrix.get_viewport_half_extents();
- if (p_cam_vaspect) {
- camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
- } else {
- camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
- }
- }
-
- Vector3 endpoints_square[8]; // frustum plane endpoints
- res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square);
- ERR_CONTINUE(!res);
- Vector3 center_square;
- real_t z_max_square = 0;
-
- for (int j = 0; j < 8; j++) {
- center_square += endpoints_square[j];
-
- real_t d_z = z_vec.dot(endpoints_square[j]);
-
- if (j == 0 || d_z > z_max_square) {
- z_max_square = d_z;
- }
- }
-
- if (cull_max > z_max_square) {
- z_max_square = cull_max;
- }
-
- center_square /= 8.0;
-
- real_t radius_square = 0;
-
- for (int j = 0; j < 8; j++) {
- real_t d = center_square.distance_to(endpoints_square[j]);
- if (d > radius_square) {
- radius_square = d;
- }
- }
-
- radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side
-
- if (pancake_size > 0) {
- z_max_square = z_vec.dot(center_square) + radius_square + pancake_size;
- }
-
- real_t z_min_cam_square = z_vec.dot(center_square) - radius_square;
-
- aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square);
-
- // this is not entirely perfect, because the cull-adjusted z-max may be different
- // but at least it's warranted that it results in a greater bias, so no acne should be present either way.
- // pancaking also helps with this.
- }
-
- {
- CameraMatrix ortho_camera;
- real_t half_x = (x_max_cam - x_min_cam) * 0.5;
- real_t half_y = (y_max_cam - y_min_cam) * 0.5;
-
- ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
-
- Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam));
-
- Transform ortho_transform;
- ortho_transform.basis = transform.basis;
- ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
-
- {
- Vector3 max_in_view = p_cam_transform.affine_inverse().xform(z_vec * cull_max);
- Vector3 dir_in_view = p_cam_transform.xform_inv(z_vec).normalized();
- cull_max = dir_in_view.dot(max_in_view);
- }
-
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale);
- }
-
- RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
- }
-
- } break;
- case RS::LIGHT_OMNI: {
- RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base);
-
- if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !RSG::scene_render->light_instances_can_render_shadow_cube()) {
- for (int i = 0; i < 2; i++) {
- //using this one ensures that raster deferred will have it
- RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i));
-
- real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
-
- real_t z = i == 0 ? -1 : 1;
- Vector<Plane> planes;
- planes.resize(6);
- planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
- planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
- planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
- planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
- planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
- planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0));
-
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, RS::INSTANCE_GEOMETRY_MASK);
- Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
-
- for (int j = 0; j < cull_count; 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) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- } else {
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
-
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
- }
- }
-
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0);
- RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
- }
- } else { //shadow cube
-
- real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
- CameraMatrix cm;
- cm.set_perspective(90, 1, 0.01, radius);
-
- for (int i = 0; i < 6; i++) {
- RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i));
- //using this one ensures that raster deferred will have it
-
- static const Vector3 view_normals[6] = {
- Vector3(+1, 0, 0),
- Vector3(-1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, +1, 0),
- Vector3(0, 0, +1),
- Vector3(0, 0, -1)
- };
- static const Vector3 view_up[6] = {
- Vector3(0, -1, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, +1),
- Vector3(0, -1, 0),
- Vector3(0, -1, 0)
- };
-
- Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]);
-
- Vector<Plane> planes = cm.get_projection_planes(xform);
-
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, RS::INSTANCE_GEOMETRY_MASK);
-
- Plane near_plane(xform.origin, -xform.basis.get_axis(2));
- for (int j = 0; j < cull_count; 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) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- } else {
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
- }
- }
-
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
- RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
- }
-
- //restore the regular DP matrix
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0);
- }
-
- } break;
- case RS::LIGHT_SPOT: {
- RENDER_TIMESTAMP("Culling Spot Light");
-
- real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
- real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
-
- CameraMatrix cm;
- cm.set_perspective(angle * 2.0, 1.0, 0.01, radius);
-
- Vector<Plane> planes = cm.get_projection_planes(light_transform);
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, RS::INSTANCE_GEOMETRY_MASK);
-
- Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
- for (int j = 0; j < cull_count; 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) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- } else {
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
- }
- }
-
- RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
- RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
-
- } break;
- }
-
- return animated_material_found;
-}
-
-void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
-// render to mono camera
-#ifndef _3D_DISABLED
-
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
-
- /* STEP 1 - SETUP CAMERA */
- CameraMatrix camera_matrix;
- bool ortho = false;
-
- switch (camera->type) {
- case Camera::ORTHOGONAL: {
- camera_matrix.set_orthogonal(
- camera->size,
- p_viewport_size.width / (float)p_viewport_size.height,
- camera->znear,
- camera->zfar,
- camera->vaspect);
- ortho = true;
- } break;
- case Camera::PERSPECTIVE: {
- camera_matrix.set_perspective(
- camera->fov,
- p_viewport_size.width / (float)p_viewport_size.height,
- camera->znear,
- camera->zfar,
- camera->vaspect);
- ortho = false;
-
- } break;
- case Camera::FRUSTUM: {
- camera_matrix.set_frustum(
- camera->size,
- p_viewport_size.width / (float)p_viewport_size.height,
- camera->offset,
- camera->znear,
- camera->zfar,
- camera->vaspect);
- ortho = false;
- } break;
- }
-
- RID environment = _render_get_environment(p_camera, p_scenario);
-
- _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
- _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1);
-#endif
-}
-
-void RenderingServerScene::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
- // render for AR/VR interface
-
- Camera *camera = camera_owner.getornull(p_camera);
- ERR_FAIL_COND(!camera);
-
- /* SETUP CAMERA, we are ignoring type and FOV here */
- float aspect = p_viewport_size.width / (float)p_viewport_size.height;
- CameraMatrix camera_matrix = p_interface->get_projection_for_eye(p_eye, aspect, camera->znear, camera->zfar);
-
- // We also ignore our camera position, it will have been positioned with a slightly old tracking position.
- // Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo!
- Transform world_origin = XRServer::get_singleton()->get_world_origin();
- Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin);
-
- RID environment = _render_get_environment(p_camera, p_scenario);
-
- // For stereo render we only prepare for our left eye and then reuse the outcome for our right eye
- if (p_eye == XRInterface::EYE_LEFT) {
- // Center our transform, we assume basis is equal.
- Transform mono_transform = cam_transform;
- Transform right_transform = p_interface->get_transform_for_eye(XRInterface::EYE_RIGHT, world_origin);
- mono_transform.origin += right_transform.origin;
- mono_transform.origin *= 0.5;
-
- // We need to combine our projection frustums for culling.
- // Ideally we should use our clipping planes for this and combine them,
- // however our shadow map logic uses our projection matrix.
- // Note: as our left and right frustums should be mirrored, we don't need our right projection matrix.
-
- // - get some base values we need
- float eye_dist = (mono_transform.origin - cam_transform.origin).length();
- float z_near = camera_matrix.get_z_near(); // get our near plane
- float z_far = camera_matrix.get_z_far(); // get our far plane
- float width = (2.0 * z_near) / camera_matrix.matrix[0][0];
- float x_shift = width * camera_matrix.matrix[2][0];
- float height = (2.0 * z_near) / camera_matrix.matrix[1][1];
- float y_shift = height * camera_matrix.matrix[2][1];
-
- // printf("Eye_dist = %f, Near = %f, Far = %f, Width = %f, Shift = %f\n", eye_dist, z_near, z_far, width, x_shift);
-
- // - calculate our near plane size (horizontal only, right_near is mirrored)
- float left_near = -eye_dist - ((width - x_shift) * 0.5);
-
- // - calculate our far plane size (horizontal only, right_far is mirrored)
- float left_far = -eye_dist - (z_far * (width - x_shift) * 0.5 / z_near);
- float left_far_right_eye = eye_dist - (z_far * (width + x_shift) * 0.5 / z_near);
- if (left_far > left_far_right_eye) {
- // on displays smaller then double our iod, the right eye far frustrum can overtake the left eyes.
- left_far = left_far_right_eye;
- }
-
- // - figure out required z-shift
- float slope = (left_far - left_near) / (z_far - z_near);
- float z_shift = (left_near / slope) - z_near;
-
- // - figure out new vertical near plane size (this will be slightly oversized thanks to our z-shift)
- float top_near = (height - y_shift) * 0.5;
- top_near += (top_near / z_near) * z_shift;
- float bottom_near = -(height + y_shift) * 0.5;
- bottom_near += (bottom_near / z_near) * z_shift;
-
- // printf("Left_near = %f, Left_far = %f, Top_near = %f, Bottom_near = %f, Z_shift = %f\n", left_near, left_far, top_near, bottom_near, z_shift);
-
- // - generate our frustum
- CameraMatrix combined_matrix;
- combined_matrix.set_frustum(left_near, -left_near, bottom_near, top_near, z_near + z_shift, z_far + z_shift);
-
- // and finally move our camera back
- Transform apply_z_shift;
- apply_z_shift.origin = Vector3(0.0, 0.0, z_shift); // z negative is forward so this moves it backwards
- mono_transform *= apply_z_shift;
-
- // now prepare our scene with our adjusted transform projection matrix
- _prepare_scene(mono_transform, combined_matrix, false, false, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
- } else if (p_eye == XRInterface::EYE_MONO) {
- // For mono render, prepare as per usual
- _prepare_scene(cam_transform, camera_matrix, false, false, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID());
- }
-
- // And render our scene...
- _render_scene(p_render_buffers, cam_transform, camera_matrix, false, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1);
-};
-
-void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) {
- // Note, in stereo rendering:
- // - p_cam_transform will be a transform in the middle of our two eyes
- // - p_cam_projection is a wider frustrum that encompasses both eyes
-
- Scenario *scenario = scenario_owner.getornull(p_scenario);
-
- render_pass++;
- uint32_t camera_layer_mask = p_visible_layers;
-
- RSG::scene_render->set_scene_pass(render_pass);
-
- if (p_render_buffers.is_valid()) {
- RSG::scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not)
- }
-
- RENDER_TIMESTAMP("Frustum Culling");
-
- //rasterizer->set_camera(camera->transform, camera_matrix,ortho);
-
- Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
-
- Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2).normalized());
- float z_far = p_cam_projection.get_z_far();
-
- /* STEP 2 - CULL */
- instance_cull_count = scenario->octree.cull_convex(planes, instance_cull_result, MAX_INSTANCE_CULL);
- light_cull_count = 0;
-
- reflection_probe_cull_count = 0;
- decal_cull_count = 0;
- gi_probe_cull_count = 0;
- lightmap_cull_count = 0;
-
- //light_samplers_culled=0;
-
- /*
- print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0));
- print_line("OTO: "+itos(p_scenario->octree.get_octant_count()));
- print_line("OTE: "+itos(p_scenario->octree.get_elem_count()));
- print_line("OTP: "+itos(p_scenario->octree.get_pair_count()));
- */
-
- /* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */
- //removed, will replace with culling
-
- /* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */
- uint64_t frame_number = RSG::rasterizer->get_frame_number();
- float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
-
- for (int i = 0; i < instance_cull_count; i++) {
- Instance *ins = instance_cull_result[i];
-
- bool keep = false;
-
- if ((camera_layer_mask & ins->layer_mask) == 0) {
- //failure
- } else if (ins->base_type == RS::INSTANCE_LIGHT && ins->visible) {
- if (light_cull_count < MAX_LIGHTS_CULLED) {
- InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
-
- if (!light->geometries.empty()) {
- //do not add this light if no geometry is affected by it..
- light_cull_result[light_cull_count] = ins;
- light_instance_cull_result[light_cull_count] = light->instance;
- if (p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(ins->base)) {
- RSG::scene_render->light_instance_mark_visible(light->instance); //mark it visible for shadow allocation later
- }
-
- light_cull_count++;
- }
- }
- } else if (ins->base_type == RS::INSTANCE_REFLECTION_PROBE && ins->visible) {
- if (reflection_probe_cull_count < MAX_REFLECTION_PROBES_CULLED) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(ins->base_data);
-
- if (p_reflection_probe != reflection_probe->instance) {
- //avoid entering The Matrix
-
- if (!reflection_probe->geometries.empty()) {
- //do not add this light if no geometry is affected by it..
-
- if (reflection_probe->reflection_dirty || RSG::scene_render->reflection_probe_instance_needs_redraw(reflection_probe->instance)) {
- if (!reflection_probe->update_list.in_list()) {
- reflection_probe->render_step = 0;
- reflection_probe_render_list.add_last(&reflection_probe->update_list);
- }
-
- reflection_probe->reflection_dirty = false;
- }
-
- if (RSG::scene_render->reflection_probe_instance_has_reflection(reflection_probe->instance)) {
- reflection_probe_instance_cull_result[reflection_probe_cull_count] = reflection_probe->instance;
- reflection_probe_cull_count++;
- }
- }
- }
- }
- } else if (ins->base_type == RS::INSTANCE_DECAL && ins->visible) {
- if (decal_cull_count < MAX_DECALS_CULLED) {
- InstanceDecalData *decal = static_cast<InstanceDecalData *>(ins->base_data);
-
- if (!decal->geometries.empty()) {
- //do not add this decal if no geometry is affected by it..
- decal_instance_cull_result[decal_cull_count] = decal->instance;
- decal_cull_count++;
- }
- }
-
- } else if (ins->base_type == RS::INSTANCE_GI_PROBE && ins->visible) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(ins->base_data);
- if (!gi_probe->update_element.in_list()) {
- gi_probe_update_list.add(&gi_probe->update_element);
- }
-
- if (gi_probe_cull_count < MAX_GI_PROBES_CULLED) {
- gi_probe_instance_cull_result[gi_probe_cull_count] = gi_probe->probe_instance;
- gi_probe_cull_count++;
- }
- } else if (ins->base_type == RS::INSTANCE_LIGHTMAP && ins->visible) {
- if (lightmap_cull_count < MAX_LIGHTMAPS_CULLED) {
- lightmap_cull_result[lightmap_cull_count] = ins;
- lightmap_cull_count++;
- }
-
- } else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
- keep = true;
-
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
-
- if (ins->redraw_if_visible) {
- RenderingServerRaster::redraw_request();
- }
-
- if (ins->base_type == RS::INSTANCE_PARTICLES) {
- //particles visible? process them
- if (RSG::storage->particles_is_inactive(ins->base)) {
- //but if nothing is going on, don't do it.
- keep = false;
- } else {
- RSG::storage->particles_request_process(ins->base);
- RSG::storage->particles_set_view_axis(ins->base, -p_cam_transform.basis.get_axis(2).normalized());
- //particles visible? request redraw
- RenderingServerRaster::redraw_request();
- }
- }
-
- if (geom->lighting_dirty) {
- int l = 0;
- //only called when lights AABB enter/exit this geometry
- ins->light_instances.resize(geom->lighting.size());
-
- for (List<Instance *>::Element *E = geom->lighting.front(); E; E = E->next()) {
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
-
- ins->light_instances.write[l++] = light->instance;
- }
-
- geom->lighting_dirty = false;
- }
-
- if (geom->reflection_dirty) {
- int l = 0;
- //only called when reflection probe AABB enter/exit this geometry
- ins->reflection_probe_instances.resize(geom->reflection_probes.size());
-
- for (List<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
-
- ins->reflection_probe_instances.write[l++] = reflection_probe->instance;
- }
-
- geom->reflection_dirty = false;
- }
-
- if (geom->gi_probes_dirty) {
- int l = 0;
- //only called when reflection probe AABB enter/exit this geometry
- ins->gi_probe_instances.resize(geom->gi_probes.size());
-
- for (List<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data);
-
- ins->gi_probe_instances.write[l++] = gi_probe->probe_instance;
- }
-
- geom->gi_probes_dirty = false;
- }
-
- if (ins->last_frame_pass != frame_number && !ins->lightmap_target_sh.empty() && !ins->lightmap_sh.empty()) {
- Color *sh = ins->lightmap_sh.ptrw();
- const Color *target_sh = ins->lightmap_target_sh.ptr();
- for (uint32_t j = 0; j < 9; j++) {
- sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
- }
- }
-
- ins->depth = near_plane.distance_to(ins->transform.origin);
- ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
- }
-
- if (!keep) {
- // remove, no reason to keep
- instance_cull_count--;
- SWAP(instance_cull_result[i], instance_cull_result[instance_cull_count]);
- i--;
- ins->last_render_pass = 0; // make invalid
- } else {
- ins->last_render_pass = render_pass;
- }
- ins->last_frame_pass = frame_number;
- }
-
- /* STEP 5 - PROCESS LIGHTS */
-
- RID *directional_light_ptr = &light_instance_cull_result[light_cull_count];
- directional_light_count = 0;
-
- // directional lights
- {
- Instance **lights_with_shadow = (Instance **)alloca(sizeof(Instance *) * scenario->directional_lights.size());
- int directional_shadow_count = 0;
-
- for (List<Instance *>::Element *E = scenario->directional_lights.front(); E; E = E->next()) {
- if (light_cull_count + directional_light_count >= MAX_LIGHTS_CULLED) {
- break;
- }
-
- if (!E->get()->visible) {
- continue;
- }
-
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
-
- //check shadow..
-
- if (light) {
- if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base)) {
- lights_with_shadow[directional_shadow_count++] = E->get();
- }
- //add to list
- directional_light_ptr[directional_light_count++] = light->instance;
- }
- }
-
- RSG::scene_render->set_directional_shadow_count(directional_shadow_count);
-
- for (int i = 0; i < directional_shadow_count; i++) {
- RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i));
-
- _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario);
-
- RENDER_TIMESTAMP("<Rendering Directional Light " + itos(i));
- }
- }
-
- if (p_using_shadows) { //setup shadow maps
-
- //SortArray<Instance*,_InstanceLightsort> sorter;
- //sorter.sort(light_cull_result,light_cull_count);
- for (int i = 0; i < light_cull_count; i++) {
- Instance *ins = light_cull_result[i];
-
- if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) {
- continue;
- }
-
- InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
-
- float coverage = 0.f;
-
- { //compute coverage
-
- Transform cam_xf = p_cam_transform;
- float zn = p_cam_projection.get_z_near();
- Plane p(cam_xf.origin + cam_xf.basis.get_axis(2) * -zn, -cam_xf.basis.get_axis(2)); //camera near plane
-
- // near plane half width and height
- Vector2 vp_half_extents = p_cam_projection.get_viewport_half_extents();
-
- switch (RSG::storage->light_get_type(ins->base)) {
- case RS::LIGHT_OMNI: {
- float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
-
- //get two points parallel to near plane
- Vector3 points[2] = {
- ins->transform.origin,
- ins->transform.origin + cam_xf.basis.get_axis(0) * radius
- };
-
- if (!p_cam_orthogonal) {
- //if using perspetive, map them to near plane
- for (int j = 0; j < 2; j++) {
- if (p.distance_to(points[j]) < 0) {
- points[j].z = -zn; //small hack to keep size constant when hitting the screen
- }
-
- p.intersects_segment(cam_xf.origin, points[j], &points[j]); //map to plane
- }
- }
-
- float screen_diameter = points[0].distance_to(points[1]) * 2;
- coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
- } break;
- case RS::LIGHT_SPOT: {
- float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
- float angle = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE);
-
- float w = radius * Math::sin(Math::deg2rad(angle));
- float d = radius * Math::cos(Math::deg2rad(angle));
-
- Vector3 base = ins->transform.origin - ins->transform.basis.get_axis(2).normalized() * d;
-
- Vector3 points[2] = {
- base,
- base + cam_xf.basis.get_axis(0) * w
- };
-
- if (!p_cam_orthogonal) {
- //if using perspetive, map them to near plane
- for (int j = 0; j < 2; j++) {
- if (p.distance_to(points[j]) < 0) {
- points[j].z = -zn; //small hack to keep size constant when hitting the screen
- }
-
- p.intersects_segment(cam_xf.origin, points[j], &points[j]); //map to plane
- }
- }
-
- float screen_diameter = points[0].distance_to(points[1]) * 2;
- coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
-
- } break;
- default: {
- ERR_PRINT("Invalid Light Type");
- }
- }
- }
-
- if (light->shadow_dirty) {
- light->last_version++;
- light->shadow_dirty = false;
- }
-
- bool redraw = RSG::scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version);
-
- if (redraw) {
- //must redraw!
- RENDER_TIMESTAMP(">Rendering Light " + itos(i));
- light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario);
- RENDER_TIMESTAMP("<Rendering Light " + itos(i));
- }
- }
- }
-
- /* UPDATE SDFGI */
-
- if (p_render_buffers.is_valid()) {
- uint32_t cascade_index[8];
- uint32_t cascade_sizes[8];
- const RID *cascade_ptrs[8];
- uint32_t cascade_count = 0;
- uint32_t sdfgi_light_cull_count = 0;
-
- uint32_t prev_cascade = 0xFFFFFFFF;
- for (int i = 0; i < RSG::scene_render->sdfgi_get_pending_region_count(p_render_buffers); i++) {
- AABB region = RSG::scene_render->sdfgi_get_pending_region_bounds(p_render_buffers, i);
- uint32_t region_cascade = RSG::scene_render->sdfgi_get_pending_region_cascade(p_render_buffers, i);
-
- if (region_cascade != prev_cascade) {
- cascade_sizes[cascade_count] = 0;
- cascade_index[cascade_count] = region_cascade;
- cascade_ptrs[cascade_count] = &sdfgi_light_cull_result[sdfgi_light_cull_count];
- cascade_count++;
- sdfgi_light_cull_pass++;
- prev_cascade = region_cascade;
- }
- uint32_t sdfgi_cull_count = scenario->octree.cull_aabb(region, instance_shadow_cull_result, MAX_INSTANCE_CULL);
-
- for (uint32_t j = 0; j < sdfgi_cull_count; j++) {
- Instance *ins = instance_shadow_cull_result[j];
-
- bool keep = false;
-
- if (ins->base_type == RS::INSTANCE_LIGHT && ins->visible) {
- InstanceLightData *instance_light = (InstanceLightData *)ins->base_data;
- if (instance_light->bake_mode != RS::LIGHT_BAKE_STATIC || region_cascade > instance_light->max_sdfgi_cascade) {
- continue;
- }
-
- if (sdfgi_light_cull_pass != instance_light->sdfgi_cascade_light_pass && sdfgi_light_cull_count < MAX_LIGHTS_CULLED) {
- instance_light->sdfgi_cascade_light_pass = sdfgi_light_cull_pass;
- sdfgi_light_cull_result[sdfgi_light_cull_count++] = instance_light->instance;
- cascade_sizes[cascade_count - 1]++;
- }
- } else if ((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
- if (ins->baked_light) {
- keep = true;
- }
- }
-
- if (!keep) {
- // remove, no reason to keep
- sdfgi_cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[sdfgi_cull_count]);
- j--;
- }
- }
-
- RSG::scene_render->render_sdfgi(p_render_buffers, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, sdfgi_cull_count);
- //have to save updated cascades, then update static lights.
- }
-
- if (sdfgi_light_cull_count) {
- RSG::scene_render->render_sdfgi_static_lights(p_render_buffers, cascade_count, cascade_index, cascade_ptrs, cascade_sizes);
- }
-
- RSG::scene_render->sdfgi_update_probes(p_render_buffers, p_environment, directional_light_ptr, directional_light_count, scenario->dynamic_lights.ptr(), scenario->dynamic_lights.size());
- }
-}
-
-RID RenderingServerScene::_render_get_environment(RID p_camera, RID p_scenario) {
- Camera *camera = camera_owner.getornull(p_camera);
- if (camera && RSG::scene_render->is_environment(camera->env)) {
- return camera->env;
- }
-
- Scenario *scenario = scenario_owner.getornull(p_scenario);
- if (!scenario) {
- return RID();
- }
- if (RSG::scene_render->is_environment(scenario->environment)) {
- return scenario->environment;
- }
-
- if (RSG::scene_render->is_environment(scenario->fallback_environment)) {
- return scenario->fallback_environment;
- }
-
- return RID();
-}
-
-void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
-
- RID camera_effects;
- if (p_force_camera_effects.is_valid()) {
- camera_effects = p_force_camera_effects;
- } else {
- camera_effects = scenario->camera_effects;
- }
- /* PROCESS GEOMETRY AND DRAW SCENE */
-
- RENDER_TIMESTAMP("Render Scene ");
- RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, (RasterizerScene::InstanceBase **)lightmap_cull_result, lightmap_cull_count, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
-}
-
-void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
-#ifndef _3D_DISABLED
-
- Scenario *scenario = scenario_owner.getornull(p_scenario);
-
- RID environment;
- if (scenario->environment.is_valid()) {
- environment = scenario->environment;
- } else {
- environment = scenario->fallback_environment;
- }
- RENDER_TIMESTAMP("Render Empty Scene ");
- RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
-#endif
-}
-
-bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
- Scenario *scenario = p_instance->scenario;
- ERR_FAIL_COND_V(!scenario, true);
-
- RenderingServerRaster::redraw_request(); //update, so it updates in editor
-
- if (p_step == 0) {
- if (!RSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
- return true; //all full
- }
- }
-
- if (p_step >= 0 && p_step < 6) {
- static const Vector3 view_normals[6] = {
- Vector3(+1, 0, 0),
- Vector3(-1, 0, 0),
- Vector3(0, +1, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, +1),
- Vector3(0, 0, -1)
- };
- static const Vector3 view_up[6] = {
- Vector3(0, -1, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, +1),
- Vector3(0, 0, -1),
- Vector3(0, -1, 0),
- Vector3(0, -1, 0)
- };
-
- Vector3 extents = RSG::storage->reflection_probe_get_extents(p_instance->base);
- Vector3 origin_offset = RSG::storage->reflection_probe_get_origin_offset(p_instance->base);
- float max_distance = RSG::storage->reflection_probe_get_origin_max_distance(p_instance->base);
-
- Vector3 edge = view_normals[p_step] * extents;
- 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);
-
- //render cubemap side
- CameraMatrix cm;
- cm.set_perspective(90, 1, 0.01, max_distance);
-
- Transform local_view;
- local_view.set_look_at(origin_offset, origin_offset + view_normals[p_step], view_up[p_step]);
-
- Transform xform = p_instance->transform * local_view;
-
- RID shadow_atlas;
-
- bool use_shadows = RSG::storage->reflection_probe_renders_shadows(p_instance->base);
- if (use_shadows) {
- shadow_atlas = scenario->reflection_probe_shadow_atlas;
- }
-
- RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step));
- _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows);
- _render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step);
-
- } else {
- //do roughness postprocess step until it believes it's done
- RENDER_TIMESTAMP("Post-Process Reflection Probe, Step " + itos(p_step));
- return RSG::scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance);
- }
-
- return false;
-}
-
-void RenderingServerScene::render_probes() {
- /* REFLECTION PROBES */
-
- SelfList<InstanceReflectionProbeData> *ref_probe = reflection_probe_render_list.first();
-
- bool busy = false;
-
- while (ref_probe) {
- SelfList<InstanceReflectionProbeData> *next = ref_probe->next();
- RID base = ref_probe->self()->owner->base;
-
- switch (RSG::storage->reflection_probe_get_update_mode(base)) {
- case RS::REFLECTION_PROBE_UPDATE_ONCE: {
- if (busy) { //already rendering something
- break;
- }
-
- bool done = _render_reflection_probe_step(ref_probe->self()->owner, ref_probe->self()->render_step);
- if (done) {
- reflection_probe_render_list.remove(ref_probe);
- } else {
- ref_probe->self()->render_step++;
- }
-
- busy = true; //do not render another one of this kind
- } break;
- case RS::REFLECTION_PROBE_UPDATE_ALWAYS: {
- int step = 0;
- bool done = false;
- while (!done) {
- done = _render_reflection_probe_step(ref_probe->self()->owner, step);
- step++;
- }
-
- reflection_probe_render_list.remove(ref_probe);
- } break;
- }
-
- ref_probe = next;
- }
-
- /* GI PROBES */
-
- SelfList<InstanceGIProbeData> *gi_probe = gi_probe_update_list.first();
-
- if (gi_probe) {
- RENDER_TIMESTAMP("Render GI Probes");
- }
-
- while (gi_probe) {
- SelfList<InstanceGIProbeData> *next = gi_probe->next();
-
- InstanceGIProbeData *probe = gi_probe->self();
- //Instance *instance_probe = probe->owner;
-
- //check if probe must be setup, but don't do if on the lighting thread
-
- bool cache_dirty = false;
- int cache_count = 0;
- {
- int light_cache_size = probe->light_cache.size();
- const InstanceGIProbeData::LightCache *caches = probe->light_cache.ptr();
- const RID *instance_caches = probe->light_instances.ptr();
-
- int idx = 0; //must count visible lights
- for (Set<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) {
- Instance *instance = E->get();
- InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
- if (!instance->visible) {
- continue;
- }
- if (cache_dirty) {
- //do nothing, since idx must count all visible lights anyway
- } else if (idx >= light_cache_size) {
- cache_dirty = true;
- } else {
- const InstanceGIProbeData::LightCache *cache = &caches[idx];
-
- if (
- instance_caches[idx] != instance_light->instance ||
- cache->has_shadow != RSG::storage->light_has_shadow(instance->base) ||
- cache->type != RSG::storage->light_get_type(instance->base) ||
- cache->transform != instance->transform ||
- cache->color != RSG::storage->light_get_color(instance->base) ||
- cache->energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
- cache->bake_energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
- cache->radius != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
- cache->attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
- cache->spot_angle != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
- cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION)) {
- cache_dirty = true;
- }
- }
-
- idx++;
- }
-
- for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) {
- Instance *instance = E->get();
- InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
- if (!instance->visible) {
- continue;
- }
- if (cache_dirty) {
- //do nothing, since idx must count all visible lights anyway
- } else if (idx >= light_cache_size) {
- cache_dirty = true;
- } else {
- const InstanceGIProbeData::LightCache *cache = &caches[idx];
-
- if (
- instance_caches[idx] != instance_light->instance ||
- cache->has_shadow != RSG::storage->light_has_shadow(instance->base) ||
- cache->type != RSG::storage->light_get_type(instance->base) ||
- cache->transform != instance->transform ||
- cache->color != RSG::storage->light_get_color(instance->base) ||
- cache->energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
- cache->bake_energy != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
- cache->radius != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
- cache->attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
- cache->spot_angle != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
- cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION)) {
- cache_dirty = true;
- }
- }
-
- idx++;
- }
-
- if (idx != light_cache_size) {
- cache_dirty = true;
- }
-
- cache_count = idx;
- }
-
- bool update_lights = RSG::scene_render->gi_probe_needs_update(probe->probe_instance);
-
- if (cache_dirty) {
- probe->light_cache.resize(cache_count);
- probe->light_instances.resize(cache_count);
-
- if (cache_count) {
- InstanceGIProbeData::LightCache *caches = probe->light_cache.ptrw();
- RID *instance_caches = probe->light_instances.ptrw();
-
- int idx = 0; //must count visible lights
- for (Set<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) {
- Instance *instance = E->get();
- InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
- if (!instance->visible) {
- continue;
- }
-
- InstanceGIProbeData::LightCache *cache = &caches[idx];
-
- instance_caches[idx] = instance_light->instance;
- cache->has_shadow = RSG::storage->light_has_shadow(instance->base);
- cache->type = RSG::storage->light_get_type(instance->base);
- cache->transform = instance->transform;
- cache->color = RSG::storage->light_get_color(instance->base);
- cache->energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
- cache->bake_energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
- cache->radius = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
- cache->attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
- cache->spot_angle = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
- cache->spot_attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
-
- idx++;
- }
- for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) {
- Instance *instance = E->get();
- InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
- if (!instance->visible) {
- continue;
- }
-
- InstanceGIProbeData::LightCache *cache = &caches[idx];
-
- instance_caches[idx] = instance_light->instance;
- cache->has_shadow = RSG::storage->light_has_shadow(instance->base);
- cache->type = RSG::storage->light_get_type(instance->base);
- cache->transform = instance->transform;
- cache->color = RSG::storage->light_get_color(instance->base);
- cache->energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
- cache->bake_energy = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
- cache->radius = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
- cache->attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
- cache->spot_angle = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
- cache->spot_attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
-
- idx++;
- }
- }
-
- update_lights = true;
- }
-
- instance_cull_count = 0;
- for (List<InstanceGIProbeData::PairInfo>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) {
- if (instance_cull_count < MAX_INSTANCE_CULL) {
- Instance *ins = E->get().geometry;
- if (!ins->visible) {
- continue;
- }
- InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data;
-
- if (geom->gi_probes_dirty) {
- //giprobes may be dirty, so update
- int l = 0;
- //only called when reflection probe AABB enter/exit this geometry
- ins->gi_probe_instances.resize(geom->gi_probes.size());
-
- for (List<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) {
- InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data);
-
- ins->gi_probe_instances.write[l++] = gi_probe2->probe_instance;
- }
-
- geom->gi_probes_dirty = false;
- }
-
- instance_cull_result[instance_cull_count++] = E->get().geometry;
- }
- }
-
- RSG::scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, instance_cull_count, (RasterizerScene::InstanceBase **)instance_cull_result);
-
- gi_probe_update_list.remove(gi_probe);
-
- gi_probe = next;
- }
-}
-
-void RenderingServerScene::render_particle_colliders() {
- while (heightfield_particle_colliders_update_list.front()) {
- Instance *hfpc = heightfield_particle_colliders_update_list.front()->get();
-
- if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::storage->particles_collision_is_heightfield(hfpc->base)) {
- //update heightfield
- int cull_count = hfpc->scenario->octree.cull_aabb(hfpc->transformed_aabb, instance_cull_result, MAX_INSTANCE_CULL); //@TODO: cull mask missing
- for (int i = 0; i < cull_count; i++) {
- Instance *instance = instance_cull_result[i];
- if (!instance->visible || !((1 << instance->base_type) & (RS::INSTANCE_GEOMETRY_MASK & (~(1 << RS::INSTANCE_PARTICLES))))) { //all but particles to avoid self collision
- cull_count--;
- SWAP(instance_cull_result[i], instance_cull_result[cull_count]);
- }
- }
-
- RSG::scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, (RasterizerScene::InstanceBase **)instance_cull_result, cull_count);
- }
- heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front());
- }
-}
-
-void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) {
- List<RasterizerStorage::InstanceShaderParam> plist;
- RSG::storage->material_get_instance_shader_parameters(p_material, &plist);
- for (List<RasterizerStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) {
- StringName name = E->get().info.name;
- if (isparams.has(name)) {
- if (isparams[name].info.type != E->get().info.type) {
- WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different data types. Only the first one (in order) will display correctly.");
- }
- if (isparams[name].index != E->get().index) {
- WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different indices. Only the first one (in order) will display correctly.");
- }
- continue; //first one found always has priority
- }
-
- RasterizerScene::InstanceBase::InstanceShaderParameter isp;
- isp.index = E->get().index;
- isp.info = E->get().info;
- isp.default_value = E->get().default_value;
- if (existing_isparams.has(name)) {
- isp.value = existing_isparams[name].value;
- } else {
- isp.value = E->get().default_value;
- }
- isparams[name] = isp;
- }
-}
-
-void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
- if (p_instance->update_aabb) {
- _update_instance_aabb(p_instance);
- }
-
- if (p_instance->update_dependencies) {
- p_instance->instance_increase_version();
-
- if (p_instance->base.is_valid()) {
- RSG::storage->base_update_dependency(p_instance->base, p_instance);
- }
-
- if (p_instance->material_override.is_valid()) {
- RSG::storage->material_update_dependency(p_instance->material_override, p_instance);
- }
-
- if (p_instance->base_type == RS::INSTANCE_MESH) {
- //remove materials no longer used and un-own them
-
- int new_mat_count = RSG::storage->mesh_get_surface_count(p_instance->base);
- p_instance->materials.resize(new_mat_count);
-
- int new_blend_shape_count = RSG::storage->mesh_get_blend_shape_count(p_instance->base);
- if (new_blend_shape_count != p_instance->blend_values.size()) {
- p_instance->blend_values.resize(new_blend_shape_count);
- for (int i = 0; i < new_blend_shape_count; i++) {
- p_instance->blend_values.write[i] = 0;
- }
- }
- }
-
- if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
-
- bool can_cast_shadows = true;
- bool is_animated = false;
- Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> isparams;
-
- if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
- can_cast_shadows = false;
- }
-
- if (p_instance->material_override.is_valid()) {
- if (!RSG::storage->material_casts_shadows(p_instance->material_override)) {
- can_cast_shadows = false;
- }
- is_animated = RSG::storage->material_is_animated(p_instance->material_override);
- _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override);
- } else {
- if (p_instance->base_type == RS::INSTANCE_MESH) {
- RID mesh = p_instance->base;
-
- if (mesh.is_valid()) {
- bool cast_shadows = false;
-
- for (int i = 0; i < p_instance->materials.size(); i++) {
- RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::storage->mesh_surface_get_material(mesh, i);
-
- if (!mat.is_valid()) {
- cast_shadows = true;
- } else {
- if (RSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- }
-
- if (RSG::storage->material_is_animated(mat)) {
- is_animated = true;
- }
-
- _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
-
- RSG::storage->material_update_dependency(mat, p_instance);
- }
- }
-
- if (!cast_shadows) {
- can_cast_shadows = false;
- }
- }
-
- } else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) {
- RID mesh = RSG::storage->multimesh_get_mesh(p_instance->base);
- if (mesh.is_valid()) {
- bool cast_shadows = false;
-
- int sc = RSG::storage->mesh_get_surface_count(mesh);
- for (int i = 0; i < sc; i++) {
- RID mat = RSG::storage->mesh_surface_get_material(mesh, i);
-
- if (!mat.is_valid()) {
- cast_shadows = true;
-
- } else {
- if (RSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- }
- if (RSG::storage->material_is_animated(mat)) {
- is_animated = true;
- }
-
- _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
-
- RSG::storage->material_update_dependency(mat, p_instance);
- }
- }
-
- if (!cast_shadows) {
- can_cast_shadows = false;
- }
-
- RSG::storage->base_update_dependency(mesh, p_instance);
- }
- } else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) {
- RID mat = RSG::storage->immediate_get_material(p_instance->base);
-
- if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) {
- can_cast_shadows = false;
- }
-
- if (mat.is_valid() && RSG::storage->material_is_animated(mat)) {
- is_animated = true;
- }
-
- if (mat.is_valid()) {
- _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
- }
-
- if (mat.is_valid()) {
- RSG::storage->material_update_dependency(mat, p_instance);
- }
-
- } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
- bool cast_shadows = false;
-
- int dp = RSG::storage->particles_get_draw_passes(p_instance->base);
-
- for (int i = 0; i < dp; i++) {
- RID mesh = RSG::storage->particles_get_draw_pass_mesh(p_instance->base, i);
- if (!mesh.is_valid()) {
- continue;
- }
-
- int sc = RSG::storage->mesh_get_surface_count(mesh);
- for (int j = 0; j < sc; j++) {
- RID mat = RSG::storage->mesh_surface_get_material(mesh, j);
-
- if (!mat.is_valid()) {
- cast_shadows = true;
- } else {
- if (RSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- }
-
- if (RSG::storage->material_is_animated(mat)) {
- is_animated = true;
- }
-
- _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
-
- RSG::storage->material_update_dependency(mat, p_instance);
- }
- }
- }
-
- if (!cast_shadows) {
- can_cast_shadows = false;
- }
- }
- }
-
- if (can_cast_shadows != geom->can_cast_shadows) {
- //ability to cast shadows change, let lights now
- for (List<Instance *>::Element *E = geom->lighting.front(); E; E = E->next()) {
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
- light->shadow_dirty = true;
- }
-
- geom->can_cast_shadows = can_cast_shadows;
- }
-
- geom->material_is_animated = is_animated;
- p_instance->instance_shader_parameters = isparams;
-
- if (p_instance->instance_allocated_shader_parameters != (p_instance->instance_shader_parameters.size() > 0)) {
- p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0);
- if (p_instance->instance_allocated_shader_parameters) {
- p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self);
- for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) {
- if (E->get().value.get_type() != Variant::NIL) {
- RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value);
- }
- }
- } else {
- RSG::storage->global_variables_instance_free(p_instance->self);
- p_instance->instance_allocated_shader_parameters_offset = -1;
- }
- }
- }
-
- if (p_instance->skeleton.is_valid()) {
- RSG::storage->skeleton_update_dependency(p_instance->skeleton, p_instance);
- }
-
- p_instance->clean_up_dependencies();
- }
-
- _instance_update_list.remove(&p_instance->update_item);
-
- _update_instance(p_instance);
-
- p_instance->update_aabb = false;
- p_instance->update_dependencies = false;
-}
-
-void RenderingServerScene::update_dirty_instances() {
- RSG::storage->update_dirty_resources();
-
- while (_instance_update_list.first()) {
- _update_dirty_instance(_instance_update_list.first()->self());
- }
-}
-
-bool RenderingServerScene::free(RID p_rid) {
- if (camera_owner.owns(p_rid)) {
- Camera *camera = camera_owner.getornull(p_rid);
-
- camera_owner.free(p_rid);
- memdelete(camera);
-
- } else if (scenario_owner.owns(p_rid)) {
- Scenario *scenario = scenario_owner.getornull(p_rid);
-
- while (scenario->instances.first()) {
- instance_set_scenario(scenario->instances.first()->self()->self, RID());
- }
- RSG::scene_render->free(scenario->reflection_probe_shadow_atlas);
- RSG::scene_render->free(scenario->reflection_atlas);
- scenario_owner.free(p_rid);
- memdelete(scenario);
-
- } else if (instance_owner.owns(p_rid)) {
- // delete the instance
-
- update_dirty_instances();
-
- Instance *instance = instance_owner.getornull(p_rid);
-
- instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0);
- instance_set_scenario(p_rid, RID());
- instance_set_base(p_rid, RID());
- instance_geometry_set_material_override(p_rid, RID());
- instance_attach_skeleton(p_rid, RID());
-
- if (instance->instance_allocated_shader_parameters) {
- //free the used shader parameters
- RSG::storage->global_variables_instance_free(instance->self);
- }
- update_dirty_instances(); //in case something changed this
-
- instance_owner.free(p_rid);
- memdelete(instance);
- } else {
- return false;
- }
-
- return true;
-}
-
-TypedArray<Image> RenderingServerScene::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) {
- return RSG::scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size);
-}
-
-RenderingServerScene *RenderingServerScene::singleton = nullptr;
-
-RenderingServerScene::RenderingServerScene() {
- render_pass = 1;
- singleton = this;
-}
-
-RenderingServerScene::~RenderingServerScene() {
-}
diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h
deleted file mode 100644
index 646b2a666f..0000000000
--- a/servers/rendering/rendering_server_scene.h
+++ /dev/null
@@ -1,476 +0,0 @@
-/*************************************************************************/
-/* rendering_server_scene.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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. */
-/*************************************************************************/
-
-#ifndef VISUALSERVERSCENE_H
-#define VISUALSERVERSCENE_H
-
-#include "servers/rendering/rasterizer.h"
-
-#include "core/math/geometry_3d.h"
-#include "core/math/octree.h"
-#include "core/os/semaphore.h"
-#include "core/os/thread.h"
-#include "core/templates/local_vector.h"
-#include "core/templates/rid_owner.h"
-#include "core/templates/self_list.h"
-#include "servers/xr/xr_interface.h"
-
-class RenderingServerScene {
-public:
- enum {
- MAX_INSTANCE_CULL = 65536,
- MAX_LIGHTS_CULLED = 4096,
- MAX_REFLECTION_PROBES_CULLED = 4096,
- MAX_DECALS_CULLED = 4096,
- MAX_GI_PROBES_CULLED = 4096,
- MAX_ROOM_CULL = 32,
- MAX_LIGHTMAPS_CULLED = 4096,
- MAX_EXTERIOR_PORTALS = 128,
- };
-
- uint64_t render_pass;
-
- static RenderingServerScene *singleton;
-
- /* CAMERA API */
-
- struct Camera {
- enum Type {
- PERSPECTIVE,
- ORTHOGONAL,
- FRUSTUM
- };
- Type type;
- float fov;
- float znear, zfar;
- float size;
- Vector2 offset;
- uint32_t visible_layers;
- bool vaspect;
- RID env;
- RID effects;
-
- Transform transform;
-
- Camera() {
- visible_layers = 0xFFFFFFFF;
- fov = 75;
- type = PERSPECTIVE;
- znear = 0.05;
- zfar = 100;
- size = 1.0;
- offset = Vector2();
- vaspect = false;
- }
- };
-
- mutable RID_PtrOwner<Camera> camera_owner;
-
- virtual RID camera_create();
- virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far);
- virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
- virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far);
- virtual void camera_set_transform(RID p_camera, const Transform &p_transform);
- virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers);
- virtual void camera_set_environment(RID p_camera, RID p_env);
- virtual void camera_set_camera_effects(RID p_camera, RID p_fx);
- virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable);
-
- /* SCENARIO API */
-
- struct Instance;
-
- struct Scenario {
- RS::ScenarioDebugMode debug;
- RID self;
-
- Octree<Instance, true> octree;
-
- List<Instance *> directional_lights;
- RID environment;
- RID fallback_environment;
- RID camera_effects;
- RID reflection_probe_shadow_atlas;
- RID reflection_atlas;
-
- SelfList<Instance>::List instances;
-
- LocalVector<RID> dynamic_lights;
-
- Scenario() { debug = RS::SCENARIO_DEBUG_DISABLED; }
- };
-
- mutable RID_PtrOwner<Scenario> scenario_owner;
-
- static void *_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int);
- static void _instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *);
-
- virtual RID scenario_create();
-
- virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode);
- virtual void scenario_set_environment(RID p_scenario, RID p_environment);
- virtual void scenario_set_camera_effects(RID p_scenario, RID p_fx);
- virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
- virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count);
-
- /* INSTANCING API */
-
- struct InstanceBaseData {
- virtual ~InstanceBaseData() {}
- };
-
- struct Instance : RasterizerScene::InstanceBase {
- RID self;
- //scenario stuff
- OctreeElementID octree_id;
- Scenario *scenario;
- SelfList<Instance> scenario_item;
-
- //aabb stuff
- bool update_aabb;
- bool update_dependencies;
-
- SelfList<Instance> update_item;
-
- AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better?
- float extra_margin;
- ObjectID object_id;
-
- float lod_begin;
- float lod_end;
- float lod_begin_hysteresis;
- float lod_end_hysteresis;
- RID lod_instance;
-
- 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_render_pass;
- uint64_t last_frame_pass;
-
- uint64_t version; // changes to this, and changes to base increase version
-
- InstanceBaseData *base_data;
-
- virtual void dependency_deleted(RID p_dependency) {
- if (p_dependency == base) {
- singleton->instance_set_base(self, RID());
- } else if (p_dependency == skeleton) {
- singleton->instance_attach_skeleton(self, RID());
- } else {
- singleton->_instance_queue_update(this, false, true);
- }
- }
-
- virtual void dependency_changed(bool p_aabb, bool p_dependencies) {
- singleton->_instance_queue_update(this, p_aabb, p_dependencies);
- }
-
- Instance() :
- scenario_item(this),
- update_item(this) {
- octree_id = 0;
- scenario = nullptr;
-
- update_aabb = false;
- update_dependencies = false;
-
- extra_margin = 0;
-
- visible = true;
-
- lod_begin = 0;
- lod_end = 0;
- lod_begin_hysteresis = 0;
- lod_end_hysteresis = 0;
-
- last_render_pass = 0;
- last_frame_pass = 0;
- version = 1;
- base_data = nullptr;
-
- custom_aabb = nullptr;
- }
-
- ~Instance() {
- if (base_data) {
- memdelete(base_data);
- }
- if (custom_aabb) {
- memdelete(custom_aabb);
- }
- }
- };
-
- SelfList<Instance>::List _instance_update_list;
- void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
-
- struct InstanceGeometryData : public InstanceBaseData {
- List<Instance *> lighting;
- bool lighting_dirty;
- bool can_cast_shadows;
- bool material_is_animated;
-
- List<Instance *> decals;
- bool decal_dirty;
-
- List<Instance *> reflection_probes;
- bool reflection_dirty;
-
- List<Instance *> gi_probes;
- bool gi_probes_dirty;
-
- List<Instance *> lightmap_captures;
-
- InstanceGeometryData() {
- lighting_dirty = false;
- reflection_dirty = true;
- can_cast_shadows = true;
- material_is_animated = true;
- gi_probes_dirty = true;
- decal_dirty = true;
- }
- };
-
- struct InstanceReflectionProbeData : public InstanceBaseData {
- Instance *owner;
-
- struct PairInfo {
- List<Instance *>::Element *L; //reflection iterator in geometry
- Instance *geometry;
- };
- List<PairInfo> geometries;
-
- RID instance;
- bool reflection_dirty;
- SelfList<InstanceReflectionProbeData> update_list;
-
- int render_step;
-
- InstanceReflectionProbeData() :
- update_list(this) {
- reflection_dirty = true;
- render_step = -1;
- }
- };
-
- struct InstanceDecalData : public InstanceBaseData {
- Instance *owner;
- RID instance;
-
- struct PairInfo {
- List<Instance *>::Element *L; //reflection iterator in geometry
- Instance *geometry;
- };
- List<PairInfo> geometries;
-
- InstanceDecalData() {
- }
- };
-
- SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
-
- struct InstanceLightData : public InstanceBaseData {
- struct PairInfo {
- List<Instance *>::Element *L; //light iterator in geometry
- Instance *geometry;
- };
-
- RID instance;
- uint64_t last_version;
- List<Instance *>::Element *D; // directional light in scenario
-
- bool shadow_dirty;
-
- List<PairInfo> geometries;
-
- Instance *baked_light;
-
- RS::LightBakeMode bake_mode;
- uint32_t max_sdfgi_cascade = 2;
-
- uint64_t sdfgi_cascade_light_pass = 0;
-
- InstanceLightData() {
- bake_mode = RS::LIGHT_BAKE_DISABLED;
- shadow_dirty = true;
- D = nullptr;
- last_version = 0;
- baked_light = nullptr;
- }
- };
-
- struct InstanceGIProbeData : public InstanceBaseData {
- Instance *owner;
-
- struct PairInfo {
- List<Instance *>::Element *L; //gi probe iterator in geometry
- Instance *geometry;
- };
-
- List<PairInfo> geometries;
- List<PairInfo> dynamic_geometries;
-
- Set<Instance *> lights;
-
- struct LightCache {
- RS::LightType type;
- Transform transform;
- Color color;
- float energy;
- float bake_energy;
- float radius;
- float attenuation;
- float spot_angle;
- float spot_attenuation;
- bool has_shadow;
- };
-
- Vector<LightCache> light_cache;
- Vector<RID> light_instances;
-
- RID probe_instance;
-
- bool invalid;
- uint32_t base_version;
-
- SelfList<InstanceGIProbeData> update_element;
-
- InstanceGIProbeData() :
- update_element(this) {
- invalid = true;
- base_version = 0;
- }
- };
-
- SelfList<InstanceGIProbeData>::List gi_probe_update_list;
-
- struct InstanceLightmapData : public InstanceBaseData {
- struct PairInfo {
- List<Instance *>::Element *L; //iterator in geometry
- Instance *geometry;
- };
- List<PairInfo> geometries;
-
- Set<Instance *> users;
-
- InstanceLightmapData() {
- }
- };
-
- Set<Instance *> heightfield_particle_colliders_update_list;
-
- int instance_cull_count;
- Instance *instance_cull_result[MAX_INSTANCE_CULL];
- Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps
- Instance *light_cull_result[MAX_LIGHTS_CULLED];
- RID sdfgi_light_cull_result[MAX_LIGHTS_CULLED];
- RID light_instance_cull_result[MAX_LIGHTS_CULLED];
- uint64_t sdfgi_light_cull_pass = 0;
- int light_cull_count;
- int directional_light_count;
- RID reflection_probe_instance_cull_result[MAX_REFLECTION_PROBES_CULLED];
- RID decal_instance_cull_result[MAX_DECALS_CULLED];
- int reflection_probe_cull_count;
- int decal_cull_count;
- RID gi_probe_instance_cull_result[MAX_GI_PROBES_CULLED];
- int gi_probe_cull_count;
- Instance *lightmap_cull_result[MAX_LIGHTS_CULLED];
- int lightmap_cull_count;
-
- RID_PtrOwner<Instance> instance_owner;
-
- virtual RID instance_create();
-
- 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_transform(RID p_instance, const Transform &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);
- virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material);
- virtual void instance_set_visible(RID p_instance, bool p_visible);
-
- virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb);
-
- virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton);
- virtual void instance_set_exterior(RID p_instance, bool p_enabled);
-
- virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin);
-
- // don't use these in a game!
- virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const;
- virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const;
- virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const;
-
- virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled);
- virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting);
- virtual void instance_geometry_set_material_override(RID p_instance, RID p_material);
-
- virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin);
- virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance);
- virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
-
- void _update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material);
-
- virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value);
- virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const;
- virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const;
- virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const;
-
- _FORCE_INLINE_ void _update_instance(Instance *p_instance);
- _FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance);
- _FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
- _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
-
- _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario);
-
- RID _render_get_environment(RID p_camera, RID p_scenario);
-
- bool _render_reflection_probe_step(Instance *p_instance, int p_step);
- void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows = true);
- void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
- void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas);
-
- void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
- void render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
- void update_dirty_instances();
-
- void render_particle_colliders();
- void render_probes();
-
- TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size);
-
- bool free(RID p_rid);
-
- RenderingServerScene();
- virtual ~RenderingServerScene();
-};
-
-#endif // VISUALSERVERSCENE_H
diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp
index 40ad228fd0..3572c4dc78 100644
--- a/servers/rendering/rendering_server_wrap_mt.cpp
+++ b/servers/rendering/rendering_server_wrap_mt.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index d33bdb043a..3db90c32df 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -129,6 +129,8 @@ public:
FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &)
FUNC2RC(Variant, shader_get_param_default, RID, const StringName &)
+ FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID)
+
/* COMMON MATERIAL API */
FUNCRID(material)
@@ -143,10 +145,12 @@ public:
/* MESH API */
- virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces) {
- return rendering_server->mesh_create_from_surfaces(p_surfaces);
+ virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) {
+ return rendering_server->mesh_create_from_surfaces(p_surfaces, p_blend_shape_count);
}
+ FUNC2(mesh_set_blend_shape_count, RID, int)
+
FUNCRID(mesh)
FUNC2(mesh_add_surface, RID, const SurfaceData &)
@@ -244,6 +248,7 @@ public:
FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
FUNC2(light_directional_set_blend_splits, RID, bool)
+ FUNC2(light_directional_set_sky_only, RID, bool)
FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
/* PROBE API */
@@ -263,6 +268,7 @@ public:
FUNC2(reflection_probe_set_enable_shadows, RID, bool)
FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
FUNC2(reflection_probe_set_resolution, RID, int)
+ FUNC2(reflection_probe_set_lod_threshold, RID, float)
/* DECAL API */
@@ -447,6 +453,8 @@ public:
FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
FUNC2(viewport_set_use_debanding, RID, bool)
+ FUNC2(viewport_set_lod_threshold, RID, float)
+
//this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport
virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) {
return rendering_server->viewport_get_render_info(p_viewport, p_info);
@@ -492,9 +500,9 @@ public:
FUNC6(environment_set_ssr, RID, bool, int, float, float, float)
FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality)
- FUNC9(environment_set_ssao, RID, bool, float, float, float, float, float, EnvironmentSSAOBlur, float)
+ FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float)
- FUNC2(environment_set_ssao_quality, EnvironmentSSAOQuality, bool)
+ FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float)
FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
@@ -506,7 +514,7 @@ public:
FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
- FUNC6(environment_set_adjustment, RID, bool, float, float, float, RID)
+ FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
@@ -572,6 +580,7 @@ public:
FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float)
FUNC2(instance_geometry_set_as_instance_lod, RID, RID)
FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
+ FUNC2(instance_geometry_set_lod_bias, RID, float)
FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
@@ -618,7 +627,7 @@ public:
FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
- FUNC4(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float)
+ FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float)
FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
@@ -769,6 +778,10 @@ public:
return rendering_server->get_frame_profile();
}
+ virtual float get_frame_setup_time_cpu() const {
+ return rendering_server->get_frame_setup_time_cpu();
+ }
+
virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {
rendering_server->sdfgi_set_debug_probe_select(p_position, p_dir);
}
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 1ab353c9d0..2fa3355d2f 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -223,7 +223,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
String ShaderLanguage::get_token_text(Token p_token) {
String name = token_names[p_token.type];
- if (p_token.type == TK_INT_CONSTANT || p_token.type == TK_REAL_CONSTANT) {
+ if (p_token.type == TK_INT_CONSTANT || p_token.type == TK_FLOAT_CONSTANT) {
name += "(" + rtos(p_token.constant) + ")";
} else if (p_token.type == TK_IDENTIFIER) {
name += "(" + String(p_token.text) + ")";
@@ -637,7 +637,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
char_idx += str.length();
Token tk;
if (period_found || exponent_found || float_suffix_found) {
- tk.type = TK_REAL_CONSTANT;
+ tk.type = TK_FLOAT_CONSTANT;
} else {
tk.type = TK_INT_CONSTANT;
}
@@ -913,6 +913,7 @@ void ShaderLanguage::clear() {
char_idx = 0;
error_set = false;
error_str = "";
+ last_const = false;
while (nodes) {
Node *n = nodes;
nodes = nodes->next;
@@ -920,7 +921,7 @@ void ShaderLanguage::clear() {
}
}
-bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) {
+bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name, ConstantNode::Value *r_constant_value) {
if (p_function_info.built_ins.has(p_identifier)) {
if (r_data_type) {
*r_data_type = p_function_info.built_ins[p_identifier].type;
@@ -968,6 +969,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
if (r_struct_name) {
*r_struct_name = p_block->variables[p_identifier].struct_name;
}
+ if (r_constant_value) {
+ *r_constant_value = p_block->variables[p_identifier].value;
+ }
return true;
}
@@ -1028,6 +1032,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
}
if (shader->constants.has(p_identifier)) {
+ if (r_is_const) {
+ *r_is_const = true;
+ }
if (r_data_type) {
*r_data_type = shader->constants[p_identifier].type;
}
@@ -1040,6 +1047,11 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
if (r_struct_name) {
*r_struct_name = shader->constants[p_identifier].type_str;
}
+ if (r_constant_value) {
+ if (shader->constants[p_identifier].initializer && shader->constants[p_identifier].initializer->values.size() == 1) {
+ *r_constant_value = shader->constants[p_identifier].initializer->values[0];
+ }
+ }
return true;
}
@@ -3174,7 +3186,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi
}
bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) {
- for (int i = 0; shader->functions.size(); i++) {
+ for (int i = 0; i < shader->functions.size(); i++) {
if (shader->functions[i].name == p_name) {
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
@@ -3208,7 +3220,7 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam
}
bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) {
- for (int i = 0; shader->functions.size(); i++) {
+ for (int i = 0; i < shader->functions.size(); i++) {
if (shader->functions[i].name == p_name) {
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
@@ -3241,6 +3253,137 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
ERR_FAIL_V(false); //bug? function not found
}
+ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size) {
+ DataType type = TYPE_VOID;
+ String struct_name = "";
+ int array_size = 0;
+ bool auto_size = false;
+ Token tk = _get_token();
+
+ if (tk.type == TK_CURLY_BRACKET_OPEN) {
+ auto_size = true;
+ } else {
+ if (shader->structs.has(tk.text)) {
+ type = TYPE_STRUCT;
+ struct_name = tk.text;
+ } else {
+ if (!is_token_variable_datatype(tk.type)) {
+ _set_error("Invalid data type for array");
+ return nullptr;
+ }
+ type = get_token_datatype(tk.type);
+ }
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_OPEN) {
+ TkPos pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ array_size = p_array_size;
+ tk = _get_token();
+ } else {
+ _set_tkpos(pos);
+
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
+ if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
+ _set_error("Expected single integer constant > 0");
+ return nullptr;
+ }
+
+ ConstantNode *cnode = (ConstantNode *)n;
+ if (cnode->values.size() == 1) {
+ array_size = cnode->values[0].sint;
+ if (array_size <= 0) {
+ _set_error("Expected single integer constant > 0");
+ return nullptr;
+ }
+ } else {
+ _set_error("Expected single integer constant > 0");
+ return nullptr;
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']'");
+ return nullptr;
+ } else {
+ tk = _get_token();
+ }
+ }
+ } else {
+ _set_error("Expected '['");
+ return nullptr;
+ }
+
+ if (type != p_type || struct_name != p_struct_name || array_size != p_array_size) {
+ String error_str = "Cannot convert from '";
+ if (type == TYPE_STRUCT) {
+ error_str += struct_name;
+ } else {
+ error_str += get_datatype_name(type);
+ }
+ error_str += "[";
+ error_str += itos(array_size);
+ error_str += "]'";
+ error_str += " to '";
+ if (type == TYPE_STRUCT) {
+ error_str += p_struct_name;
+ } else {
+ error_str += get_datatype_name(p_type);
+ }
+ error_str += "[";
+ error_str += itos(p_array_size);
+ error_str += "]'";
+ _set_error(error_str);
+ return nullptr;
+ }
+ }
+
+ ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
+ an->datatype = p_type;
+ an->struct_name = p_struct_name;
+
+ if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
+ while (true) {
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
+ if (!n) {
+ return nullptr;
+ }
+
+ if (p_type != n->get_datatype() || p_struct_name != n->get_datatype_name()) {
+ _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'");
+ return nullptr;
+ }
+
+ tk = _get_token();
+ if (tk.type == TK_COMMA) {
+ an->initializer.push_back(n);
+ } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
+ an->initializer.push_back(n);
+ break;
+ } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
+ an->initializer.push_back(n);
+ break;
+ } else {
+ if (auto_size) {
+ _set_error("Expected '}' or ','");
+ } else {
+ _set_error("Expected ')' or ','");
+ }
+ return nullptr;
+ }
+ }
+ if (an->initializer.size() != p_array_size) {
+ _set_error("Array size mismatch");
+ return nullptr;
+ }
+ } else {
+ _set_error("Expected array initialization!");
+ return nullptr;
+ }
+
+ return an;
+}
+
ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
Vector<Expression> expression;
@@ -3269,7 +3412,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
- } else if (tk.type == TK_REAL_CONSTANT) {
+ } else if (tk.type == TK_FLOAT_CONSTANT) {
ConstantNode *constant = alloc_node<ConstantNode>();
ConstantNode::Value v;
v.real = tk.constant;
@@ -3384,142 +3527,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
Node *nexpr;
if (pstruct->members[i]->array_size != 0) {
- DataType type = pstruct->members[i]->get_datatype();
- String struct_name = pstruct->members[i]->struct_name;
- int array_size = pstruct->members[i]->array_size;
-
- DataType type2;
- String struct_name2 = "";
- int array_size2 = 0;
-
- bool auto_size = false;
-
- tk = _get_token();
-
- if (tk.type == TK_CURLY_BRACKET_OPEN) {
- auto_size = true;
- } else {
- if (shader->structs.has(tk.text)) {
- type2 = TYPE_STRUCT;
- struct_name2 = tk.text;
- } else {
- if (!is_token_variable_datatype(tk.type)) {
- _set_error("Invalid data type for array");
- return nullptr;
- }
- type2 = get_token_datatype(tk.type);
- }
-
- tk = _get_token();
- if (tk.type == TK_BRACKET_OPEN) {
- TkPos pos2 = _get_tkpos();
- tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
- array_size2 = array_size;
- tk = _get_token();
- } else {
- _set_tkpos(pos2);
-
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- ConstantNode *cnode = (ConstantNode *)n;
- if (cnode->values.size() == 1) {
- array_size2 = cnode->values[0].sint;
- if (array_size2 <= 0) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
- } else {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return nullptr;
- } else {
- tk = _get_token();
- }
- }
- } else {
- _set_error("Expected '['");
- return nullptr;
- }
-
- if (type != type2 || struct_name != struct_name2 || array_size != array_size2) {
- String error_str = "Cannot convert from '";
- if (type2 == TYPE_STRUCT) {
- error_str += struct_name2;
- } else {
- error_str += get_datatype_name(type2);
- }
- error_str += "[";
- error_str += itos(array_size2);
- error_str += "]'";
- error_str += " to '";
- if (type == TYPE_STRUCT) {
- error_str += struct_name;
- } else {
- error_str += get_datatype_name(type);
- }
- error_str += "[";
- error_str += itos(array_size);
- error_str += "]'";
- _set_error(error_str);
- return nullptr;
- }
- }
-
- ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
- an->datatype = type;
- an->struct_name = struct_name;
-
- if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
- while (true) {
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (!n) {
- return nullptr;
- }
-
- if (type != n->get_datatype() || struct_name != n->get_datatype_name()) {
- _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'");
- return nullptr;
- }
-
- tk = _get_token();
- if (tk.type == TK_COMMA) {
- an->initializer.push_back(n);
- continue;
- } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
- an->initializer.push_back(n);
- break;
- } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
- an->initializer.push_back(n);
- break;
- } else {
- if (auto_size) {
- _set_error("Expected '}' or ','");
- } else {
- _set_error("Expected ')' or ','");
- }
- return nullptr;
- }
- }
- if (an->initializer.size() != array_size) {
- _set_error("Array size mismatch");
- return nullptr;
- }
- } else {
- _set_error("Expected array initialization!");
+ nexpr = _parse_array_constructor(p_block, p_function_info, pstruct->members[i]->get_datatype(), pstruct->members[i]->struct_name, pstruct->members[i]->array_size);
+ if (!nexpr) {
return nullptr;
}
-
- nexpr = an;
} else {
nexpr = _parse_and_reduce_expression(p_block, p_function_info);
if (!nexpr) {
@@ -3722,6 +3733,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else {
//an identifier
+ last_const = false;
_set_tkpos(pos);
DataType data_type;
@@ -3749,6 +3761,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
_set_error("Unknown identifier in expression: " + String(identifier));
return nullptr;
}
+ last_const = is_const;
if (ident_type == IDENTIFIER_FUNCTION) {
_set_error("Can't use function as identifier: " + String(identifier));
@@ -3758,16 +3771,30 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
Node *index_expression = nullptr;
Node *call_expression = nullptr;
+ Node *assign_expression = nullptr;
if (array_size > 0) {
tk = _get_token();
- if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD) {
- _set_error("Expected '[' or '.'");
+ if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD && tk.type != TK_OP_ASSIGN) {
+ _set_error("Expected '[','.' or '='");
return nullptr;
}
- if (tk.type == TK_PERIOD) {
+ if (tk.type == TK_OP_ASSIGN) {
+ if (is_const) {
+ _set_error("Constants cannot be modified.");
+ return nullptr;
+ }
+ if (shader->varyings.has(identifier) && current_function != String("vertex")) {
+ _set_error("Varyings can only be assigned in vertex function.");
+ return nullptr;
+ }
+ assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size);
+ if (!assign_expression) {
+ return nullptr;
+ }
+ } else if (tk.type == TK_PERIOD) {
completion_class = TAG_ARRAY;
p_block->block_tag = SubClassTag::TAG_ARRAY;
call_expression = _parse_and_reduce_expression(p_block, p_function_info);
@@ -3791,7 +3818,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index_expression->type == Node::TYPE_CONSTANT) {
ConstantNode *cnode = (ConstantNode *)index_expression;
if (cnode) {
- if (!cnode->values.empty()) {
+ if (!cnode->values.is_empty()) {
int value = cnode->values[0].sint;
if (value < 0 || value >= array_size) {
_set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1));
@@ -3814,6 +3841,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
arrname->struct_name = struct_name;
arrname->index_expression = index_expression;
arrname->call_expression = call_expression;
+ arrname->assign_expression = assign_expression;
arrname->is_const = is_const;
expr = arrname;
@@ -4154,7 +4182,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (array_size > 0) {
tk = _get_token();
- if (tk.type == TK_PERIOD) {
+ if (tk.type == TK_OP_ASSIGN) {
+ if (last_const) {
+ last_const = false;
+ _set_error("Constants cannot be modified.");
+ return nullptr;
+ }
+ Node *assign_expression = _parse_array_constructor(p_block, p_function_info, member_type, member_struct_name, array_size);
+ if (!assign_expression) {
+ return nullptr;
+ }
+ mn->assign_expression = assign_expression;
+ } else if (tk.type == TK_PERIOD) {
_set_error("Nested array length() is not yet implemented");
return nullptr;
} else if (tk.type == TK_BRACKET_OPEN) {
@@ -4171,7 +4210,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index_expression->type == Node::TYPE_CONSTANT) {
ConstantNode *cnode = (ConstantNode *)index_expression;
if (cnode) {
- if (!cnode->values.empty()) {
+ if (!cnode->values.is_empty()) {
int value = cnode->values[0].sint;
if (value < 0 || value >= array_size) {
_set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1));
@@ -4189,7 +4228,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
mn->index_expression = index_expression;
} else {
- _set_error("Expected '[' or '.'");
+ _set_error("Expected '[','.' or '='");
return nullptr;
}
}
@@ -5010,17 +5049,53 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
decl.name = name;
decl.size = 0U;
+ pos = _get_tkpos();
tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
unknown_size = true;
} else {
if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
+ _set_tkpos(pos);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
+ if (n) {
+ if (n->type == Node::TYPE_VARIABLE) {
+ VariableNode *vn = static_cast<VariableNode *>(n);
+ if (vn) {
+ ConstantNode::Value v;
+ DataType data_type;
+
+ _find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, &is_const, nullptr, nullptr, &v);
+
+ if (is_const) {
+ if (data_type == TYPE_INT) {
+ int32_t value = v.sint;
+ if (value > 0) {
+ node->size_expression = n;
+ decl.size = (uint32_t)value;
+ }
+ } else if (data_type == TYPE_UINT) {
+ uint32_t value = v.uint;
+ if (value > 0U) {
+ node->size_expression = n;
+ decl.size = value;
+ }
+ }
+ }
+ }
+ } else if (n->type == Node::TYPE_OPERATOR) {
+ _set_error("Array size expressions are not yet implemented.");
+ return ERR_PARSE_ERROR;
+ }
+ }
+ } else if (((int)tk.constant) > 0) {
+ decl.size = (uint32_t)tk.constant;
+ }
+
+ if (decl.size == 0U) {
_set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
}
-
- decl.size = ((uint32_t)tk.constant);
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
@@ -5218,7 +5293,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
_set_error("Expected array initialization");
return ERR_PARSE_ERROR;
}
- if (is_const) {
+ if (node->is_const) {
_set_error("Expected initialization of constant");
return ERR_PARSE_ERROR;
}
@@ -5252,6 +5327,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
decl.initializer = n;
+ if (n->type == Node::TYPE_CONSTANT) {
+ ConstantNode *const_node = static_cast<ConstantNode *>(n);
+ if (const_node && const_node->values.size() == 1) {
+ var.value = const_node->values[0];
+ }
+ }
+
if (var.type == TYPE_STRUCT ? (var.struct_name != n->get_datatype_name()) : (var.type != n->get_datatype())) {
_set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (var.type == TYPE_STRUCT ? String(var.struct_name) : get_datatype_name(var.type)) + "'");
return ERR_PARSE_ERROR;
@@ -5420,18 +5502,29 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ControlFlowNode *flow = (ControlFlowNode *)switch_block->statements[i];
if (flow) {
if (flow->flow_op == FLOW_OP_CASE) {
- ConstantNode *n2 = static_cast<ConstantNode *>(flow->expressions[0]);
- if (!n2) {
- return ERR_PARSE_ERROR;
- }
- if (n2->values.empty()) {
- return ERR_PARSE_ERROR;
- }
- if (constants.has(n2->values[0].sint)) {
- _set_error("Duplicated case label: '" + itos(n2->values[0].sint) + "'");
- return ERR_PARSE_ERROR;
+ if (flow->expressions[0]->type == Node::TYPE_CONSTANT) {
+ ConstantNode *cn = static_cast<ConstantNode *>(flow->expressions[0]);
+ if (!cn || cn->values.is_empty()) {
+ return ERR_PARSE_ERROR;
+ }
+ if (constants.has(cn->values[0].sint)) {
+ _set_error("Duplicated case label: '" + itos(cn->values[0].sint) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ constants.insert(cn->values[0].sint);
+ } else if (flow->expressions[0]->type == Node::TYPE_VARIABLE) {
+ VariableNode *vn = static_cast<VariableNode *>(flow->expressions[0]);
+ if (!vn) {
+ return ERR_PARSE_ERROR;
+ }
+ ConstantNode::Value v;
+ _find_identifier(p_block, false, p_function_info, vn->name, nullptr, nullptr, nullptr, nullptr, nullptr, &v);
+ if (constants.has(v.sint)) {
+ _set_error("Duplicated case label: '" + itos(v.sint) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ constants.insert(v.sint);
}
- constants.insert(n2->values[0].sint);
} else if (flow->flow_op == FLOW_OP_DEFAULT) {
continue;
} else {
@@ -5467,12 +5560,38 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
}
+ Node *n = nullptr;
+
if (tk.type != TK_INT_CONSTANT) {
- _set_error("Expected integer constant");
- return ERR_PARSE_ERROR;
- }
+ bool correct_constant_expression = false;
+ DataType data_type;
- int constant = (int)tk.constant * sign;
+ if (tk.type == TK_IDENTIFIER) {
+ bool is_const;
+ _find_identifier(p_block, false, p_function_info, tk.text, &data_type, nullptr, &is_const);
+ if (is_const) {
+ if (data_type == TYPE_INT) {
+ correct_constant_expression = true;
+ }
+ }
+ }
+ if (!correct_constant_expression) {
+ _set_error("Expected integer constant");
+ return ERR_PARSE_ERROR;
+ }
+
+ VariableNode *vn = alloc_node<VariableNode>();
+ vn->name = tk.text;
+ n = vn;
+ } else {
+ ConstantNode::Value v;
+ v.sint = (int)tk.constant * sign;
+
+ ConstantNode *cn = alloc_node<ConstantNode>();
+ cn->values.push_back(v);
+ cn->datatype = TYPE_INT;
+ n = cn;
+ }
tk = _get_token();
@@ -5484,12 +5603,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_CASE;
- ConstantNode *n = alloc_node<ConstantNode>();
- ConstantNode::Value v;
- v.sint = constant;
- n->values.push_back(v);
- n->datatype = TYPE_INT;
-
BlockNode *case_block = alloc_node<BlockNode>();
case_block->block_type = BlockNode::BLOCK_TYPE_CASE;
case_block->parent_block = p_block;
@@ -6192,7 +6305,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
uniform2.texture_order = -1;
- uniform2.order = uniforms++;
+ if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
+ uniform2.order = uniforms++;
+ }
}
uniform2.type = type;
uniform2.scope = uniform_scope;
@@ -6260,7 +6375,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- if (tk.type != TK_REAL_CONSTANT && tk.type != TK_INT_CONSTANT) {
+ if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) {
_set_error("Expected integer constant");
return ERR_PARSE_ERROR;
}
@@ -6284,7 +6399,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- if (tk.type != TK_REAL_CONSTANT && tk.type != TK_INT_CONSTANT) {
+ if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) {
_set_error("Expected integer constant after ','");
return ERR_PARSE_ERROR;
}
@@ -6297,7 +6412,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_COMMA) {
tk = _get_token();
- if (tk.type != TK_REAL_CONSTANT && tk.type != TK_INT_CONSTANT) {
+ if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) {
_set_error("Expected integer constant after ','");
return ERR_PARSE_ERROR;
}
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 3a9f408dc0..27767378f9 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -46,7 +46,7 @@ public:
TK_IDENTIFIER,
TK_TRUE,
TK_FALSE,
- TK_REAL_CONSTANT,
+ TK_FLOAT_CONSTANT,
TK_INT_CONSTANT,
TK_TYPE_VOID,
TK_TYPE_BOOL,
@@ -414,6 +414,7 @@ public:
StringName name;
Node *index_expression = nullptr;
Node *call_expression = nullptr;
+ Node *assign_expression = nullptr;
bool is_const = false;
virtual DataType get_datatype() const { return datatype_cache; }
@@ -437,6 +438,7 @@ public:
DataType datatype = TYPE_VOID;
String struct_name;
bool is_const = false;
+ Node *size_expression = nullptr;
struct Declaration {
StringName name;
@@ -496,6 +498,7 @@ public:
int line; //for completion
int array_size;
bool is_const;
+ ConstantNode::Value value;
};
Map<StringName, Variable> variables;
@@ -519,13 +522,14 @@ public:
DataType basetype = TYPE_VOID;
bool basetype_const = false;
StringName base_struct_name;
- DataPrecision precision;
+ DataPrecision precision = PRECISION_DEFAULT;
DataType datatype = TYPE_VOID;
int array_size = 0;
StringName struct_name;
StringName name;
Node *owner = nullptr;
Node *index_expression = nullptr;
+ Node *assign_expression = nullptr;
bool has_swizzling_duplicates = false;
virtual DataType get_datatype() const { return datatype; }
@@ -774,6 +778,7 @@ private:
int tk_line;
StringName current_function;
+ bool last_const = false;
struct TkPos {
int char_idx;
@@ -819,7 +824,7 @@ private:
IDENTIFIER_CONSTANT,
};
- bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr);
+ bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr, ConstantNode::Value *r_constant_value = nullptr);
bool _is_operator_assign(Operator p_op) const;
bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr);
bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr);
@@ -861,6 +866,7 @@ private:
bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin);
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
+ Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size);
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
Node *_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index bd61f2a549..e99b8504bb 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -67,6 +67,12 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = constt(ShaderLanguage::TYPE_INT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_INDICES"] = ShaderLanguage::TYPE_UVEC4;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM0"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM1"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM2"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM3"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].can_discard = false;
//builtins
@@ -88,8 +94,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3);
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL_MAP"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL_MAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["UV2"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["COLOR"] = constt(ShaderLanguage::TYPE_VEC4);
@@ -236,8 +242,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["LIGHT_VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL_MAP"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL_MAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
@@ -341,7 +347,7 @@ ShaderTypes::ShaderTypes() {
emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("custom", ShaderLanguage::TYPE_VEC4));
emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("flags", ShaderLanguage::TYPE_UINT));
emit_vertex_func.return_type = ShaderLanguage::TYPE_BOOL; //whether it could emit
- shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_particle"] = emit_vertex_func;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_subparticle"] = emit_vertex_func;
}
shader_modes[RS::SHADER_PARTICLES].modes.push_back("collision_use_scale");
diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h
index 50f910babb..e59cef6b79 100644
--- a/servers/rendering/shader_types.h
+++ b/servers/rendering/shader_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */